1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_flag = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mpop = msymbol ("pop");
406 Mundo = msymbol ("undo");
407 Mcall = msymbol ("call");
408 Mshift = msymbol ("shift");
409 Mselect = msymbol ("select");
410 Mshow = msymbol ("show");
411 Mhide = msymbol ("hide");
412 Mcommit = msymbol ("commit");
413 Munhandle = msymbol ("unhandle");
414 Mset = msymbol ("set");
415 Madd = msymbol ("add");
416 Msub = msymbol ("sub");
417 Mmul = msymbol ("mul");
418 Mdiv = msymbol ("div");
419 Mequal = msymbol ("=");
420 Mless = msymbol ("<");
421 Mgreater = msymbol (">");
422 Mless_equal = msymbol ("<=");
423 Mgreater_equal = msymbol (">=");
424 Mcond = msymbol ("cond");
425 Mplus = msymbol ("+");
426 Mminus = msymbol ("-");
427 Mstar = msymbol ("*");
428 Mslash = msymbol ("/");
429 Mand = msymbol ("&");
431 Mnot = msymbol ("!");
433 Mat_reload = msymbol ("@reload");
435 Mcandidates_group_size = msymbol ("candidates-group-size");
436 Mcandidates_charset = msymbol ("candidates-charset");
438 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
439 Mcandidate_index = msymbol (" candidate-index");
441 Minit = msymbol ("init");
442 Mfini = msymbol ("fini");
444 Mdescription = msymbol ("description");
445 Mcommand = msymbol ("command");
446 Mvariable = msymbol ("variable");
447 Mglobal = msymbol ("global");
448 Mconfig = msymbol ("config");
449 M_gettext = msymbol ("_");
451 load_im_info_keys = mplist ();
452 mplist_add (load_im_info_keys, Mstate, Mnil);
453 mplist_push (load_im_info_keys, Mmap, Mnil);
455 im_info_list = mplist ();
456 im_config_list = im_custom_list = NULL;
457 im_custom_mdb = NULL;
458 update_custom_info ();
460 update_global_info ();
462 fully_initialized = 1;
465 #define MINPUT__INIT() \
467 if (! fully_initialized) \
468 fully_initialize (); \
473 marker_code (MSymbol sym, int surrounding)
479 name = MSYMBOL_NAME (sym);
480 return (name[0] != '@' ? -1
481 : (((name[1] >= '0' && name[1] <= '9')
482 || name[1] == '<' || name[1] == '>' || name[1] == '='
483 || name[1] == '[' || name[1] == ']'
485 && name[2] == '\0') ? name[1]
486 : (name[1] != '+' && name[1] != '-') ? -1
487 : (name[2] == '\0' || surrounding) ? name[1]
492 /* Return a plist containing an integer value of VAR. */
495 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
497 MPlist *plist = mplist__assq (ic_info->vars, var);
501 plist = MPLIST_PLIST (plist);
502 return MPLIST_NEXT (plist);
506 mplist_push (ic_info->vars, Mplist, plist);
507 M17N_OBJECT_UNREF (plist);
508 plist = mplist_add (plist, Msymbol, var);
509 plist = mplist_add (plist, Minteger, (void *) 0);
514 get_surrounding_text (MInputContext *ic, int len)
518 mplist_push (ic->plist, Minteger, (void *) len);
519 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
520 && MPLIST_MTEXT_P (ic->plist))
521 mt = MPLIST_MTEXT (ic->plist);
522 mplist_pop (ic->plist);
527 delete_surrounding_text (MInputContext *ic, int pos)
529 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
531 mplist_push (ic->plist, Minteger, (void *) pos);
532 minput_callback (ic, Minput_delete_surrounding_text);
533 mplist_pop (ic->plist);
536 M17N_OBJECT_UNREF (ic_info->preceding_text);
537 ic_info->preceding_text = NULL;
541 M17N_OBJECT_UNREF (ic_info->following_text);
542 ic_info->following_text = NULL;
547 get_preceding_char (MInputContext *ic, int pos)
549 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
553 if (pos && ic_info->preceding_text)
555 len = mtext_nchars (ic_info->preceding_text);
557 return mtext_ref_char (ic_info->preceding_text, len - pos);
559 mt = get_surrounding_text (ic, - pos);
562 len = mtext_nchars (mt);
563 if (ic_info->preceding_text)
565 if (mtext_nchars (ic_info->preceding_text) < len)
567 M17N_OBJECT_UNREF (ic_info->preceding_text);
568 ic_info->preceding_text = mt;
571 M17N_OBJECT_UNREF (mt);
574 ic_info->preceding_text = mt;
577 return mtext_ref_char (ic_info->preceding_text, len - pos);
581 get_following_char (MInputContext *ic, int pos)
583 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
587 if (ic_info->following_text)
589 len = mtext_nchars (ic_info->following_text);
591 return mtext_ref_char (ic_info->following_text, pos);
593 mt = get_surrounding_text (ic, pos + 1);
596 len = mtext_nchars (mt);
597 if (ic_info->following_text)
599 if (mtext_nchars (ic_info->following_text) < len)
601 M17N_OBJECT_UNREF (ic_info->following_text);
602 ic_info->following_text = mt;
605 M17N_OBJECT_UNREF (mt);
608 ic_info->following_text = mt;
611 return mtext_ref_char (ic_info->following_text, pos);
615 surrounding_pos (MSymbol sym)
621 name = MSYMBOL_NAME (sym);
623 && (name[1] == '-' || name[1] == '+')
624 && name[2] >= '1' && name[2] <= '9')
625 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
630 integer_value (MInputContext *ic, MPlist *arg, int surrounding)
632 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
634 MText *preedit = ic->preedit;
635 int len = mtext_nchars (preedit);
637 if (MPLIST_INTEGER_P (arg))
638 return MPLIST_INTEGER (arg);
640 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
643 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
645 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
648 return ic_info->key_head;
649 if ((code == '-' || code == '+'))
651 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
655 pos = atoi (name + 1);
657 return get_preceding_char (ic, 0);
659 pos = ic->cursor_pos + pos;
661 pos = ic->cursor_pos + pos - 1;
664 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
665 return mtext_ref_char (ic->produced,
666 mtext_len (ic->produced) + pos);
667 return get_preceding_char (ic, - pos);
670 return get_following_char (ic, pos - len);
673 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
675 else if (code >= '0' && code <= '9')
677 else if (code == '=')
678 pos = ic->cursor_pos;
679 else if (code == '[')
680 pos = ic->cursor_pos - 1;
681 else if (code == ']')
682 pos = ic->cursor_pos + 1;
683 else if (code == '<')
685 else if (code == '>')
687 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
691 parse_expression (MPlist *plist)
695 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
697 if (! MPLIST_PLIST_P (plist))
699 plist = MPLIST_PLIST (plist);
700 op = MPLIST_SYMBOL (plist);
701 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
702 && op != Mand && op != Mor && op != Mnot
703 && op != Mless && op != Mgreater && op != Mequal
704 && op != Mless_equal && op != Mgreater_equal)
705 MERROR (MERROR_IM, -1);
706 MPLIST_DO (plist, MPLIST_NEXT (plist))
707 if (parse_expression (plist) < 0)
713 resolve_expression (MInputContext *ic, MPlist *plist)
718 if (MPLIST_INTEGER_P (plist))
719 return MPLIST_INTEGER (plist);
720 if (MPLIST_SYMBOL_P (plist))
721 return integer_value (ic, plist, 1);
722 if (! MPLIST_PLIST_P (plist))
724 plist = MPLIST_PLIST (plist);
725 if (! MPLIST_SYMBOL_P (plist))
727 op = MPLIST_SYMBOL (plist);
728 plist = MPLIST_NEXT (plist);
729 val = resolve_expression (ic, plist);
731 MPLIST_DO (plist, MPLIST_NEXT (plist))
732 val += resolve_expression (ic, plist);
733 else if (op == Mminus)
734 MPLIST_DO (plist, MPLIST_NEXT (plist))
735 val -= resolve_expression (ic, plist);
736 else if (op == Mstar)
737 MPLIST_DO (plist, MPLIST_NEXT (plist))
738 val *= resolve_expression (ic, plist);
739 else if (op == Mslash)
740 MPLIST_DO (plist, MPLIST_NEXT (plist))
741 val /= resolve_expression (ic, plist);
743 MPLIST_DO (plist, MPLIST_NEXT (plist))
744 val &= resolve_expression (ic, plist);
746 MPLIST_DO (plist, MPLIST_NEXT (plist))
747 val |= resolve_expression (ic, plist);
750 else if (op == Mless)
751 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
752 else if (op == Mequal)
753 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
754 else if (op == Mgreater)
755 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
756 else if (op == Mless_equal)
757 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
758 else if (op == Mgreater_equal)
759 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
763 /* Parse PLIST as an action list. PLIST should have this form:
764 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
765 Return 0 if successfully parsed, otherwise return -1. */
768 parse_action_list (MPlist *plist, MPlist *macros)
770 MPLIST_DO (plist, plist)
772 if (MPLIST_MTEXT_P (plist))
774 /* This is a short form of (insert MTEXT). */
775 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
776 MERROR (MERROR_IM, -1); */
778 else if (MPLIST_PLIST_P (plist)
779 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
780 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
784 /* This is a short form of (insert (GROUPS *)). */
785 MPLIST_DO (pl, MPLIST_PLIST (plist))
787 if (MPLIST_PLIST_P (pl))
791 MPLIST_DO (elt, MPLIST_PLIST (pl))
792 if (! MPLIST_MTEXT_P (elt)
793 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
794 MERROR (MERROR_IM, -1);
798 if (! MPLIST_MTEXT_P (pl)
799 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
800 MERROR (MERROR_IM, -1);
804 else if (MPLIST_INTEGER_P (plist))
806 int c = MPLIST_INTEGER (plist);
808 if (c < 0 || c > MCHAR_MAX)
809 MERROR (MERROR_IM, -1);
811 else if (MPLIST_PLIST_P (plist)
812 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
814 MPlist *pl = MPLIST_PLIST (plist);
815 MSymbol action_name = MPLIST_SYMBOL (pl);
817 pl = MPLIST_NEXT (pl);
819 if (action_name == M_candidates)
821 /* This is an already regularised action. */
824 if (action_name == Minsert)
826 if (MPLIST_MTEXT_P (pl))
828 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
829 MERROR (MERROR_IM, -1);
831 else if (MPLIST_INTEGER_P (pl))
833 int c = MPLIST_INTEGER (pl);
835 if (c < 0 || c > MCHAR_MAX)
836 MERROR (MERROR_IM, -1);
838 else if (MPLIST_PLIST_P (pl))
840 MPLIST_DO (pl, MPLIST_PLIST (pl))
842 if (MPLIST_PLIST_P (pl))
846 MPLIST_DO (elt, MPLIST_PLIST (pl))
847 if (! MPLIST_MTEXT_P (elt)
848 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
849 MERROR (MERROR_IM, -1);
853 if (! MPLIST_MTEXT_P (pl)
854 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
855 MERROR (MERROR_IM, -1);
859 else if (! MPLIST_SYMBOL_P (pl))
860 MERROR (MERROR_IM, -1);
862 else if (action_name == Mselect
863 || action_name == Mdelete
864 || action_name == Mmove)
866 if (parse_expression (pl) < 0)
869 else if (action_name == Mmark
870 || action_name == Mcall
871 || action_name == Mshift)
873 if (! MPLIST_SYMBOL_P (pl))
874 MERROR (MERROR_IM, -1);
876 else if (action_name == Mundo)
878 if (! MPLIST_TAIL_P (pl))
880 if (! MPLIST_SYMBOL_P (pl)
881 && ! MPLIST_INTEGER_P (pl))
882 MERROR (MERROR_IM, -1);
885 else if (action_name == Mpushback)
887 if (MPLIST_MTEXT_P (pl))
889 MText *mt = MPLIST_MTEXT (pl);
891 if (mtext_nchars (mt) != mtext_nbytes (mt))
892 MERROR (MERROR_IM, -1);
894 else if (MPLIST_PLIST_P (pl))
898 MPLIST_DO (p, MPLIST_PLIST (pl))
899 if (! MPLIST_SYMBOL_P (p))
900 MERROR (MERROR_IM, -1);
902 else if (! MPLIST_INTEGER_P (pl))
903 MERROR (MERROR_IM, -1);
905 else if (action_name == Mset || action_name == Madd
906 || action_name == Msub || action_name == Mmul
907 || action_name == Mdiv)
909 if (! MPLIST_SYMBOL_P (pl))
910 MERROR (MERROR_IM, -1);
911 if (parse_expression (MPLIST_NEXT (pl)) < 0)
914 else if (action_name == Mequal || action_name == Mless
915 || action_name == Mgreater || action_name == Mless_equal
916 || action_name == Mgreater_equal)
918 if (parse_expression (pl) < 0
919 || parse_expression (MPLIST_NEXT (pl)) < 0)
921 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
922 if (! MPLIST_PLIST_P (pl))
923 MERROR (MERROR_IM, -1);
924 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
925 MERROR (MERROR_IM, -1);
926 pl = MPLIST_NEXT (pl);
927 if (MPLIST_PLIST_P (pl)
928 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
929 MERROR (MERROR_IM, -1);
931 else if (action_name == Mshow || action_name == Mhide
932 || action_name == Mcommit || action_name == Munhandle
933 || action_name == Mpop)
935 else if (action_name == Mcond)
938 if (! MPLIST_PLIST_P (pl))
939 MERROR (MERROR_IM, -1);
941 else if (! macros || ! mplist_get (macros, action_name))
942 MERROR (MERROR_IM, -1);
944 else if (! MPLIST_SYMBOL_P (plist))
945 MERROR (MERROR_IM, -1);
952 resolve_command (MPlist *cmds, MSymbol command)
956 if (! cmds || ! (plist = mplist__assq (cmds, command)))
958 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
959 plist = MPLIST_NEXT (plist);
960 plist = MPLIST_NEXT (plist);
961 plist = MPLIST_NEXT (plist);
965 /* Load a translation into MAP from PLIST.
967 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
970 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
971 MPlist *branch_actions, MPlist *macros)
976 if (MPLIST_MTEXT_P (keylist))
978 MText *mt = MPLIST_MTEXT (keylist);
980 len = mtext_nchars (mt);
981 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
983 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
984 for (i = 0; i < len; i++)
985 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
991 if (MFAILP (MPLIST_PLIST_P (keylist)))
993 elt = MPLIST_PLIST (keylist);
994 len = MPLIST_LENGTH (elt);
995 if (MFAILP (len > 0))
997 keyseq = (MSymbol *) alloca (sizeof (int) * len);
998 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
1000 if (MPLIST_INTEGER_P (elt))
1002 int c = MPLIST_INTEGER (elt);
1004 if (MFAILP (c >= 0 && c < 0x100))
1006 keyseq[i] = one_char_symbol[c];
1010 if (MFAILP (MPLIST_SYMBOL_P (elt)))
1012 keyseq[i] = MPLIST_SYMBOL (elt);
1017 for (i = 0; i < len; i++)
1019 MIMMap *deeper = NULL;
1022 deeper = mplist_get (map->submaps, keyseq[i]);
1024 map->submaps = mplist ();
1027 /* Fixme: It is better to make all deeper maps at once. */
1028 MSTRUCT_CALLOC (deeper, MERROR_IM);
1029 mplist_put (map->submaps, keyseq[i], deeper);
1034 /* We reach a terminal map. */
1035 if (map->map_actions
1036 || map->branch_actions)
1037 /* This map is already defined. We avoid overriding it. */
1040 if (! MPLIST_TAIL_P (map_actions))
1042 if (parse_action_list (map_actions, macros) < 0)
1043 MERROR (MERROR_IM, -1);
1044 map->map_actions = map_actions;
1048 map->branch_actions = branch_actions;
1049 M17N_OBJECT_REF (branch_actions);
1055 /* Load a branch from PLIST into MAP. PLIST has this form:
1056 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1059 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1062 MPlist *branch_actions;
1064 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1066 map_name = MPLIST_SYMBOL (plist);
1067 plist = MPLIST_NEXT (plist);
1068 if (MPLIST_TAIL_P (plist))
1069 branch_actions = NULL;
1070 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1073 branch_actions = plist;
1074 if (map_name == Mnil)
1076 map->branch_actions = branch_actions;
1078 M17N_OBJECT_REF (branch_actions);
1080 else if (map_name == Mt)
1082 map->map_actions = branch_actions;
1084 M17N_OBJECT_REF (branch_actions);
1086 else if (im_info->maps)
1088 plist = (MPlist *) mplist_get (im_info->maps, map_name);
1089 if (! plist && im_info->configured_vars)
1091 MPlist *p = mplist__assq (im_info->configured_vars, map_name);
1093 if (p && MPLIST_PLIST_P (p))
1095 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p))));
1096 if (MPLIST_SYMBOL_P (p))
1097 plist = mplist_get (im_info->maps, MPLIST_SYMBOL (p));
1102 MPLIST_DO (plist, plist)
1104 MPlist *keylist, *map_actions;
1106 if (! MPLIST_PLIST_P (plist))
1107 MERROR (MERROR_IM, -1);
1108 keylist = MPLIST_PLIST (plist);
1109 map_actions = MPLIST_NEXT (keylist);
1110 if (MPLIST_SYMBOL_P (keylist))
1112 MSymbol command = MPLIST_SYMBOL (keylist);
1115 if (MFAILP (command != Mat_reload))
1117 pl = resolve_command (im_info->configured_cmds, command);
1121 load_translation (map, pl, map_actions, branch_actions,
1125 load_translation (map, keylist, map_actions, branch_actions,
1134 /* Load a macro from PLIST into IM_INFO->macros.
1135 PLIST has this from:
1136 PLIST ::= ( MACRO-NAME ACTION * )
1137 IM_INFO->macros is a plist of macro names vs action list. */
1140 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1145 if (! MPLIST_SYMBOL_P (plist))
1146 MERROR (MERROR_IM, -1);
1147 name = MPLIST_SYMBOL (plist);
1148 plist = MPLIST_NEXT (plist);
1149 if (MPLIST_TAIL_P (plist)
1150 || parse_action_list (plist, im_info->macros) < 0)
1151 MERROR (MERROR_IM, -1);
1152 pl = mplist_get (im_info->macros, name);
1153 M17N_OBJECT_UNREF (pl);
1154 mplist_put (im_info->macros, name, plist);
1155 M17N_OBJECT_REF (plist);
1159 /* Load an external module from PLIST into IM_INFO->externals.
1160 PLIST has this form:
1161 PLIST ::= ( MODULE-NAME FUNCTION * )
1162 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1165 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1170 MIMExternalModule *external;
1174 if (MPLIST_MTEXT_P (plist))
1175 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1176 else if (MPLIST_SYMBOL_P (plist))
1177 module = MPLIST_SYMBOL (plist);
1178 module_file = alloca (strlen (MSYMBOL_NAME (module))
1179 + strlen (DLOPEN_SHLIB_EXT) + 1);
1180 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1182 handle = dlopen (module_file, RTLD_NOW);
1183 if (MFAILP (handle))
1185 fprintf (stderr, "%s\n", dlerror ());
1188 func_list = mplist ();
1189 MPLIST_DO (plist, MPLIST_NEXT (plist))
1191 if (! MPLIST_SYMBOL_P (plist))
1192 MERROR_GOTO (MERROR_IM, err_label);
1193 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1196 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1199 MSTRUCT_MALLOC (external, MERROR_IM);
1200 external->handle = handle;
1201 external->func_list = func_list;
1202 mplist_add (im_info->externals, module, external);
1207 M17N_OBJECT_UNREF (func_list);
1212 free_map (MIMMap *map, int top)
1217 M17N_OBJECT_UNREF (map->map_actions);
1220 MPLIST_DO (plist, map->submaps)
1221 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1222 M17N_OBJECT_UNREF (map->submaps);
1224 M17N_OBJECT_UNREF (map->branch_actions);
1229 free_state (void *object)
1231 MIMState *state = object;
1233 M17N_OBJECT_UNREF (state->title);
1235 free_map (state->map, 1);
1239 /** Load a state from PLIST into a newly allocated state object.
1240 PLIST has this form:
1241 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1242 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1243 Return the state object. */
1246 load_state (MInputMethodInfo *im_info, MPlist *plist)
1250 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1252 M17N_OBJECT (state, free_state, MERROR_IM);
1253 state->name = MPLIST_SYMBOL (plist);
1254 plist = MPLIST_NEXT (plist);
1255 if (MPLIST_MTEXT_P (plist))
1257 state->title = MPLIST_MTEXT (plist);
1258 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1259 Mlanguage, im_info->language);
1260 M17N_OBJECT_REF (state->title);
1261 plist = MPLIST_NEXT (plist);
1263 MSTRUCT_CALLOC (state->map, MERROR_IM);
1264 MPLIST_DO (plist, plist)
1266 if (MFAILP (MPLIST_PLIST_P (plist)))
1268 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1273 /* Return a newly created IM_INFO for an input method specified by
1274 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1276 static MInputMethodInfo *
1277 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1280 MInputMethodInfo *im_info;
1283 if (name == Mnil && extra == Mnil)
1284 language = Mt, extra = Mglobal;
1285 MSTRUCT_CALLOC (im_info, MERROR_IM);
1287 im_info->language = language;
1288 im_info->name = name;
1289 im_info->extra = extra;
1292 mplist_add (plist, Mplist, elt);
1293 M17N_OBJECT_UNREF (elt);
1294 elt = mplist_add (elt, Msymbol, language);
1295 elt = mplist_add (elt, Msymbol, name);
1296 elt = mplist_add (elt, Msymbol, extra);
1297 mplist_add (elt, Mt, im_info);
1303 fini_im_info (MInputMethodInfo *im_info)
1307 M17N_OBJECT_UNREF (im_info->cmds);
1308 M17N_OBJECT_UNREF (im_info->configured_cmds);
1309 M17N_OBJECT_UNREF (im_info->bc_cmds);
1310 M17N_OBJECT_UNREF (im_info->vars);
1311 M17N_OBJECT_UNREF (im_info->configured_vars);
1312 M17N_OBJECT_UNREF (im_info->bc_vars);
1313 M17N_OBJECT_UNREF (im_info->description);
1314 M17N_OBJECT_UNREF (im_info->title);
1315 if (im_info->states)
1317 MPLIST_DO (plist, im_info->states)
1319 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1321 M17N_OBJECT_UNREF (state);
1323 M17N_OBJECT_UNREF (im_info->states);
1326 if (im_info->macros)
1328 MPLIST_DO (plist, im_info->macros)
1329 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1330 M17N_OBJECT_UNREF (im_info->macros);
1333 if (im_info->externals)
1335 MPLIST_DO (plist, im_info->externals)
1337 MIMExternalModule *external = MPLIST_VAL (plist);
1339 dlclose (external->handle);
1340 M17N_OBJECT_UNREF (external->func_list);
1342 MPLIST_KEY (plist) = Mt;
1344 M17N_OBJECT_UNREF (im_info->externals);
1348 MPLIST_DO (plist, im_info->maps)
1350 MPlist *p = MPLIST_PLIST (plist);
1352 M17N_OBJECT_UNREF (p);
1354 M17N_OBJECT_UNREF (im_info->maps);
1361 free_im_info (MInputMethodInfo *im_info)
1363 fini_im_info (im_info);
1368 free_im_list (MPlist *plist)
1372 MPLIST_DO (pl, plist)
1374 MInputMethodInfo *im_info;
1376 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1377 im_info = MPLIST_VAL (elt);
1378 free_im_info (im_info);
1380 M17N_OBJECT_UNREF (plist);
1383 static MInputMethodInfo *
1384 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1386 if (name == Mnil && extra == Mnil)
1387 language = Mt, extra = Mglobal;
1388 while ((plist = mplist__assq (plist, language)))
1390 MPlist *elt = MPLIST_PLIST (plist);
1392 plist = MPLIST_NEXT (plist);
1393 elt = MPLIST_NEXT (elt);
1394 if (MPLIST_SYMBOL (elt) != name)
1396 elt = MPLIST_NEXT (elt);
1397 if (MPLIST_SYMBOL (elt) != extra)
1399 elt = MPLIST_NEXT (elt);
1400 return MPLIST_VAL (elt);
1405 static void load_im_info (MPlist *, MInputMethodInfo *);
1407 #define get_custom_info(im_info) \
1409 ? lookup_im_info (im_custom_list, (im_info)->language, \
1410 (im_info)->name, (im_info)->extra) \
1413 #define get_config_info(im_info) \
1415 ? lookup_im_info (im_config_list, (im_info)->language, \
1416 (im_info)->name, (im_info)->extra) \
1420 update_custom_info (void)
1426 if (mdatabase__check (im_custom_mdb) > 0)
1431 MDatabaseInfo *custom_dir_info;
1432 char custom_path[PATH_MAX + 1];
1434 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1435 if (! custom_dir_info->filename
1436 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1438 strcpy (custom_path, custom_dir_info->filename);
1439 strcat (custom_path, CUSTOM_FILE);
1440 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1446 free_im_list (im_custom_list);
1447 im_custom_list = NULL;
1449 plist = mdatabase_load (im_custom_mdb);
1452 im_custom_list = mplist ();
1454 MPLIST_DO (pl, plist)
1456 MSymbol language, name, extra;
1457 MInputMethodInfo *im_info;
1458 MPlist *im_data, *p;
1460 if (! MPLIST_PLIST_P (pl))
1462 p = MPLIST_PLIST (pl);
1463 im_data = MPLIST_NEXT (p);
1464 if (! MPLIST_PLIST_P (p))
1466 p = MPLIST_PLIST (p);
1467 if (! MPLIST_SYMBOL_P (p)
1468 || MPLIST_SYMBOL (p) != Minput_method)
1470 p = MPLIST_NEXT (p);
1471 if (! MPLIST_SYMBOL_P (p))
1473 language = MPLIST_SYMBOL (p);
1474 p = MPLIST_NEXT (p);
1475 if (! MPLIST_SYMBOL_P (p))
1477 name = MPLIST_SYMBOL (p);
1478 p = MPLIST_NEXT (p);
1479 if (MPLIST_TAIL_P (p))
1481 else if (MPLIST_SYMBOL_P (p))
1482 extra = MPLIST_SYMBOL (p);
1483 if (language == Mnil || (name == Mnil && extra == Mnil))
1485 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1486 load_im_info (im_data, im_info);
1488 M17N_OBJECT_UNREF (plist);
1493 update_global_info (void)
1499 int ret = mdatabase__check (global_info->mdb);
1503 fini_im_info (global_info);
1507 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1511 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1513 if (! global_info->mdb
1514 || ! (plist = mdatabase_load (global_info->mdb)))
1517 load_im_info (plist, global_info);
1518 M17N_OBJECT_UNREF (plist);
1523 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1524 and EXTRA. KEY, if not Mnil, tells which kind of information about
1525 the input method is necessary, and the returned IM_INFO may contain
1526 only that information. */
1528 static MInputMethodInfo *
1529 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1532 MInputMethodInfo *im_info;
1535 if (name == Mnil && extra == Mnil)
1536 language = Mt, extra = Mglobal;
1537 im_info = lookup_im_info (im_info_list, language, name, extra);
1540 if (key == Mnil ? im_info->states != NULL
1541 : key == Mcommand ? im_info->cmds != NULL
1542 : key == Mvariable ? im_info->vars != NULL
1543 : key == Mtitle ? im_info->title != NULL
1544 : key == Mdescription ? im_info->description != NULL
1546 /* IM_INFO already contains required information. */
1548 /* We have not yet loaded required information. */
1552 mdb = mdatabase_find (Minput_method, language, name, extra);
1555 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1560 plist = mdatabase_load (im_info->mdb);
1564 mplist_push (load_im_info_keys, key, Mt);
1565 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1566 mplist_pop (load_im_info_keys);
1570 MERROR (MERROR_IM, im_info);
1571 update_global_info ();
1572 load_im_info (plist, im_info);
1573 M17N_OBJECT_UNREF (plist);
1576 if (! im_info->cmds)
1577 im_info->cmds = mplist ();
1578 if (! im_info->vars)
1579 im_info->vars = mplist ();
1580 if (! im_info->states)
1581 im_info->states = mplist ();
1583 if (! im_info->title
1584 && (key == Mnil || key == Mtitle))
1585 im_info->title = (name == Mnil ? mtext ()
1586 : mtext_from_data (MSYMBOL_NAME (name),
1587 MSYMBOL_NAMELEN (name),
1588 MTEXT_FORMAT_US_ASCII));
1592 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1593 If updated, but got unloadable, return -1. Otherwise, update
1594 contents of IM_INFO from the new database, and return 1. */
1597 reload_im_info (MInputMethodInfo *im_info)
1602 update_custom_info ();
1603 update_global_info ();
1604 check = mdatabase__check (im_info->mdb);
1607 plist = mdatabase_load (im_info->mdb);
1610 fini_im_info (im_info);
1611 load_im_info (plist, im_info);
1612 M17N_OBJECT_UNREF (plist);
1613 if (! im_info->cmds)
1614 im_info->cmds = mplist ();
1615 if (! im_info->vars)
1616 im_info->vars = mplist ();
1617 if (! im_info->title)
1619 MSymbol name = im_info->name;
1621 im_info->title = (name == Mnil ? mtext ()
1622 : mtext_from_data (MSYMBOL_NAME (name),
1623 MSYMBOL_NAMELEN (name),
1624 MTEXT_FORMAT_US_ASCII));
1629 static MInputMethodInfo *
1630 get_im_info_by_tags (MPlist *plist)
1635 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1636 i++, plist = MPLIST_NEXT (plist))
1637 tag[i] = MPLIST_SYMBOL (plist);
1642 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1647 check_description (MPlist *plist)
1651 if (MPLIST_MTEXT_P (plist))
1653 if (MPLIST_PLIST_P (plist))
1655 MPlist *pl = MPLIST_PLIST (plist);
1657 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1659 pl =MPLIST_NEXT (pl);
1660 if (MFAILP (MPLIST_MTEXT_P (pl)))
1662 mt = MPLIST_MTEXT (pl);
1663 M17N_OBJECT_REF (mt);
1666 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1668 if (translated == (char *) MTEXT_DATA (mt))
1669 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1670 if (translated != (char *) MTEXT_DATA (mt))
1672 M17N_OBJECT_UNREF (mt);
1673 mt = mtext__from_data (translated, strlen (translated),
1674 MTEXT_FORMAT_UTF_8, 1);
1678 mplist_set (plist, Mtext, mt);
1679 M17N_OBJECT_UNREF (mt);
1682 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1688 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1692 check_command_keyseq (MPlist *keyseq)
1694 if (MPLIST_PLIST_P (keyseq))
1696 MPlist *p = MPLIST_PLIST (keyseq);
1699 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1703 if (MPLIST_MTEXT_P (keyseq))
1705 MText *mt = MPLIST_MTEXT (keyseq);
1708 for (i = 0; i < mtext_nchars (mt); i++)
1709 if (mtext_ref_char (mt, i) >= 256)
1716 /* Load command defitions from PLIST into IM_INFO->cmds.
1718 PLIST is well-formed and has this form;
1719 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1720 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1721 M-text or a plist of symbols.
1723 The returned list has the same form, but for each element...
1725 (1) If DESCRIPTION and the rest are omitted, the element is not
1726 stored in the returned list.
1728 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1729 description in global_info->cmds (if any). */
1732 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1736 im_info->cmds = tail = mplist ();
1738 MPLIST_DO (plist, MPLIST_NEXT (plist))
1740 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1743 if (MFAILP (MPLIST_PLIST_P (plist)))
1745 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1746 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1748 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1749 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1751 if (MFAILP (im_info != global_info))
1752 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1756 if (! check_description (p))
1757 mplist_set (p, Msymbol, Mnil);
1758 p = MPLIST_NEXT (p);
1759 while (! MPLIST_TAIL_P (p))
1761 if (MFAILP (check_command_keyseq (p)))
1762 mplist__pop_unref (p);
1764 p = MPLIST_NEXT (p);
1767 tail = mplist_add (tail, Mplist, pl);
1772 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1773 MPlist *config_cmds)
1775 MPlist *global = NULL, *custom = NULL, *config = NULL;
1776 MSymbol name = MPLIST_SYMBOL (plist);
1778 MPlist *description, *keyseq;
1780 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1781 global = MPLIST_NEXT (MPLIST_PLIST (global));
1783 plist = MPLIST_NEXT (plist);
1784 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1786 description = plist;
1787 plist = MPLIST_NEXT (plist);
1791 description = global;
1792 if (! MPLIST_TAIL_P (plist))
1793 plist = MPLIST_NEXT (plist);
1795 if (MPLIST_TAIL_P (plist) && global)
1797 keyseq = MPLIST_NEXT (global);
1798 status = Minherited;
1806 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1808 status = Mconfigured;
1809 config = MPLIST_NEXT (MPLIST_PLIST (config));
1810 if (! MPLIST_TAIL_P (config))
1813 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1815 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1817 if (MPLIST_TAIL_P (this_keyseq))
1818 mplist__pop_unref (custom);
1821 status = Mcustomized;
1822 keyseq = this_keyseq;
1827 mplist_add (plist, Msymbol, name);
1829 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1831 mplist_add (plist, Msymbol, Mnil);
1832 mplist_add (plist, Msymbol, status);
1833 mplist__conc (plist, keyseq);
1838 config_all_commands (MInputMethodInfo *im_info)
1840 MPlist *global_cmds, *custom_cmds, *config_cmds;
1841 MInputMethodInfo *temp;
1842 MPlist *tail, *plist;
1844 M17N_OBJECT_UNREF (im_info->configured_cmds);
1846 if (MPLIST_TAIL_P (im_info->cmds)
1850 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1851 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1852 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1854 im_info->configured_cmds = tail = mplist ();
1855 MPLIST_DO (plist, im_info->cmds)
1857 MPlist *pl = config_command (MPLIST_PLIST (plist),
1858 global_cmds, custom_cmds, config_cmds);
1861 tail = mplist_add (tail, Mplist, pl);
1862 M17N_OBJECT_UNREF (pl);
1867 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1868 valid, return 0 if not. */
1871 check_variable_value (MPlist *val, MPlist *global)
1873 MSymbol type = MPLIST_KEY (val);
1874 MPlist *valids = MPLIST_NEXT (val);
1876 if (type != Minteger && type != Mtext && type != Msymbol)
1880 if (MPLIST_KEY (global) != Mt
1881 && MPLIST_KEY (global) != MPLIST_KEY (val))
1883 if (MPLIST_TAIL_P (valids))
1884 valids = MPLIST_NEXT (global);
1886 if (MPLIST_TAIL_P (valids))
1889 if (type == Minteger)
1891 int n = MPLIST_INTEGER (val);
1893 MPLIST_DO (valids, valids)
1895 if (MPLIST_INTEGER_P (valids))
1897 if (n == MPLIST_INTEGER (valids))
1900 else if (MPLIST_PLIST_P (valids))
1902 MPlist *p = MPLIST_PLIST (valids);
1903 int min_bound, max_bound;
1905 if (! MPLIST_INTEGER_P (p))
1906 MERROR (MERROR_IM, 0);
1907 min_bound = MPLIST_INTEGER (p);
1908 p = MPLIST_NEXT (p);
1909 if (! MPLIST_INTEGER_P (p))
1910 MERROR (MERROR_IM, 0);
1911 max_bound = MPLIST_INTEGER (p);
1912 if (n >= min_bound && n <= max_bound)
1917 else if (type == Msymbol)
1919 MSymbol sym = MPLIST_SYMBOL (val);
1921 MPLIST_DO (valids, valids)
1923 if (! MPLIST_SYMBOL_P (valids))
1924 MERROR (MERROR_IM, 0);
1925 if (sym == MPLIST_SYMBOL (valids))
1931 MText *mt = MPLIST_MTEXT (val);
1933 MPLIST_DO (valids, valids)
1935 if (! MPLIST_MTEXT_P (valids))
1936 MERROR (MERROR_IM, 0);
1937 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1942 return (! MPLIST_TAIL_P (valids));
1945 /* Load variable defitions from PLIST into IM_INFO->vars.
1947 PLIST is well-formed and has this form;
1948 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1950 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1952 The returned list has the same form, but for each element...
1954 (1) If DESCRIPTION and the rest are omitted, the element is not
1955 stored in the returned list.
1957 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1958 description in global_info->vars (if any). */
1961 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1963 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1964 ? global_info->vars : NULL);
1967 im_info->vars = tail = mplist ();
1968 MPLIST_DO (plist, MPLIST_NEXT (plist))
1972 if (MFAILP (MPLIST_PLIST_P (plist)))
1974 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1975 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1977 if (im_info == global_info)
1979 /* Loading a global variable. */
1980 p = MPLIST_NEXT (pl);
1981 if (MPLIST_TAIL_P (p))
1982 mplist_add (p, Msymbol, Mnil);
1985 if (! check_description (p))
1986 mplist_set (p, Msymbol, Mnil);
1987 p = MPLIST_NEXT (p);
1988 if (MFAILP (! MPLIST_TAIL_P (p)
1989 && check_variable_value (p, NULL)))
1990 mplist_set (p, Mt, NULL);
1993 else if (im_info->mdb)
1995 /* Loading a local variable. */
1996 MSymbol name = MPLIST_SYMBOL (pl);
1997 MPlist *global = NULL;
2000 && (p = mplist__assq (global_vars, name)))
2002 /* P ::= ((NAME DESC ...) ...) */
2003 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
2004 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
2005 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
2008 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
2009 if (! MPLIST_TAIL_P (p))
2011 if (! check_description (p))
2012 mplist_set (p, Msymbol, Mnil);
2013 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
2014 if (MFAILP (! MPLIST_TAIL_P (p)))
2015 mplist_set (p, Mt, NULL);
2018 MPlist *valid_values = MPLIST_NEXT (p);
2020 if (! MPLIST_TAIL_P (valid_values)
2021 ? MFAILP (check_variable_value (p, NULL))
2022 : global && MFAILP (check_variable_value (p, global)))
2023 mplist_set (p, Mt, NULL);
2029 /* Loading a variable customization. */
2030 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2031 if (MFAILP (! MPLIST_TAIL_P (p)))
2033 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2034 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2035 || MPLIST_MTEXT_P (p)))
2038 tail = mplist_add (tail, Mplist, pl);
2043 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2044 MPlist *config_vars)
2046 MPlist *global = NULL, *custom = NULL, *config = NULL;
2047 MSymbol name = MPLIST_SYMBOL (plist);
2049 MPlist *description = NULL, *value, *valids;
2053 global = mplist__assq (global_vars, name);
2055 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2058 plist = MPLIST_NEXT (plist);
2059 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2060 description = plist;
2062 description = global;
2064 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2066 if (MPLIST_TAIL_P (plist))
2068 /* Inherit from global (if any). */
2072 if (MPLIST_KEY (value) == Mt)
2074 valids = MPLIST_NEXT (global);
2075 status = Minherited;
2087 value = plist = MPLIST_NEXT (plist);
2088 valids = MPLIST_NEXT (value);
2089 if (MPLIST_KEY (value) == Mt)
2091 if (! MPLIST_TAIL_P (valids))
2094 valids = MPLIST_NEXT (global);
2098 if (config_vars && (config = mplist__assq (config_vars, name)))
2100 status = Mconfigured;
2101 config = MPLIST_NEXT (MPLIST_PLIST (config));
2102 if (! MPLIST_TAIL_P (config))
2105 if (MFAILP (check_variable_value (value, global ? global : plist)))
2109 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2111 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2113 if (MPLIST_TAIL_P (this_value))
2114 mplist__pop_unref (custom);
2118 if (MFAILP (check_variable_value (value, global ? global : plist)))
2120 status = Mcustomized;
2125 mplist_add (plist, Msymbol, name);
2127 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2129 mplist_add (plist, Msymbol, Mnil);
2130 mplist_add (plist, Msymbol, status);
2132 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2134 mplist_add (plist, Mt, NULL);
2135 if (valids && ! MPLIST_TAIL_P (valids))
2136 mplist__conc (plist, valids);
2140 /* Return a configured variable definition list based on
2141 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2142 get it from global_info->vars. */
2145 config_all_variables (MInputMethodInfo *im_info)
2147 MPlist *global_vars, *custom_vars, *config_vars;
2148 MInputMethodInfo *temp;
2149 MPlist *tail, *plist;
2151 M17N_OBJECT_UNREF (im_info->configured_vars);
2153 if (MPLIST_TAIL_P (im_info->vars)
2157 global_vars = im_info != global_info ? global_info->vars : NULL;
2158 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2159 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2161 im_info->configured_vars = tail = mplist ();
2162 MPLIST_DO (plist, im_info->vars)
2164 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2165 global_vars, custom_vars, config_vars);
2168 tail = mplist_add (tail, Mplist, pl);
2169 M17N_OBJECT_UNREF (pl);
2174 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2175 CONFIG contains configuration information of the input method. */
2178 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2182 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2184 load_commands (im_info, MPLIST_PLIST (pl));
2185 config_all_commands (im_info);
2186 pl = mplist_pop (pl);
2187 M17N_OBJECT_UNREF (pl);
2190 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2192 load_variables (im_info, MPLIST_PLIST (pl));
2193 config_all_variables (im_info);
2194 pl = mplist_pop (pl);
2195 M17N_OBJECT_UNREF (pl);
2198 MPLIST_DO (plist, plist)
2199 if (MPLIST_PLIST_P (plist))
2201 MPlist *elt = MPLIST_PLIST (plist);
2204 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2206 key = MPLIST_SYMBOL (elt);
2211 elt = MPLIST_NEXT (elt);
2212 if (MFAILP (MPLIST_MTEXT_P (elt)))
2214 im_info->title = MPLIST_MTEXT (elt);
2215 M17N_OBJECT_REF (im_info->title);
2217 else if (key == Mmap)
2219 pl = mplist__from_alist (MPLIST_NEXT (elt));
2222 if (! im_info->maps)
2226 mplist__conc (im_info->maps, pl);
2227 M17N_OBJECT_UNREF (pl);
2230 else if (key == Mmacro)
2232 if (! im_info->macros)
2233 im_info->macros = mplist ();
2234 MPLIST_DO (elt, MPLIST_NEXT (elt))
2236 if (MFAILP (MPLIST_PLIST_P (elt)))
2238 load_macros (im_info, MPLIST_PLIST (elt));
2241 else if (key == Mmodule)
2243 if (! im_info->externals)
2244 im_info->externals = mplist ();
2245 MPLIST_DO (elt, MPLIST_NEXT (elt))
2247 if (MFAILP (MPLIST_PLIST_P (elt)))
2249 load_external_module (im_info, MPLIST_PLIST (elt));
2252 else if (key == Mstate)
2254 MPLIST_DO (elt, MPLIST_NEXT (elt))
2258 if (MFAILP (MPLIST_PLIST_P (elt)))
2260 pl = MPLIST_PLIST (elt);
2261 if (! im_info->states)
2262 im_info->states = mplist ();
2263 state = load_state (im_info, MPLIST_PLIST (elt));
2266 mplist_put (im_info->states, state->name, state);
2269 else if (key == Minclude)
2271 /* elt ::= include (tag1 tag2 ...) key item ... */
2273 MInputMethodInfo *temp;
2275 elt = MPLIST_NEXT (elt);
2276 if (MFAILP (MPLIST_PLIST_P (elt)))
2278 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2281 elt = MPLIST_NEXT (elt);
2282 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2284 key = MPLIST_SYMBOL (elt);
2285 elt = MPLIST_NEXT (elt);
2288 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2290 if (! im_info->maps)
2291 im_info->maps = mplist ();
2292 MPLIST_DO (pl, temp->maps)
2294 p = MPLIST_VAL (pl);
2295 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2296 M17N_OBJECT_REF (p);
2299 else if (key == Mmacro)
2301 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2303 if (! im_info->macros)
2304 im_info->macros = mplist ();
2305 MPLIST_DO (pl, temp->macros)
2307 p = MPLIST_VAL (pl);
2308 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2309 M17N_OBJECT_REF (p);
2312 else if (key == Mstate)
2314 if (! temp->states || MPLIST_TAIL_P (temp->states))
2316 if (! im_info->states)
2317 im_info->states = mplist ();
2318 MPLIST_DO (pl, temp->states)
2320 MIMState *state = MPLIST_VAL (pl);
2322 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2323 M17N_OBJECT_REF (state);
2327 else if (key == Mdescription)
2329 if (im_info->description)
2331 elt = MPLIST_NEXT (elt);
2332 if (! check_description (elt))
2334 im_info->description = MPLIST_MTEXT (elt);
2335 M17N_OBJECT_REF (im_info->description);
2338 im_info->tick = time (NULL);
2343 static int take_action_list (MInputContext *ic, MPlist *action_list);
2344 static void preedit_commit (MInputContext *ic, int need_prefix);
2347 shift_state (MInputContext *ic, MSymbol state_name)
2349 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2350 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2351 MIMState *orig_state = ic_info->state, *state;
2353 /* Find a state to shift to. If not found, shift to the initial
2355 if (state_name == Mt)
2357 if (! ic_info->prev_state)
2359 state = ic_info->prev_state;
2361 else if (state_name == Mnil)
2363 state = (MIMState *) MPLIST_VAL (im_info->states);
2367 state = (MIMState *) mplist_get (im_info->states, state_name);
2369 state = (MIMState *) MPLIST_VAL (im_info->states);
2375 MDEBUG_PRINT2 ("\n [IM] [%s] (shift %s)\n",
2376 MSYMBOL_NAME (orig_state->name),
2377 MSYMBOL_NAME (state->name));
2379 MDEBUG_PRINT1 (" (shift %s)\n", MSYMBOL_NAME (state->name));
2382 /* Enter the new state. */
2383 ic_info->state = state;
2384 ic_info->map = state->map;
2385 ic_info->state_key_head = ic_info->key_head;
2386 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2388 /* We have shifted to the initial state. */
2389 preedit_commit (ic, 0);
2390 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2391 ic_info->state_pos = ic->cursor_pos;
2392 if (state != orig_state)
2394 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2396 /* Shifted to the initial state. */
2397 ic_info->prev_state = NULL;
2398 M17N_OBJECT_UNREF (ic_info->vars_saved);
2399 ic_info->vars_saved = mplist_copy (ic_info->vars);
2402 ic_info->prev_state = orig_state;
2405 ic->status = state->title;
2407 ic->status = im_info->title;
2408 ic->status_changed = 1;
2409 if (ic_info->map == ic_info->state->map
2410 && ic_info->map->map_actions)
2412 MDEBUG_PRINT1 (" [IM] [%s] init-actions:",
2413 MSYMBOL_NAME (state->name));
2414 take_action_list (ic, ic_info->map->map_actions);
2419 /* Find a candidate group that contains a candidate number INDEX from
2420 PLIST. Set START_INDEX to the first candidate number of the group,
2421 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2422 candidate group number if they are non-NULL. If INDEX is -1, find
2423 the last candidate group. */
2426 find_candidates_group (MPlist *plist, int index,
2427 int *start_index, int *end_index, int *group_index)
2429 int i = 0, gidx = 0, len;
2431 MPLIST_DO (plist, plist)
2433 if (MPLIST_MTEXT_P (plist))
2434 len = mtext_nchars (MPLIST_MTEXT (plist));
2436 len = mplist_length (MPLIST_PLIST (plist));
2437 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2443 *end_index = i + len;
2445 *group_index = gidx;
2454 /* Adjust markers for the change of preedit text.
2455 If FROM == TO, the change is insertion of INS chars.
2456 If FROM < TO and INS == 0, the change is deletion of the range.
2457 If FROM < TO and INS > 0, the change is replacement. */
2460 adjust_markers (MInputContext *ic, int from, int to, int ins)
2462 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2467 MPLIST_DO (markers, ic_info->markers)
2468 if (MPLIST_INTEGER (markers) > from)
2469 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2470 if (ic->cursor_pos >= from)
2471 ic->cursor_pos += ins;
2475 MPLIST_DO (markers, ic_info->markers)
2477 if (MPLIST_INTEGER (markers) >= to)
2478 MPLIST_VAL (markers)
2479 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2480 else if (MPLIST_INTEGER (markers) > from)
2481 MPLIST_VAL (markers) = (void *) from;
2483 if (ic->cursor_pos >= to)
2484 ic->cursor_pos += ins - (to - from);
2485 else if (ic->cursor_pos > from)
2486 ic->cursor_pos = from;
2492 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2494 int nchars = mt ? mtext_nchars (mt) : 1;
2498 mtext_ins (ic->preedit, pos, mt);
2499 MDEBUG_PRINT1 ("(\"%s\")", MTEXT_DATA (mt));
2503 mtext_ins_char (ic->preedit, pos, c, 1);
2505 MDEBUG_PRINT1 ("('%c')", c);
2507 MDEBUG_PRINT1 ("(U+%04X)", c);
2509 adjust_markers (ic, pos, pos, nchars);
2510 ic->preedit_changed = 1;
2515 preedit_delete (MInputContext *ic, int from, int to)
2517 mtext_del (ic->preedit, from, to);
2518 adjust_markers (ic, from, to, 0);
2519 ic->preedit_changed = 1;
2523 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2527 mtext_del (ic->preedit, from, to);
2530 mtext_ins (ic->preedit, from, mt);
2531 ins = mtext_nchars (mt);
2535 mtext_ins_char (ic->preedit, from, c, 1);
2538 adjust_markers (ic, from, to, ins);
2539 ic->preedit_changed = 1;
2544 preedit_commit (MInputContext *ic, int need_prefix)
2546 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2547 int preedit_len = mtext_nchars (ic->preedit);
2549 if (preedit_len > 0)
2553 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2554 Mcandidate_list, NULL, 0);
2555 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2556 Mcandidate_index, NULL, 0);
2557 mtext_cat (ic->produced, ic->preedit);
2563 MDEBUG_PRINT1 ("\n [IM] [%s]",
2564 MSYMBOL_NAME (ic_info->state->name));
2565 MDEBUG_PRINT (" (commit");
2566 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2567 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2571 mtext_reset (ic->preedit);
2572 mtext_reset (ic_info->preedit_saved);
2573 MPLIST_DO (p, ic_info->markers)
2575 ic->cursor_pos = ic_info->state_pos = 0;
2576 ic->preedit_changed = 1;
2577 ic_info->commit_key_head = ic_info->key_head;
2579 if (ic->candidate_list)
2581 M17N_OBJECT_UNREF (ic->candidate_list);
2582 ic->candidate_list = NULL;
2583 ic->candidate_index = 0;
2584 ic->candidate_from = ic->candidate_to = 0;
2585 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2586 if (ic->candidate_show)
2588 ic->candidate_show = 0;
2589 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2595 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2597 int code = marker_code (sym, 0);
2599 if (mt && (code == '[' || code == ']'))
2603 if (code == '[' && current > 0)
2605 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2609 else if (code == ']' && current < mtext_nchars (mt))
2611 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2617 return (code == '<' ? 0
2618 : code == '>' ? limit
2619 : code == '-' ? current - 1
2620 : code == '+' ? current + 1
2621 : code == '=' ? current
2622 : code - '0' > limit ? limit
2626 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2630 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2632 int from = mtext_property_start (prop);
2633 int to = mtext_property_end (prop);
2635 MPlist *candidate_list = mtext_property_value (prop);
2636 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2638 int ingroup_index = idx - start;
2641 candidate_list = mplist_copy (candidate_list);
2642 if (MPLIST_MTEXT_P (group))
2644 mt = MPLIST_MTEXT (group);
2645 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2653 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2654 i++, plist = MPLIST_NEXT (plist));
2655 mt = MPLIST_MTEXT (plist);
2656 preedit_replace (ic, from, to, mt, 0);
2657 to = from + mtext_nchars (mt);
2659 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2660 M17N_OBJECT_UNREF (candidate_list);
2661 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2662 ic->cursor_pos = to;
2666 get_select_charset (MInputContextInfo * ic_info)
2668 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2671 if (! MPLIST_VAL (plist))
2673 sym = MPLIST_SYMBOL (plist);
2676 return MCHARSET (sym);
2680 adjust_candidates (MPlist *plist, MCharset *charset)
2684 /* plist ::= MTEXT ... | PLIST ... */
2685 plist = mplist_copy (plist);
2686 if (MPLIST_MTEXT_P (plist))
2689 while (! MPLIST_TAIL_P (pl))
2691 /* pl ::= MTEXT ... */
2692 MText *mt = MPLIST_MTEXT (pl);
2696 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2698 c = mtext_ref_char (mt, i);
2699 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2703 mt = mtext_dup (mt);
2704 mplist_set (pl, Mtext, mt);
2705 M17N_OBJECT_UNREF (mt);
2708 mtext_del (mt, i, i + 1);
2711 if (mtext_len (mt) > 0)
2712 pl = MPLIST_NEXT (pl);
2716 M17N_OBJECT_UNREF (mt);
2720 else /* MPLIST_PLIST_P (plist) */
2723 while (! MPLIST_TAIL_P (pl))
2725 /* pl ::= (MTEXT ...) ... */
2726 MPlist *p = MPLIST_PLIST (pl);
2728 /* p ::= MTEXT ... */
2732 while (! MPLIST_TAIL_P (p0))
2734 MText *mt = MPLIST_MTEXT (p0);
2737 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2739 c = mtext_ref_char (mt, i);
2740 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2745 p0 = MPLIST_NEXT (p0);
2752 p = mplist_copy (p);
2753 mplist_set (pl, Mplist, p);
2754 M17N_OBJECT_UNREF (p);
2758 p0 = MPLIST_NEXT (p0);
2761 M17N_OBJECT_UNREF (mt);
2764 if (! MPLIST_TAIL_P (p))
2765 pl = MPLIST_NEXT (pl);
2769 M17N_OBJECT_UNREF (p);
2773 if (MPLIST_TAIL_P (plist))
2775 M17N_OBJECT_UNREF (plist);
2782 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2784 MCharset *charset = get_select_charset (ic_info);
2789 plist = resolve_variable (ic_info, Mcandidates_group_size);
2790 column = MPLIST_INTEGER (plist);
2792 plist = MPLIST_PLIST (args);
2794 plist = adjust_candidates (plist, charset);
2796 if (plist && column > 0)
2798 if (MPLIST_MTEXT_P (plist))
2800 MText *mt = MPLIST_MTEXT (plist);
2801 MPlist *next = MPLIST_NEXT (plist);
2803 if (MPLIST_TAIL_P (next))
2804 M17N_OBJECT_REF (mt);
2807 mt = mtext_dup (mt);
2808 while (! MPLIST_TAIL_P (next))
2810 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2811 next = MPLIST_NEXT (next);
2815 M17N_OBJECT_UNREF (plist);
2817 len = mtext_nchars (mt);
2819 mplist_add (plist, Mtext, mt);
2822 for (i = 0; i < len; i += column)
2824 int to = (i + column < len ? i + column : len);
2825 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2827 mplist_add (plist, Mtext, sub);
2828 M17N_OBJECT_UNREF (sub);
2831 M17N_OBJECT_UNREF (mt);
2833 else if (! MPLIST_TAIL_P (plist))
2835 MPlist *tail = plist;
2836 MPlist *new = mplist ();
2837 MPlist *this = mplist ();
2840 MPLIST_DO (tail, tail)
2842 MPlist *p = MPLIST_PLIST (tail);
2846 MText *mt = MPLIST_MTEXT (p);
2848 if (count == column)
2850 mplist_add (new, Mplist, this);
2851 M17N_OBJECT_UNREF (this);
2855 mplist_add (this, Mtext, mt);
2859 mplist_add (new, Mplist, this);
2860 M17N_OBJECT_UNREF (this);
2861 mplist_set (plist, Mnil, NULL);
2862 MPLIST_DO (tail, new)
2864 MPlist *elt = MPLIST_PLIST (tail);
2866 mplist_add (plist, Mplist, elt);
2868 M17N_OBJECT_UNREF (new);
2877 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2879 MPlist *action = NULL;
2883 if (MPLIST_SYMBOL_P (action_list))
2885 MSymbol var = MPLIST_SYMBOL (action_list);
2888 MPLIST_DO (p, ic_info->vars)
2889 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2891 if (MPLIST_TAIL_P (p))
2893 action = MPLIST_NEXT (MPLIST_PLIST (p));
2894 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2897 if (MPLIST_PLIST_P (action_list))
2899 action = MPLIST_PLIST (action_list);
2900 if (MPLIST_SYMBOL_P (action))
2902 name = MPLIST_SYMBOL (action);
2903 args = MPLIST_NEXT (action);
2905 && MPLIST_PLIST_P (args))
2906 mplist_set (action, Msymbol, M_candidates);
2908 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2911 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2912 mplist_push (action, Msymbol, M_candidates);
2913 mplist_set (action_list, Mplist, action);
2914 M17N_OBJECT_UNREF (action);
2917 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2920 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2921 mplist_push (action, Msymbol, Minsert);
2922 mplist_set (action_list, Mplist, action);
2923 M17N_OBJECT_UNREF (action);
2928 /* Perform list of actions in ACTION_LIST for the current input
2929 context IC. If unhandle action was not performed, return 0.
2930 Otherwise, return -1. */
2933 take_action_list (MInputContext *ic, MPlist *action_list)
2935 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2936 MPlist *candidate_list = ic->candidate_list;
2937 int candidate_index = ic->candidate_index;
2938 int candidate_show = ic->candidate_show;
2939 MTextProperty *prop;
2941 MPLIST_DO (action_list, action_list)
2943 MPlist *action = regularize_action (action_list, ic_info);
2949 name = MPLIST_SYMBOL (action);
2950 args = MPLIST_NEXT (action);
2952 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2953 if (name == Minsert)
2955 if (MPLIST_SYMBOL_P (args))
2957 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2958 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2961 if (MPLIST_MTEXT_P (args))
2962 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2963 else /* MPLIST_INTEGER_P (args)) */
2964 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2966 else if (name == M_candidates)
2968 MPlist *plist = get_candidate_list (ic_info, args);
2971 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2973 if (MPLIST_MTEXT_P (plist))
2975 preedit_insert (ic, ic->cursor_pos, NULL,
2976 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2979 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2983 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2985 preedit_insert (ic, ic->cursor_pos, mt, 0);
2986 len = mtext_nchars (mt);
2988 plist = mplist_copy (plist);
2989 mtext_put_prop (ic->preedit,
2990 ic->cursor_pos - len, ic->cursor_pos,
2991 Mcandidate_list, plist);
2992 M17N_OBJECT_UNREF (plist);
2993 mtext_put_prop (ic->preedit,
2994 ic->cursor_pos - len, ic->cursor_pos,
2995 Mcandidate_index, (void *) 0);
2997 else if (name == Mselect)
3000 int code, idx, gindex;
3001 int pos = ic->cursor_pos;
3003 int idx_decided = 0;
3006 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
3009 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
3010 group = find_candidates_group (mtext_property_value (prop), idx,
3011 &start, &end, &gindex);
3012 if (MPLIST_SYMBOL_P (args))
3014 code = marker_code (MPLIST_SYMBOL (args), 0);
3017 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3018 if (! MPLIST_INTEGER_P (args))
3020 idx = start + MPLIST_INTEGER (args);
3021 if (idx < start || idx >= end)
3029 if (code != '[' && code != ']')
3034 ? new_index (NULL, ic->candidate_index - start,
3035 end - start - 1, MPLIST_SYMBOL (args),
3037 : MPLIST_INTEGER (args)));
3040 find_candidates_group (mtext_property_value (prop), -1,
3045 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
3050 int ingroup_index = idx - start;
3053 group = mtext_property_value (prop);
3054 len = mplist_length (group);
3067 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3068 idx += (MPLIST_MTEXT_P (group)
3069 ? mtext_nchars (MPLIST_MTEXT (group))
3070 : mplist_length (MPLIST_PLIST (group)));
3071 len = (MPLIST_MTEXT_P (group)
3072 ? mtext_nchars (MPLIST_MTEXT (group))
3073 : mplist_length (MPLIST_PLIST (group)));
3074 if (ingroup_index >= len)
3075 ingroup_index = len - 1;
3076 idx += ingroup_index;
3078 update_candidate (ic, prop, idx);
3079 MDEBUG_PRINT1 ("(%d)", idx);
3081 else if (name == Mshow)
3082 ic->candidate_show = 1;
3083 else if (name == Mhide)
3084 ic->candidate_show = 0;
3085 else if (name == Mdelete)
3087 int len = mtext_nchars (ic->preedit);
3091 if (MPLIST_SYMBOL_P (args)
3092 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3094 to = ic->cursor_pos + pos;
3097 delete_surrounding_text (ic, to);
3102 delete_surrounding_text (ic, to - len);
3108 to = (MPLIST_SYMBOL_P (args)
3109 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3111 : MPLIST_INTEGER (args));
3116 pos = to - ic->cursor_pos;
3118 MDEBUG_PRINT1 ("(%d)", pos);
3119 if (to < ic->cursor_pos)
3120 preedit_delete (ic, to, ic->cursor_pos);
3121 else if (to > ic->cursor_pos)
3122 preedit_delete (ic, ic->cursor_pos, to);
3124 else if (name == Mmove)
3126 int len = mtext_nchars (ic->preedit);
3128 = (MPLIST_SYMBOL_P (args)
3129 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3131 : MPLIST_INTEGER (args));
3137 if (pos != ic->cursor_pos)
3139 ic->cursor_pos = pos;
3140 ic->preedit_changed = 1;
3142 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3144 else if (name == Mmark)
3146 int code = marker_code (MPLIST_SYMBOL (args), 0);
3150 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3151 (void *) ic->cursor_pos);
3152 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3155 else if (name == Mpushback)
3157 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3161 if (MPLIST_SYMBOL_P (args))
3163 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3164 if (MPLIST_INTEGER_P (args))
3165 num = MPLIST_INTEGER (args);
3170 num = MPLIST_INTEGER (args);
3173 ic_info->key_head -= num;
3175 ic_info->key_head = 0;
3177 ic_info->key_head = - num;
3178 if (ic_info->key_head > ic_info->used)
3179 ic_info->key_head = ic_info->used;
3181 else if (MPLIST_MTEXT_P (args))
3183 MText *mt = MPLIST_MTEXT (args);
3184 int i, len = mtext_nchars (mt);
3187 ic_info->key_head--;
3188 for (i = 0; i < len; i++)
3190 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3191 if (ic_info->key_head + i < ic_info->used)
3192 ic_info->keys[ic_info->key_head + i] = key;
3194 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3199 MPlist *plist = MPLIST_PLIST (args), *pl;
3203 ic_info->key_head--;
3205 MPLIST_DO (pl, plist)
3207 key = MPLIST_SYMBOL (pl);
3208 if (ic_info->key_head < ic_info->used)
3209 ic_info->keys[ic_info->key_head + i] = key;
3211 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3216 else if (name == Mpop)
3218 if (ic_info->key_head < ic_info->used)
3219 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3221 else if (name == Mcall)
3223 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3224 MIMExternalFunc func = NULL;
3225 MSymbol module, func_name;
3226 MPlist *func_args, *val;
3229 module = MPLIST_SYMBOL (args);
3230 args = MPLIST_NEXT (args);
3231 func_name = MPLIST_SYMBOL (args);
3233 if (im_info->externals)
3235 MIMExternalModule *external
3236 = (MIMExternalModule *) mplist_get (im_info->externals,
3239 func = ((MIMExternalFunc)
3240 mplist_get_func (external->func_list, func_name));
3244 func_args = mplist ();
3245 mplist_add (func_args, Mt, ic);
3246 MPLIST_DO (args, MPLIST_NEXT (args))
3250 if (MPLIST_KEY (args) == Msymbol
3251 && MPLIST_KEY (args) != Mnil
3252 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3254 code = new_index (ic, ic->cursor_pos,
3255 mtext_nchars (ic->preedit),
3256 MPLIST_SYMBOL (args), ic->preedit);
3257 mplist_add (func_args, Minteger, (void *) code);
3260 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3262 val = (func) (func_args);
3263 M17N_OBJECT_UNREF (func_args);
3264 if (val && ! MPLIST_TAIL_P (val))
3265 ret = take_action_list (ic, val);
3266 M17N_OBJECT_UNREF (val);
3270 else if (name == Mshift)
3272 shift_state (ic, MPLIST_SYMBOL (args));
3274 else if (name == Mundo)
3276 int intarg = (MPLIST_TAIL_P (args)
3278 : integer_value (ic, args, 0));
3280 mtext_reset (ic->preedit);
3281 mtext_reset (ic_info->preedit_saved);
3282 mtext_reset (ic->produced);
3283 M17N_OBJECT_UNREF (ic_info->vars);
3284 ic_info->vars = mplist_copy (ic_info->vars_saved);
3285 ic->cursor_pos = ic_info->state_pos = 0;
3286 ic_info->state_key_head = ic_info->key_head
3287 = ic_info->commit_key_head = 0;
3289 shift_state (ic, Mnil);
3292 if (MPLIST_TAIL_P (args))
3297 ic_info->used += intarg;
3300 ic_info->used = intarg;
3303 else if (name == Mset || name == Madd || name == Msub
3304 || name == Mmul || name == Mdiv)
3306 MSymbol sym = MPLIST_SYMBOL (args);
3307 MPlist *value = resolve_variable (ic_info, sym);
3311 val1 = MPLIST_INTEGER (value);
3312 args = MPLIST_NEXT (args);
3313 val2 = resolve_expression (ic, args);
3315 val1 = val2, op = "=";
3316 else if (name == Madd)
3317 val1 += val2, op = "+=";
3318 else if (name == Msub)
3319 val1 -= val2, op = "-=";
3320 else if (name == Mmul)
3321 val1 *= val2, op = "*=";
3323 val1 /= val2, op = "/=";
3324 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3325 MSYMBOL_NAME (sym), op, val1, val1);
3326 mplist_set (value, Minteger, (void *) val1);
3328 else if (name == Mequal || name == Mless || name == Mgreater
3329 || name == Mless_equal || name == Mgreater_equal)
3332 MPlist *actions1, *actions2;
3335 val1 = resolve_expression (ic, args);
3336 args = MPLIST_NEXT (args);
3337 val2 = resolve_expression (ic, args);
3338 args = MPLIST_NEXT (args);
3339 actions1 = MPLIST_PLIST (args);
3340 args = MPLIST_NEXT (args);
3341 if (MPLIST_TAIL_P (args))
3344 actions2 = MPLIST_PLIST (args);
3345 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3346 if (name == Mequal ? val1 == val2
3347 : name == Mless ? val1 < val2
3348 : name == Mgreater ? val1 > val2
3349 : name == Mless_equal ? val1 <= val2
3352 MDEBUG_PRINT ("ok");
3353 ret = take_action_list (ic, actions1);
3357 MDEBUG_PRINT ("no");
3359 ret = take_action_list (ic, actions2);
3364 else if (name == Mcond)
3368 MPLIST_DO (args, args)
3373 if (! MPLIST_PLIST (args))
3375 cond = MPLIST_PLIST (args);
3376 if (resolve_expression (ic, cond) != 0)
3378 MDEBUG_PRINT1 ("(%dth)", idx);
3379 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3385 else if (name == Mcommit)
3387 preedit_commit (ic, 0);
3389 else if (name == Munhandle)
3391 preedit_commit (ic, 0);
3396 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3400 && (actions = mplist_get (im_info->macros, name)))
3402 if (take_action_list (ic, actions) < 0)
3408 if (ic->candidate_list)
3410 M17N_OBJECT_UNREF (ic->candidate_list);
3411 ic->candidate_list = NULL;
3413 if (ic->cursor_pos > 0
3414 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3417 ic->candidate_list = mtext_property_value (prop);
3418 M17N_OBJECT_REF (ic->candidate_list);
3420 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3422 ic->candidate_from = mtext_property_start (prop);
3423 ic->candidate_to = mtext_property_end (prop);
3426 if (candidate_list != ic->candidate_list)
3427 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3428 if (candidate_index != ic->candidate_index)
3429 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3430 if (candidate_show != ic->candidate_show)
3431 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3436 /* Handle the input key KEY in the current state and map specified in
3437 the input context IC. If KEY is handled correctly, return 0.
3438 Otherwise, return -1. */
3441 handle_key (MInputContext *ic)
3443 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3444 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3445 MIMMap *map = ic_info->map;
3446 MIMMap *submap = NULL;
3447 MSymbol key = ic_info->keys[ic_info->key_head];
3448 MSymbol alias = Mnil;
3451 MDEBUG_PRINT2 (" [IM] [%s] handle `%s'",
3452 MSYMBOL_NAME (ic_info->state->name), msymbol_name (key));
3456 submap = mplist_get (map->submaps, key);
3459 && (alias = msymbol_get (alias, M_key_alias))
3461 submap = mplist_get (map->submaps, alias);
3466 if (! alias || alias == key)
3467 MDEBUG_PRINT (" submap-found");
3469 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3470 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3471 ic->preedit_changed = 1;
3472 ic->cursor_pos = ic_info->state_pos;
3473 ic_info->key_head++;
3474 ic_info->map = map = submap;
3475 if (map->map_actions)
3477 MDEBUG_PRINT (" map-actions:");
3478 if (take_action_list (ic, map->map_actions) < 0)
3480 MDEBUG_PRINT ("\n");
3484 else if (map->submaps)
3486 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3488 MSymbol key = ic_info->keys[i];
3489 char *name = msymbol_name (key);
3491 if (! name[0] || ! name[1])
3492 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3496 /* If this is the terminal map or we have shifted to another
3497 state, perform branch actions (if any). */
3498 if (! map->submaps || map != ic_info->map)
3500 if (map->branch_actions)
3502 MDEBUG_PRINT (" branch-actions:");
3503 if (take_action_list (ic, map->branch_actions) < 0)
3505 MDEBUG_PRINT ("\n");
3509 /* If MAP is still not the root map, shift to the current
3511 if (ic_info->map != ic_info->state->map)
3512 shift_state (ic, ic_info->state->name);
3517 /* MAP can not handle KEY. */
3519 /* Perform branch actions if any. */
3520 if (map->branch_actions)
3522 MDEBUG_PRINT (" branch-actions:");
3523 if (take_action_list (ic, map->branch_actions) < 0)
3525 MDEBUG_PRINT ("\n");
3530 if (map == ic_info->map)
3532 /* The above branch actions didn't change the state. */
3534 /* If MAP is the root map of the initial state, and there
3535 still exist an unhandled key, it means that the current
3536 input method can not handle it. */
3537 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3538 && ic_info->key_head < ic_info->used)
3540 MDEBUG_PRINT (" unhandled\n");
3544 if (map != ic_info->state->map)
3546 /* MAP is not the root map. Shift to the root map of the
3548 shift_state (ic, ic_info->state->name);
3550 else if (! map->branch_actions)
3552 /* MAP is the root map without any default branch
3553 actions. Shift to the initial state. */
3554 shift_state (ic, Mnil);
3558 MDEBUG_PRINT ("\n");
3562 /* Initialize IC->ic_info. */
3565 init_ic_info (MInputContext *ic)
3567 MInputMethodInfo *im_info = ic->im->info;
3568 MInputContextInfo *ic_info = ic->info;
3571 MLIST_INIT1 (ic_info, keys, 8);;
3573 ic_info->markers = mplist ();
3575 ic_info->vars = mplist ();
3576 if (im_info->configured_vars)
3577 MPLIST_DO (plist, im_info->configured_vars)
3579 MPlist *pl = MPLIST_PLIST (plist);
3580 MSymbol name = MPLIST_SYMBOL (pl);
3582 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3583 if (MPLIST_KEY (pl) != Mt)
3585 MPlist *p = mplist ();
3587 mplist_push (ic_info->vars, Mplist, p);
3588 M17N_OBJECT_UNREF (p);
3589 mplist_add (p, Msymbol, name);
3590 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3593 ic_info->vars_saved = mplist_copy (ic_info->vars);
3595 if (im_info->externals)
3597 MPlist *func_args = mplist (), *plist;
3599 mplist_add (func_args, Mt, ic);
3600 MPLIST_DO (plist, im_info->externals)
3602 MIMExternalModule *external = MPLIST_VAL (plist);
3603 MIMExternalFunc func
3604 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3609 M17N_OBJECT_UNREF (func_args);
3612 ic_info->preedit_saved = mtext ();
3613 ic_info->tick = im_info->tick;
3616 /* Finalize IC->ic_info. */
3619 fini_ic_info (MInputContext *ic)
3621 MInputMethodInfo *im_info = ic->im->info;
3622 MInputContextInfo *ic_info = ic->info;
3624 if (im_info->externals)
3626 MPlist *func_args = mplist (), *plist;
3628 mplist_add (func_args, Mt, ic);
3629 MPLIST_DO (plist, im_info->externals)
3631 MIMExternalModule *external = MPLIST_VAL (plist);
3632 MIMExternalFunc func
3633 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3638 M17N_OBJECT_UNREF (func_args);
3641 MLIST_FREE1 (ic_info, keys);
3642 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3643 M17N_OBJECT_UNREF (ic_info->markers);
3644 M17N_OBJECT_UNREF (ic_info->vars);
3645 M17N_OBJECT_UNREF (ic_info->vars_saved);
3646 M17N_OBJECT_UNREF (ic_info->preceding_text);
3647 M17N_OBJECT_UNREF (ic_info->following_text);
3649 memset (ic_info, 0, sizeof (MInputContextInfo));
3653 re_init_ic (MInputContext *ic, int reload)
3655 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3656 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3657 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3659 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3660 preedit_changed = mtext_nchars (ic->preedit) > 0;
3661 cursor_pos_changed = ic->cursor_pos > 0;
3662 candidates_changed = 0;
3663 if (ic->candidate_list)
3665 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3666 M17N_OBJECT_UNREF (ic->candidate_list);
3667 ic->candidate_list = NULL;
3669 if (ic->candidate_show)
3671 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3672 ic->candidate_show = 0;
3674 if (ic->candidate_index > 0)
3676 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3677 ic->candidate_index = 0;
3678 ic->candidate_from = ic->candidate_to = 0;
3680 if (mtext_nchars (ic->produced) > 0)
3681 mtext_reset (ic->produced);
3682 if (mtext_nchars (ic->preedit) > 0)
3683 mtext_reset (ic->preedit);
3685 M17N_OBJECT_UNREF (ic->plist);
3686 ic->plist = mplist ();
3690 reload_im_info (im_info);
3691 if (! im_info->states)
3693 struct MIMState *state;
3695 M17N_OBJECT (state, free_state, MERROR_IM);
3696 state->name = msymbol ("init");
3697 state->title = mtext__from_data ("ERROR!", 6, MTEXT_FORMAT_US_ASCII, 0);
3698 MSTRUCT_CALLOC (state->map, MERROR_IM);
3699 im_info->states = mplist ();
3700 mplist_add (im_info->states, state->name, state);
3703 shift_state (ic, Mnil);
3705 ic->status_changed = status_changed;
3706 ic->preedit_changed = preedit_changed;
3707 ic->cursor_pos_changed = cursor_pos_changed;
3708 ic->candidates_changed = candidates_changed;
3712 reset_ic (MInputContext *ic, MSymbol ignore)
3714 MDEBUG_PRINT ("\n [IM] reset\n");
3719 open_im (MInputMethod *im)
3721 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3723 if (! im_info || ! im_info->states)
3724 MERROR (MERROR_IM, -1);
3731 close_im (MInputMethod *im)
3737 create_ic (MInputContext *ic)
3739 MInputContextInfo *ic_info;
3741 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3744 shift_state (ic, Mnil);
3749 destroy_ic (MInputContext *ic)
3756 check_reload (MInputContext *ic, MSymbol key)
3758 MInputMethodInfo *im_info = ic->im->info;
3759 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3763 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3767 MPLIST_DO (plist, plist)
3769 MSymbol this_key, alias;
3771 if (MPLIST_MTEXT_P (plist))
3773 MText *mt = MPLIST_MTEXT (plist);
3774 int c = mtext_ref_char (mt, 0);
3778 this_key = one_char_symbol[c];
3782 MPlist *pl = MPLIST_PLIST (plist);
3784 this_key = MPLIST_SYMBOL (pl);
3788 && (alias = msymbol_get (alias, M_key_alias))
3789 && alias != this_key);
3793 if (MPLIST_TAIL_P (plist))
3796 MDEBUG_PRINT ("\n [IM] reload");
3802 /** Handle the input key KEY in the current state and map of IC->info.
3803 If KEY is handled but no text is produced, return 0, otherwise
3809 filter (MInputContext *ic, MSymbol key, void *arg)
3811 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3812 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3815 if (check_reload (ic, key))
3818 if (! ic_info->state)
3820 ic_info->key_unhandled = 1;
3823 mtext_reset (ic->produced);
3824 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3825 M17N_OBJECT_UNREF (ic_info->preceding_text);
3826 M17N_OBJECT_UNREF (ic_info->following_text);
3827 ic_info->preceding_text = ic_info->following_text = NULL;
3828 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3829 ic_info->key_unhandled = 0;
3832 if (handle_key (ic) < 0)
3834 /* KEY was not handled. Delete it from the current key sequence. */
3835 if (ic_info->used > 0)
3837 memmove (ic_info->keys, ic_info->keys + 1,
3838 sizeof (int) * (ic_info->used - 1));
3840 if (ic_info->state_key_head > 0)
3841 ic_info->state_key_head--;
3842 if (ic_info->commit_key_head > 0)
3843 ic_info->commit_key_head--;
3845 /* This forces returning 1. */
3846 ic_info->key_unhandled = 1;
3852 reset_ic (ic, Mnil);
3853 ic_info->key_unhandled = 1;
3856 /* Break the loop if all keys were handled. */
3857 } while (ic_info->key_head < ic_info->used);
3859 /* If the current map is the root of the initial state, we should
3860 produce any preedit text in ic->produced. */
3861 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3862 preedit_commit (ic, 1);
3864 if (mtext_nchars (ic->produced) > 0)
3868 MDEBUG_PRINT1 ("\n [IM] [%s] (produced",
3869 MSYMBOL_NAME (ic_info->state->name));
3870 for (i = 0; i < mtext_nchars (ic->produced); i++)
3871 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3875 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3876 Mlanguage, ic->im->language);
3878 if (ic_info->commit_key_head > 0)
3880 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3881 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3882 ic_info->used -= ic_info->commit_key_head;
3883 ic_info->key_head -= ic_info->commit_key_head;
3884 ic_info->state_key_head -= ic_info->commit_key_head;
3885 ic_info->commit_key_head = 0;
3887 if (ic_info->key_unhandled)
3890 ic_info->key_head = ic_info->state_key_head
3891 = ic_info->commit_key_head = 0;
3894 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3898 /** Return 1 if the last event or key was not handled, otherwise
3901 There is no need of looking up because ic->produced should already
3902 contain the produced text (if any).
3907 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3909 mtext_cat (mt, ic->produced);
3910 mtext_reset (ic->produced);
3911 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3915 /* Input method command handler. */
3917 /* List of all (global and local) commands.
3918 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3919 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3920 Global commands are stored as (t (t COMMAND ...)) */
3923 /* Input method variable handler. */
3926 /* Support functions for mdebug_dump_im. */
3929 dump_im_map (MPlist *map_list, int indent)
3932 MSymbol key = MPLIST_KEY (map_list);
3933 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3935 prefix = (char *) alloca (indent + 1);
3936 memset (prefix, 32, indent);
3937 prefix[indent] = '\0';
3939 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3940 if (map->map_actions)
3941 mdebug_dump_plist (map->map_actions, indent + 2);
3944 MPLIST_DO (map_list, map->submaps)
3946 fprintf (stderr, "\n%s ", prefix);
3947 dump_im_map (map_list, indent + 2);
3950 if (map->branch_actions)
3952 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3953 mdebug_dump_plist (map->branch_actions, indent + 4);
3954 fprintf (stderr, ")");
3956 fprintf (stderr, ")");
3961 dump_im_state (MIMState *state, int indent)
3966 prefix = (char *) alloca (indent + 1);
3967 memset (prefix, 32, indent);
3968 prefix[indent] = '\0';
3970 fprintf (stderr, "(%s", msymbol_name (state->name));
3971 if (state->map->submaps)
3973 MPLIST_DO (map_list, state->map->submaps)
3975 fprintf (stderr, "\n%s ", prefix);
3976 dump_im_map (map_list, indent + 2);
3979 fprintf (stderr, ")");
3987 Minput_driver = msymbol ("input-driver");
3989 Minput_preedit_start = msymbol ("input-preedit-start");
3990 Minput_preedit_done = msymbol ("input-preedit-done");
3991 Minput_preedit_draw = msymbol ("input-preedit-draw");
3992 Minput_status_start = msymbol ("input-status-start");
3993 Minput_status_done = msymbol ("input-status-done");
3994 Minput_status_draw = msymbol ("input-status-draw");
3995 Minput_candidates_start = msymbol ("input-candidates-start");
3996 Minput_candidates_done = msymbol ("input-candidates-done");
3997 Minput_candidates_draw = msymbol ("input-candidates-draw");
3998 Minput_set_spot = msymbol ("input-set-spot");
3999 Minput_focus_move = msymbol ("input-focus-move");
4000 Minput_focus_in = msymbol ("input-focus-in");
4001 Minput_focus_out = msymbol ("input-focus-out");
4002 Minput_toggle = msymbol ("input-toggle");
4003 Minput_reset = msymbol ("input-reset");
4004 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
4005 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
4006 Mcustomized = msymbol ("customized");
4007 Mconfigured = msymbol ("configured");
4008 Minherited = msymbol ("inherited");
4010 minput_default_driver.open_im = open_im;
4011 minput_default_driver.close_im = close_im;
4012 minput_default_driver.create_ic = create_ic;
4013 minput_default_driver.destroy_ic = destroy_ic;
4014 minput_default_driver.filter = filter;
4015 minput_default_driver.lookup = lookup;
4016 minput_default_driver.callback_list = mplist ();
4017 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
4018 M17N_FUNC (reset_ic));
4019 minput_driver = &minput_default_driver;
4021 fully_initialized = 0;
4028 if (fully_initialized)
4030 free_im_list (im_info_list);
4032 free_im_list (im_custom_list);
4034 free_im_list (im_config_list);
4035 M17N_OBJECT_UNREF (load_im_info_keys);
4038 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
4039 M17N_OBJECT_UNREF (minput_driver->callback_list);
4044 minput__char_to_key (int c)
4046 if (c < 0 || c >= 0x100)
4049 return one_char_symbol[c];
4053 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
4058 /*** @addtogroup m17nInputMethod */
4063 @name Variables: Predefined symbols for callback commands.
4065 These are the predefined symbols that are used as the @c COMMAND
4066 argument of callback functions of an input method driver (see
4067 #MInputDriver::callback_list).
4069 Most of them do not require extra argument nor return any value;
4070 exceptions are these:
4072 Minput_get_surrounding_text: When a callback function assigned for
4073 this command is called, the first element of #MInputContext::plist
4074 has key #Minteger and the value specifies which portion of the
4075 surrounding text should be retrieved. If the value is positive,
4076 it specifies the number of characters following the current cursor
4077 position. If the value is negative, the absolute value specifies
4078 the number of characters preceding the current cursor position.
4079 If the value is zero, it means that the caller just wants to know
4080 if the surrounding text is currently supported or not.
4082 If the surrounding text is currently supported, the callback
4083 function must set the key of this element to #Mtext and the value
4084 to the retrieved M-text. The length of the M-text may be shorter
4085 than the requested number of characters, if the available text is
4086 not that long. The length can be zero in the worst case. Or, the
4087 length may be longer if an application thinks it is more efficient
4088 to return that length.
4090 If the surrounding text is not currently supported, the callback
4091 function should return without changing the first element of
4092 #MInputContext::plist.
4094 Minput_delete_surrounding_text: When a callback function assigned
4095 for this command is called, the first element of
4096 #MInputContext::plist has key #Minteger and the value specifies
4097 which portion of the surrounding text should be deleted in the
4098 same way as the case of Minput_get_surrounding_text. The callback
4099 function must delete the specified text. It should not alter
4100 #MInputContext::plist. */
4102 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4104 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4105 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4107 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4109 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4110 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4111 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4112 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4113 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4114 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4115 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4117 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4118 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4119 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4120 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4121 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4123 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4124 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4126 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4127 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4128 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4129 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4130 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4131 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4135 MSymbol Minput_preedit_start;
4136 MSymbol Minput_preedit_done;
4137 MSymbol Minput_preedit_draw;
4138 MSymbol Minput_status_start;
4139 MSymbol Minput_status_done;
4140 MSymbol Minput_status_draw;
4141 MSymbol Minput_candidates_start;
4142 MSymbol Minput_candidates_done;
4143 MSymbol Minput_candidates_draw;
4144 MSymbol Minput_set_spot;
4145 MSymbol Minput_toggle;
4146 MSymbol Minput_reset;
4147 MSymbol Minput_get_surrounding_text;
4148 MSymbol Minput_delete_surrounding_text;
4154 @name Variables: Predefined symbols for special input events.
4156 These are the predefined symbols that are used as the @c KEY
4157 argument of minput_filter (). */
4159 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4161 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4166 MSymbol Minput_focus_out;
4167 MSymbol Minput_focus_in;
4168 MSymbol Minput_focus_move;
4174 @name Variables: Predefined symbols used in input method information.
4176 These are the predefined symbols describing status of input method
4177 command and variable, and are used in a return value of
4178 minput_get_command () and minput_get_variable (). */
4180 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4182 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4183 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4187 MSymbol Mcustomized;
4188 MSymbol Mconfigured;
4194 @brief The default driver for internal input methods.
4196 The variable #minput_default_driver is the default driver for
4197 internal input methods.
4199 The member MInputDriver::open_im () searches the m17n database for
4200 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4201 $NAME\> and loads it.
4203 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4204 programmers responsibility to set it to a plist of proper callback
4205 functions. Otherwise, no feedback information (e.g. preedit text)
4206 can be shown to users.
4208 The macro M17N_INIT () sets the variable #minput_driver to the
4209 pointer to this driver so that all internal input methods use it.
4211 Therefore, unless @c minput_driver is set differently, the driver
4212 dependent arguments $ARG of the functions whose name begins with
4213 "minput_" are all ignored. */
4215 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4217 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4219 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4220 \< #Minput_method, $LANGUAGE, $NAME\>
4221 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4223 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4224 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4225 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4226 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4228 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4229 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4231 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4232 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4234 MInputDriver minput_default_driver;
4238 @brief The driver for internal input methods.
4240 The variable #minput_driver is a pointer to the input method
4241 driver that is used by internal input methods. The macro
4242 M17N_INIT () initializes it to a pointer to #minput_default_driver
4243 if <m17n<EM></EM>.h> is included. */
4245 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4247 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4248 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4249 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4250 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4252 MInputDriver *minput_driver;
4254 MSymbol Minput_driver;
4269 @brief Open an input method.
4271 The minput_open_im () function opens an input method whose
4272 language and name match $LANGUAGE and $NAME, and returns a pointer
4273 to the input method object newly allocated.
4275 This function at first decides a driver for the input method as
4278 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4279 #minput_driver is used.
4281 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4282 driver pointed to by the property value is used to open the input
4283 method. If $NAME has no such a property, @c NULL is returned.
4285 Then, the member MInputDriver::open_im () of the driver is
4288 $ARG is set in the member @c arg of the structure MInputMethod so
4289 that the driver can refer to it. */
4291 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4293 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4294 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4296 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4298 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4299 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4301 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4302 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4303 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4305 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4307 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4309 @latexonly \IPAlabel{minput_open} @endlatexonly
4314 minput_open_im (MSymbol language, MSymbol name, void *arg)
4317 MInputDriver *driver;
4321 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4322 msymbol_name (language), msymbol_name (name));
4324 driver = minput_driver;
4327 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4329 MERROR (MERROR_IM, NULL);
4332 MSTRUCT_CALLOC (im, MERROR_IM);
4333 im->language = language;
4336 im->driver = *driver;
4337 if ((*im->driver.open_im) (im) < 0)
4339 MDEBUG_PRINT (" failed\n");
4343 MDEBUG_PRINT (" ok\n");
4350 @brief Close an input method.
4352 The minput_close_im () function closes the input method $IM, which
4353 must have been created by minput_open_im (). */
4356 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4358 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4359 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4362 minput_close_im (MInputMethod *im)
4364 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4365 msymbol_name (im->name), msymbol_name (im->language));
4366 (*im->driver.close_im) (im);
4368 MDEBUG_PRINT (" done\n");
4374 @brief Create an input context.
4376 The minput_create_ic () function creates an input context object
4377 associated with input method $IM, and calls callback functions
4378 corresponding to #Minput_preedit_start, #Minput_status_start, and
4379 #Minput_status_draw in this order.
4382 If an input context is successfully created, minput_create_ic ()
4383 returns a pointer to it. Otherwise it returns @c NULL. */
4386 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4388 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4389 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4390 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4391 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4394 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4395 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4399 minput_create_ic (MInputMethod *im, void *arg)
4403 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4404 msymbol_name (im->name), msymbol_name (im->language));
4405 MSTRUCT_CALLOC (ic, MERROR_IM);
4408 ic->preedit = mtext ();
4409 ic->candidate_list = NULL;
4410 ic->produced = mtext ();
4411 ic->spot.x = ic->spot.y = 0;
4413 ic->plist = mplist ();
4414 if ((*im->driver.create_ic) (ic) < 0)
4416 MDEBUG_PRINT (" failed\n");
4417 M17N_OBJECT_UNREF (ic->preedit);
4418 M17N_OBJECT_UNREF (ic->produced);
4419 M17N_OBJECT_UNREF (ic->plist);
4424 if (im->driver.callback_list)
4426 minput_callback (ic, Minput_preedit_start);
4427 minput_callback (ic, Minput_status_start);
4428 minput_callback (ic, Minput_status_draw);
4431 MDEBUG_PRINT (" ok\n");
4438 @brief Destroy an input context.
4440 The minput_destroy_ic () function destroys the input context $IC,
4441 which must have been created by minput_create_ic (). It calls
4442 callback functions corresponding to #Minput_preedit_done,
4443 #Minput_status_done, and #Minput_candidates_done in this order. */
4446 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4448 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4449 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4450 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4451 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4452 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4456 minput_destroy_ic (MInputContext *ic)
4458 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4459 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4460 if (ic->im->driver.callback_list)
4462 minput_callback (ic, Minput_preedit_done);
4463 minput_callback (ic, Minput_status_done);
4464 minput_callback (ic, Minput_candidates_done);
4466 (*ic->im->driver.destroy_ic) (ic);
4467 M17N_OBJECT_UNREF (ic->preedit);
4468 M17N_OBJECT_UNREF (ic->produced);
4469 M17N_OBJECT_UNREF (ic->plist);
4470 MDEBUG_PRINT (" done\n");
4477 @brief Filter an input key.
4479 The minput_filter () function filters input key $KEY according to
4480 input context $IC, and calls callback functions corresponding to
4481 #Minput_preedit_draw, #Minput_status_draw, and
4482 #Minput_candidates_draw if the preedit text, the status, and the
4483 current candidate are changed respectively.
4485 To make the input method commit the current preedit text (if any)
4486 and shift to the initial state, call this function with #Mnil as
4489 To inform the input method about the focus-out event, call this
4490 function with #Minput_focus_out as $KEY.
4492 To inform the input method about the focus-in event, call this
4493 function with #Minput_focus_in as $KEY.
4495 To inform the input method about the focus-move event (i.e. input
4496 spot change within the same input context), call this function
4497 with #Minput_focus_move as $KEY.
4500 If $KEY is filtered out, this function returns 1. In that case,
4501 the caller should discard the key. Otherwise, it returns 0, and
4502 the caller should handle the key, for instance, by calling the
4503 function minput_lookup () with the same key. */
4506 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4508 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4509 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4510 #Minput_preedit_draw, #Minput_status_draw,
4511 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4514 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4515 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4516 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4517 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4519 @latexonly \IPAlabel{minput_filter} @endlatexonly
4523 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4530 if (ic->im->driver.callback_list
4531 && mtext_nchars (ic->preedit) > 0)
4532 minput_callback (ic, Minput_preedit_draw);
4534 ret = (*ic->im->driver.filter) (ic, key, arg);
4536 if (ic->im->driver.callback_list)
4538 if (ic->preedit_changed)
4539 minput_callback (ic, Minput_preedit_draw);
4540 if (ic->status_changed)
4541 minput_callback (ic, Minput_status_draw);
4542 if (ic->candidates_changed)
4543 minput_callback (ic, Minput_candidates_draw);
4552 @brief Look up a text produced in the input context.
4554 The minput_lookup () function looks up a text in the input context
4555 $IC. $KEY must be identical to the one that was used in the previous call of
4558 If a text was produced by the input method, it is concatenated
4561 This function calls #MInputDriver::lookup .
4564 If $KEY was correctly handled by the input method, this function
4565 returns 0. Otherwise, it returns -1, even though some text
4566 might be produced in $MT. */
4569 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4571 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4572 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4574 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4577 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4580 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4581 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4582 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4584 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4587 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4589 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4594 @brief Set the spot of the input context.
4596 The minput_set_spot () function sets the spot of input context $IC
4597 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4598 The semantics of these values depends on the input method driver.
4600 For instance, a driver designed to work in a CUI environment may
4601 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4602 $DESCENT . A driver designed to work in a window system may
4603 interpret $X and $Y as the pixel offsets relative to the origin of the
4604 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4605 descent pixels of the line at ($X . $Y ).
4607 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4609 $MT and $POS are the M-text and the character position at the spot.
4610 $MT may be @c NULL, in which case, the input method cannot get
4611 information about the text around the spot. */
4614 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4616 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4617 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4618 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4620 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4621 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4622 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4623 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4624 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4625 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4627 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4629 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4630 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4634 minput_set_spot (MInputContext *ic, int x, int y,
4635 int ascent, int descent, int fontsize,
4640 ic->spot.ascent = ascent;
4641 ic->spot.descent = descent;
4642 ic->spot.fontsize = fontsize;
4645 if (ic->im->driver.callback_list)
4646 minput_callback (ic, Minput_set_spot);
4651 @brief Toggle input method.
4653 The minput_toggle () function toggles the input method associated
4654 with input context $IC. */
4656 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4658 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4659 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4663 minput_toggle (MInputContext *ic)
4665 if (ic->im->driver.callback_list)
4666 minput_callback (ic, Minput_toggle);
4667 ic->active = ! ic->active;
4673 @brief Reset an input context.
4675 The minput_reset_ic () function resets input context $IC by
4676 calling a callback function corresponding to #Minput_reset. It
4677 resets the status of $IC to its initial one. As the
4678 current preedit text is deleted without commitment, if necessary,
4679 call minput_filter () with the arg @r key #Mnil to force the input
4680 method to commit the preedit in advance. */
4683 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4685 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4686 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4687 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4688 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4689 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4690 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4693 minput_reset_ic (MInputContext *ic)
4695 if (ic->im->driver.callback_list)
4696 minput_callback (ic, Minput_reset);
4702 @brief Get title and icon filename of an input method.
4704 The minput_get_title_icon () function returns a plist containing a
4705 title and icon filename (if any) of an input method specified by
4706 $LANGUAGE and $NAME.
4708 The first element of the plist has key #Mtext and the value is an
4709 M-text of the title for identifying the input method. The second
4710 element (if any) has key #Mtext and the value is an M-text of the
4711 icon image (absolute) filename for the same purpose.
4714 If there exists a specified input method and it defines an title,
4715 a plist is returned. Otherwise, NULL is returned. The caller
4716 must free the plist by m17n_object_unref (). */
4718 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4720 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4721 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4724 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4725 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4726 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4729 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4730 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4731 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4734 minput_get_title_icon (MSymbol language, MSymbol name)
4736 MInputMethodInfo *im_info;
4743 im_info = get_im_info (language, name, Mnil, Mtitle);
4744 if (! im_info || !im_info->title)
4746 mt = mtext_get_prop (im_info->title, 0, Mtext);
4748 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4751 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4754 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4755 (char *) MSYMBOL_NAME (name));
4756 file = mdatabase__find_file (buf);
4757 if (! file && language == Mt)
4759 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4760 file = mdatabase__find_file (buf);
4765 mplist_add (plist, Mtext, im_info->title);
4768 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4770 mplist_add (plist, Mtext, mt);
4771 M17N_OBJECT_UNREF (mt);
4779 @brief Get description text of an input method.
4781 The minput_get_description () function returns an M-text that
4782 describes the input method specified by $LANGUAGE and $NAME.
4785 If the specified input method has a description text, a pointer to
4786 #MText is returned. The caller has to free it by m17n_object_unref ().
4787 If the input method does not have a description text, @c NULL is
4790 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4792 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4793 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4796 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4797 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4798 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4799 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4802 minput_get_description (MSymbol language, MSymbol name)
4804 MInputMethodInfo *im_info;
4812 extra = language, language = Mt;
4814 im_info = get_im_info (language, name, extra, Mdescription);
4815 if (! im_info || ! im_info->description)
4817 M17N_OBJECT_REF (im_info->description);
4818 return im_info->description;
4824 @brief Get information about input method command(s).
4826 The minput_get_command () function returns information about
4827 the command $COMMAND of the input method specified by $LANGUAGE and
4828 $NAME. An input method command is a pseudo key event to which one
4829 or more actual input key sequences are assigned.
4831 There are two kinds of commands, global and local. A global
4832 command has a global definition, and the description and the key
4833 assignment may be inherited by a local command. Each input method
4834 defines a local command which has a local key assignment. It may
4835 also declare a local command that inherits the definition of a
4836 global command of the same name.
4838 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4839 information about a global command. Otherwise information about a
4840 local command is returned.
4842 If $COMMAND is #Mnil, information about all commands is returned.
4844 The return value is a @e well-formed plist (@ref m17nPlist) of this
4847 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4849 @c NAME is a symbol representing the command name.
4851 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4852 command has no description.
4854 @c STATUS is a symbol representing how the key assignment is decided.
4855 The value is #Mnil (the default key assignment), #Mcustomized (the
4856 key assignment is customized by per-user customization file), or
4857 #Mconfigured (the key assignment is set by the call of
4858 minput_config_command ()). For a local command only, it may also
4859 be #Minherited (the key assignment is inherited from the
4860 corresponding global command).
4862 @c KEYSEQ is a plist of one or more symbols representing a key
4863 sequence assigned to the command. If there's no KEYSEQ, the
4864 command is currently disabled (i.e. no key sequence can trigger
4865 actions of the command).
4867 If $COMMAND is not #Mnil, the first element of the returned plist
4868 contains the information about $COMMAND.
4872 If the requested information was found, a pointer to a non-empty
4873 plist is returned. As the plist is kept in the library, the
4874 caller must not modify nor free it.
4876 Otherwise (the specified input method or the specified command
4877 does not exist), @c NULL is returned. */
4879 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4881 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4882 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4883 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4884 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4886 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4887 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4888 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4889 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4890 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4892 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4893 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4896 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4898 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
4901 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4903 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4905 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4908 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4909 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4910 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4911 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4912 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4913 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4916 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4917 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4918 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4919 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4921 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4922 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4926 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4927 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4930 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4935 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4937 /* Return a description of the command COMMAND of the input method
4938 specified by LANGUAGE and NAME. */
4939 MPlist *cmd = minput_get_command (langauge, name, command);
4944 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4945 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4946 return (mplist_key (plist) == Mtext
4947 ? (MText *) mplist_value (plist)
4953 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4955 MInputMethodInfo *im_info;
4959 im_info = get_im_info (language, name, Mnil, Mcommand);
4961 || ! im_info->configured_cmds
4962 || MPLIST_TAIL_P (im_info->configured_cmds))
4964 if (command == Mnil)
4965 return im_info->configured_cmds;
4966 return mplist__assq (im_info->configured_cmds, command);
4972 @brief Configure the key sequence of an input method command.
4974 The minput_config_command () function assigns a list of key
4975 sequences $KEYSEQLIST to the command $COMMAND of the input method
4976 specified by $LANGUAGE and $NAME.
4978 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4979 sequences, and each key sequence must be a plist of symbols.
4981 If $KEYSEQLIST is an empty plist, any configuration and
4982 customization of the command are cancelled, and default key
4983 sequences become effective.
4985 If $KEYSEQLIST is NULL, the configuration of the command is
4986 canceled, and the original key sequences (what saved in per-user
4987 customization file, or the default one) become effective.
4989 In the latter two cases, $COMMAND can be #Mnil to make all the
4990 commands of the input method the target of the operation.
4992 If $NAME is #Mnil, this function configures the key assignment of a
4993 global command, not that of a specific input method.
4995 The configuration takes effect for input methods opened or
4996 re-opened later in the current session. In order to make the
4997 configuration take effect for the future session, it must be saved
4998 in a per-user customization file by the function
4999 minput_save_config ().
5002 If the operation was successful, this function returns 0,
5003 otherwise returns -1. The operation fails in these cases:
5005 <li>$KEYSEQLIST is not in a valid form.
5006 <li>$COMMAND is not available for the input method.
5007 <li>$LANGUAGE and $NAME do not specify an existing input method.
5011 minput_get_commands (), minput_save_config ().
5014 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
5016 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
5017 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
5018 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
5020 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
5021 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
5023 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
5024 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
5026 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
5027 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
5028 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
5030 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
5031 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5033 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5034 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
5036 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5037 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5038 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5039 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5043 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5045 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
5046 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5047 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5051 minput_get_commands (), minput_save_config ().
5055 /* Add "C-x u" to the "start" command of Unicode input method. */
5057 MSymbol start_command = msymbol ("start");
5058 MSymbol unicode = msymbol ("unicode");
5059 MPlist *cmd, *plist, *key_seq_list, *key_seq;
5061 /* At first get the current key-sequence assignment. */
5062 cmd = minput_get_command (Mt, unicode, start_command);
5065 /* The input method does not have the command "start". Here
5066 should come some error handling code. */
5068 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5069 Extract the part (KEY-SEQUENCE ...). */
5070 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5071 /* Copy it because we should not modify it directly. */
5072 key_seq_list = mplist_copy (plist);
5074 key_seq = mplist ();
5075 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5076 mplist_add (key_seq, Msymbol, msymbol ("u"));
5077 mplist_add (key_seq_list, Mplist, key_seq);
5078 m17n_object_unref (key_seq);
5080 minput_config_command (Mt, unicode, start_command, key_seq_list);
5081 m17n_object_unref (key_seq_list);
5086 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5089 MInputMethodInfo *im_info, *config;
5094 im_info = get_im_info (language, name, Mnil, Mcommand);
5096 MERROR (MERROR_IM, -1);
5097 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5099 || ! mplist__assq (im_info->configured_cmds, command)))
5100 MERROR (MERROR_IM, -1);
5101 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5103 MPLIST_DO (plist, keyseqlist)
5104 if (! check_command_keyseq (plist))
5105 MERROR (MERROR_IM, -1);
5108 config = get_config_info (im_info);
5111 if (! im_config_list)
5112 im_config_list = mplist ();
5113 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5114 config->cmds = mplist ();
5115 config->vars = mplist ();
5118 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5119 /* Nothing to do. */
5122 if (command == Mnil)
5126 /* Cancal the configuration. */
5127 if (MPLIST_TAIL_P (config->cmds))
5129 mplist_set (config->cmds, Mnil, NULL);
5133 /* Cancal the customization. */
5134 MInputMethodInfo *custom = get_custom_info (im_info);
5136 if (MPLIST_TAIL_P (config->cmds)
5137 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5138 /* Nothing to do. */
5140 mplist_set (config->cmds, Mnil, NULL);
5141 MPLIST_DO (plist, custom->cmds)
5143 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5145 mplist_add (plist, Msymbol, command);
5146 mplist_push (config->cmds, Mplist, plist);
5147 M17N_OBJECT_UNREF (plist);
5153 plist = mplist__assq (config->cmds, command);
5156 /* Cancel the configuration. */
5159 mplist__pop_unref (plist);
5161 else if (MPLIST_TAIL_P (keyseqlist))
5163 /* Cancel the customization. */
5164 MInputMethodInfo *custom = get_custom_info (im_info);
5165 int no_custom = (! custom || ! custom->cmds
5166 || ! mplist__assq (custom->cmds, command));
5172 mplist_add (config->cmds, Mplist, plist);
5173 M17N_OBJECT_UNREF (plist);
5174 plist = mplist_add (plist, Msymbol, command);
5179 mplist__pop_unref (plist);
5182 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5183 plist = MPLIST_NEXT (plist);
5184 mplist_set (plist, Mnil, NULL);
5194 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5195 if (! MPLIST_TAIL_P (plist))
5196 mplist_set (plist, Mnil, NULL);
5201 mplist_add (config->cmds, Mplist, plist);
5202 M17N_OBJECT_UNREF (plist);
5203 plist = mplist_add (plist, Msymbol, command);
5204 plist = MPLIST_NEXT (plist);
5206 MPLIST_DO (keyseqlist, keyseqlist)
5208 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5209 plist = mplist_add (plist, Mplist, pl);
5210 M17N_OBJECT_UNREF (pl);
5214 config_all_commands (im_info);
5215 im_info->tick = time (NULL);
5222 @brief Get information about input method variable(s).
5224 The minput_get_variable () function returns information about
5225 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5226 An input method variable controls behavior of an input method.
5228 There are two kinds of variables, global and local. A global
5229 variable has a global definition, and the description and the value
5230 may be inherited by a local variable. Each input method defines a
5231 local variable which has local value. It may also declare a
5232 local variable that inherits definition of a global variable of
5235 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5236 variable is returned. Otherwise information about a local variable
5239 If $VARIABLE is #Mnil, information about all variables is
5242 The return value is a @e well-formed plist (@ref m17nPlist) of this
5245 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5247 @c NAME is a symbol representing the variable name.
5249 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5250 variable has no description.
5252 @c STATUS is a symbol representing how the value is decided. The
5253 value is #Mnil (the default value), #Mcustomized (the value is
5254 customized by per-user customization file), or #Mconfigured (the
5255 value is set by the call of minput_config_variable ()). For a
5256 local variable only, it may also be #Minherited (the value is
5257 inherited from the corresponding global variable).
5259 @c VALUE is the initial value of the variable. If the key of this
5260 element is #Mt, the variable has no initial value. Otherwise, the
5261 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5264 @c VALID-VALUEs (if any) specify which values the variable can have.
5265 They have the same type (i.e. having the same key) as @c VALUE except
5266 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5267 may be a plist of two integers specifying the range of possible
5270 If there no @c VALID-VALUE, the variable can have any value as long
5271 as the type is the same as @c VALUE.
5273 If $VARIABLE is not #Mnil, the first element of the returned plist
5274 contains the information about $VARIABLE.
5278 If the requested information was found, a pointer to a non-empty
5279 plist is returned. As the plist is kept in the library, the
5280 caller must not modify nor free it.
5282 Otherwise (the specified input method or the specified variable
5283 does not exist), @c NULL is returned. */
5285 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5287 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5288 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5289 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5291 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5292 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5293 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5294 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5297 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5298 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5300 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5302 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (@ref m17nPlist) ¤Ç¤¢¤ë¡£
5304 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5307 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5309 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5312 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5313 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5314 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5315 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5316 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5317 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5319 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5320 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5321 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5323 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5324 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5325 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5326 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5328 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5331 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5332 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5336 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5337 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5340 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5344 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5346 MInputMethodInfo *im_info;
5350 im_info = get_im_info (language, name, Mnil, Mvariable);
5351 if (! im_info || ! im_info->configured_vars)
5353 if (variable == Mnil)
5354 return im_info->configured_vars;
5355 return mplist__assq (im_info->configured_vars, variable);
5361 @brief Configure the value of an input method variable.
5363 The minput_config_variable () function assigns $VALUE to the
5364 variable $VARIABLE of the input method specified by $LANGUAGE and
5367 If $VALUE is a non-empty plist, it must be a plist of one element
5368 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5369 the corresponding type. That value is assigned to the variable.
5371 If $VALUE is an empty plist, any configuration and customization
5372 of the variable are canceled, and the default value is assigned to
5375 If $VALUE is NULL, the configuration of the variable is canceled,
5376 and the original value (what saved in per-user customization file,
5377 or the default value) is assigned to the variable.
5379 In the latter two cases, $VARIABLE can be #Mnil to make all the
5380 variables of the input method the target of the operation.
5382 If $NAME is #Mnil, this function configures the value of global
5383 variable, not that of a specific input method.
5385 The configuration takes effect for input methods opened or
5386 re-opened later in the current session. To make the configuration
5387 take effect for the future session, it must be saved in a per-user
5388 customization file by the function minput_save_config ().
5392 If the operation was successful, this function returns 0,
5393 otherwise returns -1. The operation fails in these cases:
5395 <li>$VALUE is not in a valid form, the type does not match the
5396 definition, or the value is our of range.
5397 <li>$VARIABLE is not available for the input method.
5398 <li>$LANGUAGE and $NAME do not specify an existing input method.
5402 minput_get_variable (), minput_save_config (). */
5404 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5406 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5407 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5409 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5410 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5411 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5413 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5414 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5416 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5417 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5419 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5420 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5422 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5423 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5425 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5426 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5427 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5428 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5432 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5434 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5435 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5436 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5440 minput_get_commands (), minput_save_config ().
5443 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5446 MInputMethodInfo *im_info, *config;
5451 im_info = get_im_info (language, name, Mnil, Mvariable);
5453 MERROR (MERROR_IM, -1);
5454 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5456 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5457 MERROR (MERROR_IM, -1);
5459 if (value && ! MPLIST_TAIL_P (value))
5461 plist = MPLIST_PLIST (plist);
5462 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5463 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5464 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5465 if (MPLIST_KEY (plist) != Mt
5466 && ! check_variable_value (value, plist))
5467 MERROR (MERROR_IM, -1);
5470 config = get_config_info (im_info);
5473 if (! im_config_list)
5474 im_config_list = mplist ();
5475 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5476 config->cmds = mplist ();
5477 config->vars = mplist ();
5480 if (! value && MPLIST_TAIL_P (config->vars))
5481 /* Nothing to do. */
5484 if (variable == Mnil)
5488 /* Cancel the configuration. */
5489 if (MPLIST_TAIL_P (config->vars))
5491 mplist_set (config->vars, Mnil, NULL);
5495 /* Cancel the customization. */
5496 MInputMethodInfo *custom = get_custom_info (im_info);
5498 if (MPLIST_TAIL_P (config->vars)
5499 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5500 /* Nothing to do. */
5502 mplist_set (config->vars, Mnil, NULL);
5503 MPLIST_DO (plist, custom->vars)
5505 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5507 mplist_add (plist, Msymbol, variable);
5508 mplist_push (config->vars, Mplist, plist);
5509 M17N_OBJECT_UNREF (plist);
5515 plist = mplist__assq (config->vars, variable);
5518 /* Cancel the configuration. */
5521 mplist__pop_unref (plist);
5523 else if (MPLIST_TAIL_P (value))
5525 /* Cancel the customization. */
5526 MInputMethodInfo *custom = get_custom_info (im_info);
5527 int no_custom = (! custom || ! custom->vars
5528 || ! mplist__assq (custom->vars, variable));
5534 mplist_add (config->vars, Mplist, plist);
5535 M17N_OBJECT_UNREF (plist);
5536 plist = mplist_add (plist, Msymbol, variable);
5541 mplist__pop_unref (plist);
5544 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5545 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5546 mplist_set (plist, Mnil ,NULL);
5554 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5555 if (! MPLIST_TAIL_P (plist))
5556 mplist_set (plist, Mnil, NULL);
5561 mplist_add (config->vars, Mplist, plist);
5562 M17N_OBJECT_UNREF (plist);
5563 plist = mplist_add (plist, Msymbol, variable);
5564 plist = MPLIST_NEXT (plist);
5566 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5569 config_all_variables (im_info);
5570 im_info->tick = time (NULL);
5577 @brief Get the name of per-user customization file.
5579 The minput_config_file () function returns the absolute path name
5580 of per-user customization file into which minput_save_config ()
5581 save configurations. It is usually @c config.mic under the
5582 directory <tt>${HOME}/.m17n.d</tt> (${HOME} is user's home
5583 directory). It is not assured that the file of the returned name
5584 exists nor is readable/writable. If minput_save_config () fails
5585 and returns -1, an application program might check the file, make
5586 it writable (if possible), and try minput_save_config () again.
5590 This function returns a string. As the string is kept in the
5591 library, the caller must not modify nor free it.
5594 minput_save_config ()
5597 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5599 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5600 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5601 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5602 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5603 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5604 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5605 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5610 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5611 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5614 minput_save_config ()
5618 minput_config_file ()
5622 return mdatabase__file (im_custom_mdb);
5628 @brief Save configurations in per-user customization file.
5630 The minput_save_config () function saves the configurations done
5631 so far in the current session into the per-user customization
5636 If the operation was successful, 1 is returned. If the per-user
5637 customization file is currently locked, 0 is returned. In that
5638 case, the caller may wait for a while and try again. If the
5639 configuration file is not writable, -1 is returned. In that case,
5640 the caller may check the name of the file by calling
5641 minput_config_file (), make it writable if possible, and try
5645 minput_config_file () */
5647 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5649 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5650 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5654 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5655 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5656 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5657 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5661 minput_config_file () */
5664 minput_save_config (void)
5666 MPlist *data, *tail, *plist, *p, *elt;
5670 ret = mdatabase__lock (im_custom_mdb);
5673 if (! im_config_list)
5675 update_custom_info ();
5676 if (! im_custom_list)
5677 im_custom_list = mplist ();
5679 /* At first, reflect configuration in customization. */
5680 MPLIST_DO (plist, im_config_list)
5682 MPlist *pl = MPLIST_PLIST (plist);
5683 MSymbol language, name, extra, command, variable;
5684 MInputMethodInfo *custom, *config;
5686 language = MPLIST_SYMBOL (pl);
5687 pl = MPLIST_NEXT (pl);
5688 name = MPLIST_SYMBOL (pl);
5689 pl = MPLIST_NEXT (pl);
5690 extra = MPLIST_SYMBOL (pl);
5691 pl = MPLIST_NEXT (pl);
5692 config = MPLIST_VAL (pl);
5693 custom = get_custom_info (config);
5695 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5697 MPLIST_DO (pl, config->cmds)
5699 elt = MPLIST_PLIST (pl);
5700 command = MPLIST_SYMBOL (elt);
5702 p = mplist__assq (custom->cmds, command);
5704 custom->cmds = mplist (), p = NULL;
5705 elt = MPLIST_NEXT (elt);
5708 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5709 mplist_set (p, Mnil, NULL);
5714 mplist_add (custom->cmds, Mplist, p);
5715 M17N_OBJECT_UNREF (p);
5716 mplist_add (p, Msymbol, command);
5717 p = mplist_add (p, Msymbol, Mnil);
5718 p = MPLIST_NEXT (p);
5720 mplist__conc (p, elt);
5723 MPLIST_DO (pl, config->vars)
5725 elt = MPLIST_PLIST (pl);
5726 variable = MPLIST_SYMBOL (elt);
5728 p = mplist__assq (custom->vars, variable);
5730 custom->vars = mplist (), p = NULL;
5731 elt = MPLIST_NEXT (elt);
5734 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5735 mplist_set (p, Mnil, NULL);
5740 mplist_add (custom->vars, Mplist, p);
5741 M17N_OBJECT_UNREF (p);
5742 mplist_add (p, Msymbol, variable);
5743 p = mplist_add (p, Msymbol, Mnil);
5744 p = MPLIST_NEXT (p);
5746 mplist__conc (p, elt);
5749 free_im_list (im_config_list);
5750 im_config_list = NULL;
5752 /* Next, reflect customization to the actual plist to be written. */
5753 data = tail = mplist ();
5754 MPLIST_DO (plist, im_custom_list)
5756 MPlist *pl = MPLIST_PLIST (plist);
5757 MSymbol language, name, extra;
5758 MInputMethodInfo *custom, *im_info;
5760 language = MPLIST_SYMBOL (pl);
5761 pl = MPLIST_NEXT (pl);
5762 name = MPLIST_SYMBOL (pl);
5763 pl = MPLIST_NEXT (pl);
5764 extra = MPLIST_SYMBOL (pl);
5765 pl = MPLIST_NEXT (pl);
5766 custom = MPLIST_VAL (pl);
5767 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5768 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5770 im_info = lookup_im_info (im_info_list, language, name, extra);
5774 config_all_commands (im_info);
5776 config_all_variables (im_info);
5780 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5782 MPLIST_DO (p, custom->cmds)
5783 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5785 if (! MPLIST_TAIL_P (p))
5789 mplist_add (elt, Mplist, pl);
5790 M17N_OBJECT_UNREF (pl);
5791 pl = mplist_add (pl, Msymbol, Mcommand);
5792 MPLIST_DO (p, custom->cmds)
5793 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5794 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5797 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5799 MPLIST_DO (p, custom->vars)
5800 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5802 if (! MPLIST_TAIL_P (p))
5807 mplist_add (elt, Mplist, pl);
5808 M17N_OBJECT_UNREF (pl);
5809 pl = mplist_add (pl, Msymbol, Mvariable);
5810 MPLIST_DO (p, custom->vars)
5811 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5812 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5818 mplist_push (elt, Mplist, pl);
5819 M17N_OBJECT_UNREF (pl);
5820 pl = mplist_add (pl, Msymbol, Minput_method);
5821 pl = mplist_add (pl, Msymbol, language);
5822 pl = mplist_add (pl, Msymbol, name);
5824 pl = mplist_add (pl, Msymbol, extra);
5825 tail = mplist_add (tail, Mplist, elt);
5826 M17N_OBJECT_UNREF (elt);
5830 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5831 ret = mdatabase__save (im_custom_mdb, data);
5832 mdatabase__unlock (im_custom_mdb);
5833 M17N_OBJECT_UNREF (data);
5834 return (ret < 0 ? -1 : 1);
5841 @name Obsolete functions
5844 @name Obsolete ¤Ê´Ø¿ô
5850 @brief Get a list of variables of an input method (obsolete).
5852 This function is obsolete. Use minput_get_variable () instead.
5854 The minput_get_variables () function returns a plist (#MPlist) of
5855 variables used to control the behavior of the input method
5856 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5857 (@ref m17nPlist) of the following format:
5860 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5861 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5865 @c VARNAME is a symbol representing the variable name.
5867 @c DOC-MTEXT is an M-text describing the variable.
5869 @c DEFAULT-VALUE is the default value of the variable. It is a
5870 symbol, integer, or M-text.
5872 @c VALUEs (if any) specifies the possible values of the variable.
5873 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5874 @c TO), where @c FROM and @c TO specifies a range of possible
5877 For instance, suppose an input method has the variables:
5879 @li name:intvar, description:"value is an integer",
5880 initial value:0, value-range:0..3,10,20
5882 @li name:symvar, description:"value is a symbol",
5883 initial value:nil, value-range:a, b, c, nil
5885 @li name:txtvar, description:"value is an M-text",
5886 initial value:empty text, no value-range (i.e. any text)
5888 Then, the returned plist is as follows.
5891 (intvar ("value is an integer" 0 (0 3) 10 20)
5892 symvar ("value is a symbol" nil a b c nil)
5893 txtvar ("value is an M-text" ""))
5897 If the input method uses any variables, a pointer to #MPlist is
5898 returned. As the plist is kept in the library, the caller must not
5899 modify nor free it. If the input method does not use any
5900 variable, @c NULL is returned. */
5902 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5904 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5905 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5906 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(@ref m17nPlist) °Ê
5910 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5911 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5915 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5917 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5919 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5922 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5923 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5924 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5926 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5928 @li name:intvar, ÀâÌÀ:"value is an integer",
5929 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5931 @li name:symvar, ÀâÌÀ:"value is a symbol",
5932 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5934 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5935 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5937 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5940 (intvar ("value is an integer" 0 (0 3) 10 20)
5941 symvar ("value is a symbol" nil a b c nil)
5942 txtvar ("value is an M-text" ""))
5946 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5947 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5948 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5951 minput_get_variables (MSymbol language, MSymbol name)
5953 MInputMethodInfo *im_info;
5958 im_info = get_im_info (language, name, Mnil, Mvariable);
5959 if (! im_info || ! im_info->configured_vars)
5962 M17N_OBJECT_UNREF (im_info->bc_vars);
5963 im_info->bc_vars = mplist ();
5964 MPLIST_DO (vars, im_info->configured_vars)
5966 MPlist *plist = MPLIST_PLIST (vars);
5967 MPlist *elt = mplist ();
5969 mplist_push (im_info->bc_vars, Mplist, elt);
5970 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5971 elt = MPLIST_NEXT (elt);
5972 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5973 M17N_OBJECT_UNREF (elt);
5975 return im_info->bc_vars;
5981 @brief Set the initial value of an input method variable.
5983 The minput_set_variable () function sets the initial value of
5984 input method variable $VARIABLE to $VALUE for the input method
5985 specified by $LANGUAGE and $NAME.
5987 By default, the initial value is 0.
5989 This setting gets effective in a newly opened input method.
5992 If the operation was successful, 0 is returned. Otherwise -1 is
5993 returned, and #merror_code is set to #MERROR_IM. */
5995 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5997 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5998 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5999 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
6001 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
6003 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
6006 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6007 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6010 minput_set_variable (MSymbol language, MSymbol name,
6011 MSymbol variable, void *value)
6014 MInputMethodInfo *im_info;
6019 if (variable == Mnil)
6020 MERROR (MERROR_IM, -1);
6021 plist = minput_get_variable (language, name, variable);
6022 plist = MPLIST_PLIST (plist);
6023 plist = MPLIST_NEXT (plist);
6025 mplist_add (pl, MPLIST_KEY (plist), value);
6026 ret = minput_config_variable (language, name, variable, pl);
6027 M17N_OBJECT_UNREF (pl);
6030 im_info = get_im_info (language, name, Mnil, Mvariable);
6039 @brief Get information about input method commands.
6041 The minput_get_commands () function returns information about
6042 input method commands of the input method specified by $LANGUAGE
6043 and $NAME. An input method command is a pseudo key event to which
6044 one or more actual input key sequences are assigned.
6046 There are two kinds of commands, global and local. Global
6047 commands are used by multiple input methods for the same purpose,
6048 and have global key assignments. Local commands are used only by
6049 a specific input method, and have only local key assignments.
6051 Each input method may locally change key assignments for global
6052 commands. The global key assignment for a global command is
6053 effective only when the current input method does not have local
6054 key assignments for that command.
6056 If $NAME is #Mnil, information about global commands is returned.
6057 In this case $LANGUAGE is ignored.
6059 If $NAME is not #Mnil, information about those commands that have
6060 local key assignments in the input method specified by $LANGUAGE
6061 and $NAME is returned.
6064 If no input method commands are found, this function returns @c NULL.
6066 Otherwise, a pointer to a plist is returned. The key of each
6067 element in the plist is a symbol representing a command, and the
6068 value is a plist of the form COMMAND-INFO described below.
6070 The first element of COMMAND-INFO has the key #Mtext, and the
6071 value is an M-text describing the command.
6073 If there are no more elements, that means no key sequences are
6074 assigned to the command. Otherwise, each of the remaining
6075 elements has the key #Mplist, and the value is a plist whose keys are
6076 #Msymbol and values are symbols representing input keys, which are
6077 currently assigned to the command.
6079 As the returned plist is kept in the library, the caller must not
6080 modify nor free it. */
6082 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6084 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6085 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6086 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6087 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6089 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6090 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6091 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6092 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6094 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6095 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6096 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6099 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6100 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6102 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6103 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6107 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6109 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6110 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6111 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6113 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6114 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6115 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6118 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6119 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6120 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6121 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6122 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6124 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6125 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6128 minput_get_commands (MSymbol language, MSymbol name)
6130 MInputMethodInfo *im_info;
6135 im_info = get_im_info (language, name, Mnil, Mcommand);
6136 if (! im_info || ! im_info->configured_vars)
6138 M17N_OBJECT_UNREF (im_info->bc_cmds);
6139 im_info->bc_cmds = mplist ();
6140 MPLIST_DO (cmds, im_info->configured_cmds)
6142 MPlist *plist = MPLIST_PLIST (cmds);
6143 MPlist *elt = mplist ();
6145 mplist_push (im_info->bc_cmds, Mplist, elt);
6146 mplist_add (elt, MPLIST_SYMBOL (plist),
6147 mplist_copy (MPLIST_NEXT (plist)));
6148 M17N_OBJECT_UNREF (elt);
6150 return im_info->bc_cmds;
6156 @brief Assign a key sequence to an input method command (obsolete).
6158 This function is obsolete. Use minput_config_command () instead.
6160 The minput_assign_command_keys () function assigns input key
6161 sequence $KEYSEQ to input method command $COMMAND for the input
6162 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6163 key sequence is assigned globally no matter what $LANGUAGE is.
6164 Otherwise the key sequence is assigned locally.
6166 Each element of $KEYSEQ must have the key $Msymbol and the value
6167 must be a symbol representing an input key.
6169 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6170 globally or locally.
6172 This assignment gets effective in a newly opened input method.
6175 If the operation was successful, 0 is returned. Otherwise -1 is
6176 returned, and #merror_code is set to #MERROR_IM. */
6178 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6180 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6181 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6182 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6183 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6184 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6186 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6187 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6189 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6190 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6192 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6196 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6197 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6200 minput_assign_command_keys (MSymbol language, MSymbol name,
6201 MSymbol command, MPlist *keyseq)
6207 if (command == Mnil)
6208 MERROR (MERROR_IM, -1);
6213 if (! check_command_keyseq (keyseq))
6214 MERROR (MERROR_IM, -1);
6216 mplist_add (plist, Mplist, keyseq);
6221 ret = minput_config_command (language, name, command, keyseq);
6222 M17N_OBJECT_UNREF (keyseq);
6229 @brief Call a callback function
6231 The minput_callback () functions calls a callback function
6232 $COMMAND assigned for the input context $IC. The caller must set
6233 specific elements in $IC->plist if the callback function requires.
6236 If there exists a specified callback function, 0 is returned.
6237 Otherwise -1 is returned. By side effects, $IC->plist may be
6241 minput_callback (MInputContext *ic, MSymbol command)
6243 MInputCallbackFunc func;
6245 if (! ic->im->driver.callback_list)
6247 func = ((MInputCallbackFunc)
6248 mplist_get_func (ic->im->driver.callback_list, command));
6251 (func) (ic, command);
6258 /*** @addtogroup m17nDebug */
6264 @brief Dump an input method.
6266 The mdebug_dump_im () function prints the input method $IM in a
6267 human readable way to the stderr. $INDENT specifies how many
6268 columns to indent the lines but the first one.
6271 This function returns $IM. */
6273 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6275 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6276 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6279 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6282 mdebug_dump_im (MInputMethod *im, int indent)
6284 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6287 prefix = (char *) alloca (indent + 1);
6288 memset (prefix, 32, indent);
6289 prefix[indent] = '\0';
6291 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6292 msymbol_name (im->name));
6293 mdebug_dump_mtext (im_info->title, 0, 0);
6294 if (im->name != Mnil)
6298 MPLIST_DO (state, im_info->states)
6300 fprintf (stderr, "\n%s ", prefix);
6301 dump_im_state (MPLIST_VAL (state), indent + 2);
6304 fprintf (stderr, ")");