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> ³°ÉôÆþÎϥ᥽¥Ã¥É @anchor foreign-input-method
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï #Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 #Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_flag = MDEBUG_INPUT;
168 static int fully_initialized;
170 /** Symbols to load an input method data. */
171 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
173 /** Symbols for actions. */
174 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
175 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
176 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
177 static MSymbol Mless_equal, Mgreater_equal;
178 static MSymbol Mcond;
179 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
181 /** Special action symbol. */
182 static MSymbol Mat_reload;
184 static MSymbol M_candidates;
186 static MSymbol Mcandidate_list, Mcandidate_index;
188 static MSymbol Minit, Mfini;
190 /** Symbols for variables. */
191 static MSymbol Mcandidates_group_size, Mcandidates_charset;
193 /** Symbols for key events. */
194 static MSymbol one_char_symbol[256];
196 static MSymbol M_key_alias;
198 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
200 static MSymbol M_gettext;
202 /** Structure to hold a map. */
206 /** List of actions to take when we reach the map. In a root map,
207 the actions are executed only when there is no more key. */
210 /** List of deeper maps. If NULL, this is a terminal map. */
213 /** List of actions to take when we leave the map successfully. In
214 a root map, the actions are executed only when none of submaps
215 handle the current key. */
216 MPlist *branch_actions;
219 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
224 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
231 /** Name of the state. */
234 /** Title of the state, or NULL. */
237 /** Key translation map of the state. Built by merging all maps of
242 #define CUSTOM_FILE "config.mic"
244 static MPlist *load_im_info_keys;
246 /* List of input method information. The format is:
247 (LANGUAGE NAME t:IM_INFO ... ... ...) */
248 static MPlist *im_info_list;
250 /* Database for user's customization file. */
251 static MDatabase *im_custom_mdb;
253 /* List of input method information loaded from im_custom_mdb. The
254 format is the same as im_info_list. */
255 static MPlist *im_custom_list;
257 /* List of input method information configured by
258 minput_config_command and minput_config_variable. The format is
259 the same as im_info_list. */
260 static MPlist *im_config_list;
262 /* Global input method information. It points into the element of
263 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
265 static MInputMethodInfo *global_info;
267 static int update_global_info (void);
268 static int update_custom_info (void);
269 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
276 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
277 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
278 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
280 char buf[6], buf2[32], buf3[2];
282 /* Maximum case: '\215', C-M-m, C-M-M, M-Return, C-A-m, C-A-M, A-Return
283 plus one for cyclic alias. */
286 M_key_alias = msymbol (" key-alias");
290 /* Aliases for 0x00-0x1F */
294 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
298 alias[j++] = msymbol (buf3);
299 alias[j++] = one_char_symbol[i] = msymbol (buf);
300 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
304 /* Ex: `Escape' == `C-[' */
305 alias[j++] = msymbol (key_names[i]);
307 if (buf[2] >= 'A' && buf[2] <= 'Z')
309 /* Ex: `C-a' == `C-A' */
311 alias[j++] = msymbol (buf);
315 /* Establish cyclic alias chain. */
318 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
321 /* Aliases for 0x20-0x7E */
323 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
325 one_char_symbol[i] = msymbol (buf + 2);
326 if (i >= 'A' && i <= 'Z')
328 /* Ex: `A' == `S-A' == `S-a'. */
329 alias[0] = alias[3] = one_char_symbol[i];
330 alias[1] = msymbol (buf);
332 alias[2] = msymbol (buf);
334 for (j = 0; j < 3; j++)
335 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
339 /* Aliases for 0x7F */
341 alias[0] = alias[3] = msymbol (buf3);
342 alias[1] = one_char_symbol[127] = msymbol ("Delete");
343 alias[2] = msymbol ("C-?");
344 for (j = 0; j < 3; j++)
345 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
347 /* Aliases for 0x80-0x9F */
349 /* buf[1] = '-'; -- already done */
353 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
357 alias[j++] = msymbol (buf3);
358 /* `C-M-a' == `C-A-a' */
360 alias[j++] = one_char_symbol[i] = msymbol (buf);
362 alias[j++] = msymbol (buf);
363 if (key_names[i - 128])
365 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
367 strcpy (buf2 + 2, key_names[i - 128]);
368 alias[j++] = msymbol (buf2);
370 alias[j++] = msymbol (buf2);
372 if (buf[4] >= 'A' && buf[4] <= 'Z')
374 /* Ex: `C-M-a' == `C-M-A'. */
377 alias[j++] = msymbol (buf);
379 alias[j++] = msymbol (buf);
383 /* Establish cyclic alias chain. */
386 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
389 /* Aliases for 0xA0-0xFF */
390 for (i = 160, buf[4] = ' '; i < 255; i++, buf[4]++)
394 alias[j++] = msymbol (buf3);
396 alias[j++] = one_char_symbol[i] = msymbol (buf + 2);
398 alias[j++] = msymbol (buf + 2);
401 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
405 alias[0] = alias[3] = msymbol (buf3);
406 alias[1] = one_char_symbol[255] = msymbol ("M-Delete");
407 alias[2] = msymbol ("A-Delete");
408 for (j = 0; j < 3; j++)
409 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
411 /* Aliases for keys that can't be mapped to one-char-symbol
413 /* buf is already set to "C-?-". */
414 for (i = ' '; i <= '~'; i++)
428 alias[0] = alias[2] = msymbol (buf);
430 alias[1] = msymbol (buf);
431 for (j = 0; j < 2; j++)
432 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
435 Minput_method = msymbol ("input-method");
436 Mtitle = msymbol ("title");
437 Mmacro = msymbol ("macro");
438 Mmodule = msymbol ("module");
439 Mmap = msymbol ("map");
440 Mstate = msymbol ("state");
441 Minclude = msymbol ("include");
442 Minsert = msymbol ("insert");
443 M_candidates = msymbol (" candidates");
444 Mdelete = msymbol ("delete");
445 Mmove = msymbol ("move");
446 Mmark = msymbol ("mark");
447 Mpushback = msymbol ("pushback");
448 Mpop = msymbol ("pop");
449 Mundo = msymbol ("undo");
450 Mcall = msymbol ("call");
451 Mshift = msymbol ("shift");
452 Mselect = msymbol ("select");
453 Mshow = msymbol ("show");
454 Mhide = msymbol ("hide");
455 Mcommit = msymbol ("commit");
456 Munhandle = msymbol ("unhandle");
457 Mset = msymbol ("set");
458 Madd = msymbol ("add");
459 Msub = msymbol ("sub");
460 Mmul = msymbol ("mul");
461 Mdiv = msymbol ("div");
462 Mequal = msymbol ("=");
463 Mless = msymbol ("<");
464 Mgreater = msymbol (">");
465 Mless_equal = msymbol ("<=");
466 Mgreater_equal = msymbol (">=");
467 Mcond = msymbol ("cond");
468 Mplus = msymbol ("+");
469 Mminus = msymbol ("-");
470 Mstar = msymbol ("*");
471 Mslash = msymbol ("/");
472 Mand = msymbol ("&");
474 Mnot = msymbol ("!");
476 Mat_reload = msymbol ("-reload");
478 Mcandidates_group_size = msymbol ("candidates-group-size");
479 Mcandidates_charset = msymbol ("candidates-charset");
481 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
482 Mcandidate_index = msymbol (" candidate-index");
484 Minit = msymbol ("init");
485 Mfini = msymbol ("fini");
487 Mdescription = msymbol ("description");
488 Mcommand = msymbol ("command");
489 Mvariable = msymbol ("variable");
490 Mglobal = msymbol ("global");
491 Mconfig = msymbol ("config");
492 M_gettext = msymbol ("_");
494 load_im_info_keys = mplist ();
495 mplist_add (load_im_info_keys, Mstate, Mnil);
496 mplist_push (load_im_info_keys, Mmap, Mnil);
498 im_info_list = mplist ();
499 im_config_list = im_custom_list = NULL;
500 im_custom_mdb = NULL;
501 update_custom_info ();
503 update_global_info ();
505 fully_initialized = 1;
508 #define MINPUT__INIT() \
510 if (! fully_initialized) \
511 fully_initialize (); \
516 marker_code (MSymbol sym, int surrounding)
522 name = MSYMBOL_NAME (sym);
523 return (name[0] != '@' ? -1
524 : (((name[1] >= '0' && name[1] <= '9')
525 || name[1] == '<' || name[1] == '>' || name[1] == '='
526 || name[1] == '[' || name[1] == ']'
528 && name[2] == '\0') ? name[1]
529 : (name[1] != '+' && name[1] != '-') ? -1
530 : (name[2] == '\0' || surrounding) ? name[1]
535 /* Return a plist containing an integer value of VAR. The plist must
539 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
541 MPlist *plist = mplist__assq (ic_info->vars, var);
545 plist = MPLIST_PLIST (plist);
546 return MPLIST_NEXT (plist);
550 mplist_push (ic_info->vars, Mplist, plist);
551 M17N_OBJECT_UNREF (plist);
552 plist = mplist_add (plist, Msymbol, var);
553 plist = mplist_add (plist, Minteger, (void *) 0);
558 get_surrounding_text (MInputContext *ic, int len)
562 mplist_push (ic->plist, Minteger, (void *) len);
563 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
564 && MPLIST_MTEXT_P (ic->plist))
565 mt = MPLIST_MTEXT (ic->plist);
566 mplist_pop (ic->plist);
571 delete_surrounding_text (MInputContext *ic, int pos)
573 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
575 mplist_push (ic->plist, Minteger, (void *) pos);
576 minput_callback (ic, Minput_delete_surrounding_text);
577 mplist_pop (ic->plist);
580 M17N_OBJECT_UNREF (ic_info->preceding_text);
581 ic_info->preceding_text = NULL;
585 M17N_OBJECT_UNREF (ic_info->following_text);
586 ic_info->following_text = NULL;
591 get_preceding_char (MInputContext *ic, int pos)
593 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
597 if (pos && ic_info->preceding_text)
599 len = mtext_nchars (ic_info->preceding_text);
601 return mtext_ref_char (ic_info->preceding_text, len - pos);
603 mt = get_surrounding_text (ic, - pos);
606 len = mtext_nchars (mt);
607 if (ic_info->preceding_text)
609 if (mtext_nchars (ic_info->preceding_text) < len)
611 M17N_OBJECT_UNREF (ic_info->preceding_text);
612 ic_info->preceding_text = mt;
615 M17N_OBJECT_UNREF (mt);
618 ic_info->preceding_text = mt;
621 return mtext_ref_char (ic_info->preceding_text, len - pos);
625 get_following_char (MInputContext *ic, int pos)
627 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
631 if (ic_info->following_text)
633 len = mtext_nchars (ic_info->following_text);
635 return mtext_ref_char (ic_info->following_text, pos);
637 mt = get_surrounding_text (ic, pos + 1);
640 len = mtext_nchars (mt);
641 if (ic_info->following_text)
643 if (mtext_nchars (ic_info->following_text) < len)
645 M17N_OBJECT_UNREF (ic_info->following_text);
646 ic_info->following_text = mt;
649 M17N_OBJECT_UNREF (mt);
652 ic_info->following_text = mt;
655 return mtext_ref_char (ic_info->following_text, pos);
659 surrounding_pos (MSymbol sym, int *pos)
665 name = MSYMBOL_NAME (sym);
667 && (name[1] == '-' ? (name[2] >= '1' && name[2] <= '9')
668 : name[1] == '+' ? (name[2] >= '0' && name[2] <= '9')
671 *pos = name[1] == '-' ? - atoi (name + 2) : atoi (name + 2);
678 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
680 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
682 MText *preedit = ic->preedit;
683 int len = mtext_nchars (preedit);
685 if (MPLIST_INTEGER_P (arg))
686 return MPLIST_INTEGER (arg);
688 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
691 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
693 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
696 return ic_info->key_head;
697 if ((code == '-' || code == '+'))
699 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
703 pos = atoi (name + 1);
704 if (pos == 0 && code == '-')
705 return get_preceding_char (ic, 0);
706 pos = ic->cursor_pos + pos;
709 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
710 return mtext_ref_char (ic->produced,
711 mtext_len (ic->produced) + pos);
712 return get_preceding_char (ic, - pos);
715 return get_following_char (ic, pos - len);
718 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
720 else if (code >= '0' && code <= '9')
722 else if (code == '=')
723 pos = ic->cursor_pos;
724 else if (code == '[')
725 pos = ic->cursor_pos - 1;
726 else if (code == ']')
727 pos = ic->cursor_pos + 1;
728 else if (code == '<')
730 else if (code == '>')
732 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
736 parse_expression (MPlist *plist)
740 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
742 if (! MPLIST_PLIST_P (plist))
744 plist = MPLIST_PLIST (plist);
745 op = MPLIST_SYMBOL (plist);
746 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
747 && op != Mand && op != Mor && op != Mnot
748 && op != Mless && op != Mgreater && op != Mequal
749 && op != Mless_equal && op != Mgreater_equal)
750 MERROR (MERROR_IM, -1);
751 MPLIST_DO (plist, MPLIST_NEXT (plist))
752 if (parse_expression (plist) < 0)
758 resolve_expression (MInputContext *ic, MPlist *plist)
763 if (MPLIST_INTEGER_P (plist))
764 return MPLIST_INTEGER (plist);
765 if (MPLIST_SYMBOL_P (plist))
766 return integer_value (ic, plist, 1);
767 if (! MPLIST_PLIST_P (plist))
769 plist = MPLIST_PLIST (plist);
770 if (! MPLIST_SYMBOL_P (plist))
772 op = MPLIST_SYMBOL (plist);
773 plist = MPLIST_NEXT (plist);
774 val = resolve_expression (ic, plist);
776 MPLIST_DO (plist, MPLIST_NEXT (plist))
777 val += resolve_expression (ic, plist);
778 else if (op == Mminus)
779 MPLIST_DO (plist, MPLIST_NEXT (plist))
780 val -= resolve_expression (ic, plist);
781 else if (op == Mstar)
782 MPLIST_DO (plist, MPLIST_NEXT (plist))
783 val *= resolve_expression (ic, plist);
784 else if (op == Mslash)
785 MPLIST_DO (plist, MPLIST_NEXT (plist))
786 val /= resolve_expression (ic, plist);
788 MPLIST_DO (plist, MPLIST_NEXT (plist))
789 val &= resolve_expression (ic, plist);
791 MPLIST_DO (plist, MPLIST_NEXT (plist))
792 val |= resolve_expression (ic, plist);
795 else if (op == Mless)
796 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
797 else if (op == Mequal)
798 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
799 else if (op == Mgreater)
800 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
801 else if (op == Mless_equal)
802 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
803 else if (op == Mgreater_equal)
804 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
808 /* Parse PLIST as an action list. PLIST should have this form:
809 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
810 Return 0 if successfully parsed, otherwise return -1. */
813 parse_action_list (MPlist *plist, MPlist *macros)
815 MPLIST_DO (plist, plist)
817 if (MPLIST_MTEXT_P (plist))
819 /* This is a short form of (insert MTEXT). */
820 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
821 MERROR (MERROR_IM, -1); */
823 else if (MPLIST_PLIST_P (plist)
824 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
825 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
829 /* This is a short form of (insert (GROUPS *)). */
830 MPLIST_DO (pl, MPLIST_PLIST (plist))
832 if (MPLIST_PLIST_P (pl))
836 MPLIST_DO (elt, MPLIST_PLIST (pl))
837 if (! MPLIST_MTEXT_P (elt)
838 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
839 MERROR (MERROR_IM, -1);
843 if (! MPLIST_MTEXT_P (pl)
844 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
845 MERROR (MERROR_IM, -1);
849 else if (MPLIST_INTEGER_P (plist))
851 int c = MPLIST_INTEGER (plist);
853 if (c < 0 || c > MCHAR_MAX)
854 MERROR (MERROR_IM, -1);
856 else if (MPLIST_PLIST_P (plist)
857 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
859 MPlist *pl = MPLIST_PLIST (plist);
860 MSymbol action_name = MPLIST_SYMBOL (pl);
862 pl = MPLIST_NEXT (pl);
864 if (action_name == M_candidates)
866 /* This is an already regularised action. */
869 if (action_name == Minsert)
871 if (MPLIST_MTEXT_P (pl))
873 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
874 MERROR (MERROR_IM, -1);
876 else if (MPLIST_INTEGER_P (pl))
878 int c = MPLIST_INTEGER (pl);
880 if (c < 0 || c > MCHAR_MAX)
881 MERROR (MERROR_IM, -1);
883 else if (MPLIST_PLIST_P (pl))
885 MPLIST_DO (pl, MPLIST_PLIST (pl))
887 if (MPLIST_PLIST_P (pl))
891 MPLIST_DO (elt, MPLIST_PLIST (pl))
892 if (! MPLIST_MTEXT_P (elt)
893 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
894 MERROR (MERROR_IM, -1);
898 if (! MPLIST_MTEXT_P (pl)
899 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
900 MERROR (MERROR_IM, -1);
904 else if (! MPLIST_SYMBOL_P (pl))
905 MERROR (MERROR_IM, -1);
907 else if (action_name == Mselect
908 || action_name == Mdelete
909 || action_name == Mmove)
911 if (parse_expression (pl) < 0)
914 else if (action_name == Mmark
915 || action_name == Mcall
916 || action_name == Mshift)
918 if (! MPLIST_SYMBOL_P (pl))
919 MERROR (MERROR_IM, -1);
921 else if (action_name == Mundo)
923 if (! MPLIST_TAIL_P (pl))
925 if (! MPLIST_SYMBOL_P (pl)
926 && ! MPLIST_INTEGER_P (pl))
927 MERROR (MERROR_IM, -1);
930 else if (action_name == Mpushback)
932 if (MPLIST_MTEXT_P (pl))
934 MText *mt = MPLIST_MTEXT (pl);
936 if (mtext_nchars (mt) != mtext_nbytes (mt))
937 MERROR (MERROR_IM, -1);
939 else if (MPLIST_PLIST_P (pl))
943 MPLIST_DO (p, MPLIST_PLIST (pl))
944 if (! MPLIST_SYMBOL_P (p))
945 MERROR (MERROR_IM, -1);
947 else if (! MPLIST_INTEGER_P (pl))
948 MERROR (MERROR_IM, -1);
950 else if (action_name == Mset || action_name == Madd
951 || action_name == Msub || action_name == Mmul
952 || action_name == Mdiv)
954 if (! MPLIST_SYMBOL_P (pl))
955 MERROR (MERROR_IM, -1);
956 if (parse_expression (MPLIST_NEXT (pl)) < 0)
959 else if (action_name == Mequal || action_name == Mless
960 || action_name == Mgreater || action_name == Mless_equal
961 || action_name == Mgreater_equal)
963 if (parse_expression (pl) < 0
964 || parse_expression (MPLIST_NEXT (pl)) < 0)
966 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
967 if (! MPLIST_PLIST_P (pl))
968 MERROR (MERROR_IM, -1);
969 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
970 MERROR (MERROR_IM, -1);
971 pl = MPLIST_NEXT (pl);
972 if (MPLIST_PLIST_P (pl)
973 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
974 MERROR (MERROR_IM, -1);
976 else if (action_name == Mshow || action_name == Mhide
977 || action_name == Mcommit || action_name == Munhandle
978 || action_name == Mpop)
980 else if (action_name == Mcond)
983 if (! MPLIST_PLIST_P (pl))
984 MERROR (MERROR_IM, -1);
986 else if (! macros || ! mplist_get (macros, action_name))
987 MERROR (MERROR_IM, -1);
989 else if (! MPLIST_SYMBOL_P (plist))
990 MERROR (MERROR_IM, -1);
997 resolve_command (MPlist *cmds, MSymbol command)
1001 if (! cmds || ! (plist = mplist__assq (cmds, command)))
1003 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
1004 plist = MPLIST_NEXT (plist);
1005 plist = MPLIST_NEXT (plist);
1006 plist = MPLIST_NEXT (plist);
1010 /* Load a translation into MAP from PLIST.
1011 PLIST has this form:
1012 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
1015 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
1016 MPlist *branch_actions, MPlist *macros)
1021 if (MPLIST_MTEXT_P (keylist))
1023 MText *mt = MPLIST_MTEXT (keylist);
1025 len = mtext_nchars (mt);
1026 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
1028 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
1029 for (i = 0; i < len; i++)
1030 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
1036 if (MFAILP (MPLIST_PLIST_P (keylist)))
1038 elt = MPLIST_PLIST (keylist);
1039 len = MPLIST_LENGTH (elt);
1040 if (MFAILP (len > 0))
1042 keyseq = (MSymbol *) alloca (sizeof (int) * len);
1043 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1045 if (MPLIST_INTEGER_P (elt))
1047 int c = MPLIST_INTEGER (elt);
1049 if (MFAILP (c >= 0 && c < 0x100))
1051 keyseq[i] = one_char_symbol[c];
1055 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1057 keyseq[i] = MPLIST_SYMBOL (elt);
1062 for (i = 0; i < len; i++)
1064 MIMMap *deeper = NULL;
1067 deeper = mplist_get (map->submaps, keyseq[i]);
1069 map->submaps = mplist ();
1072 /* Fixme: It is better to make all deeper maps at once. */
1073 MSTRUCT_CALLOC (deeper, MERROR_IM);
1074 mplist_put (map->submaps, keyseq[i], deeper);
1079 /* We reach a terminal map. */
1080 if (map->map_actions
1081 || map->branch_actions)
1082 /* This map is already defined. We avoid overriding it. */
1085 if (! MPLIST_TAIL_P (map_actions))
1087 if (parse_action_list (map_actions, macros) < 0)
1088 MERROR (MERROR_IM, -1);
1089 map->map_actions = map_actions;
1093 map->branch_actions = branch_actions;
1094 M17N_OBJECT_REF (branch_actions);
1100 /* Load a branch from PLIST into MAP. PLIST has this form:
1101 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1104 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1107 MPlist *branch_actions;
1109 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1111 map_name = MPLIST_SYMBOL (plist);
1112 plist = MPLIST_NEXT (plist);
1113 if (MPLIST_TAIL_P (plist))
1114 branch_actions = NULL;
1115 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1118 branch_actions = plist;
1119 if (map_name == Mnil)
1121 map->branch_actions = branch_actions;
1123 M17N_OBJECT_REF (branch_actions);
1125 else if (map_name == Mt)
1127 map->map_actions = branch_actions;
1129 M17N_OBJECT_REF (branch_actions);
1131 else if (im_info->maps)
1133 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1134 if (! plist && im_info->configured_vars)
1136 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1138 if (p && MPLIST_PLIST_P (p))
1140 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1141 if (MPLIST_SYMBOL_P (p))
1142 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1147 MPLIST_DO (plist, plist)
1149 MPlist *keylist, *map_actions;
1151 if (! MPLIST_PLIST_P (plist))
1152 MERROR (MERROR_IM, -1);
1153 keylist = MPLIST_PLIST (plist);
1154 map_actions = MPLIST_NEXT (keylist);
1155 if (MPLIST_SYMBOL_P (keylist))
1157 MSymbol command = MPLIST_SYMBOL (keylist);
1160 if (MFAILP (command != Mat_reload))
1162 pl = resolve_command (im_info->configured_cmds, command);
1166 load_translation (map, pl, map_actions, branch_actions,
1170 load_translation (map, keylist, map_actions, branch_actions,
1179 /* Load a macro from PLIST into IM_INFO->macros.
1180 PLIST has this form:
1181 PLIST ::= ( MACRO-NAME ACTION * )
1182 IM_INFO->macros is a plist of macro names vs action list. */
1185 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1190 if (! MPLIST_SYMBOL_P (plist))
1191 MERROR (MERROR_IM, -1);
1192 name = MPLIST_SYMBOL (plist);
1193 plist = MPLIST_NEXT (plist);
1194 if (MFAILP (! MPLIST_TAIL_P (plist)))
1195 MERROR (MERROR_IM, -1);
1196 pl = mplist_get (im_info->macros, name);
1197 M17N_OBJECT_UNREF (pl);
1198 mplist_put (im_info->macros, name, plist);
1199 M17N_OBJECT_REF (plist);
1203 /* Load an external module from PLIST into IM_INFO->externals.
1204 PLIST has this form:
1205 PLIST ::= ( MODULE-NAME FUNCTION * )
1206 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1209 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1214 MIMExternalModule *external;
1218 if (MPLIST_MTEXT_P (plist))
1219 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1220 else if (MPLIST_SYMBOL_P (plist))
1221 module = MPLIST_SYMBOL (plist);
1222 module_file = alloca (strlen (MSYMBOL_NAME (module))
1223 + strlen (DLOPEN_SHLIB_EXT) + 1);
1224 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1226 handle = dlopen (module_file, RTLD_NOW);
1227 if (MFAILP (handle))
1229 fprintf (stderr, "%s\n", dlerror ());
1232 func_list = mplist ();
1233 MPLIST_DO (plist, MPLIST_NEXT (plist))
1235 if (! MPLIST_SYMBOL_P (plist))
1236 MERROR_GOTO (MERROR_IM, err_label);
1237 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1240 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1243 MSTRUCT_MALLOC (external, MERROR_IM);
1244 external->handle = handle;
1245 external->func_list = func_list;
1246 mplist_add (im_info->externals, module, external);
1251 M17N_OBJECT_UNREF (func_list);
1256 free_map (MIMMap *map, int top)
1261 M17N_OBJECT_UNREF (map->map_actions);
1264 MPLIST_DO (plist, map->submaps)
1265 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1266 M17N_OBJECT_UNREF (map->submaps);
1268 M17N_OBJECT_UNREF (map->branch_actions);
1273 free_state (void *object)
1275 MIMState *state = object;
1277 M17N_OBJECT_UNREF (state->title);
1279 free_map (state->map, 1);
1283 /** Load a state from PLIST into a newly allocated state object.
1284 PLIST has this form:
1285 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1286 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1287 Return the state object. */
1290 load_state (MInputMethodInfo *im_info, MPlist *plist)
1294 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1296 M17N_OBJECT (state, free_state, MERROR_IM);
1297 state->name = MPLIST_SYMBOL (plist);
1298 plist = MPLIST_NEXT (plist);
1299 if (MPLIST_MTEXT_P (plist))
1301 state->title = MPLIST_MTEXT (plist);
1302 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1303 Mlanguage, im_info->language);
1304 M17N_OBJECT_REF (state->title);
1305 plist = MPLIST_NEXT (plist);
1307 MSTRUCT_CALLOC (state->map, MERROR_IM);
1308 MPLIST_DO (plist, plist)
1310 if (MFAILP (MPLIST_PLIST_P (plist)))
1312 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1317 /* Return a newly created IM_INFO for an input method specified by
1318 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1320 static MInputMethodInfo *
1321 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1324 MInputMethodInfo *im_info;
1327 if (name == Mnil && extra == Mnil)
1328 language = Mt, extra = Mglobal;
1329 MSTRUCT_CALLOC (im_info, MERROR_IM);
1331 im_info->language = language;
1332 im_info->name = name;
1333 im_info->extra = extra;
1336 mplist_add (plist, Mplist, elt);
1337 M17N_OBJECT_UNREF (elt);
1338 elt = mplist_add (elt, Msymbol, language);
1339 elt = mplist_add (elt, Msymbol, name);
1340 elt = mplist_add (elt, Msymbol, extra);
1341 mplist_add (elt, Mt, im_info);
1347 fini_im_info (MInputMethodInfo *im_info)
1351 M17N_OBJECT_UNREF (im_info->cmds);
1352 M17N_OBJECT_UNREF (im_info->configured_cmds);
1353 M17N_OBJECT_UNREF (im_info->bc_cmds);
1354 M17N_OBJECT_UNREF (im_info->vars);
1355 M17N_OBJECT_UNREF (im_info->configured_vars);
1356 M17N_OBJECT_UNREF (im_info->bc_vars);
1357 M17N_OBJECT_UNREF (im_info->description);
1358 M17N_OBJECT_UNREF (im_info->title);
1359 if (im_info->states)
1361 MPLIST_DO (plist, im_info->states)
1363 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1365 M17N_OBJECT_UNREF (state);
1367 M17N_OBJECT_UNREF (im_info->states);
1370 if (im_info->macros)
1372 MPLIST_DO (plist, im_info->macros)
1373 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1374 M17N_OBJECT_UNREF (im_info->macros);
1377 if (im_info->externals)
1379 MPLIST_DO (plist, im_info->externals)
1381 MIMExternalModule *external = MPLIST_VAL (plist);
1383 dlclose (external->handle);
1384 M17N_OBJECT_UNREF (external->func_list);
1386 MPLIST_KEY (plist) = Mt;
1388 M17N_OBJECT_UNREF (im_info->externals);
1392 MPLIST_DO (plist, im_info->maps)
1394 MPlist *p = MPLIST_PLIST (plist);
1396 M17N_OBJECT_UNREF (p);
1398 M17N_OBJECT_UNREF (im_info->maps);
1405 free_im_info (MInputMethodInfo *im_info)
1407 fini_im_info (im_info);
1412 free_im_list (MPlist *plist)
1416 MPLIST_DO (pl, plist)
1418 MInputMethodInfo *im_info;
1420 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1421 im_info = MPLIST_VAL (elt);
1422 free_im_info (im_info);
1424 M17N_OBJECT_UNREF (plist);
1427 static MInputMethodInfo *
1428 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1430 if (name == Mnil && extra == Mnil)
1431 language = Mt, extra = Mglobal;
1432 while ((plist = mplist__assq (plist, language)))
1434 MPlist *elt = MPLIST_PLIST (plist);
1436 plist = MPLIST_NEXT (plist);
1437 elt = MPLIST_NEXT (elt);
1438 if (MPLIST_SYMBOL (elt) != name)
1440 elt = MPLIST_NEXT (elt);
1441 if (MPLIST_SYMBOL (elt) != extra)
1443 elt = MPLIST_NEXT (elt);
1444 return MPLIST_VAL (elt);
1449 static void load_im_info (MPlist *, MInputMethodInfo *);
1451 #define get_custom_info(im_info) \
1453 ? lookup_im_info (im_custom_list, (im_info)->language, \
1454 (im_info)->name, (im_info)->extra) \
1457 #define get_config_info(im_info) \
1459 ? lookup_im_info (im_config_list, (im_info)->language, \
1460 (im_info)->name, (im_info)->extra) \
1464 update_custom_info (void)
1470 if (mdatabase__check (im_custom_mdb) > 0)
1475 MDatabaseInfo *custom_dir_info;
1476 char custom_path[PATH_MAX + 1];
1478 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1479 if (! custom_dir_info->filename
1480 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1482 strcpy (custom_path, custom_dir_info->filename);
1483 strcat (custom_path, CUSTOM_FILE);
1484 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1490 free_im_list (im_custom_list);
1491 im_custom_list = NULL;
1493 plist = mdatabase_load (im_custom_mdb);
1496 im_custom_list = mplist ();
1498 MPLIST_DO (pl, plist)
1500 MSymbol language, name, extra;
1501 MInputMethodInfo *im_info;
1502 MPlist *im_data, *p;
1504 if (! MPLIST_PLIST_P (pl))
1506 p = MPLIST_PLIST (pl);
1507 im_data = MPLIST_NEXT (p);
1508 if (! MPLIST_PLIST_P (p))
1510 p = MPLIST_PLIST (p);
1511 if (! MPLIST_SYMBOL_P (p)
1512 || MPLIST_SYMBOL (p) != Minput_method)
1514 p = MPLIST_NEXT (p);
1515 if (! MPLIST_SYMBOL_P (p))
1517 language = MPLIST_SYMBOL (p);
1518 p = MPLIST_NEXT (p);
1519 if (! MPLIST_SYMBOL_P (p))
1521 name = MPLIST_SYMBOL (p);
1522 p = MPLIST_NEXT (p);
1523 if (MPLIST_TAIL_P (p))
1525 else if (MPLIST_SYMBOL_P (p))
1526 extra = MPLIST_SYMBOL (p);
1527 if (language == Mnil || (name == Mnil && extra == Mnil))
1529 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1530 load_im_info (im_data, im_info);
1532 M17N_OBJECT_UNREF (plist);
1537 update_global_info (void)
1543 int ret = mdatabase__check (global_info->mdb);
1547 fini_im_info (global_info);
1551 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1555 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1557 if (! global_info->mdb
1558 || ! (plist = mdatabase_load (global_info->mdb)))
1561 load_im_info (plist, global_info);
1562 M17N_OBJECT_UNREF (plist);
1567 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1568 and EXTRA. KEY, if not Mnil, tells which kind of information about
1569 the input method is necessary, and the returned IM_INFO may contain
1570 only that information. */
1572 static MInputMethodInfo *
1573 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1576 MInputMethodInfo *im_info;
1579 if (name == Mnil && extra == Mnil)
1580 language = Mt, extra = Mglobal;
1581 im_info = lookup_im_info (im_info_list, language, name, extra);
1584 if (key == Mnil ? im_info->states != NULL
1585 : key == Mcommand ? im_info->cmds != NULL
1586 : key == Mvariable ? im_info->vars != NULL
1587 : key == Mtitle ? im_info->title != NULL
1588 : key == Mdescription ? im_info->description != NULL
1590 /* IM_INFO already contains required information. */
1592 /* We have not yet loaded required information. */
1596 mdb = mdatabase_find (Minput_method, language, name, extra);
1599 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1604 plist = mdatabase_load (im_info->mdb);
1608 mplist_push (load_im_info_keys, key, Mt);
1609 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1610 mplist_pop (load_im_info_keys);
1614 MERROR (MERROR_IM, im_info);
1615 update_global_info ();
1616 load_im_info (plist, im_info);
1617 M17N_OBJECT_UNREF (plist);
1620 if (! im_info->cmds)
1621 im_info->cmds = mplist ();
1622 if (! im_info->vars)
1623 im_info->vars = mplist ();
1624 if (! im_info->states)
1625 im_info->states = mplist ();
1627 if (! im_info->title
1628 && (key == Mnil || key == Mtitle))
1629 im_info->title = (name == Mnil ? mtext ()
1630 : mtext_from_data (MSYMBOL_NAME (name),
1631 MSYMBOL_NAMELEN (name),
1632 MTEXT_FORMAT_US_ASCII));
1636 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1637 If updated, but got unloadable, return -1. Otherwise, update
1638 contents of IM_INFO from the new database, and return 1. */
1641 reload_im_info (MInputMethodInfo *im_info)
1646 update_custom_info ();
1647 update_global_info ();
1648 check = mdatabase__check (im_info->mdb);
1651 plist = mdatabase_load (im_info->mdb);
1654 fini_im_info (im_info);
1655 load_im_info (plist, im_info);
1656 M17N_OBJECT_UNREF (plist);
1657 if (! im_info->cmds)
1658 im_info->cmds = mplist ();
1659 if (! im_info->vars)
1660 im_info->vars = mplist ();
1661 if (! im_info->title)
1663 MSymbol name = im_info->name;
1665 im_info->title = (name == Mnil ? mtext ()
1666 : mtext_from_data (MSYMBOL_NAME (name),
1667 MSYMBOL_NAMELEN (name),
1668 MTEXT_FORMAT_US_ASCII));
1673 static MInputMethodInfo *
1674 get_im_info_by_tags (MPlist *plist)
1679 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1680 i++, plist = MPLIST_NEXT (plist))
1681 tag[i] = MPLIST_SYMBOL (plist);
1686 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1691 check_description (MPlist *plist)
1695 if (MPLIST_MTEXT_P (plist))
1697 if (MPLIST_PLIST_P (plist))
1699 MPlist *pl = MPLIST_PLIST (plist);
1701 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1703 pl =MPLIST_NEXT (pl);
1704 if (MFAILP (MPLIST_MTEXT_P (pl)))
1706 mt = MPLIST_MTEXT (pl);
1707 M17N_OBJECT_REF (mt);
1710 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1712 if (translated == (char *) MTEXT_DATA (mt))
1713 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1714 if (translated != (char *) MTEXT_DATA (mt))
1716 M17N_OBJECT_UNREF (mt);
1717 mt = mtext__from_data (translated, strlen (translated),
1718 MTEXT_FORMAT_UTF_8, 1);
1722 mplist_set (plist, Mtext, mt);
1723 M17N_OBJECT_UNREF (mt);
1726 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1732 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1736 check_command_keyseq (MPlist *keyseq)
1738 if (MPLIST_PLIST_P (keyseq))
1740 MPlist *p = MPLIST_PLIST (keyseq);
1743 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1747 if (MPLIST_MTEXT_P (keyseq))
1749 MText *mt = MPLIST_MTEXT (keyseq);
1752 for (i = 0; i < mtext_nchars (mt); i++)
1753 if (mtext_ref_char (mt, i) >= 256)
1760 /* Load command defitions from PLIST into IM_INFO->cmds.
1762 PLIST is well-formed and has this form;
1763 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1764 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1765 M-text or a plist of symbols.
1767 The returned list has the same form, but for each element...
1769 (1) If DESCRIPTION and the rest are omitted, the element is not
1770 stored in the returned list.
1772 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1773 description in global_info->cmds (if any). */
1776 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1780 im_info->cmds = tail = mplist ();
1782 MPLIST_DO (plist, MPLIST_NEXT (plist))
1784 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1787 if (MFAILP (MPLIST_PLIST_P (plist)))
1789 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1790 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1792 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1793 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1795 if (MFAILP (im_info != global_info))
1796 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1800 if (! check_description (p))
1801 mplist_set (p, Msymbol, Mnil);
1802 p = MPLIST_NEXT (p);
1803 while (! MPLIST_TAIL_P (p))
1805 if (MFAILP (check_command_keyseq (p)))
1806 mplist__pop_unref (p);
1808 p = MPLIST_NEXT (p);
1811 tail = mplist_add (tail, Mplist, pl);
1816 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1817 MPlist *config_cmds)
1819 MPlist *global = NULL, *custom = NULL, *config = NULL;
1820 MSymbol name = MPLIST_SYMBOL (plist);
1822 MPlist *description, *keyseq;
1824 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1825 global = MPLIST_NEXT (MPLIST_PLIST (global));
1827 plist = MPLIST_NEXT (plist);
1828 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1830 description = plist;
1831 plist = MPLIST_NEXT (plist);
1835 description = global;
1836 if (! MPLIST_TAIL_P (plist))
1837 plist = MPLIST_NEXT (plist);
1839 if (MPLIST_TAIL_P (plist) && global)
1841 keyseq = MPLIST_NEXT (global);
1842 status = Minherited;
1850 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1852 status = Mconfigured;
1853 config = MPLIST_NEXT (MPLIST_PLIST (config));
1854 if (! MPLIST_TAIL_P (config))
1857 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1859 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1861 if (MPLIST_TAIL_P (this_keyseq))
1862 mplist__pop_unref (custom);
1865 status = Mcustomized;
1866 keyseq = this_keyseq;
1871 mplist_add (plist, Msymbol, name);
1873 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1875 mplist_add (plist, Msymbol, Mnil);
1876 mplist_add (plist, Msymbol, status);
1877 mplist__conc (plist, keyseq);
1882 config_all_commands (MInputMethodInfo *im_info)
1884 MPlist *global_cmds, *custom_cmds, *config_cmds;
1885 MInputMethodInfo *temp;
1886 MPlist *tail, *plist;
1888 M17N_OBJECT_UNREF (im_info->configured_cmds);
1890 if (MPLIST_TAIL_P (im_info->cmds)
1894 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1895 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1896 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1898 im_info->configured_cmds = tail = mplist ();
1899 MPLIST_DO (plist, im_info->cmds)
1901 MPlist *pl = config_command (MPLIST_PLIST (plist),
1902 global_cmds, custom_cmds, config_cmds);
1905 tail = mplist_add (tail, Mplist, pl);
1906 M17N_OBJECT_UNREF (pl);
1911 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1912 valid, return 0 if not. */
1915 check_variable_value (MPlist *val, MPlist *global)
1917 MSymbol type = MPLIST_KEY (val);
1918 MPlist *valids = MPLIST_NEXT (val);
1920 if (type != Minteger && type != Mtext && type != Msymbol)
1924 if (MPLIST_KEY (global) != Mt
1925 && MPLIST_KEY (global) != MPLIST_KEY (val))
1927 if (MPLIST_TAIL_P (valids))
1928 valids = MPLIST_NEXT (global);
1930 if (MPLIST_TAIL_P (valids))
1933 if (type == Minteger)
1935 int n = MPLIST_INTEGER (val);
1937 MPLIST_DO (valids, valids)
1939 if (MPLIST_INTEGER_P (valids))
1941 if (n == MPLIST_INTEGER (valids))
1944 else if (MPLIST_PLIST_P (valids))
1946 MPlist *p = MPLIST_PLIST (valids);
1947 int min_bound, max_bound;
1949 if (! MPLIST_INTEGER_P (p))
1950 MERROR (MERROR_IM, 0);
1951 min_bound = MPLIST_INTEGER (p);
1952 p = MPLIST_NEXT (p);
1953 if (! MPLIST_INTEGER_P (p))
1954 MERROR (MERROR_IM, 0);
1955 max_bound = MPLIST_INTEGER (p);
1956 if (n >= min_bound && n <= max_bound)
1961 else if (type == Msymbol)
1963 MSymbol sym = MPLIST_SYMBOL (val);
1965 MPLIST_DO (valids, valids)
1967 if (! MPLIST_SYMBOL_P (valids))
1968 MERROR (MERROR_IM, 0);
1969 if (sym == MPLIST_SYMBOL (valids))
1975 MText *mt = MPLIST_MTEXT (val);
1977 MPLIST_DO (valids, valids)
1979 if (! MPLIST_MTEXT_P (valids))
1980 MERROR (MERROR_IM, 0);
1981 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1986 return (! MPLIST_TAIL_P (valids));
1989 /* Load variable defitions from PLIST into IM_INFO->vars.
1991 PLIST is well-formed and has this form;
1992 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1994 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1996 The returned list has the same form, but for each element...
1998 (1) If DESCRIPTION and the rest are omitted, the element is not
1999 stored in the returned list.
2001 (2) If DESCRIPTION is nil, it is complemented by the corresponding
2002 description in global_info->vars (if any). */
2005 load_variables (MInputMethodInfo *im_info, MPlist *plist)
2007 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
2008 ? global_info->vars : NULL);
2011 im_info->vars = tail = mplist ();
2012 MPLIST_DO (plist, MPLIST_NEXT (plist))
2016 if (MFAILP (MPLIST_PLIST_P (plist)))
2018 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
2019 if (MFAILP (MPLIST_SYMBOL_P (pl)))
2021 if (im_info == global_info)
2023 /* Loading a global variable. */
2024 p = MPLIST_NEXT (pl);
2025 if (MPLIST_TAIL_P (p))
2026 mplist_add (p, Msymbol, Mnil);
2029 if (! check_description (p))
2030 mplist_set (p, Msymbol, Mnil);
2031 p = MPLIST_NEXT (p);
2032 if (MFAILP (! MPLIST_TAIL_P (p)
2033 && check_variable_value (p, NULL)))
2034 mplist_set (p, Mt, NULL);
2037 else if (im_info->mdb)
2039 /* Loading a local variable. */
2040 MSymbol name = MPLIST_SYMBOL (pl);
2041 MPlist *global = NULL;
2044 && (p = mplist__assq (global_vars, name)))
2046 /* P ::= ((NAME DESC ...) ...) */
2047 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2048 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2049 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2052 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2053 if (! MPLIST_TAIL_P (p))
2055 if (! check_description (p))
2056 mplist_set (p, Msymbol, Mnil);
2057 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2058 if (MFAILP (! MPLIST_TAIL_P (p)))
2059 mplist_set (p, Mt, NULL);
2062 MPlist *valid_values = MPLIST_NEXT (p);
2064 if (! MPLIST_TAIL_P (valid_values)
2065 ? MFAILP (check_variable_value (p, NULL))
2066 : global && MFAILP (check_variable_value (p, global)))
2067 mplist_set (p, Mt, NULL);
2073 /* Loading a variable customization. */
2074 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2075 if (MFAILP (! MPLIST_TAIL_P (p)))
2077 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2078 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2079 || MPLIST_MTEXT_P (p)))
2082 tail = mplist_add (tail, Mplist, pl);
2087 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2088 MPlist *config_vars)
2090 MPlist *global = NULL, *custom = NULL, *config = NULL;
2091 MSymbol name = MPLIST_SYMBOL (plist);
2093 MPlist *description = NULL, *value, *valids;
2097 global = mplist__assq (global_vars, name);
2099 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2102 plist = MPLIST_NEXT (plist);
2103 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2104 description = plist;
2106 description = global;
2108 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2110 if (MPLIST_TAIL_P (plist))
2112 /* Inherit from global (if any). */
2116 if (MPLIST_KEY (value) == Mt)
2118 valids = MPLIST_NEXT (global);
2119 status = Minherited;
2131 value = plist = MPLIST_NEXT (plist);
2132 valids = MPLIST_NEXT (value);
2133 if (MPLIST_KEY (value) == Mt)
2135 if (! MPLIST_TAIL_P (valids))
2138 valids = MPLIST_NEXT (global);
2142 if (config_vars && (config = mplist__assq (config_vars, name)))
2144 status = Mconfigured;
2145 config = MPLIST_NEXT (MPLIST_PLIST (config));
2146 if (! MPLIST_TAIL_P (config))
2149 if (MFAILP (check_variable_value (value, global ? global : plist)))
2153 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2155 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2157 if (MPLIST_TAIL_P (this_value))
2158 mplist__pop_unref (custom);
2162 if (MFAILP (check_variable_value (value, global ? global : plist)))
2164 status = Mcustomized;
2169 mplist_add (plist, Msymbol, name);
2171 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2173 mplist_add (plist, Msymbol, Mnil);
2174 mplist_add (plist, Msymbol, status);
2176 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2178 mplist_add (plist, Mt, NULL);
2179 if (valids && ! MPLIST_TAIL_P (valids))
2180 mplist__conc (plist, valids);
2184 /* Return a configured variable definition list based on
2185 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2186 get it from global_info->vars. */
2189 config_all_variables (MInputMethodInfo *im_info)
2191 MPlist *global_vars, *custom_vars, *config_vars;
2192 MInputMethodInfo *temp;
2193 MPlist *tail, *plist;
2195 M17N_OBJECT_UNREF (im_info->configured_vars);
2197 if (MPLIST_TAIL_P (im_info->vars)
2201 global_vars = im_info != global_info ? global_info->vars : NULL;
2202 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2203 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2205 im_info->configured_vars = tail = mplist ();
2206 MPLIST_DO (plist, im_info->vars)
2208 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2209 global_vars, custom_vars, config_vars);
2212 tail = mplist_add (tail, Mplist, pl);
2213 M17N_OBJECT_UNREF (pl);
2218 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2219 CONFIG contains configuration information of the input method. */
2222 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2226 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2228 load_commands (im_info, MPLIST_PLIST (pl));
2229 config_all_commands (im_info);
2230 pl = mplist_pop (pl);
2231 M17N_OBJECT_UNREF (pl);
2234 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2236 load_variables (im_info, MPLIST_PLIST (pl));
2237 config_all_variables (im_info);
2238 pl = mplist_pop (pl);
2239 M17N_OBJECT_UNREF (pl);
2242 MPLIST_DO (plist, plist)
2243 if (MPLIST_PLIST_P (plist))
2245 MPlist *elt = MPLIST_PLIST (plist);
2248 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2250 key = MPLIST_SYMBOL (elt);
2255 elt = MPLIST_NEXT (elt);
2256 if (MFAILP (MPLIST_MTEXT_P (elt)))
2258 im_info->title = MPLIST_MTEXT (elt);
2259 M17N_OBJECT_REF (im_info->title);
2261 else if (key == Mmap)
2263 pl = mplist__from_alist (MPLIST_NEXT (elt));
2266 if (! im_info->maps)
2270 mplist__conc (im_info->maps, pl);
2271 M17N_OBJECT_UNREF (pl);
2274 else if (key == Mmacro)
2276 if (! im_info->macros)
2277 im_info->macros = mplist ();
2278 MPLIST_DO (elt, MPLIST_NEXT (elt))
2280 if (MFAILP (MPLIST_PLIST_P (elt)))
2282 load_macros (im_info, MPLIST_PLIST (elt));
2285 else if (key == Mmodule)
2287 if (! im_info->externals)
2288 im_info->externals = mplist ();
2289 MPLIST_DO (elt, MPLIST_NEXT (elt))
2291 if (MFAILP (MPLIST_PLIST_P (elt)))
2293 load_external_module (im_info, MPLIST_PLIST (elt));
2296 else if (key == Mstate)
2298 MPLIST_DO (elt, MPLIST_NEXT (elt))
2302 if (MFAILP (MPLIST_PLIST_P (elt)))
2304 pl = MPLIST_PLIST (elt);
2305 if (! im_info->states)
2306 im_info->states = mplist ();
2307 state = load_state (im_info, MPLIST_PLIST (elt));
2310 mplist_put (im_info->states, state->name, state);
2313 else if (key == Minclude)
2315 /* elt ::= include (tag1 tag2 ...) key item ... */
2317 MInputMethodInfo *temp;
2319 elt = MPLIST_NEXT (elt);
2320 if (MFAILP (MPLIST_PLIST_P (elt)))
2322 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2325 elt = MPLIST_NEXT (elt);
2326 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2328 key = MPLIST_SYMBOL (elt);
2329 elt = MPLIST_NEXT (elt);
2332 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2334 if (! im_info->maps)
2335 im_info->maps = mplist ();
2336 MPLIST_DO (pl, temp->maps)
2338 p = MPLIST_VAL (pl);
2339 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2340 M17N_OBJECT_REF (p);
2343 else if (key == Mmacro)
2345 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2347 if (! im_info->macros)
2348 im_info->macros = mplist ();
2349 MPLIST_DO (pl, temp->macros)
2351 p = MPLIST_VAL (pl);
2352 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2353 M17N_OBJECT_REF (p);
2356 else if (key == Mstate)
2358 if (! temp->states || MPLIST_TAIL_P (temp->states))
2360 if (! im_info->states)
2361 im_info->states = mplist ();
2362 MPLIST_DO (pl, temp->states)
2364 MIMState *state = MPLIST_VAL (pl);
2366 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2367 M17N_OBJECT_REF (state);
2371 else if (key == Mdescription)
2373 if (im_info->description)
2375 elt = MPLIST_NEXT (elt);
2376 if (! check_description (elt))
2378 im_info->description = MPLIST_MTEXT (elt);
2379 M17N_OBJECT_REF (im_info->description);
2382 if (im_info->macros)
2384 MPLIST_DO (pl, im_info->macros)
2385 parse_action_list (MPLIST_PLIST (pl), im_info->macros);
2388 im_info->tick = time (NULL);
2393 static int take_action_list (MInputContext *ic, MPlist *action_list);
2394 static void preedit_commit (MInputContext *ic, int need_prefix);
2397 shift_state (MInputContext *ic, MSymbol state_name)
2399 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2400 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2401 MIMState *orig_state = ic_info->state, *state;
2403 /* Find a state to shift to. If not found, shift to the initial
2405 if (state_name == Mt)
2407 if (! ic_info->prev_state)
2409 state = ic_info->prev_state;
2411 else if (state_name == Mnil)
2413 state = (MIMState *) MPLIST_VAL (im_info->states);
2417 state = (MIMState *) mplist_get (im_info->states, state_name);
2419 state = (MIMState *) MPLIST_VAL (im_info->states);
2425 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2426 MSYMBOL_NAME (orig_state->name),
2427 MSYMBOL_NAME (state->name));
2429 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2432 /* Enter the new state. */
2433 ic_info->state = state;
2434 ic_info->map = state->map;
2435 ic_info->state_key_head = ic_info->key_head;
2436 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2438 /* We have shifted to the initial state. */
2439 preedit_commit (ic, 0);
2440 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2441 ic_info->state_pos = ic->cursor_pos;
2442 if (state != orig_state)
2444 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2446 /* Shifted to the initial state. */
2447 ic_info->prev_state = NULL;
2448 M17N_OBJECT_UNREF (ic_info->vars_saved);
2449 ic_info->vars_saved = mplist_copy (ic_info->vars);
2452 ic_info->prev_state = orig_state;
2455 ic->status = state->title;
2457 ic->status = im_info->title;
2458 ic->status_changed = 1;
2459 if (ic_info->map == ic_info->state->map
2460 && ic_info->map->map_actions)
2462 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2463 MSYMBOL_NAME (state->name));
2464 take_action_list (ic, ic_info->map->map_actions);
2469 /* Find a candidate group that contains a candidate number INDEX from
2470 PLIST. Set START_INDEX to the first candidate number of the group,
2471 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2472 candidate group number if they are non-NULL. If INDEX is -1, find
2473 the last candidate group. */
2476 find_candidates_group (MPlist *plist, int index,
2477 int *start_index, int *end_index, int *group_index)
2479 int i = 0, gidx = 0, len;
2481 MPLIST_DO (plist, plist)
2483 if (MPLIST_MTEXT_P (plist))
2484 len = mtext_nchars (MPLIST_MTEXT (plist));
2486 len = mplist_length (MPLIST_PLIST (plist));
2487 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2493 *end_index = i + len;
2495 *group_index = gidx;
2504 /* Adjust markers for the change of preedit text.
2505 If FROM == TO, the change is insertion of INS chars.
2506 If FROM < TO and INS == 0, the change is deletion of the range.
2507 If FROM < TO and INS > 0, the change is replacement. */
2510 adjust_markers (MInputContext *ic, int from, int to, int ins)
2512 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2517 MPLIST_DO (markers, ic_info->markers)
2518 if (MPLIST_INTEGER (markers) > from)
2519 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2520 if (ic->cursor_pos >= from)
2521 ic->cursor_pos += ins;
2525 MPLIST_DO (markers, ic_info->markers)
2527 if (MPLIST_INTEGER (markers) >= to)
2528 MPLIST_VAL (markers)
2529 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2530 else if (MPLIST_INTEGER (markers) > from)
2531 MPLIST_VAL (markers) = (void *) from;
2533 if (ic->cursor_pos >= to)
2534 ic->cursor_pos += ins - (to - from);
2535 else if (ic->cursor_pos > from)
2536 ic->cursor_pos = from;
2542 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2544 int nchars = mt ? mtext_nchars (mt) : 1;
2548 mtext_ins (ic->preedit, pos, mt);
2549 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2553 mtext_ins_char (ic->preedit, pos, c, 1);
2555 MDEBUG_PRINT1 ("('%c')", c);
2557 MDEBUG_PRINT1 ("(U+%04X)", c);
2559 adjust_markers (ic, pos, pos, nchars);
2560 ic->preedit_changed = 1;
2565 preedit_delete (MInputContext *ic, int from, int to)
2567 mtext_del (ic->preedit, from, to);
2568 adjust_markers (ic, from, to, 0);
2569 ic->preedit_changed = 1;
2573 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2577 mtext_del (ic->preedit, from, to);
2580 mtext_ins (ic->preedit, from, mt);
2581 ins = mtext_nchars (mt);
2585 mtext_ins_char (ic->preedit, from, c, 1);
2588 adjust_markers (ic, from, to, ins);
2589 ic->preedit_changed = 1;
2594 preedit_commit (MInputContext *ic, int need_prefix)
2596 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2597 int preedit_len = mtext_nchars (ic->preedit);
2599 if (preedit_len > 0)
2603 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2604 Mcandidate_list, NULL, 0);
2605 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2606 Mcandidate_index, NULL, 0);
2607 mtext_cat (ic->produced, ic->preedit);
2613 MDEBUG_PRINT1 ("\n [IM] [%s]",
2614 MSYMBOL_NAME (ic_info->state->name));
2615 MDEBUG_PRINT (" (commit");
2616 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2617 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2621 mtext_reset (ic->preedit);
2622 mtext_reset (ic_info->preedit_saved);
2623 MPLIST_DO (p, ic_info->markers)
2625 ic->cursor_pos = ic_info->state_pos = 0;
2626 ic->preedit_changed = 1;
2627 ic_info->commit_key_head = ic_info->key_head;
2629 if (ic->candidate_list)
2631 M17N_OBJECT_UNREF (ic->candidate_list);
2632 ic->candidate_list = NULL;
2633 ic->candidate_index = 0;
2634 ic->candidate_from = ic->candidate_to = 0;
2635 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2636 if (ic->candidate_show)
2638 ic->candidate_show = 0;
2639 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2645 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2647 int code = marker_code (sym, 0);
2649 if (mt && (code == '[' || code == ']'))
2653 if (code == '[' && current > 0)
2655 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2659 else if (code == ']' && current < mtext_nchars (mt))
2661 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2667 return (code == '<' ? 0
2668 : code == '>' ? limit
2669 : code == '-' ? current - 1
2670 : code == '+' ? current + 1
2671 : code == '=' ? current
2672 : code - '0' > limit ? limit
2676 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2680 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2682 int from = mtext_property_start (prop);
2683 int to = mtext_property_end (prop);
2685 MPlist *candidate_list = mtext_property_value (prop);
2686 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2688 int ingroup_index = idx - start;
2691 candidate_list = mplist_copy (candidate_list);
2692 if (MPLIST_MTEXT_P (group))
2694 mt = MPLIST_MTEXT (group);
2695 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2703 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2704 i++, plist = MPLIST_NEXT (plist));
2705 mt = MPLIST_MTEXT (plist);
2706 preedit_replace (ic, from, to, mt, 0);
2707 to = from + mtext_nchars (mt);
2709 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2710 M17N_OBJECT_UNREF (candidate_list);
2711 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2712 ic->cursor_pos = to;
2716 get_select_charset (MInputContextInfo * ic_info)
2718 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2721 if (! MPLIST_VAL (plist))
2723 sym = MPLIST_SYMBOL (plist);
2726 return MCHARSET (sym);
2729 /* The returned plist must be UNREFed. */
2732 adjust_candidates (MPlist *plist, MCharset *charset)
2736 /* plist ::= MTEXT ... | PLIST ... */
2737 plist = mplist_copy (plist);
2738 if (MPLIST_MTEXT_P (plist))
2741 while (! MPLIST_TAIL_P (pl))
2743 /* pl ::= MTEXT ... */
2744 MText *mt = MPLIST_MTEXT (pl);
2748 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2750 c = mtext_ref_char (mt, i);
2751 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2755 mt = mtext_dup (mt);
2756 mplist_set (pl, Mtext, mt);
2757 M17N_OBJECT_UNREF (mt);
2760 mtext_del (mt, i, i + 1);
2763 if (mtext_len (mt) > 0)
2764 pl = MPLIST_NEXT (pl);
2768 M17N_OBJECT_UNREF (mt);
2772 else /* MPLIST_PLIST_P (plist) */
2775 while (! MPLIST_TAIL_P (pl))
2777 /* pl ::= (MTEXT ...) ... */
2778 MPlist *p = MPLIST_PLIST (pl);
2780 /* p ::= MTEXT ... */
2784 while (! MPLIST_TAIL_P (p0))
2786 MText *mt = MPLIST_MTEXT (p0);
2789 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2791 c = mtext_ref_char (mt, i);
2792 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2797 p0 = MPLIST_NEXT (p0);
2804 p = mplist_copy (p);
2805 mplist_set (pl, Mplist, p);
2806 M17N_OBJECT_UNREF (p);
2810 p0 = MPLIST_NEXT (p0);
2813 M17N_OBJECT_UNREF (mt);
2816 if (! MPLIST_TAIL_P (p))
2817 pl = MPLIST_NEXT (pl);
2821 M17N_OBJECT_UNREF (p);
2825 if (MPLIST_TAIL_P (plist))
2827 M17N_OBJECT_UNREF (plist);
2833 /* The returned Plist must be UNREFed. */
2836 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2838 MCharset *charset = get_select_charset (ic_info);
2843 plist = resolve_variable (ic_info, Mcandidates_group_size);
2844 column = MPLIST_INTEGER (plist);
2846 plist = MPLIST_PLIST (args);
2851 plist = adjust_candidates (plist, charset);
2856 M17N_OBJECT_REF (plist);
2861 if (MPLIST_MTEXT_P (plist))
2863 MText *mt = MPLIST_MTEXT (plist);
2864 MPlist *next = MPLIST_NEXT (plist);
2866 if (MPLIST_TAIL_P (next))
2867 M17N_OBJECT_REF (mt);
2870 mt = mtext_dup (mt);
2871 while (! MPLIST_TAIL_P (next))
2873 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2874 next = MPLIST_NEXT (next);
2877 M17N_OBJECT_UNREF (plist);
2879 len = mtext_nchars (mt);
2881 mplist_add (plist, Mtext, mt);
2884 for (i = 0; i < len; i += column)
2886 int to = (i + column < len ? i + column : len);
2887 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2889 mplist_add (plist, Mtext, sub);
2890 M17N_OBJECT_UNREF (sub);
2893 M17N_OBJECT_UNREF (mt);
2895 else if (MPLIST_PLIST_P (plist))
2897 MPlist *tail = plist;
2898 MPlist *new = mplist ();
2899 MPlist *this = mplist ();
2902 MPLIST_DO (tail, tail)
2904 MPlist *p = MPLIST_PLIST (tail);
2908 MText *mt = MPLIST_MTEXT (p);
2910 if (count == column)
2912 mplist_add (new, Mplist, this);
2913 M17N_OBJECT_UNREF (this);
2917 mplist_add (this, Mtext, mt);
2921 mplist_add (new, Mplist, this);
2922 M17N_OBJECT_UNREF (this);
2923 mplist_set (plist, Mnil, NULL);
2924 MPLIST_DO (tail, new)
2926 MPlist *elt = MPLIST_PLIST (tail);
2928 mplist_add (plist, Mplist, elt);
2930 M17N_OBJECT_UNREF (new);
2938 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2940 MPlist *action = NULL;
2944 if (MPLIST_SYMBOL_P (action_list))
2946 MSymbol var = MPLIST_SYMBOL (action_list);
2949 MPLIST_DO (p, ic_info->vars)
2950 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2952 if (MPLIST_TAIL_P (p))
2954 action = MPLIST_NEXT (MPLIST_PLIST (p));
2955 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2958 if (MPLIST_PLIST_P (action_list))
2960 action = MPLIST_PLIST (action_list);
2961 if (MPLIST_SYMBOL_P (action))
2963 name = MPLIST_SYMBOL (action);
2964 args = MPLIST_NEXT (action);
2966 && MPLIST_PLIST_P (args))
2967 mplist_set (action, Msymbol, M_candidates);
2969 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2972 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2973 mplist_push (action, Msymbol, M_candidates);
2974 mplist_set (action_list, Mplist, action);
2975 M17N_OBJECT_UNREF (action);
2978 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2981 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2982 mplist_push (action, Msymbol, Minsert);
2983 mplist_set (action_list, Mplist, action);
2984 M17N_OBJECT_UNREF (action);
2989 /* Perform list of actions in ACTION_LIST for the current input
2990 context IC. If unhandle action was not performed, return 0.
2991 Otherwise, return -1. */
2994 take_action_list (MInputContext *ic, MPlist *action_list)
2996 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2997 MPlist *candidate_list = ic->candidate_list;
2998 int candidate_index = ic->candidate_index;
2999 int candidate_show = ic->candidate_show;
3000 MTextProperty *prop;
3002 MPLIST_DO (action_list, action_list)
3004 MPlist *action = regularize_action (action_list, ic_info);
3010 name = MPLIST_SYMBOL (action);
3011 args = MPLIST_NEXT (action);
3013 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
3014 if (name == Minsert)
3016 if (MPLIST_SYMBOL_P (args))
3018 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3019 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
3022 if (MPLIST_MTEXT_P (args))
3023 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
3024 else /* MPLIST_INTEGER_P (args)) */
3025 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
3027 else if (name == M_candidates)
3029 MPlist *plist = get_candidate_list (ic_info, args);
3035 if (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist))
3037 M17N_OBJECT_UNREF (plist);
3040 if (MPLIST_MTEXT_P (plist))
3042 preedit_insert (ic, ic->cursor_pos, NULL,
3043 mtext_ref_char (MPLIST_MTEXT (plist), 0));
3048 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
3050 preedit_insert (ic, ic->cursor_pos, mt, 0);
3051 len = mtext_nchars (mt);
3053 pl = mplist_copy (plist);
3054 M17N_OBJECT_UNREF (plist);
3055 mtext_put_prop (ic->preedit,
3056 ic->cursor_pos - len, ic->cursor_pos,
3057 Mcandidate_list, pl);
3058 M17N_OBJECT_UNREF (pl);
3059 mtext_put_prop (ic->preedit,
3060 ic->cursor_pos - len, ic->cursor_pos,
3061 Mcandidate_index, (void *) 0);
3063 else if (name == Mselect)
3066 int code, idx, gindex;
3067 int pos = ic->cursor_pos;
3069 int idx_decided = 0;
3072 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3075 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3076 group = find_candidates_group (mtext_property_value (prop), idx,
3077 &start, &end, &gindex);
3078 if (MPLIST_SYMBOL_P (args))
3080 code = marker_code (MPLIST_SYMBOL (args), 0);
3083 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3084 if (! MPLIST_INTEGER_P (args))
3086 idx = start + MPLIST_INTEGER (args);
3087 if (idx < start || idx >= end)
3095 if (code != '[' && code != ']')
3100 ? new_index (NULL, ic->candidate_index - start,
3101 end - start - 1, MPLIST_SYMBOL (args),
3103 : MPLIST_INTEGER (args)));
3106 find_candidates_group (mtext_property_value (prop), -1,
3111 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3116 int ingroup_index = idx - start;
3119 group = mtext_property_value (prop);
3120 len = mplist_length (group);
3133 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3134 idx += (MPLIST_MTEXT_P (group)
3135 ? mtext_nchars (MPLIST_MTEXT (group))
3136 : mplist_length (MPLIST_PLIST (group)));
3137 len = (MPLIST_MTEXT_P (group)
3138 ? mtext_nchars (MPLIST_MTEXT (group))
3139 : mplist_length (MPLIST_PLIST (group)));
3140 if (ingroup_index >= len)
3141 ingroup_index = len - 1;
3142 idx += ingroup_index;
3144 update_candidate (ic, prop, idx);
3145 MDEBUG_PRINT1 ("(%d)", idx);
3147 else if (name == Mshow)
3148 ic->candidate_show = 1;
3149 else if (name == Mhide)
3150 ic->candidate_show = 0;
3151 else if (name == Mdelete)
3153 int len = mtext_nchars (ic->preedit);
3157 if (MPLIST_SYMBOL_P (args)
3158 && surrounding_pos (MPLIST_SYMBOL (args), &pos))
3160 to = ic->cursor_pos + pos;
3163 delete_surrounding_text (ic, to);
3168 delete_surrounding_text (ic, to - len);
3174 to = (MPLIST_SYMBOL_P (args)
3175 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3177 : MPLIST_INTEGER (args));
3182 pos = to - ic->cursor_pos;
3184 MDEBUG_PRINT1 ("(%d)", pos);
3185 if (to < ic->cursor_pos)
3186 preedit_delete (ic, to, ic->cursor_pos);
3187 else if (to > ic->cursor_pos)
3188 preedit_delete (ic, ic->cursor_pos, to);
3190 else if (name == Mmove)
3192 int len = mtext_nchars (ic->preedit);
3194 = (MPLIST_SYMBOL_P (args)
3195 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3197 : MPLIST_INTEGER (args));
3203 if (pos != ic->cursor_pos)
3205 ic->cursor_pos = pos;
3206 ic->preedit_changed = 1;
3208 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3210 else if (name == Mmark)
3212 int code = marker_code (MPLIST_SYMBOL (args), 0);
3216 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3217 (void *) ic->cursor_pos);
3218 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3221 else if (name == Mpushback)
3223 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3227 if (MPLIST_SYMBOL_P (args))
3229 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3230 if (MPLIST_INTEGER_P (args))
3231 num = MPLIST_INTEGER (args);
3236 num = MPLIST_INTEGER (args);
3239 ic_info->key_head -= num;
3241 ic_info->key_head = 0;
3243 ic_info->key_head = - num;
3244 if (ic_info->key_head > ic_info->used)
3245 ic_info->key_head = ic_info->used;
3247 else if (MPLIST_MTEXT_P (args))
3249 MText *mt = MPLIST_MTEXT (args);
3250 int i, len = mtext_nchars (mt);
3253 ic_info->key_head--;
3254 for (i = 0; i < len; i++)
3256 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3257 if (ic_info->key_head + i < ic_info->used)
3258 ic_info->keys[ic_info->key_head + i] = key;
3260 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3265 MPlist *plist = MPLIST_PLIST (args), *pl;
3269 ic_info->key_head--;
3271 MPLIST_DO (pl, plist)
3273 key = MPLIST_SYMBOL (pl);
3274 if (ic_info->key_head < ic_info->used)
3275 ic_info->keys[ic_info->key_head + i] = key;
3277 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3282 else if (name == Mpop)
3284 if (ic_info->key_head < ic_info->used)
3285 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3287 else if (name == Mcall)
3289 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3290 MIMExternalFunc func = NULL;
3291 MSymbol module, func_name;
3292 MPlist *func_args, *val;
3295 module = MPLIST_SYMBOL (args);
3296 args = MPLIST_NEXT (args);
3297 func_name = MPLIST_SYMBOL (args);
3299 if (im_info->externals)
3301 MIMExternalModule *external
3302 = (MIMExternalModule *) mplist_get (im_info->externals,
3305 func = ((MIMExternalFunc)
3306 mplist_get_func (external->func_list, func_name));
3310 func_args = mplist ();
3311 mplist_add (func_args, Mt, ic);
3312 MPLIST_DO (args, MPLIST_NEXT (args))
3316 if (MPLIST_KEY (args) == Msymbol
3317 && MPLIST_KEY (args) != Mnil
3318 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3320 code = new_index (ic, ic->cursor_pos,
3321 mtext_nchars (ic->preedit),
3322 MPLIST_SYMBOL (args), ic->preedit);
3323 mplist_add (func_args, Minteger, (void *) code);
3326 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3328 val = (func) (func_args);
3329 M17N_OBJECT_UNREF (func_args);
3330 if (val && ! MPLIST_TAIL_P (val))
3331 ret = take_action_list (ic, val);
3332 M17N_OBJECT_UNREF (val);
3336 else if (name == Mshift)
3338 shift_state (ic, MPLIST_SYMBOL (args));
3340 else if (name == Mundo)
3342 int intarg = (MPLIST_TAIL_P (args)
3344 : integer_value (ic, args, 0));
3346 mtext_reset (ic->preedit);
3347 mtext_reset (ic_info->preedit_saved);
3348 mtext_reset (ic->produced);
3349 M17N_OBJECT_UNREF (ic_info->vars);
3350 ic_info->vars = mplist_copy (ic_info->vars_saved);
3351 ic->cursor_pos = ic_info->state_pos = 0;
3352 ic_info->state_key_head = ic_info->key_head
3353 = ic_info->commit_key_head = 0;
3355 shift_state (ic, Mnil);
3358 if (MPLIST_TAIL_P (args))
3363 ic_info->used += intarg;
3366 ic_info->used = intarg;
3369 else if (name == Mset || name == Madd || name == Msub
3370 || name == Mmul || name == Mdiv)
3372 MSymbol sym = MPLIST_SYMBOL (args);
3373 MPlist *value = resolve_variable (ic_info, sym);
3377 val1 = MPLIST_INTEGER (value);
3378 args = MPLIST_NEXT (args);
3379 val2 = resolve_expression (ic, args);
3381 val1 = val2, op = "=";
3382 else if (name == Madd)
3383 val1 += val2, op = "+=";
3384 else if (name == Msub)
3385 val1 -= val2, op = "-=";
3386 else if (name == Mmul)
3387 val1 *= val2, op = "*=";
3389 val1 /= val2, op = "/=";
3390 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3391 MSYMBOL_NAME (sym), op, val1, val1);
3392 mplist_set (value, Minteger, (void *) val1);
3394 else if (name == Mequal || name == Mless || name == Mgreater
3395 || name == Mless_equal || name == Mgreater_equal)
3398 MPlist *actions1, *actions2;
3401 val1 = resolve_expression (ic, args);
3402 args = MPLIST_NEXT (args);
3403 val2 = resolve_expression (ic, args);
3404 args = MPLIST_NEXT (args);
3405 actions1 = MPLIST_PLIST (args);
3406 args = MPLIST_NEXT (args);
3407 if (MPLIST_TAIL_P (args))
3410 actions2 = MPLIST_PLIST (args);
3411 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3412 if (name == Mequal ? val1 == val2
3413 : name == Mless ? val1 < val2
3414 : name == Mgreater ? val1 > val2
3415 : name == Mless_equal ? val1 <= val2
3418 MDEBUG_PRINT ("ok");
3419 ret = take_action_list (ic, actions1);
3423 MDEBUG_PRINT ("no");
3425 ret = take_action_list (ic, actions2);
3430 else if (name == Mcond)
3434 MPLIST_DO (args, args)
3439 if (! MPLIST_PLIST (args))
3441 cond = MPLIST_PLIST (args);
3442 if (resolve_expression (ic, cond) != 0)
3444 MDEBUG_PRINT1 ("(%dth)", idx);
3445 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3451 else if (name == Mcommit)
3453 preedit_commit (ic, 0);
3455 else if (name == Munhandle)
3457 preedit_commit (ic, 0);
3462 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3466 && (actions = mplist_get (im_info->macros, name)))
3468 if (take_action_list (ic, actions) < 0)
3474 if (ic->candidate_list)
3476 M17N_OBJECT_UNREF (ic->candidate_list);
3477 ic->candidate_list = NULL;
3479 if (ic->cursor_pos > 0
3480 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3483 ic->candidate_list = mtext_property_value (prop);
3484 M17N_OBJECT_REF (ic->candidate_list);
3486 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3488 ic->candidate_from = mtext_property_start (prop);
3489 ic->candidate_to = mtext_property_end (prop);
3492 if (candidate_list != ic->candidate_list)
3493 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3494 if (candidate_index != ic->candidate_index)
3495 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3496 if (candidate_show != ic->candidate_show)
3497 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3502 /* Handle the input key KEY in the current state and map specified in
3503 the input context IC. If KEY is handled correctly, return 0.
3504 Otherwise, return -1. */
3507 handle_key (MInputContext *ic)
3509 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3510 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3511 MIMMap *map = ic_info->map;
3512 MIMMap *submap = NULL;
3513 MSymbol key = ic_info->keys[ic_info->key_head];
3514 MSymbol alias = Mnil;
3517 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3518 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3522 submap = mplist_get (map->submaps, key);
3525 && (alias = msymbol_get (alias, M_key_alias))
3527 submap = mplist_get (map->submaps, alias);
3532 if (! alias || alias == key)
3533 MDEBUG_PRINT (" submap-found");
3535 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3536 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3537 ic->preedit_changed = 1;
3538 ic->cursor_pos = ic_info->state_pos;
3539 ic_info->key_head++;
3540 ic_info->map = map = submap;
3541 if (map->map_actions)
3543 MDEBUG_PRINT (" map-actions:");
3544 if (take_action_list (ic, map->map_actions) < 0)
3546 MDEBUG_PRINT ("\n");
3550 else if (map->submaps)
3552 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3554 MSymbol key = ic_info->keys[i];
3555 char *name = msymbol_name (key);
3557 if (! name[0] || ! name[1])
3558 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3562 /* If this is the terminal map or we have shifted to another
3563 state, perform branch actions (if any). */
3564 if (! map->submaps || map != ic_info->map)
3566 if (map->branch_actions)
3568 MDEBUG_PRINT (" branch-actions:");
3569 if (take_action_list (ic, map->branch_actions) < 0)
3571 MDEBUG_PRINT ("\n");
3575 /* If MAP is still not the root map, shift to the current
3577 if (ic_info->map != ic_info->state->map)
3578 shift_state (ic, ic_info->state->name);
3583 /* MAP can not handle KEY. */
3585 /* Perform branch actions if any. */
3586 if (map->branch_actions)
3588 MDEBUG_PRINT (" branch-actions:");
3589 if (take_action_list (ic, map->branch_actions) < 0)
3591 MDEBUG_PRINT ("\n");
3596 if (map == ic_info->map)
3598 /* The above branch actions didn't change the state. */
3600 /* If MAP is the root map of the initial state, and there
3601 still exist an unhandled key, it means that the current
3602 input method can not handle it. */
3603 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3604 && ic_info->key_head < ic_info->used)
3606 MDEBUG_PRINT (" unhandled\n");
3610 if (map != ic_info->state->map)
3612 /* MAP is not the root map. Shift to the root map of the
3614 shift_state (ic, ic_info->state->name);
3616 else if (! map->branch_actions)
3618 /* MAP is the root map without any default branch
3619 actions. Shift to the initial state. */
3620 shift_state (ic, Mnil);
3624 MDEBUG_PRINT ("\n");
3628 /* Initialize IC->ic_info. */
3631 init_ic_info (MInputContext *ic)
3633 MInputMethodInfo *im_info = ic->im->info;
3634 MInputContextInfo *ic_info = ic->info;
3637 MLIST_INIT1 (ic_info, keys, 8);;
3639 ic_info->markers = mplist ();
3641 ic_info->vars = mplist ();
3642 if (im_info->configured_vars)
3643 MPLIST_DO (plist, im_info->configured_vars)
3645 MPlist *pl = MPLIST_PLIST (plist);
3646 MSymbol name = MPLIST_SYMBOL (pl);
3648 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3649 if (MPLIST_KEY (pl) != Mt)
3651 MPlist *p = mplist ();
3653 mplist_push (ic_info->vars, Mplist, p);
3654 M17N_OBJECT_UNREF (p);
3655 mplist_add (p, Msymbol, name);
3656 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3659 ic_info->vars_saved = mplist_copy (ic_info->vars);
3661 if (im_info->externals)
3663 MPlist *func_args = mplist (), *plist;
3665 mplist_add (func_args, Mt, ic);
3666 MPLIST_DO (plist, im_info->externals)
3668 MIMExternalModule *external = MPLIST_VAL (plist);
3669 MIMExternalFunc func
3670 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3675 M17N_OBJECT_UNREF (func_args);
3678 ic_info->preedit_saved = mtext ();
3679 ic_info->tick = im_info->tick;
3682 /* Finalize IC->ic_info. */
3685 fini_ic_info (MInputContext *ic)
3687 MInputMethodInfo *im_info = ic->im->info;
3688 MInputContextInfo *ic_info = ic->info;
3690 if (im_info->externals)
3692 MPlist *func_args = mplist (), *plist;
3694 mplist_add (func_args, Mt, ic);
3695 MPLIST_DO (plist, im_info->externals)
3697 MIMExternalModule *external = MPLIST_VAL (plist);
3698 MIMExternalFunc func
3699 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3704 M17N_OBJECT_UNREF (func_args);
3707 MLIST_FREE1 (ic_info, keys);
3708 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3709 M17N_OBJECT_UNREF (ic_info->markers);
3710 M17N_OBJECT_UNREF (ic_info->vars);
3711 M17N_OBJECT_UNREF (ic_info->vars_saved);
3712 M17N_OBJECT_UNREF (ic_info->preceding_text);
3713 M17N_OBJECT_UNREF (ic_info->following_text);
3715 memset (ic_info, 0, sizeof (MInputContextInfo));
3719 re_init_ic (MInputContext *ic, int reload)
3721 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3722 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3723 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3725 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3726 preedit_changed = mtext_nchars (ic->preedit) > 0;
3727 cursor_pos_changed = ic->cursor_pos > 0;
3728 candidates_changed = 0;
3729 if (ic->candidate_list)
3731 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3732 M17N_OBJECT_UNREF (ic->candidate_list);
3733 ic->candidate_list = NULL;
3735 if (ic->candidate_show)
3737 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3738 ic->candidate_show = 0;
3740 if (ic->candidate_index > 0)
3742 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3743 ic->candidate_index = 0;
3744 ic->candidate_from = ic->candidate_to = 0;
3746 if (mtext_nchars (ic->produced) > 0)
3747 mtext_reset (ic->produced);
3748 if (mtext_nchars (ic->preedit) > 0)
3749 mtext_reset (ic->preedit);
3751 M17N_OBJECT_UNREF (ic->plist);
3752 ic->plist = mplist ();
3756 reload_im_info (im_info);
3757 if (! im_info->states)
3759 struct MIMState *state;
3761 M17N_OBJECT (state, free_state, MERROR_IM);
3762 state->name = msymbol ("init");
3763 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3764 MSTRUCT_CALLOC (state->map, MERROR_IM);
3765 im_info->states = mplist ();
3766 mplist_add (im_info->states, state->name, state);
3769 shift_state (ic, Mnil);
3771 ic->status_changed = status_changed;
3772 ic->preedit_changed = preedit_changed;
3773 ic->cursor_pos_changed = cursor_pos_changed;
3774 ic->candidates_changed = candidates_changed;
3778 reset_ic (MInputContext *ic, MSymbol ignore)
3780 MDEBUG_PRINT ("\n [IM] reset\n");
3785 open_im (MInputMethod *im)
3787 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3789 if (! im_info || ! im_info->states)
3790 MERROR (MERROR_IM, -1);
3797 close_im (MInputMethod *im)
3803 create_ic (MInputContext *ic)
3805 MInputContextInfo *ic_info;
3807 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3810 shift_state (ic, Mnil);
3815 destroy_ic (MInputContext *ic)
3822 check_reload (MInputContext *ic, MSymbol key)
3824 MInputMethodInfo *im_info = ic->im->info;
3825 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3829 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3833 MPLIST_DO (plist, plist)
3835 MSymbol this_key, alias;
3837 if (MPLIST_MTEXT_P (plist))
3839 MText *mt = MPLIST_MTEXT (plist);
3840 int c = mtext_ref_char (mt, 0);
3844 this_key = one_char_symbol[c];
3848 MPlist *pl = MPLIST_PLIST (plist);
3850 this_key = MPLIST_SYMBOL (pl);
3854 && (alias = msymbol_get (alias, M_key_alias))
3855 && alias != this_key);
3859 if (MPLIST_TAIL_P (plist))
3862 MDEBUG_PRINT ("\n [IM] reload");
3868 /** Handle the input key KEY in the current state and map of IC->info.
3869 If KEY is handled but no text is produced, return 0, otherwise
3875 filter (MInputContext *ic, MSymbol key, void *arg)
3877 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3878 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3881 if (check_reload (ic, key))
3884 if (! ic_info->state)
3886 ic_info->key_unhandled = 1;
3889 mtext_reset (ic->produced);
3890 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3891 M17N_OBJECT_UNREF (ic_info->preceding_text);
3892 M17N_OBJECT_UNREF (ic_info->following_text);
3893 ic_info->preceding_text = ic_info->following_text = NULL;
3894 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3895 ic_info->key_unhandled = 0;
3898 if (handle_key (ic) < 0)
3900 /* KEY was not handled. Delete it from the current key sequence. */
3901 if (ic_info->used > 0)
3903 memmove (ic_info->keys, ic_info->keys + 1,
3904 sizeof (int) * (ic_info->used - 1));
3906 if (ic_info->state_key_head > 0)
3907 ic_info->state_key_head--;
3908 if (ic_info->commit_key_head > 0)
3909 ic_info->commit_key_head--;
3911 /* This forces returning 1. */
3912 ic_info->key_unhandled = 1;
3918 reset_ic (ic, Mnil);
3919 ic_info->key_unhandled = 1;
3922 /* Break the loop if all keys were handled. */
3923 } while (ic_info->key_head < ic_info->used);
3925 /* If the current map is the root of the initial state, we should
3926 produce any preedit text in ic->produced. */
3927 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3928 preedit_commit (ic, 1);
3930 if (mtext_nchars (ic->produced) > 0)
3934 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3935 MSYMBOL_NAME (ic_info->state->name));
3936 for (i = 0; i < mtext_nchars (ic->produced); i++)
3937 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3941 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3942 Mlanguage, ic->im->language);
3944 if (ic_info->commit_key_head > 0)
3946 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3947 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3948 ic_info->used -= ic_info->commit_key_head;
3949 ic_info->key_head -= ic_info->commit_key_head;
3950 ic_info->state_key_head -= ic_info->commit_key_head;
3951 ic_info->commit_key_head = 0;
3953 if (ic_info->key_unhandled)
3956 ic_info->key_head = ic_info->state_key_head
3957 = ic_info->commit_key_head = 0;
3960 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3964 /** Return 1 if the last event or key was not handled, otherwise
3967 There is no need of looking up because ic->produced should already
3968 contain the produced text (if any).
3973 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3975 mtext_cat (mt, ic->produced);
3976 mtext_reset (ic->produced);
3977 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3981 /* Input method command handler. */
3983 /* List of all (global and local) commands.
3984 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3985 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3986 Global commands are stored as (t (t COMMAND ...)) */
3989 /* Input method variable handler. */
3992 /* Support functions for mdebug_dump_im. */
3995 dump_im_map (MPlist *map_list, int indent)
3998 MSymbol key = MPLIST_KEY (map_list);
3999 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
4001 prefix = (char *) alloca (indent + 1);
4002 memset (prefix, 32, indent);
4003 prefix[indent] = '\0';
4005 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
4006 if (map->map_actions)
4007 mdebug_dump_plist (map->map_actions, indent + 2);
4010 MPLIST_DO (map_list, map->submaps)
4012 fprintf (stderr, "\n%s ", prefix);
4013 dump_im_map (map_list, indent + 2);
4016 if (map->branch_actions)
4018 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
4019 mdebug_dump_plist (map->branch_actions, indent + 4);
4020 fprintf (stderr, ")");
4022 fprintf (stderr, ")");
4027 dump_im_state (MIMState *state, int indent)
4032 prefix = (char *) alloca (indent + 1);
4033 memset (prefix, 32, indent);
4034 prefix[indent] = '\0';
4036 fprintf (stderr, "(%s", msymbol_name (state->name));
4037 if (state->map->submaps)
4039 MPLIST_DO (map_list, state->map->submaps)
4041 fprintf (stderr, "\n%s ", prefix);
4042 dump_im_map (map_list, indent + 2);
4045 fprintf (stderr, ")");
4053 Minput_driver = msymbol ("input-driver");
4055 Minput_preedit_start = msymbol ("input-preedit-start");
4056 Minput_preedit_done = msymbol ("input-preedit-done");
4057 Minput_preedit_draw = msymbol ("input-preedit-draw");
4058 Minput_status_start = msymbol ("input-status-start");
4059 Minput_status_done = msymbol ("input-status-done");
4060 Minput_status_draw = msymbol ("input-status-draw");
4061 Minput_candidates_start = msymbol ("input-candidates-start");
4062 Minput_candidates_done = msymbol ("input-candidates-done");
4063 Minput_candidates_draw = msymbol ("input-candidates-draw");
4064 Minput_set_spot = msymbol ("input-set-spot");
4065 Minput_focus_move = msymbol ("input-focus-move");
4066 Minput_focus_in = msymbol ("input-focus-in");
4067 Minput_focus_out = msymbol ("input-focus-out");
4068 Minput_toggle = msymbol ("input-toggle");
4069 Minput_reset = msymbol ("input-reset");
4070 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4071 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4072 Mcustomized = msymbol ("customized");
4073 Mconfigured = msymbol ("configured");
4074 Minherited = msymbol ("inherited");
4076 minput_default_driver.open_im = open_im;
4077 minput_default_driver.close_im = close_im;
4078 minput_default_driver.create_ic = create_ic;
4079 minput_default_driver.destroy_ic = destroy_ic;
4080 minput_default_driver.filter = filter;
4081 minput_default_driver.lookup = lookup;
4082 minput_default_driver.callback_list = mplist ();
4083 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4084 M17N_FUNC (reset_ic));
4085 minput_driver = &minput_default_driver;
4087 fully_initialized = 0;
4094 if (fully_initialized)
4096 free_im_list (im_info_list);
4098 free_im_list (im_custom_list);
4100 free_im_list (im_config_list);
4101 M17N_OBJECT_UNREF (load_im_info_keys);
4104 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4105 M17N_OBJECT_UNREF (minput_driver->callback_list);
4110 minput__char_to_key (int c)
4112 if (c < 0 || c >= 0x100)
4115 return one_char_symbol[c];
4119 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4124 /*** @addtogroup m17nInputMethod */
4129 @brief Symbol whose name is "input-method".
4132 @brief "input-method" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
4134 MSymbol Minput_method;
4137 @name Variables: Predefined symbols for callback commands. */
4139 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4142 These are the predefined symbols that are used as the @c COMMAND
4143 argument of callback functions of an input method driver (see
4144 #MInputDriver::callback_list).
4146 Most of them do not require extra argument nor return any value;
4147 exceptions are these:
4149 @b Minput_get_surrounding_text: When a callback function assigned for
4150 this command is called, the first element of #MInputContext::plist
4151 has key #Minteger and the value specifies which portion of the
4152 surrounding text should be retrieved. If the value is positive,
4153 it specifies the number of characters following the current cursor
4154 position. If the value is negative, the absolute value specifies
4155 the number of characters preceding the current cursor position.
4156 If the value is zero, it means that the caller just wants to know
4157 if the surrounding text is currently supported or not.
4159 If the surrounding text is currently supported, the callback
4160 function must set the key of this element to #Mtext and the value
4161 to the retrieved M-text. The length of the M-text may be shorter
4162 than the requested number of characters, if the available text is
4163 not that long. The length can be zero in the worst case. Or, the
4164 length may be longer if an application thinks it is more efficient
4165 to return that length.
4167 If the surrounding text is not currently supported, the callback
4168 function should return without changing the first element of
4169 #MInputContext::plist.
4171 @b Minput_delete_surrounding_text: When a callback function assigned
4172 for this command is called, the first element of
4173 #MInputContext::plist has key #Minteger and the value specifies
4174 which portion of the surrounding text should be deleted in the
4175 same way as the case of Minput_get_surrounding_text. The callback
4176 function must delete the specified text. It should not alter
4177 #MInputContext::plist. */
4179 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4180 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4182 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4184 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4185 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4186 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4187 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4188 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4189 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4190 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4192 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4193 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4194 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4195 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4196 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4198 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4199 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4201 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4202 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4203 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4204 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4205 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4206 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4207 MSymbol Minput_preedit_start;
4208 MSymbol Minput_preedit_done;
4209 MSymbol Minput_preedit_draw;
4210 MSymbol Minput_status_start;
4211 MSymbol Minput_status_done;
4212 MSymbol Minput_status_draw;
4213 MSymbol Minput_candidates_start;
4214 MSymbol Minput_candidates_done;
4215 MSymbol Minput_candidates_draw;
4216 MSymbol Minput_set_spot;
4217 MSymbol Minput_toggle;
4218 MSymbol Minput_reset;
4219 MSymbol Minput_get_surrounding_text;
4220 MSymbol Minput_delete_surrounding_text;
4226 @name Variables: Predefined symbols for special input events.
4228 These are the predefined symbols that are used as the @c KEY
4229 argument of minput_filter (). */
4231 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4233 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4238 MSymbol Minput_focus_out;
4239 MSymbol Minput_focus_in;
4240 MSymbol Minput_focus_move;
4246 @name Variables: Predefined symbols used in input method information. */
4248 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë. */
4252 These are the predefined symbols describing status of input method
4253 command and variable, and are used in a return value of
4254 minput_get_command () and minput_get_variable (). */
4256 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4257 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4259 MSymbol Mcustomized;
4260 MSymbol Mconfigured;
4266 @brief The default driver for internal input methods.
4268 The variable #minput_default_driver is the default driver for
4269 internal input methods.
4271 The member MInputDriver::open_im () searches the m17n database for
4272 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4273 $NAME\> and loads it.
4275 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4276 programmers responsibility to set it to a plist of proper callback
4277 functions. Otherwise, no feedback information (e.g. preedit text)
4278 can be shown to users.
4280 The macro M17N_INIT () sets the variable #minput_driver to the
4281 pointer to this driver so that all internal input methods use it.
4283 Therefore, unless @c minput_driver is set differently, the driver
4284 dependent arguments $ARG of the functions whose name begins with
4285 "minput_" are all ignored. */
4287 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4289 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4291 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4292 \< #Minput_method, $LANGUAGE, $NAME\>
4293 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4295 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4296 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4297 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4298 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4300 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4301 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4303 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4304 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4306 MInputDriver minput_default_driver;
4310 @brief The driver for internal input methods.
4312 The variable #minput_driver is a pointer to the input method
4313 driver that is used by internal input methods. The macro
4314 M17N_INIT () initializes it to a pointer to #minput_default_driver
4315 if <m17n<EM></EM>.h> is included. */
4317 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4319 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4320 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4321 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4322 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4324 MInputDriver *minput_driver;
4328 The variable #Minput_driver is a symbol for a foreign input method.
4329 See @ref foreign-input-method "foreign input method" for the detail. */
4330 MSymbol Minput_driver;
4345 @brief Open an input method.
4347 The minput_open_im () function opens an input method whose
4348 language and name match $LANGUAGE and $NAME, and returns a pointer
4349 to the input method object newly allocated.
4351 This function at first decides a driver for the input method as
4354 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4355 #minput_driver is used.
4357 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4358 driver pointed to by the property value is used to open the input
4359 method. If $NAME has no such a property, @c NULL is returned.
4361 Then, the member MInputDriver::open_im () of the driver is
4364 $ARG is set in the member @c arg of the structure MInputMethod so
4365 that the driver can refer to it. */
4367 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4369 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4370 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4372 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4374 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4375 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4377 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4378 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4379 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4381 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4383 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4385 @latexonly \IPAlabel{minput_open} @endlatexonly
4390 minput_open_im (MSymbol language, MSymbol name, void *arg)
4393 MInputDriver *driver;
4397 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4398 msymbol_name (language), msymbol_name (name));
4402 MERROR (MERROR_IM, NULL);
4403 driver = minput_driver;
4407 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4409 MERROR (MERROR_IM, NULL);
4412 MSTRUCT_CALLOC (im, MERROR_IM);
4413 im->language = language;
4416 im->driver = *driver;
4417 if ((*im->driver.open_im) (im) < 0)
4419 MDEBUG_PRINT (" failed\n");
4423 MDEBUG_PRINT (" ok\n");
4430 @brief Close an input method.
4432 The minput_close_im () function closes the input method $IM, which
4433 must have been created by minput_open_im (). */
4436 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4438 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4439 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4442 minput_close_im (MInputMethod *im)
4444 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4445 msymbol_name (im->name), msymbol_name (im->language));
4446 (*im->driver.close_im) (im);
4448 MDEBUG_PRINT (" done\n");
4454 @brief Create an input context.
4456 The minput_create_ic () function creates an input context object
4457 associated with input method $IM, and calls callback functions
4458 corresponding to @b Minput_preedit_start, @b Minput_status_start, and
4459 @b Minput_status_draw in this order.
4462 If an input context is successfully created, minput_create_ic ()
4463 returns a pointer to it. Otherwise it returns @c NULL. */
4466 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4468 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4469 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4470 @b Minput_preedit_start, @b Minput_status_start, @b Minput_status_draw
4471 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4474 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4475 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4479 minput_create_ic (MInputMethod *im, void *arg)
4483 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4484 msymbol_name (im->name), msymbol_name (im->language));
4485 MSTRUCT_CALLOC (ic, MERROR_IM);
4488 ic->preedit = mtext ();
4489 ic->candidate_list = NULL;
4490 ic->produced = mtext ();
4491 ic->spot.x = ic->spot.y = 0;
4493 ic->plist = mplist ();
4494 if ((*im->driver.create_ic) (ic) < 0)
4496 MDEBUG_PRINT (" failed\n");
4497 M17N_OBJECT_UNREF (ic->preedit);
4498 M17N_OBJECT_UNREF (ic->produced);
4499 M17N_OBJECT_UNREF (ic->plist);
4504 if (im->driver.callback_list)
4506 minput_callback (ic, Minput_preedit_start);
4507 minput_callback (ic, Minput_status_start);
4508 minput_callback (ic, Minput_status_draw);
4511 MDEBUG_PRINT (" ok\n");
4518 @brief Destroy an input context.
4520 The minput_destroy_ic () function destroys the input context $IC,
4521 which must have been created by minput_create_ic (). It calls
4522 callback functions corresponding to @b Minput_preedit_done,
4523 @b Minput_status_done, and @b Minput_candidates_done in this order. */
4526 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4528 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4529 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4530 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4531 @b Minput_preedit_done, @b Minput_status_done, @b Minput_candidates_done
4532 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4536 minput_destroy_ic (MInputContext *ic)
4538 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4539 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4540 if (ic->im->driver.callback_list)
4542 minput_callback (ic, Minput_preedit_done);
4543 minput_callback (ic, Minput_status_done);
4544 minput_callback (ic, Minput_candidates_done);
4546 (*ic->im->driver.destroy_ic) (ic);
4547 M17N_OBJECT_UNREF (ic->preedit);
4548 M17N_OBJECT_UNREF (ic->produced);
4549 M17N_OBJECT_UNREF (ic->plist);
4550 MDEBUG_PRINT (" done\n");
4557 @brief Filter an input key.
4559 The minput_filter () function filters input key $KEY according to
4560 input context $IC, and calls callback functions corresponding to
4561 @b Minput_preedit_draw, @b Minput_status_draw, and
4562 @b Minput_candidates_draw if the preedit text, the status, and the
4563 current candidate are changed respectively.
4565 To make the input method commit the current preedit text (if any)
4566 and shift to the initial state, call this function with #Mnil as
4569 To inform the input method about the focus-out event, call this
4570 function with @b Minput_focus_out as $KEY.
4572 To inform the input method about the focus-in event, call this
4573 function with @b Minput_focus_in as $KEY.
4575 To inform the input method about the focus-move event (i.e. input
4576 spot change within the same input context), call this function
4577 with @b Minput_focus_move as $KEY.
4580 If $KEY is filtered out, this function returns 1. In that case,
4581 the caller should discard the key. Otherwise, it returns 0, and
4582 the caller should handle the key, for instance, by calling the
4583 function minput_lookup () with the same key. */
4586 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4588 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4589 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4590 @b Minput_preedit_draw, @b Minput_status_draw,
4591 @b Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4594 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4595 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4596 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4597 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4599 @latexonly \IPAlabel{minput_filter} @endlatexonly
4603 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4610 if (ic->im->driver.callback_list
4611 && mtext_nchars (ic->preedit) > 0)
4612 minput_callback (ic, Minput_preedit_draw);
4614 ret = (*ic->im->driver.filter) (ic, key, arg);
4616 if (ic->im->driver.callback_list)
4618 if (ic->preedit_changed)
4619 minput_callback (ic, Minput_preedit_draw);
4620 if (ic->status_changed)
4621 minput_callback (ic, Minput_status_draw);
4622 if (ic->candidates_changed)
4623 minput_callback (ic, Minput_candidates_draw);
4632 @brief Look up a text produced in the input context.
4634 The minput_lookup () function looks up a text in the input context
4635 $IC. $KEY must be identical to the one that was used in the previous call of
4638 If a text was produced by the input method, it is concatenated
4641 This function calls #MInputDriver::lookup .
4644 If $KEY was correctly handled by the input method, this function
4645 returns 0. Otherwise, it returns -1, even though some text
4646 might be produced in $MT. */
4649 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4651 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4652 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4654 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4657 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4660 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4661 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4662 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4664 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4667 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4669 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4674 @brief Set the spot of the input context.
4676 The minput_set_spot () function sets the spot of input context $IC
4677 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4678 The semantics of these values depends on the input method driver.
4680 For instance, a driver designed to work in a CUI environment may
4681 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4682 $DESCENT . A driver designed to work in a window system may
4683 interpret $X and $Y as the pixel offsets relative to the origin of the
4684 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4685 descent pixels of the line at ($X . $Y ).
4687 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4689 $MT and $POS are the M-text and the character position at the spot.
4690 $MT may be @c NULL, in which case, the input method cannot get
4691 information about the text around the spot. */
4694 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4696 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4697 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4698 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4700 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4701 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4702 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4703 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4704 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4705 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4707 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4709 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4710 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4714 minput_set_spot (MInputContext *ic, int x, int y,
4715 int ascent, int descent, int fontsize,
4720 ic->spot.ascent = ascent;
4721 ic->spot.descent = descent;
4722 ic->spot.fontsize = fontsize;
4725 if (ic->im->driver.callback_list)
4726 minput_callback (ic, Minput_set_spot);
4731 @brief Toggle input method.
4733 The minput_toggle () function toggles the input method associated
4734 with input context $IC. */
4736 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4738 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4739 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4743 minput_toggle (MInputContext *ic)
4745 if (ic->im->driver.callback_list)
4746 minput_callback (ic, Minput_toggle);
4747 ic->active = ! ic->active;
4753 @brief Reset an input context.
4755 The minput_reset_ic () function resets input context $IC by
4756 calling a callback function corresponding to @b Minput_reset. It
4757 resets the status of $IC to its initial one. As the
4758 current preedit text is deleted without commitment, if necessary,
4759 call minput_filter () with the arg @b key #Mnil to force the input
4760 method to commit the preedit in advance. */
4763 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4765 ´Ø¿ô minput_reset_ic () ¤Ï @b Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4766 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4767 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4768 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4769 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @b key #Mnil ¤Ç¸Æ¤ó¤Ç
4770 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4773 minput_reset_ic (MInputContext *ic)
4775 if (ic->im->driver.callback_list)
4776 minput_callback (ic, Minput_reset);
4782 @brief Get title and icon filename of an input method.
4784 The minput_get_title_icon () function returns a plist containing a
4785 title and icon filename (if any) of an input method specified by
4786 $LANGUAGE and $NAME.
4788 The first element of the plist has key #Mtext and the value is an
4789 M-text of the title for identifying the input method. The second
4790 element (if any) has key #Mtext and the value is an M-text of the
4791 icon image (absolute) filename for the same purpose.
4794 If there exists a specified input method and it defines an title,
4795 a plist is returned. Otherwise, NULL is returned. The caller
4796 must free the plist by m17n_object_unref (). */
4798 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4800 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4801 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4804 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4805 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4806 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4809 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4810 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4811 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4814 minput_get_title_icon (MSymbol language, MSymbol name)
4816 MInputMethodInfo *im_info;
4823 im_info = get_im_info (language, name, Mnil, Mtitle);
4824 if (! im_info || !im_info->title)
4826 mt = mtext_get_prop (im_info->title, 0, Mtext);
4828 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4831 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4834 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4835 (char *) MSYMBOL_NAME (name));
4836 file = mdatabase__find_file (buf);
4837 if (! file && language == Mt)
4839 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4840 file = mdatabase__find_file (buf);
4845 mplist_add (plist, Mtext, im_info->title);
4848 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4850 mplist_add (plist, Mtext, mt);
4851 M17N_OBJECT_UNREF (mt);
4859 @brief Get description text of an input method.
4861 The minput_get_description () function returns an M-text that
4862 describes the input method specified by $LANGUAGE and $NAME.
4865 If the specified input method has a description text, a pointer to
4866 #MText is returned. The caller has to free it by m17n_object_unref ().
4867 If the input method does not have a description text, @c NULL is
4870 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4872 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4873 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4876 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4877 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4878 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4879 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4882 minput_get_description (MSymbol language, MSymbol name)
4884 MInputMethodInfo *im_info;
4892 extra = language, language = Mt;
4894 im_info = get_im_info (language, name, extra, Mdescription);
4895 if (! im_info || ! im_info->description)
4897 M17N_OBJECT_REF (im_info->description);
4898 return im_info->description;
4904 @brief Get information about input method command(s).
4906 The minput_get_command () function returns information about
4907 the command $COMMAND of the input method specified by $LANGUAGE and
4908 $NAME. An input method command is a pseudo key event to which one
4909 or more actual input key sequences are assigned.
4911 There are two kinds of commands, global and local. A global
4912 command has a global definition, and the description and the key
4913 assignment may be inherited by a local command. Each input method
4914 defines a local command which has a local key assignment. It may
4915 also declare a local command that inherits the definition of a
4916 global command of the same name.
4918 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4919 information about a global command. Otherwise information about a
4920 local command is returned.
4922 If $COMMAND is #Mnil, information about all commands is returned.
4924 The return value is a @e well-formed plist (@ref m17nPlist) of this
4927 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4929 @c NAME is a symbol representing the command name.
4931 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4932 command has no description.
4934 @c STATUS is a symbol representing how the key assignment is decided.
4935 The value is #Mnil (the default key assignment), @b Mcustomized (the
4936 key assignment is customized by per-user customization file), or
4937 @b Mconfigured (the key assignment is set by the call of
4938 minput_config_command ()). For a local command only, it may also
4939 be @b Minherited (the key assignment is inherited from the
4940 corresponding global command).
4942 @c KEYSEQ is a plist of one or more symbols representing a key
4943 sequence assigned to the command. If there's no KEYSEQ, the
4944 command is currently disabled (i.e. no key sequence can trigger
4945 actions of the command).
4947 If $COMMAND is not #Mnil, the first element of the returned plist
4948 contains the information about $COMMAND.
4952 If the requested information was found, a pointer to a non-empty
4953 plist is returned. As the plist is kept in the library, the
4954 caller must not modify nor free it.
4956 Otherwise (the specified input method or the specified command
4957 does not exist), @c NULL is returned. */
4959 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4961 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4962 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4963 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4964 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4966 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4967 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4968 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4969 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4970 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4972 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4973 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4976 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4978 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4981 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4983 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4985 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4988 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4989 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, @b Mcustomized ¡Ê¥æ¡¼
4990 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4991 @b Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4992 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4993 @b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4996 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4997 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4998 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4999 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
5001 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
5002 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5006 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5007 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5010 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5015 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
5017 /* Return a description of the command COMMAND of the input method
5018 specified by LANGUAGE and NAME. */
5019 MPlist *cmd = minput_get_command (langauge, name, command);
5024 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
5025 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
5026 return (mplist_key (plist) == Mtext
5027 ? (MText *) mplist_value (plist)
5033 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
5035 MInputMethodInfo *im_info;
5039 im_info = get_im_info (language, name, Mnil, Mcommand);
5041 || ! im_info->configured_cmds
5042 || MPLIST_TAIL_P (im_info->configured_cmds))
5044 if (command == Mnil)
5045 return im_info->configured_cmds;
5046 return mplist__assq (im_info->configured_cmds, command);
5052 @brief Configure the key sequence of an input method command.
5054 The minput_config_command () function assigns a list of key
5055 sequences $KEYSEQLIST to the command $COMMAND of the input method
5056 specified by $LANGUAGE and $NAME.
5058 If $KEYSEQLIST is a non-empty plist, it must be a list of key
5059 sequences, and each key sequence must be a plist of symbols.
5061 If $KEYSEQLIST is an empty plist, any configuration and
5062 customization of the command are cancelled, and default key
5063 sequences become effective.
5065 If $KEYSEQLIST is NULL, the configuration of the command is
5066 canceled, and the original key sequences (what saved in per-user
5067 customization file, or the default one) become effective.
5069 In the latter two cases, $COMMAND can be #Mnil to make all the
5070 commands of the input method the target of the operation.
5072 If $NAME is #Mnil, this function configures the key assignment of a
5073 global command, not that of a specific input method.
5075 The configuration takes effect for input methods opened or
5076 re-opened later in the current session. In order to make the
5077 configuration take effect for the future session, it must be saved
5078 in a per-user customization file by the function
5079 minput_save_config ().
5082 If the operation was successful, this function returns 0,
5083 otherwise returns -1. The operation fails in these cases:
5085 <li>$KEYSEQLIST is not in a valid form.
5086 <li>$COMMAND is not available for the input method.
5087 <li>$LANGUAGE and $NAME do not specify an existing input method.
5091 minput_get_commands (), minput_save_config ().
5094 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5096 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5097 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5098 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5100 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5101 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5103 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5104 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5106 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5107 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5108 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5110 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5111 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5113 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5114 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5116 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5117 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5118 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5119 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5123 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5125 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5126 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5127 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5131 minput_get_commands (), minput_save_config ().
5135 /* Add "C-x u" to the "start" command of Unicode input method. */
5137 MSymbol start_command = msymbol ("start");
5138 MSymbol unicode = msymbol ("unicode");
5139 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5141 /* At first get the current key-sequence assignment. */
5142 cmd = minput_get_command (Mt, unicode, start_command);
5145 /* The input method does not have the command "start". Here
5146 should come some error handling code. */
5148 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5149 Extract the part (KEY-SEQUENCE ...). */
5150 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5151 /* Copy it because we should not modify it directly. */
5152 key_seq_list = mplist_copy (plist);
5154 key_seq = mplist ();
5155 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5156 mplist_add (key_seq, Msymbol, msymbol ("u"));
5157 mplist_add (key_seq_list, Mplist, key_seq);
5158 m17n_object_unref (key_seq);
5160 minput_config_command (Mt, unicode, start_command, key_seq_list);
5161 m17n_object_unref (key_seq_list);
5166 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5169 MInputMethodInfo *im_info, *config;
5174 im_info = get_im_info (language, name, Mnil, Mcommand);
5176 MERROR (MERROR_IM, -1);
5177 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5179 || ! mplist__assq (im_info->configured_cmds, command)))
5180 MERROR (MERROR_IM, -1);
5181 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5183 MPLIST_DO (plist, keyseqlist)
5184 if (! check_command_keyseq (plist))
5185 MERROR (MERROR_IM, -1);
5188 config = get_config_info (im_info);
5191 if (! im_config_list)
5192 im_config_list = mplist ();
5193 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5194 config->cmds = mplist ();
5195 config->vars = mplist ();
5198 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5199 /* Nothing to do. */
5202 if (command == Mnil)
5206 /* Cancal the configuration. */
5207 if (MPLIST_TAIL_P (config->cmds))
5209 mplist_set (config->cmds, Mnil, NULL);
5213 /* Cancal the customization. */
5214 MInputMethodInfo *custom = get_custom_info (im_info);
5216 if (MPLIST_TAIL_P (config->cmds)
5217 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5218 /* Nothing to do. */
5220 mplist_set (config->cmds, Mnil, NULL);
5221 MPLIST_DO (plist, custom->cmds)
5223 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5225 mplist_add (plist, Msymbol, command);
5226 mplist_push (config->cmds, Mplist, plist);
5227 M17N_OBJECT_UNREF (plist);
5233 plist = mplist__assq (config->cmds, command);
5236 /* Cancel the configuration. */
5239 mplist__pop_unref (plist);
5241 else if (MPLIST_TAIL_P (keyseqlist))
5243 /* Cancel the customization. */
5244 MInputMethodInfo *custom = get_custom_info (im_info);
5245 int no_custom = (! custom || ! custom->cmds
5246 || ! mplist__assq (custom->cmds, command));
5252 mplist_add (config->cmds, Mplist, plist);
5253 M17N_OBJECT_UNREF (plist);
5254 plist = mplist_add (plist, Msymbol, command);
5259 mplist__pop_unref (plist);
5262 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5263 plist = MPLIST_NEXT (plist);
5264 mplist_set (plist, Mnil, NULL);
5274 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5275 if (! MPLIST_TAIL_P (plist))
5276 mplist_set (plist, Mnil, NULL);
5281 mplist_add (config->cmds, Mplist, plist);
5282 M17N_OBJECT_UNREF (plist);
5283 plist = mplist_add (plist, Msymbol, command);
5284 plist = MPLIST_NEXT (plist);
5286 MPLIST_DO (keyseqlist, keyseqlist)
5288 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5289 plist = mplist_add (plist, Mplist, pl);
5290 M17N_OBJECT_UNREF (pl);
5294 config_all_commands (im_info);
5295 im_info->tick = time (NULL);
5302 @brief Get information about input method variable(s).
5304 The minput_get_variable () function returns information about
5305 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5306 An input method variable controls behavior of an input method.
5308 There are two kinds of variables, global and local. A global
5309 variable has a global definition, and the description and the value
5310 may be inherited by a local variable. Each input method defines a
5311 local variable which has local value. It may also declare a
5312 local variable that inherits definition of a global variable of
5315 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5316 variable is returned. Otherwise information about a local variable
5319 If $VARIABLE is #Mnil, information about all variables is
5322 The return value is a @e well-formed plist (@ref m17nPlist) of this
5325 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5327 @c NAME is a symbol representing the variable name.
5329 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5330 variable has no description.
5332 @c STATUS is a symbol representing how the value is decided. The
5333 value is #Mnil (the default value), @b Mcustomized (the value is
5334 customized by per-user customization file), or @b Mconfigured (the
5335 value is set by the call of minput_config_variable ()). For a
5336 local variable only, it may also be @b Minherited (the value is
5337 inherited from the corresponding global variable).
5339 @c VALUE is the initial value of the variable. If the key of this
5340 element is #Mt, the variable has no initial value. Otherwise, the
5341 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5344 @c VALID-VALUEs (if any) specify which values the variable can have.
5345 They have the same type (i.e. having the same key) as @c VALUE except
5346 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5347 may be a plist of two integers specifying the range of possible
5350 If there no @c VALID-VALUE, the variable can have any value as long
5351 as the type is the same as @c VALUE.
5353 If $VARIABLE is not #Mnil, the first element of the returned plist
5354 contains the information about $VARIABLE.
5358 If the requested information was found, a pointer to a non-empty
5359 plist is returned. As the plist is kept in the library, the
5360 caller must not modify nor free it.
5362 Otherwise (the specified input method or the specified variable
5363 does not exist), @c NULL is returned. */
5365 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5367 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5368 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5369 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5371 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5372 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5373 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5374 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5377 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5378 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5380 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5382 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5384 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5387 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5389 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5392 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5393 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, @b Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5394 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, @b Mconfigured
5395 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5396 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢@b Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5397 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5399 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5400 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5401 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5403 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5404 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5405 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5406 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5408 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5411 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5412 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5416 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5417 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5420 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5424 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5426 MInputMethodInfo *im_info;
5430 im_info = get_im_info (language, name, Mnil, Mvariable);
5431 if (! im_info || ! im_info->configured_vars)
5433 if (variable == Mnil)
5434 return im_info->configured_vars;
5435 return mplist__assq (im_info->configured_vars, variable);
5441 @brief Configure the value of an input method variable.
5443 The minput_config_variable () function assigns $VALUE to the
5444 variable $VARIABLE of the input method specified by $LANGUAGE and
5447 If $VALUE is a non-empty plist, it must be a plist of one element
5448 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5449 the corresponding type. That value is assigned to the variable.
5451 If $VALUE is an empty plist, any configuration and customization
5452 of the variable are canceled, and the default value is assigned to
5455 If $VALUE is NULL, the configuration of the variable is canceled,
5456 and the original value (what saved in per-user customization file,
5457 or the default value) is assigned to the variable.
5459 In the latter two cases, $VARIABLE can be #Mnil to make all the
5460 variables of the input method the target of the operation.
5462 If $NAME is #Mnil, this function configures the value of global
5463 variable, not that of a specific input method.
5465 The configuration takes effect for input methods opened or
5466 re-opened later in the current session. To make the configuration
5467 take effect for the future session, it must be saved in a per-user
5468 customization file by the function minput_save_config ().
5472 If the operation was successful, this function returns 0,
5473 otherwise returns -1. The operation fails in these cases:
5475 <li>$VALUE is not in a valid form, the type does not match the
5476 definition, or the value is our of range.
5477 <li>$VARIABLE is not available for the input method.
5478 <li>$LANGUAGE and $NAME do not specify an existing input method.
5482 minput_get_variable (), minput_save_config (). */
5484 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5486 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5487 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5489 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5490 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5491 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5493 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5494 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5496 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5497 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5499 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5500 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5502 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5503 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5505 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5506 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5507 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5508 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5512 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5514 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5515 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5516 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5520 minput_get_commands (), minput_save_config ().
5523 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5526 MInputMethodInfo *im_info, *config;
5531 im_info = get_im_info (language, name, Mnil, Mvariable);
5533 MERROR (MERROR_IM, -1);
5534 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5536 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5537 MERROR (MERROR_IM, -1);
5539 if (value && ! MPLIST_TAIL_P (value))
5541 plist = MPLIST_PLIST (plist);
5542 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5543 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5544 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5545 if (MPLIST_KEY (plist) != Mt
5546 && ! check_variable_value (value, plist))
5547 MERROR (MERROR_IM, -1);
5550 config = get_config_info (im_info);
5553 if (! im_config_list)
5554 im_config_list = mplist ();
5555 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5556 config->cmds = mplist ();
5557 config->vars = mplist ();
5560 if (! value && MPLIST_TAIL_P (config->vars))
5561 /* Nothing to do. */
5564 if (variable == Mnil)
5568 /* Cancel the configuration. */
5569 if (MPLIST_TAIL_P (config->vars))
5571 mplist_set (config->vars, Mnil, NULL);
5575 /* Cancel the customization. */
5576 MInputMethodInfo *custom = get_custom_info (im_info);
5578 if (MPLIST_TAIL_P (config->vars)
5579 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5580 /* Nothing to do. */
5582 mplist_set (config->vars, Mnil, NULL);
5583 MPLIST_DO (plist, custom->vars)
5585 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5587 mplist_add (plist, Msymbol, variable);
5588 mplist_push (config->vars, Mplist, plist);
5589 M17N_OBJECT_UNREF (plist);
5595 plist = mplist__assq (config->vars, variable);
5598 /* Cancel the configuration. */
5601 mplist__pop_unref (plist);
5603 else if (MPLIST_TAIL_P (value))
5605 /* Cancel the customization. */
5606 MInputMethodInfo *custom = get_custom_info (im_info);
5607 int no_custom = (! custom || ! custom->vars
5608 || ! mplist__assq (custom->vars, variable));
5614 mplist_add (config->vars, Mplist, plist);
5615 M17N_OBJECT_UNREF (plist);
5616 plist = mplist_add (plist, Msymbol, variable);
5621 mplist__pop_unref (plist);
5624 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5625 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5626 mplist_set (plist, Mnil ,NULL);
5634 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5635 if (! MPLIST_TAIL_P (plist))
5636 mplist_set (plist, Mnil, NULL);
5641 mplist_add (config->vars, Mplist, plist);
5642 M17N_OBJECT_UNREF (plist);
5643 plist = mplist_add (plist, Msymbol, variable);
5644 plist = MPLIST_NEXT (plist);
5646 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5649 config_all_variables (im_info);
5650 im_info->tick = time (NULL);
5657 @brief Get the name of per-user customization file.
5659 The minput_config_file () function returns the absolute path name
5660 of per-user customization file into which minput_save_config ()
5661 save configurations. It is usually @c config.mic under the
5662 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5663 directory). It is not assured that the file of the returned name
5664 exists nor is readable/writable. If minput_save_config () fails
5665 and returns -1, an application program might check the file, make
5666 it writable (if possible), and try minput_save_config () again.
5670 This function returns a string. As the string is kept in the
5671 library, the caller must not modify nor free it.
5674 minput_save_config ()
5677 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5679 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5680 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5681 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5682 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5683 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5684 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5685 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5690 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5691 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5694 minput_save_config ()
5698 minput_config_file ()
5702 return mdatabase__file (im_custom_mdb);
5708 @brief Save configurations in per-user customization file.
5710 The minput_save_config () function saves the configurations done
5711 so far in the current session into the per-user customization
5716 If the operation was successful, 1 is returned. If the per-user
5717 customization file is currently locked, 0 is returned. In that
5718 case, the caller may wait for a while and try again. If the
5719 configuration file is not writable, -1 is returned. In that case,
5720 the caller may check the name of the file by calling
5721 minput_config_file (), make it writable if possible, and try
5725 minput_config_file () */
5727 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5729 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5730 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5734 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5735 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5736 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5737 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5741 minput_config_file () */
5744 minput_save_config (void)
5746 MPlist *data, *tail, *plist, *p, *elt;
5750 ret = mdatabase__lock (im_custom_mdb);
5753 if (! im_config_list)
5755 update_custom_info ();
5756 if (! im_custom_list)
5757 im_custom_list = mplist ();
5759 /* At first, reflect configuration in customization. */
5760 MPLIST_DO (plist, im_config_list)
5762 MPlist *pl = MPLIST_PLIST (plist);
5763 MSymbol language, name, extra, command, variable;
5764 MInputMethodInfo *custom, *config;
5766 language = MPLIST_SYMBOL (pl);
5767 pl = MPLIST_NEXT (pl);
5768 name = MPLIST_SYMBOL (pl);
5769 pl = MPLIST_NEXT (pl);
5770 extra = MPLIST_SYMBOL (pl);
5771 pl = MPLIST_NEXT (pl);
5772 config = MPLIST_VAL (pl);
5773 custom = get_custom_info (config);
5775 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5777 MPLIST_DO (pl, config->cmds)
5779 elt = MPLIST_PLIST (pl);
5780 command = MPLIST_SYMBOL (elt);
5782 p = mplist__assq (custom->cmds, command);
5784 custom->cmds = mplist (), p = NULL;
5785 elt = MPLIST_NEXT (elt);
5788 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5789 mplist_set (p, Mnil, NULL);
5794 mplist_add (custom->cmds, Mplist, p);
5795 M17N_OBJECT_UNREF (p);
5796 mplist_add (p, Msymbol, command);
5797 p = mplist_add (p, Msymbol, Mnil);
5798 p = MPLIST_NEXT (p);
5800 mplist__conc (p, elt);
5803 MPLIST_DO (pl, config->vars)
5805 elt = MPLIST_PLIST (pl);
5806 variable = MPLIST_SYMBOL (elt);
5808 p = mplist__assq (custom->vars, variable);
5810 custom->vars = mplist (), p = NULL;
5811 elt = MPLIST_NEXT (elt);
5814 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5815 mplist_set (p, Mnil, NULL);
5820 mplist_add (custom->vars, Mplist, p);
5821 M17N_OBJECT_UNREF (p);
5822 mplist_add (p, Msymbol, variable);
5823 p = mplist_add (p, Msymbol, Mnil);
5824 p = MPLIST_NEXT (p);
5826 mplist__conc (p, elt);
5829 free_im_list (im_config_list);
5830 im_config_list = NULL;
5832 /* Next, reflect customization to the actual plist to be written. */
5833 data = tail = mplist ();
5834 MPLIST_DO (plist, im_custom_list)
5836 MPlist *pl = MPLIST_PLIST (plist);
5837 MSymbol language, name, extra;
5838 MInputMethodInfo *custom, *im_info;
5840 language = MPLIST_SYMBOL (pl);
5841 pl = MPLIST_NEXT (pl);
5842 name = MPLIST_SYMBOL (pl);
5843 pl = MPLIST_NEXT (pl);
5844 extra = MPLIST_SYMBOL (pl);
5845 pl = MPLIST_NEXT (pl);
5846 custom = MPLIST_VAL (pl);
5847 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5848 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5850 im_info = lookup_im_info (im_info_list, language, name, extra);
5854 config_all_commands (im_info);
5856 config_all_variables (im_info);
5860 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5862 MPLIST_DO (p, custom->cmds)
5863 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5865 if (! MPLIST_TAIL_P (p))
5869 mplist_add (elt, Mplist, pl);
5870 M17N_OBJECT_UNREF (pl);
5871 pl = mplist_add (pl, Msymbol, Mcommand);
5872 MPLIST_DO (p, custom->cmds)
5873 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5874 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5877 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5879 MPLIST_DO (p, custom->vars)
5880 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5882 if (! MPLIST_TAIL_P (p))
5887 mplist_add (elt, Mplist, pl);
5888 M17N_OBJECT_UNREF (pl);
5889 pl = mplist_add (pl, Msymbol, Mvariable);
5890 MPLIST_DO (p, custom->vars)
5891 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5892 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5898 mplist_push (elt, Mplist, pl);
5899 M17N_OBJECT_UNREF (pl);
5900 pl = mplist_add (pl, Msymbol, Minput_method);
5901 pl = mplist_add (pl, Msymbol, language);
5902 pl = mplist_add (pl, Msymbol, name);
5904 pl = mplist_add (pl, Msymbol, extra);
5905 tail = mplist_add (tail, Mplist, elt);
5906 M17N_OBJECT_UNREF (elt);
5910 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5911 ret = mdatabase__save (im_custom_mdb, data);
5912 mdatabase__unlock (im_custom_mdb);
5913 M17N_OBJECT_UNREF (data);
5914 return (ret < 0 ? -1 : 1);
5921 @name Obsolete functions
5924 @name Obsolete ¤Ê´Ø¿ô
5930 @brief Get a list of variables of an input method (obsolete).
5932 This function is obsolete. Use minput_get_variable () instead.
5934 The minput_get_variables () function returns a plist (#MPlist) of
5935 variables used to control the behavior of the input method
5936 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5937 (@ref m17nPlist) of the following format:
5940 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5941 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5945 @c VARNAME is a symbol representing the variable name.
5947 @c DOC-MTEXT is an M-text describing the variable.
5949 @c DEFAULT-VALUE is the default value of the variable. It is a
5950 symbol, integer, or M-text.
5952 @c VALUEs (if any) specifies the possible values of the variable.
5953 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5954 @c TO), where @c FROM and @c TO specifies a range of possible
5957 For instance, suppose an input method has the variables:
5959 @li name:intvar, description:"value is an integer",
5960 initial value:0, value-range:0..3,10,20
5962 @li name:symvar, description:"value is a symbol",
5963 initial value:nil, value-range:a, b, c, nil
5965 @li name:txtvar, description:"value is an M-text",
5966 initial value:empty text, no value-range (i.e. any text)
5968 Then, the returned plist is as follows.
5971 (intvar ("value is an integer" 0 (0 3) 10 20)
5972 symvar ("value is a symbol" nil a b c nil)
5973 txtvar ("value is an M-text" ""))
5977 If the input method uses any variables, a pointer to #MPlist is
5978 returned. As the plist is kept in the library, the caller must not
5979 modify nor free it. If the input method does not use any
5980 variable, @c NULL is returned. */
5982 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5984 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5985 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5986 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5990 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5991 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5995 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5997 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5999 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
6002 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
6003 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
6004 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
6006 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
6008 @li name:intvar, ÀâÌÀ:"value is an integer",
6009 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
6011 @li name:symvar, ÀâÌÀ:"value is a symbol",
6012 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
6014 @li name:txtvar, ÀâÌÀ:"value is an M-text",
6015 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
6017 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
6020 (intvar ("value is an integer" 0 (0 3) 10 20)
6021 symvar ("value is a symbol" nil a b c nil)
6022 txtvar ("value is an M-text" ""))
6026 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
6027 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6028 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
6031 minput_get_variables (MSymbol language, MSymbol name)
6033 MInputMethodInfo *im_info;
6038 im_info = get_im_info (language, name, Mnil, Mvariable);
6039 if (! im_info || ! im_info->configured_vars)
6042 M17N_OBJECT_UNREF (im_info->bc_vars);
6043 im_info->bc_vars = mplist ();
6044 MPLIST_DO (vars, im_info->configured_vars)
6046 MPlist *plist = MPLIST_PLIST (vars);
6047 MPlist *elt = mplist ();
6049 mplist_push (im_info->bc_vars, Mplist, elt);
6050 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
6051 elt = MPLIST_NEXT (elt);
6052 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
6053 M17N_OBJECT_UNREF (elt);
6055 return im_info->bc_vars;
6061 @brief Set the initial value of an input method variable.
6063 The minput_set_variable () function sets the initial value of
6064 input method variable $VARIABLE to $VALUE for the input method
6065 specified by $LANGUAGE and $NAME.
6067 By default, the initial value is 0.
6069 This setting gets effective in a newly opened input method.
6072 If the operation was successful, 0 is returned. Otherwise -1 is
6073 returned, and #merror_code is set to @c MERROR_IM. */
6075 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
6077 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
6078 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
6079 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6081 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6083 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6086 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6087 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6090 minput_set_variable (MSymbol language, MSymbol name,
6091 MSymbol variable, void *value)
6094 MInputMethodInfo *im_info;
6099 if (variable == Mnil)
6100 MERROR (MERROR_IM, -1);
6101 plist = minput_get_variable (language, name, variable);
6102 plist = MPLIST_PLIST (plist);
6103 plist = MPLIST_NEXT (plist);
6105 mplist_add (pl, MPLIST_KEY (plist), value);
6106 ret = minput_config_variable (language, name, variable, pl);
6107 M17N_OBJECT_UNREF (pl);
6110 im_info = get_im_info (language, name, Mnil, Mvariable);
6119 @brief Get information about input method commands.
6121 The minput_get_commands () function returns information about
6122 input method commands of the input method specified by $LANGUAGE
6123 and $NAME. An input method command is a pseudo key event to which
6124 one or more actual input key sequences are assigned.
6126 There are two kinds of commands, global and local. Global
6127 commands are used by multiple input methods for the same purpose,
6128 and have global key assignments. Local commands are used only by
6129 a specific input method, and have only local key assignments.
6131 Each input method may locally change key assignments for global
6132 commands. The global key assignment for a global command is
6133 effective only when the current input method does not have local
6134 key assignments for that command.
6136 If $NAME is #Mnil, information about global commands is returned.
6137 In this case $LANGUAGE is ignored.
6139 If $NAME is not #Mnil, information about those commands that have
6140 local key assignments in the input method specified by $LANGUAGE
6141 and $NAME is returned.
6144 If no input method commands are found, this function returns @c NULL.
6146 Otherwise, a pointer to a plist is returned. The key of each
6147 element in the plist is a symbol representing a command, and the
6148 value is a plist of the form COMMAND-INFO described below.
6150 The first element of COMMAND-INFO has the key #Mtext, and the
6151 value is an M-text describing the command.
6153 If there are no more elements, that means no key sequences are
6154 assigned to the command. Otherwise, each of the remaining
6155 elements has the key #Mplist, and the value is a plist whose keys are
6156 #Msymbol and values are symbols representing input keys, which are
6157 currently assigned to the command.
6159 As the returned plist is kept in the library, the caller must not
6160 modify nor free it. */
6162 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6164 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6165 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6166 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6167 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6169 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6170 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6171 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6172 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6174 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6175 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6176 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6179 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6180 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6182 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6183 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6187 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6189 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6190 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6191 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6193 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6194 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6195 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6198 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6199 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6200 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6201 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6202 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6204 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6205 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6208 minput_get_commands (MSymbol language, MSymbol name)
6210 MInputMethodInfo *im_info;
6215 im_info = get_im_info (language, name, Mnil, Mcommand);
6216 if (! im_info || ! im_info->configured_vars)
6218 M17N_OBJECT_UNREF (im_info->bc_cmds);
6219 im_info->bc_cmds = mplist ();
6220 MPLIST_DO (cmds, im_info->configured_cmds)
6222 MPlist *plist = MPLIST_PLIST (cmds);
6223 MPlist *elt = mplist ();
6225 mplist_push (im_info->bc_cmds, Mplist, elt);
6226 mplist_add (elt, MPLIST_SYMBOL (plist),
6227 mplist_copy (MPLIST_NEXT (plist)));
6228 M17N_OBJECT_UNREF (elt);
6230 return im_info->bc_cmds;
6236 @brief Assign a key sequence to an input method command (obsolete).
6238 This function is obsolete. Use minput_config_command () instead.
6240 The minput_assign_command_keys () function assigns input key
6241 sequence $KEYSEQ to input method command $COMMAND for the input
6242 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6243 key sequence is assigned globally no matter what $LANGUAGE is.
6244 Otherwise the key sequence is assigned locally.
6246 Each element of $KEYSEQ must have the key $Msymbol and the value
6247 must be a symbol representing an input key.
6249 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6250 globally or locally.
6252 This assignment gets effective in a newly opened input method.
6255 If the operation was successful, 0 is returned. Otherwise -1 is
6256 returned, and #merror_code is set to @c MERROR_IM. */
6258 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6260 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6261 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6262 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6263 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6264 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6266 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6267 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6269 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6270 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6272 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6276 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6277 #merror_code ¤ò @c MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6280 minput_assign_command_keys (MSymbol language, MSymbol name,
6281 MSymbol command, MPlist *keyseq)
6287 if (command == Mnil)
6288 MERROR (MERROR_IM, -1);
6293 if (! check_command_keyseq (keyseq))
6294 MERROR (MERROR_IM, -1);
6296 mplist_add (plist, Mplist, keyseq);
6301 ret = minput_config_command (language, name, command, keyseq);
6302 M17N_OBJECT_UNREF (keyseq);
6309 @brief Call a callback function
6311 The minput_callback () functions calls a callback function
6312 $COMMAND assigned for the input context $IC. The caller must set
6313 specific elements in $IC->plist if the callback function requires.
6316 If there exists a specified callback function, 0 is returned.
6317 Otherwise -1 is returned. By side effects, $IC->plist may be
6321 minput_callback (MInputContext *ic, MSymbol command)
6323 MInputCallbackFunc func;
6325 if (! ic->im->driver.callback_list)
6327 func = ((MInputCallbackFunc)
6328 mplist_get_func (ic->im->driver.callback_list, command));
6331 (func) (ic, command);
6338 /*** @addtogroup m17nDebug */
6344 @brief Dump an input method.
6346 The mdebug_dump_im () function prints the input method $IM in a
6347 human readable way to the stderr. $INDENT specifies how many
6348 columns to indent the lines but the first one.
6351 This function returns $IM. */
6353 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6355 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6356 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6359 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6362 mdebug_dump_im (MInputMethod *im, int indent)
6364 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6367 prefix = (char *) alloca (indent + 1);
6368 memset (prefix, 32, indent);
6369 prefix[indent] = '\0';
6371 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6372 msymbol_name (im->name));
6373 mdebug_dump_mtext (im_info->title, 0, 0);
6374 if (im->name != Mnil)
6378 MPLIST_DO (state, im_info->states)
6380 fprintf (stderr, "\n%s ", prefix);
6381 dump_im_state (MPLIST_VAL (state), indent + 2);
6384 fprintf (stderr, ")");