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>
156 #include "m17n-gui.h"
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_mask = 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]
493 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
495 MPlist *plist = mplist__assq (ic_info->vars, var);
499 plist = MPLIST_PLIST (plist);
500 return MPLIST_NEXT (plist);
504 mplist_push (ic_info->vars, Mplist, plist);
505 M17N_OBJECT_UNREF (plist);
506 plist = mplist_add (plist, Msymbol, var);
507 plist = mplist_add (plist, Minteger, (void *) 0);
512 get_surrounding_text (MInputContext *ic, int len)
516 mplist_push (ic->plist, Minteger, (void *) len);
517 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
518 && MPLIST_MTEXT_P (ic->plist))
519 mt = MPLIST_MTEXT (ic->plist);
520 mplist_pop (ic->plist);
525 delete_surrounding_text (MInputContext *ic, int pos)
527 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
529 mplist_push (ic->plist, Minteger, (void *) pos);
530 minput_callback (ic, Minput_delete_surrounding_text);
531 mplist_pop (ic->plist);
534 M17N_OBJECT_UNREF (ic_info->preceding_text);
535 ic_info->preceding_text = NULL;
539 M17N_OBJECT_UNREF (ic_info->following_text);
540 ic_info->following_text = NULL;
545 get_preceding_char (MInputContext *ic, int pos)
547 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
551 if (pos && ic_info->preceding_text)
553 len = mtext_nchars (ic_info->preceding_text);
555 return mtext_ref_char (ic_info->preceding_text, len - pos);
557 mt = get_surrounding_text (ic, - pos);
560 len = mtext_nchars (mt);
561 if (ic_info->preceding_text)
563 if (mtext_nchars (ic_info->preceding_text) < len)
565 M17N_OBJECT_UNREF (ic_info->preceding_text);
566 ic_info->preceding_text = mt;
569 M17N_OBJECT_UNREF (mt);
572 ic_info->preceding_text = mt;
575 return mtext_ref_char (ic_info->preceding_text, len - pos);
579 get_following_char (MInputContext *ic, int pos)
581 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
585 if (ic_info->following_text)
587 len = mtext_nchars (ic_info->following_text);
589 return mtext_ref_char (ic_info->following_text, pos - 1);
591 mt = get_surrounding_text (ic, pos);
594 len = mtext_nchars (mt);
595 if (ic_info->following_text)
597 if (mtext_nchars (ic_info->following_text) < len)
599 M17N_OBJECT_UNREF (ic_info->following_text);
600 ic_info->following_text = mt;
603 M17N_OBJECT_UNREF (mt);
606 ic_info->following_text = mt;
609 return mtext_ref_char (ic_info->following_text, pos - 1);
613 surrounding_pos (MSymbol sym)
619 name = MSYMBOL_NAME (sym);
621 && (name[1] == '-' || name[1] == '+')
622 && name[2] >= '1' && name[2] <= '9')
623 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
628 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
630 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
632 MText *preedit = ic->preedit;
633 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));
647 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
650 return ic_info->key_head;
651 if ((code == '-' || code == '+'))
653 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
657 pos = atoi (name + 1);
659 return get_preceding_char (ic, 0);
660 pos = ic->cursor_pos + pos;
663 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
664 return mtext_ref_char (ic->produced,
665 mtext_len (ic->produced) + pos);
666 return get_preceding_char (ic, - pos);
669 return get_following_char (ic, pos - len + 1);
672 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
674 else if (code >= '0' && code <= '9')
676 else if (code == '=')
677 pos = ic->cursor_pos;
678 else if (code == '[')
679 pos = ic->cursor_pos - 1;
680 else if (code == ']')
681 pos = ic->cursor_pos + 1;
682 else if (code == '<')
684 else if (code == '>')
686 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
690 parse_expression (MPlist *plist)
694 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
696 if (! MPLIST_PLIST_P (plist))
698 plist = MPLIST_PLIST (plist);
699 op = MPLIST_SYMBOL (plist);
700 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
701 && op != Mand && op != Mor && op != Mnot
702 && op != Mless && op != Mgreater && op != Mequal
703 && op != Mless_equal && op != Mgreater_equal)
704 MERROR (MERROR_IM, -1);
705 MPLIST_DO (plist, MPLIST_NEXT (plist))
706 if (parse_expression (plist) < 0)
712 resolve_expression (MInputContext *ic, MPlist *plist)
717 if (MPLIST_INTEGER_P (plist))
718 return MPLIST_INTEGER (plist);
719 if (MPLIST_SYMBOL_P (plist))
720 return integer_value (ic, plist, NULL, 1);
721 if (! MPLIST_PLIST_P (plist))
723 plist = MPLIST_PLIST (plist);
724 if (! MPLIST_SYMBOL_P (plist))
726 op = MPLIST_SYMBOL (plist);
727 plist = MPLIST_NEXT (plist);
728 val = resolve_expression (ic, plist);
730 MPLIST_DO (plist, MPLIST_NEXT (plist))
731 val += resolve_expression (ic, plist);
732 else if (op == Mminus)
733 MPLIST_DO (plist, MPLIST_NEXT (plist))
734 val -= resolve_expression (ic, plist);
735 else if (op == Mstar)
736 MPLIST_DO (plist, MPLIST_NEXT (plist))
737 val *= resolve_expression (ic, plist);
738 else if (op == Mslash)
739 MPLIST_DO (plist, MPLIST_NEXT (plist))
740 val /= resolve_expression (ic, plist);
742 MPLIST_DO (plist, MPLIST_NEXT (plist))
743 val &= resolve_expression (ic, plist);
745 MPLIST_DO (plist, MPLIST_NEXT (plist))
746 val |= resolve_expression (ic, plist);
749 else if (op == Mless)
750 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
751 else if (op == Mequal)
752 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
753 else if (op == Mgreater)
754 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
755 else if (op == Mless_equal)
756 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
757 else if (op == Mgreater_equal)
758 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
762 /* Parse PLIST as an action list. PLIST should have this form:
763 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
764 Return 0 if successfully parsed, otherwise return -1. */
767 parse_action_list (MPlist *plist, MPlist *macros)
769 MPLIST_DO (plist, plist)
771 if (MPLIST_MTEXT_P (plist))
773 /* This is a short form of (insert MTEXT). */
774 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
775 MERROR (MERROR_IM, -1); */
777 else if (MPLIST_PLIST_P (plist)
778 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
779 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
783 /* This is a short form of (insert (GROUPS *)). */
784 MPLIST_DO (pl, MPLIST_PLIST (plist))
786 if (MPLIST_PLIST_P (pl))
790 MPLIST_DO (elt, MPLIST_PLIST (pl))
791 if (! MPLIST_MTEXT_P (elt)
792 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
793 MERROR (MERROR_IM, -1);
797 if (! MPLIST_MTEXT_P (pl)
798 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
799 MERROR (MERROR_IM, -1);
803 else if (MPLIST_INTEGER_P (plist))
805 int c = MPLIST_INTEGER (plist);
807 if (c < 0 || c > MCHAR_MAX)
808 MERROR (MERROR_IM, -1);
810 else if (MPLIST_PLIST_P (plist)
811 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
813 MPlist *pl = MPLIST_PLIST (plist);
814 MSymbol action_name = MPLIST_SYMBOL (pl);
816 pl = MPLIST_NEXT (pl);
818 if (action_name == Minsert)
820 if (MPLIST_MTEXT_P (pl))
822 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
823 MERROR (MERROR_IM, -1);
825 else if (MPLIST_PLIST_P (pl))
827 MPLIST_DO (pl, MPLIST_PLIST (pl))
829 if (MPLIST_PLIST_P (pl))
833 MPLIST_DO (elt, MPLIST_PLIST (pl))
834 if (! MPLIST_MTEXT_P (elt)
835 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
836 MERROR (MERROR_IM, -1);
840 if (! MPLIST_MTEXT_P (pl)
841 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
842 MERROR (MERROR_IM, -1);
846 else if (! MPLIST_SYMBOL_P (pl))
847 MERROR (MERROR_IM, -1);
849 else if (action_name == Mselect
850 || action_name == Mdelete
851 || action_name == Mmove)
853 if (parse_expression (pl) < 0)
856 else if (action_name == Mmark
857 || action_name == Mcall
858 || action_name == Mshift)
860 if (! MPLIST_SYMBOL_P (pl))
861 MERROR (MERROR_IM, -1);
863 else if (action_name == Mundo)
865 if (! MPLIST_TAIL_P (pl))
867 if (! MPLIST_SYMBOL_P (pl)
868 && ! MPLIST_INTEGER_P (pl))
869 MERROR (MERROR_IM, -1);
872 else if (action_name == Mpushback)
874 if (MPLIST_MTEXT_P (pl))
876 MText *mt = MPLIST_MTEXT (pl);
878 if (mtext_nchars (mt) != mtext_nbytes (mt))
879 MERROR (MERROR_IM, -1);
881 else if (MPLIST_PLIST_P (pl))
885 MPLIST_DO (p, MPLIST_PLIST (pl))
886 if (! MPLIST_SYMBOL_P (p))
887 MERROR (MERROR_IM, -1);
889 else if (! MPLIST_INTEGER_P (pl))
890 MERROR (MERROR_IM, -1);
892 else if (action_name == Mset || action_name == Madd
893 || action_name == Msub || action_name == Mmul
894 || action_name == Mdiv)
896 if (! MPLIST_SYMBOL_P (pl))
897 MERROR (MERROR_IM, -1);
898 if (parse_expression (MPLIST_NEXT (pl)) < 0)
901 else if (action_name == Mequal || action_name == Mless
902 || action_name == Mgreater || action_name == Mless_equal
903 || action_name == Mgreater_equal)
905 if (parse_expression (pl) < 0
906 || parse_expression (MPLIST_NEXT (pl)) < 0)
908 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
909 if (! MPLIST_PLIST_P (pl))
910 MERROR (MERROR_IM, -1);
911 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
912 MERROR (MERROR_IM, -1);
913 pl = MPLIST_NEXT (pl);
914 if (MPLIST_PLIST_P (pl)
915 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
916 MERROR (MERROR_IM, -1);
918 else if (action_name == Mshow || action_name == Mhide
919 || action_name == Mcommit || action_name == Munhandle
920 || action_name == Mpop)
922 else if (action_name == Mcond)
925 if (! MPLIST_PLIST_P (pl))
926 MERROR (MERROR_IM, -1);
928 else if (! macros || ! mplist_get (macros, action_name))
929 MERROR (MERROR_IM, -1);
931 else if (! MPLIST_SYMBOL_P (plist))
932 MERROR (MERROR_IM, -1);
939 resolve_command (MPlist *cmds, MSymbol command)
943 if (! cmds || ! (plist = mplist__assq (cmds, command)))
945 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
946 plist = MPLIST_NEXT (plist);
947 plist = MPLIST_NEXT (plist);
948 plist = MPLIST_NEXT (plist);
952 /* Load a translation into MAP from PLIST.
954 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
957 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
958 MPlist *branch_actions, MPlist *macros)
963 if (MPLIST_MTEXT_P (keylist))
965 MText *mt = MPLIST_MTEXT (keylist);
967 len = mtext_nchars (mt);
968 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
970 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
971 for (i = 0; i < len; i++)
972 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
978 if (MFAILP (MPLIST_PLIST_P (keylist)))
980 elt = MPLIST_PLIST (keylist);
981 len = MPLIST_LENGTH (elt);
982 if (MFAILP (len > 0))
984 keyseq = (MSymbol *) alloca (sizeof (int) * len);
985 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
987 if (MPLIST_INTEGER_P (elt))
989 int c = MPLIST_INTEGER (elt);
991 if (MFAILP (c >= 0 && c < 0x100))
993 keyseq[i] = one_char_symbol[c];
997 if (MFAILP (MPLIST_SYMBOL_P (elt)))
999 keyseq[i] = MPLIST_SYMBOL (elt);
1004 for (i = 0; i < len; i++)
1006 MIMMap *deeper = NULL;
1009 deeper = mplist_get (map->submaps, keyseq[i]);
1011 map->submaps = mplist ();
1014 /* Fixme: It is better to make all deeper maps at once. */
1015 MSTRUCT_CALLOC (deeper, MERROR_IM);
1016 mplist_put (map->submaps, keyseq[i], deeper);
1021 /* We reach a terminal map. */
1022 if (map->map_actions
1023 || map->branch_actions)
1024 /* This map is already defined. We avoid overriding it. */
1027 if (! MPLIST_TAIL_P (map_actions))
1029 if (parse_action_list (map_actions, macros) < 0)
1030 MERROR (MERROR_IM, -1);
1031 map->map_actions = map_actions;
1035 map->branch_actions = branch_actions;
1036 M17N_OBJECT_REF (branch_actions);
1042 /* Load a branch from PLIST into MAP. PLIST has this form:
1043 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1046 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1049 MPlist *branch_actions;
1051 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1053 map_name = MPLIST_SYMBOL (plist);
1054 plist = MPLIST_NEXT (plist);
1055 if (MPLIST_TAIL_P (plist))
1056 branch_actions = NULL;
1057 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1060 branch_actions = plist;
1061 if (map_name == Mnil)
1063 map->branch_actions = branch_actions;
1065 M17N_OBJECT_REF (branch_actions);
1067 else if (map_name == Mt)
1069 map->map_actions = branch_actions;
1071 M17N_OBJECT_REF (branch_actions);
1073 else if (im_info->maps
1074 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1076 MPLIST_DO (plist, plist)
1078 MPlist *keylist, *map_actions;
1080 if (! MPLIST_PLIST_P (plist))
1081 MERROR (MERROR_IM, -1);
1082 keylist = MPLIST_PLIST (plist);
1083 map_actions = MPLIST_NEXT (keylist);
1084 if (MPLIST_SYMBOL_P (keylist))
1086 MSymbol command = MPLIST_SYMBOL (keylist);
1089 if (MFAILP (command != Mat_reload))
1091 pl = resolve_command (im_info->configured_cmds, command);
1095 load_translation (map, pl, map_actions, branch_actions,
1099 load_translation (map, keylist, map_actions, branch_actions,
1107 /* Load a macro from PLIST into IM_INFO->macros.
1108 PLIST has this from:
1109 PLIST ::= ( MACRO-NAME ACTION * )
1110 IM_INFO->macros is a plist of macro names vs action list. */
1113 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1118 if (! MPLIST_SYMBOL_P (plist))
1119 MERROR (MERROR_IM, -1);
1120 name = MPLIST_SYMBOL (plist);
1121 plist = MPLIST_NEXT (plist);
1122 if (MPLIST_TAIL_P (plist)
1123 || parse_action_list (plist, im_info->macros) < 0)
1124 MERROR (MERROR_IM, -1);
1125 pl = mplist_get (im_info->macros, name);
1126 M17N_OBJECT_UNREF (pl);
1127 mplist_put (im_info->macros, name, plist);
1128 M17N_OBJECT_REF (plist);
1132 /* Load an external module from PLIST into IM_INFO->externals.
1133 PLIST has this form:
1134 PLIST ::= ( MODULE-NAME FUNCTION * )
1135 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1138 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1143 MIMExternalModule *external;
1147 if (MPLIST_MTEXT_P (plist))
1148 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1149 else if (MPLIST_SYMBOL_P (plist))
1150 module = MPLIST_SYMBOL (plist);
1151 module_file = alloca (strlen (MSYMBOL_NAME (module))
1152 + strlen (DLOPEN_SHLIB_EXT) + 1);
1153 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1155 handle = dlopen (module_file, RTLD_NOW);
1156 if (MFAILP (handle))
1158 fprintf (stderr, "%s\n", dlerror ());
1161 func_list = mplist ();
1162 MPLIST_DO (plist, MPLIST_NEXT (plist))
1164 if (! MPLIST_SYMBOL_P (plist))
1165 MERROR_GOTO (MERROR_IM, err_label);
1166 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1169 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1172 MSTRUCT_MALLOC (external, MERROR_IM);
1173 external->handle = handle;
1174 external->func_list = func_list;
1175 mplist_add (im_info->externals, module, external);
1180 M17N_OBJECT_UNREF (func_list);
1185 free_map (MIMMap *map, int top)
1190 M17N_OBJECT_UNREF (map->map_actions);
1193 MPLIST_DO (plist, map->submaps)
1194 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1195 M17N_OBJECT_UNREF (map->submaps);
1197 M17N_OBJECT_UNREF (map->branch_actions);
1202 free_state (void *object)
1204 MIMState *state = object;
1206 M17N_OBJECT_UNREF (state->title);
1208 free_map (state->map, 1);
1212 /** Load a state from PLIST into a newly allocated state object.
1213 PLIST has this form:
1214 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1215 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1216 Return the state object. */
1219 load_state (MInputMethodInfo *im_info, MPlist *plist)
1223 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1225 M17N_OBJECT (state, free_state, MERROR_IM);
1226 state->name = MPLIST_SYMBOL (plist);
1227 plist = MPLIST_NEXT (plist);
1228 if (MPLIST_MTEXT_P (plist))
1230 state->title = MPLIST_MTEXT (plist);
1231 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1232 Mlanguage, im_info->language);
1233 M17N_OBJECT_REF (state->title);
1234 plist = MPLIST_NEXT (plist);
1236 MSTRUCT_CALLOC (state->map, MERROR_IM);
1237 MPLIST_DO (plist, plist)
1239 if (MFAILP (MPLIST_PLIST_P (plist)))
1241 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1246 /* Return a newly created IM_INFO for an input method specified by
1247 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1249 static MInputMethodInfo *
1250 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1253 MInputMethodInfo *im_info;
1256 if (name == Mnil && extra == Mnil)
1257 language = Mt, extra = Mglobal;
1258 MSTRUCT_CALLOC (im_info, MERROR_IM);
1260 im_info->language = language;
1261 im_info->name = name;
1262 im_info->extra = extra;
1265 mplist_add (plist, Mplist, elt);
1266 M17N_OBJECT_UNREF (elt);
1267 elt = mplist_add (elt, Msymbol, language);
1268 elt = mplist_add (elt, Msymbol, name);
1269 elt = mplist_add (elt, Msymbol, extra);
1270 mplist_add (elt, Mt, im_info);
1276 fini_im_info (MInputMethodInfo *im_info)
1280 M17N_OBJECT_UNREF (im_info->cmds);
1281 M17N_OBJECT_UNREF (im_info->configured_cmds);
1282 M17N_OBJECT_UNREF (im_info->bc_cmds);
1283 M17N_OBJECT_UNREF (im_info->vars);
1284 M17N_OBJECT_UNREF (im_info->configured_vars);
1285 M17N_OBJECT_UNREF (im_info->bc_vars);
1286 M17N_OBJECT_UNREF (im_info->description);
1287 M17N_OBJECT_UNREF (im_info->title);
1288 if (im_info->states)
1290 MPLIST_DO (plist, im_info->states)
1292 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1294 M17N_OBJECT_UNREF (state);
1296 M17N_OBJECT_UNREF (im_info->states);
1299 if (im_info->macros)
1301 MPLIST_DO (plist, im_info->macros)
1302 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1303 M17N_OBJECT_UNREF (im_info->macros);
1306 if (im_info->externals)
1308 MPLIST_DO (plist, im_info->externals)
1310 MIMExternalModule *external = MPLIST_VAL (plist);
1312 dlclose (external->handle);
1313 M17N_OBJECT_UNREF (external->func_list);
1315 MPLIST_KEY (plist) = Mt;
1317 M17N_OBJECT_UNREF (im_info->externals);
1321 MPLIST_DO (plist, im_info->maps)
1323 MPlist *p = MPLIST_PLIST (plist);
1325 M17N_OBJECT_UNREF (p);
1327 M17N_OBJECT_UNREF (im_info->maps);
1334 free_im_info (MInputMethodInfo *im_info)
1336 fini_im_info (im_info);
1341 free_im_list (MPlist *plist)
1345 MPLIST_DO (pl, plist)
1347 MInputMethodInfo *im_info;
1349 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1350 im_info = MPLIST_VAL (elt);
1351 free_im_info (im_info);
1353 M17N_OBJECT_UNREF (plist);
1356 static MInputMethodInfo *
1357 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1359 if (name == Mnil && extra == Mnil)
1360 language = Mt, extra = Mglobal;
1361 while ((plist = mplist__assq (plist, language)))
1363 MPlist *elt = MPLIST_PLIST (plist);
1365 plist = MPLIST_NEXT (plist);
1366 elt = MPLIST_NEXT (elt);
1367 if (MPLIST_SYMBOL (elt) != name)
1369 elt = MPLIST_NEXT (elt);
1370 if (MPLIST_SYMBOL (elt) != extra)
1372 elt = MPLIST_NEXT (elt);
1373 return MPLIST_VAL (elt);
1378 static void load_im_info (MPlist *, MInputMethodInfo *);
1380 #define get_custom_info(im_info) \
1382 ? lookup_im_info (im_custom_list, (im_info)->language, \
1383 (im_info)->name, (im_info)->extra) \
1386 #define get_config_info(im_info) \
1388 ? lookup_im_info (im_config_list, (im_info)->language, \
1389 (im_info)->name, (im_info)->extra) \
1393 update_custom_info (void)
1399 if (mdatabase__check (im_custom_mdb) > 0)
1404 MDatabaseInfo *custom_dir_info;
1405 char custom_path[PATH_MAX + 1];
1407 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1408 if (! custom_dir_info->filename
1409 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1411 strcpy (custom_path, custom_dir_info->filename);
1412 strcat (custom_path, CUSTOM_FILE);
1413 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1419 free_im_list (im_custom_list);
1420 im_custom_list = NULL;
1422 plist = mdatabase_load (im_custom_mdb);
1425 im_custom_list = mplist ();
1427 MPLIST_DO (pl, plist)
1429 MSymbol language, name, extra;
1430 MInputMethodInfo *im_info;
1431 MPlist *im_data, *p;
1433 if (! MPLIST_PLIST_P (pl))
1435 p = MPLIST_PLIST (pl);
1436 im_data = MPLIST_NEXT (p);
1437 if (! MPLIST_PLIST_P (p))
1439 p = MPLIST_PLIST (p);
1440 if (! MPLIST_SYMBOL_P (p)
1441 || MPLIST_SYMBOL (p) != Minput_method)
1443 p = MPLIST_NEXT (p);
1444 if (! MPLIST_SYMBOL_P (p))
1446 language = MPLIST_SYMBOL (p);
1447 p = MPLIST_NEXT (p);
1448 if (! MPLIST_SYMBOL_P (p))
1450 name = MPLIST_SYMBOL (p);
1451 p = MPLIST_NEXT (p);
1452 if (MPLIST_TAIL_P (p))
1454 else if (MPLIST_SYMBOL_P (p))
1455 extra = MPLIST_SYMBOL (p);
1456 if (language == Mnil || (name == Mnil && extra == Mnil))
1458 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1459 load_im_info (im_data, im_info);
1461 M17N_OBJECT_UNREF (plist);
1466 update_global_info (void)
1472 int ret = mdatabase__check (global_info->mdb);
1476 fini_im_info (global_info);
1480 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1482 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1484 if (! global_info->mdb
1485 || ! (plist = mdatabase_load (global_info->mdb)))
1488 load_im_info (plist, global_info);
1489 M17N_OBJECT_UNREF (plist);
1494 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1495 and EXTRA. KEY, if not Mnil, tells which kind of information about
1496 the input method is necessary, and the returned IM_INFO may contain
1497 only that information. */
1499 static MInputMethodInfo *
1500 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1503 MInputMethodInfo *im_info;
1506 if (name == Mnil && extra == Mnil)
1507 language = Mt, extra = Mglobal;
1508 im_info = lookup_im_info (im_info_list, language, name, extra);
1511 if (key == Mnil ? im_info->states != NULL
1512 : key == Mcommand ? im_info->cmds != NULL
1513 : key == Mvariable ? im_info->vars != NULL
1514 : key == Mtitle ? im_info->title != NULL
1515 : key == Mdescription ? im_info->description != NULL
1517 /* IM_INFO already contains required information. */
1519 /* We have not yet loaded required information. */
1523 mdb = mdatabase_find (Minput_method, language, name, extra);
1526 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1531 plist = mdatabase_load (im_info->mdb);
1535 mplist_push (load_im_info_keys, key, Mt);
1536 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1537 mplist_pop (load_im_info_keys);
1541 MERROR (MERROR_IM, im_info);
1542 update_global_info ();
1543 load_im_info (plist, im_info);
1544 M17N_OBJECT_UNREF (plist);
1547 if (! im_info->cmds)
1548 im_info->cmds = mplist ();
1549 if (! im_info->vars)
1550 im_info->vars = mplist ();
1552 if (! im_info->title
1553 && (key == Mnil || key == Mtitle))
1554 im_info->title = (name == Mnil ? mtext ()
1555 : mtext_from_data (MSYMBOL_NAME (name),
1556 MSYMBOL_NAMELEN (name),
1557 MTEXT_FORMAT_US_ASCII));
1561 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1562 If updated, but got unloadable, return -1. Otherwise, update
1563 contents of IM_INFO from the new database, and return 1. */
1566 reload_im_info (MInputMethodInfo *im_info)
1571 update_custom_info ();
1572 update_global_info ();
1573 check = mdatabase__check (im_info->mdb);
1576 plist = mdatabase_load (im_info->mdb);
1579 fini_im_info (im_info);
1580 load_im_info (plist, im_info);
1581 M17N_OBJECT_UNREF (plist);
1582 if (! im_info->cmds)
1583 im_info->cmds = mplist ();
1584 if (! im_info->vars)
1585 im_info->vars = mplist ();
1586 if (! im_info->title)
1588 MSymbol name = im_info->name;
1590 im_info->title = (name == Mnil ? mtext ()
1591 : mtext_from_data (MSYMBOL_NAME (name),
1592 MSYMBOL_NAMELEN (name),
1593 MTEXT_FORMAT_US_ASCII));
1598 static MInputMethodInfo *
1599 get_im_info_by_tags (MPlist *plist)
1604 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1605 i++, plist = MPLIST_NEXT (plist))
1606 tag[i] = MPLIST_SYMBOL (plist);
1611 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1616 check_description (MPlist *plist)
1620 if (MPLIST_MTEXT_P (plist))
1622 if (MPLIST_PLIST_P (plist))
1624 MPlist *pl = MPLIST_PLIST (plist);
1626 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1628 pl =MPLIST_NEXT (pl);
1629 if (MFAILP (MPLIST_MTEXT_P (pl)))
1631 mt = MPLIST_MTEXT (pl);
1632 M17N_OBJECT_REF (mt);
1635 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1637 if (translated == (char *) MTEXT_DATA (mt))
1638 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1639 if (translated != (char *) MTEXT_DATA (mt))
1641 M17N_OBJECT_UNREF (mt);
1642 mt = mtext__from_data (translated, strlen (translated),
1643 MTEXT_FORMAT_UTF_8, 0);
1647 mplist_set (plist, Mtext, mt);
1648 M17N_OBJECT_UNREF (mt);
1651 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1657 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1661 check_command_keyseq (MPlist *keyseq)
1663 if (MPLIST_PLIST_P (keyseq))
1665 MPlist *p = MPLIST_PLIST (keyseq);
1668 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1672 if (MPLIST_MTEXT_P (keyseq))
1674 MText *mt = MPLIST_MTEXT (keyseq);
1677 for (i = 0; i < mtext_nchars (mt); i++)
1678 if (mtext_ref_char (mt, i) >= 256)
1685 /* Load command defitions from PLIST into IM_INFO->cmds.
1687 PLIST is well-formed and has this form;
1688 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1689 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1690 M-text or a plist of symbols.
1692 The returned list has the same form, but for each element...
1694 (1) If DESCRIPTION and the rest are omitted, the element is not
1695 stored in the returned list.
1697 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1698 description in global_info->cmds (if any). */
1701 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1705 im_info->cmds = tail = mplist ();
1707 MPLIST_DO (plist, MPLIST_NEXT (plist))
1709 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1712 if (MFAILP (MPLIST_PLIST_P (plist)))
1714 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1715 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1717 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1718 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1720 if (MFAILP (im_info != global_info))
1721 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1725 if (! check_description (p))
1726 mplist_set (p, Msymbol, Mnil);
1727 p = MPLIST_NEXT (p);
1728 while (! MPLIST_TAIL_P (p))
1730 if (MFAILP (check_command_keyseq (p)))
1731 mplist__pop_unref (p);
1733 p = MPLIST_NEXT (p);
1736 tail = mplist_add (tail, Mplist, pl);
1741 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1742 MPlist *config_cmds)
1744 MPlist *global = NULL, *custom = NULL, *config = NULL;
1747 MPlist *description, *keyseq;
1749 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1750 global = MPLIST_NEXT (MPLIST_PLIST (global));
1752 name = MPLIST_SYMBOL (plist);
1753 plist = MPLIST_NEXT (plist);
1754 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1756 description = plist;
1757 plist = MPLIST_NEXT (plist);
1761 description = global;
1762 if (! MPLIST_TAIL_P (plist))
1763 plist = MPLIST_NEXT (plist);
1765 if (MPLIST_TAIL_P (plist) && global)
1767 keyseq = MPLIST_NEXT (global);
1768 status = Minherited;
1776 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1778 status = Mconfigured;
1779 config = MPLIST_NEXT (MPLIST_PLIST (config));
1780 if (! MPLIST_TAIL_P (config))
1783 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1785 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1786 if (! MPLIST_TAIL_P (custom))
1788 status = Mcustomized;
1794 mplist_add (plist, Msymbol, name);
1796 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1798 mplist_add (plist, Msymbol, Mnil);
1799 mplist_add (plist, Msymbol, status);
1800 mplist__conc (plist, keyseq);
1805 config_all_commands (MInputMethodInfo *im_info)
1807 MPlist *global_cmds, *custom_cmds, *config_cmds;
1808 MInputMethodInfo *temp;
1809 MPlist *tail, *plist;
1811 M17N_OBJECT_UNREF (im_info->configured_cmds);
1813 if (MPLIST_TAIL_P (im_info->cmds)
1817 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1818 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1819 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1821 im_info->configured_cmds = tail = mplist ();
1822 MPLIST_DO (plist, im_info->cmds)
1824 MPlist *pl = config_command (MPLIST_PLIST (plist),
1825 global_cmds, custom_cmds, config_cmds);
1828 tail = mplist_add (tail, Mplist, pl);
1829 M17N_OBJECT_UNREF (pl);
1834 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1835 valid, return 0 if not. */
1838 check_variable_value (MPlist *val, MPlist *global)
1840 MSymbol type = MPLIST_KEY (val);
1841 MPlist *valids = MPLIST_NEXT (val);
1843 if (type != Minteger && type != Mtext && type != Msymbol)
1847 if (MPLIST_KEY (global) != Mt
1848 && MPLIST_KEY (global) != MPLIST_KEY (val))
1850 if (MPLIST_TAIL_P (valids))
1851 valids = MPLIST_NEXT (global);
1853 if (MPLIST_TAIL_P (valids))
1856 if (type == Minteger)
1858 int n = MPLIST_INTEGER (val);
1860 MPLIST_DO (valids, valids)
1862 if (MPLIST_INTEGER_P (valids))
1864 if (n == MPLIST_INTEGER (valids))
1867 else if (MPLIST_PLIST_P (valids))
1869 MPlist *p = MPLIST_PLIST (valids);
1870 int min_bound, max_bound;
1872 if (! MPLIST_INTEGER_P (p))
1873 MERROR (MERROR_IM, 0);
1874 min_bound = MPLIST_INTEGER (p);
1875 p = MPLIST_NEXT (p);
1876 if (! MPLIST_INTEGER_P (p))
1877 MERROR (MERROR_IM, 0);
1878 max_bound = MPLIST_INTEGER (p);
1879 if (n >= min_bound && n <= max_bound)
1884 else if (type == Msymbol)
1886 MSymbol sym = MPLIST_SYMBOL (val);
1888 MPLIST_DO (valids, valids)
1890 if (! MPLIST_SYMBOL_P (valids))
1891 MERROR (MERROR_IM, 0);
1892 if (sym == MPLIST_SYMBOL (valids))
1898 MText *mt = MPLIST_MTEXT (val);
1900 MPLIST_DO (valids, valids)
1902 if (! MPLIST_MTEXT_P (valids))
1903 MERROR (MERROR_IM, 0);
1904 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1909 return (! MPLIST_TAIL_P (valids));
1912 /* Load variable defitions from PLIST into IM_INFO->vars.
1914 PLIST is well-formed and has this form;
1915 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1917 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1919 The returned list has the same form, but for each element...
1921 (1) If DESCRIPTION and the rest are omitted, the element is not
1922 stored in the returned list.
1924 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1925 description in global_info->vars (if any). */
1928 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1930 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1931 ? global_info->vars : NULL);
1934 im_info->vars = tail = mplist ();
1935 MPLIST_DO (plist, MPLIST_NEXT (plist))
1939 if (MFAILP (MPLIST_PLIST_P (plist)))
1941 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1942 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1944 if (im_info == global_info)
1946 /* Loading a global variable. */
1947 p = MPLIST_NEXT (pl);
1948 if (MPLIST_TAIL_P (p))
1949 mplist_add (p, Msymbol, Mnil);
1952 if (! check_description (p))
1953 mplist_set (p, Msymbol, Mnil);
1954 p = MPLIST_NEXT (p);
1955 if (MFAILP (! MPLIST_TAIL_P (p)
1956 && check_variable_value (p, NULL)))
1957 mplist_set (p, Mt, NULL);
1960 else if (im_info->mdb)
1962 /* Loading a local variable. */
1963 MSymbol name = MPLIST_SYMBOL (pl);
1964 MPlist *global = NULL;
1967 && (p = mplist__assq (global_vars, name)))
1969 /* P ::= ((NAME DESC ...) ...) */
1970 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1971 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1972 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1975 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1976 if (! MPLIST_TAIL_P (p))
1978 if (! check_description (p))
1979 mplist_set (p, Msymbol, Mnil);
1980 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1981 if (MFAILP (! MPLIST_TAIL_P (p)))
1982 mplist_set (p, Mt, NULL);
1985 MPlist *valid_values = MPLIST_NEXT (p);
1987 if (! MPLIST_TAIL_P (valid_values)
1988 ? MFAILP (check_variable_value (p, NULL))
1989 : global && MFAILP (check_variable_value (p, global)))
1990 mplist_set (p, Mt, NULL);
1996 /* Loading a variable customization. */
1997 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1998 if (MFAILP (! MPLIST_TAIL_P (p)))
2000 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2001 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2002 || MPLIST_MTEXT_P (p)))
2005 tail = mplist_add (tail, Mplist, pl);
2010 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2011 MPlist *config_vars)
2013 MPlist *global = NULL, *custom = NULL, *config = NULL;
2014 MSymbol name = MPLIST_SYMBOL (plist);
2016 MPlist *description = NULL, *value, *valids;
2020 global = mplist__assq (global_vars, name);
2022 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2025 plist = MPLIST_NEXT (plist);
2026 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2027 description = plist;
2029 description = global;
2031 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2033 if (MPLIST_TAIL_P (plist))
2035 /* Inherit from global (if any). */
2039 if (MPLIST_KEY (value) == Mt)
2041 valids = MPLIST_NEXT (global);
2042 status = Minherited;
2054 value = plist = MPLIST_NEXT (plist);
2055 valids = MPLIST_NEXT (value);
2056 if (MPLIST_KEY (value) == Mt)
2058 if (! MPLIST_TAIL_P (valids))
2061 valids = MPLIST_NEXT (global);
2065 if (config_vars && (config = mplist__assq (config_vars, name)))
2067 status = Mconfigured;
2068 config = MPLIST_NEXT (MPLIST_PLIST (config));
2069 if (! MPLIST_TAIL_P (config))
2072 if (MFAILP (check_variable_value (value, global ? global : plist)))
2076 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2078 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2079 if (! MPLIST_TAIL_P (custom))
2082 if (MFAILP (check_variable_value (value, global ? global : plist)))
2084 status = Mcustomized;
2089 mplist_add (plist, Msymbol, name);
2091 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2093 mplist_add (plist, Msymbol, Mnil);
2094 mplist_add (plist, Msymbol, status);
2096 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2098 mplist_add (plist, Mt, NULL);
2099 if (valids && ! MPLIST_TAIL_P (valids))
2100 mplist__conc (plist, valids);
2104 /* Return a configured variable definition list based on
2105 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2106 get it from global_info->vars. */
2109 config_all_variables (MInputMethodInfo *im_info)
2111 MPlist *global_vars, *custom_vars, *config_vars;
2112 MInputMethodInfo *temp;
2113 MPlist *tail, *plist;
2115 M17N_OBJECT_UNREF (im_info->configured_vars);
2117 if (MPLIST_TAIL_P (im_info->vars)
2121 global_vars = im_info != global_info ? global_info->vars : NULL;
2122 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2123 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2125 im_info->configured_vars = tail = mplist ();
2126 MPLIST_DO (plist, im_info->vars)
2128 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2129 global_vars, custom_vars, config_vars);
2132 tail = mplist_add (tail, Mplist, pl);
2133 M17N_OBJECT_UNREF (pl);
2138 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2139 CONFIG contains configuration information of the input method. */
2142 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2146 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2148 load_commands (im_info, MPLIST_PLIST (pl));
2149 config_all_commands (im_info);
2150 pl = mplist_pop (pl);
2151 M17N_OBJECT_UNREF (pl);
2154 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2156 load_variables (im_info, MPLIST_PLIST (pl));
2157 config_all_variables (im_info);
2158 pl = mplist_pop (pl);
2159 M17N_OBJECT_UNREF (pl);
2162 MPLIST_DO (plist, plist)
2163 if (MPLIST_PLIST_P (plist))
2165 MPlist *elt = MPLIST_PLIST (plist);
2168 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2170 key = MPLIST_SYMBOL (elt);
2175 elt = MPLIST_NEXT (elt);
2176 if (MFAILP (MPLIST_MTEXT_P (elt)))
2178 im_info->title = MPLIST_MTEXT (elt);
2179 M17N_OBJECT_REF (im_info->title);
2181 else if (key == Mmap)
2183 pl = mplist__from_alist (MPLIST_NEXT (elt));
2186 if (! im_info->maps)
2190 mplist__conc (im_info->maps, pl);
2191 M17N_OBJECT_UNREF (pl);
2194 else if (key == Mmacro)
2196 if (! im_info->macros)
2197 im_info->macros = mplist ();
2198 MPLIST_DO (elt, MPLIST_NEXT (elt))
2200 if (MFAILP (MPLIST_PLIST_P (elt)))
2202 load_macros (im_info, MPLIST_PLIST (elt));
2205 else if (key == Mmodule)
2207 if (! im_info->externals)
2208 im_info->externals = mplist ();
2209 MPLIST_DO (elt, MPLIST_NEXT (elt))
2211 if (MFAILP (MPLIST_PLIST_P (elt)))
2213 load_external_module (im_info, MPLIST_PLIST (elt));
2216 else if (key == Mstate)
2218 MPLIST_DO (elt, MPLIST_NEXT (elt))
2222 if (MFAILP (MPLIST_PLIST_P (elt)))
2224 pl = MPLIST_PLIST (elt);
2225 if (! im_info->states)
2226 im_info->states = mplist ();
2227 state = load_state (im_info, MPLIST_PLIST (elt));
2230 mplist_put (im_info->states, state->name, state);
2233 else if (key == Minclude)
2235 /* elt ::= include (tag1 tag2 ...) key item ... */
2237 MInputMethodInfo *temp;
2239 elt = MPLIST_NEXT (elt);
2240 if (MFAILP (MPLIST_PLIST_P (elt)))
2242 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2245 elt = MPLIST_NEXT (elt);
2246 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2248 key = MPLIST_SYMBOL (elt);
2249 elt = MPLIST_NEXT (elt);
2252 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2254 if (! im_info->maps)
2255 im_info->maps = mplist ();
2256 MPLIST_DO (pl, temp->maps)
2258 p = MPLIST_VAL (pl);
2259 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2260 M17N_OBJECT_REF (p);
2263 else if (key == Mmacro)
2265 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2267 if (! im_info->macros)
2268 im_info->macros = mplist ();
2269 MPLIST_DO (pl, temp->macros)
2271 p = MPLIST_VAL (pl);
2272 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2273 M17N_OBJECT_REF (p);
2276 else if (key == Mstate)
2278 if (! temp->states || MPLIST_TAIL_P (temp->states))
2280 if (! im_info->states)
2281 im_info->states = mplist ();
2282 MPLIST_DO (pl, temp->states)
2284 MIMState *state = MPLIST_VAL (pl);
2286 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2287 M17N_OBJECT_REF (state);
2291 else if (key == Mdescription)
2293 if (im_info->description)
2295 elt = MPLIST_NEXT (elt);
2296 if (! check_description (elt))
2298 im_info->description = MPLIST_MTEXT (elt);
2299 M17N_OBJECT_REF (im_info->description);
2302 im_info->tick = time (NULL);
2307 static int take_action_list (MInputContext *ic, MPlist *action_list);
2308 static void preedit_commit (MInputContext *ic);
2311 shift_state (MInputContext *ic, MSymbol state_name)
2313 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2314 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2315 MIMState *orig_state = ic_info->state, *state;
2317 /* Find a state to shift to. If not found, shift to the initial
2319 if (state_name == Mt)
2321 if (! ic_info->prev_state)
2323 state = ic_info->prev_state;
2325 else if (state_name == Mnil)
2327 state = (MIMState *) MPLIST_VAL (im_info->states);
2331 state = (MIMState *) mplist_get (im_info->states, state_name);
2333 state = (MIMState *) MPLIST_VAL (im_info->states);
2336 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2338 /* Enter the new state. */
2339 ic_info->state = state;
2340 ic_info->map = state->map;
2341 ic_info->state_key_head = ic_info->key_head;
2342 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2344 /* We have shifted to the initial state. */
2345 preedit_commit (ic);
2346 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2347 ic_info->state_pos = ic->cursor_pos;
2348 if (state != orig_state)
2350 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2352 /* Shifted to the initial state. */
2353 ic_info->prev_state = NULL;
2354 M17N_OBJECT_UNREF (ic_info->vars_saved);
2355 ic_info->vars_saved = mplist_copy (ic_info->vars);
2358 ic_info->prev_state = orig_state;
2361 ic->status = state->title;
2363 ic->status = im_info->title;
2364 ic->status_changed = 1;
2365 if (ic_info->map == ic_info->state->map
2366 && ic_info->map->map_actions)
2368 MDEBUG_PRINT (" init-actions:");
2369 take_action_list (ic, ic_info->map->map_actions);
2374 /* Find a candidate group that contains a candidate number INDEX from
2375 PLIST. Set START_INDEX to the first candidate number of the group,
2376 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2377 candidate group number if they are non-NULL. If INDEX is -1, find
2378 the last candidate group. */
2381 find_candidates_group (MPlist *plist, int index,
2382 int *start_index, int *end_index, int *group_index)
2384 int i = 0, gidx = 0, len;
2386 MPLIST_DO (plist, plist)
2388 if (MPLIST_MTEXT_P (plist))
2389 len = mtext_nchars (MPLIST_MTEXT (plist));
2391 len = mplist_length (MPLIST_PLIST (plist));
2392 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2398 *end_index = i + len;
2400 *group_index = gidx;
2409 /* Adjust markers for the change of preedit text.
2410 If FROM == TO, the change is insertion of INS chars.
2411 If FROM < TO and INS == 0, the change is deletion of the range.
2412 If FROM < TO and INS > 0, the change is replacement. */
2415 adjust_markers (MInputContext *ic, int from, int to, int ins)
2417 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2422 MPLIST_DO (markers, ic_info->markers)
2423 if (MPLIST_INTEGER (markers) > from)
2424 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2425 if (ic->cursor_pos >= from)
2426 ic->cursor_pos += ins;
2430 MPLIST_DO (markers, ic_info->markers)
2432 if (MPLIST_INTEGER (markers) >= to)
2433 MPLIST_VAL (markers)
2434 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2435 else if (MPLIST_INTEGER (markers) > from)
2436 MPLIST_VAL (markers) = (void *) from;
2438 if (ic->cursor_pos >= to)
2439 ic->cursor_pos += ins - (to - from);
2440 else if (ic->cursor_pos > from)
2441 ic->cursor_pos = from;
2447 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2449 int nchars = mt ? mtext_nchars (mt) : 1;
2452 mtext_ins (ic->preedit, pos, mt);
2454 mtext_ins_char (ic->preedit, pos, c, 1);
2455 adjust_markers (ic, pos, pos, nchars);
2456 ic->preedit_changed = 1;
2461 preedit_delete (MInputContext *ic, int from, int to)
2463 mtext_del (ic->preedit, from, to);
2464 adjust_markers (ic, from, to, 0);
2465 ic->preedit_changed = 1;
2469 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2473 mtext_del (ic->preedit, from, to);
2476 mtext_ins (ic->preedit, from, mt);
2477 ins = mtext_nchars (mt);
2481 mtext_ins_char (ic->preedit, from, c, 1);
2484 adjust_markers (ic, from, to, ins);
2485 ic->preedit_changed = 1;
2490 preedit_commit (MInputContext *ic)
2492 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2493 int preedit_len = mtext_nchars (ic->preedit);
2495 if (preedit_len > 0)
2499 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2500 Mcandidate_list, NULL, 0);
2501 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2502 Mcandidate_index, NULL, 0);
2503 mtext_cat (ic->produced, ic->preedit);
2504 if (mdebug__flag & mdebug_mask)
2508 MDEBUG_PRINT (" (commit");
2509 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2510 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2514 mtext_reset (ic->preedit);
2515 mtext_reset (ic_info->preedit_saved);
2516 MPLIST_DO (p, ic_info->markers)
2518 ic->cursor_pos = ic_info->state_pos = 0;
2519 ic->preedit_changed = 1;
2520 ic_info->commit_key_head = ic_info->key_head;
2522 if (ic->candidate_list)
2524 M17N_OBJECT_UNREF (ic->candidate_list);
2525 ic->candidate_list = NULL;
2526 ic->candidate_index = 0;
2527 ic->candidate_from = ic->candidate_to = 0;
2528 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2529 if (ic->candidate_show)
2531 ic->candidate_show = 0;
2532 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2538 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2540 int code = marker_code (sym, 0);
2542 if (mt && (code == '[' || code == ']'))
2546 if (code == '[' && current > 0)
2548 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2552 else if (code == ']' && current < mtext_nchars (mt))
2554 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2560 return (code == '<' ? 0
2561 : code == '>' ? limit
2562 : code == '-' ? current - 1
2563 : code == '+' ? current + 1
2564 : code == '=' ? current
2565 : code - '0' > limit ? limit
2569 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2573 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2575 int from = mtext_property_start (prop);
2576 int to = mtext_property_end (prop);
2578 MPlist *candidate_list = mtext_property_value (prop);
2579 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2581 int ingroup_index = idx - start;
2584 if (MPLIST_MTEXT_P (group))
2586 mt = MPLIST_MTEXT (group);
2587 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2595 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2596 i++, plist = MPLIST_NEXT (plist));
2597 mt = MPLIST_MTEXT (plist);
2598 preedit_replace (ic, from, to, mt, 0);
2599 to = from + mtext_nchars (mt);
2601 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2602 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2603 ic->cursor_pos = to;
2607 get_select_charset (MInputContextInfo * ic_info)
2609 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2612 if (! MPLIST_VAL (plist))
2614 sym = MPLIST_SYMBOL (plist);
2617 return MCHARSET (sym);
2621 adjust_candidates (MPlist *plist, MCharset *charset)
2625 /* plist ::= MTEXT ... | PLIST ... */
2626 plist = mplist_copy (plist);
2627 if (MPLIST_MTEXT_P (plist))
2630 while (! MPLIST_TAIL_P (pl))
2632 /* pl ::= MTEXT ... */
2633 MText *mt = MPLIST_MTEXT (pl);
2637 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2639 c = mtext_ref_char (mt, i);
2640 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2644 mt = mtext_dup (mt);
2645 mplist_set (pl, Mtext, mt);
2646 M17N_OBJECT_UNREF (mt);
2649 mtext_del (mt, i, i + 1);
2652 if (mtext_len (mt) > 0)
2653 pl = MPLIST_NEXT (pl);
2657 M17N_OBJECT_UNREF (mt);
2661 else /* MPLIST_PLIST_P (plist) */
2664 while (! MPLIST_TAIL_P (pl))
2666 /* pl ::= (MTEXT ...) ... */
2667 MPlist *p = MPLIST_PLIST (pl);
2669 /* p ::= MTEXT ... */
2673 while (! MPLIST_TAIL_P (p0))
2675 MText *mt = MPLIST_MTEXT (p0);
2678 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2680 c = mtext_ref_char (mt, i);
2681 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2686 p0 = MPLIST_NEXT (p0);
2693 p = mplist_copy (p);
2694 mplist_set (pl, Mplist, p);
2695 M17N_OBJECT_UNREF (p);
2699 p0 = MPLIST_NEXT (p0);
2702 M17N_OBJECT_UNREF (mt);
2705 if (! MPLIST_TAIL_P (p))
2706 pl = MPLIST_NEXT (pl);
2710 M17N_OBJECT_UNREF (p);
2714 if (MPLIST_TAIL_P (plist))
2716 M17N_OBJECT_UNREF (plist);
2723 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2725 MCharset *charset = get_select_charset (ic_info);
2730 plist = resolve_variable (ic_info, Mcandidates_group_size);
2731 column = MPLIST_INTEGER (plist);
2733 plist = MPLIST_PLIST (args);
2735 plist = adjust_candidates (plist, charset);
2737 if (plist && column > 0)
2739 if (MPLIST_MTEXT_P (plist))
2741 MText *mt = MPLIST_MTEXT (plist);
2742 MPlist *next = MPLIST_NEXT (plist);
2744 if (MPLIST_TAIL_P (next))
2745 M17N_OBJECT_REF (mt);
2748 mt = mtext_dup (mt);
2749 while (! MPLIST_TAIL_P (next))
2751 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2752 next = MPLIST_NEXT (next);
2756 M17N_OBJECT_UNREF (plist);
2758 len = mtext_nchars (mt);
2760 mplist_add (plist, Mtext, mt);
2763 for (i = 0; i < len; i += column)
2765 int to = (i + column < len ? i + column : len);
2766 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2768 mplist_add (plist, Mtext, sub);
2769 M17N_OBJECT_UNREF (sub);
2772 M17N_OBJECT_UNREF (mt);
2774 else if (! MPLIST_TAIL_P (plist))
2776 MPlist *tail = plist;
2777 MPlist *new = mplist ();
2778 MPlist *this = mplist ();
2781 MPLIST_DO (tail, tail)
2783 MPlist *p = MPLIST_PLIST (tail);
2787 MText *mt = MPLIST_MTEXT (p);
2789 if (count == column)
2791 mplist_add (new, Mplist, this);
2792 M17N_OBJECT_UNREF (this);
2796 mplist_add (this, Mtext, mt);
2800 mplist_add (new, Mplist, this);
2801 M17N_OBJECT_UNREF (this);
2802 mplist_set (plist, Mnil, NULL);
2803 MPLIST_DO (tail, new)
2805 MPlist *elt = MPLIST_PLIST (tail);
2807 mplist_add (plist, Mplist, elt);
2809 M17N_OBJECT_UNREF (new);
2818 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2820 MPlist *action = NULL;
2824 if (MPLIST_SYMBOL_P (action_list))
2826 MSymbol var = MPLIST_SYMBOL (action_list);
2829 MPLIST_DO (p, ic_info->vars)
2830 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2832 if (MPLIST_TAIL_P (p))
2834 action = MPLIST_NEXT (MPLIST_PLIST (p));
2835 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2838 if (MPLIST_PLIST_P (action_list))
2840 action = MPLIST_PLIST (action_list);
2841 if (MPLIST_SYMBOL_P (action))
2843 name = MPLIST_SYMBOL (action);
2844 args = MPLIST_NEXT (action);
2846 && MPLIST_PLIST_P (args))
2847 mplist_set (action, Msymbol, M_candidates);
2849 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2852 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2853 mplist_push (action, Msymbol, M_candidates);
2854 mplist_set (action_list, Mplist, action);
2855 M17N_OBJECT_UNREF (action);
2858 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2861 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2862 mplist_push (action, Msymbol, Minsert);
2863 mplist_set (action_list, Mplist, action);
2864 M17N_OBJECT_UNREF (action);
2869 /* Perform list of actions in ACTION_LIST for the current input
2870 context IC. If unhandle action was not performed, return 0.
2871 Otherwise, return -1. */
2874 take_action_list (MInputContext *ic, MPlist *action_list)
2876 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2877 MPlist *candidate_list = ic->candidate_list;
2878 int candidate_index = ic->candidate_index;
2879 int candidate_show = ic->candidate_show;
2880 MTextProperty *prop;
2882 MPLIST_DO (action_list, action_list)
2884 MPlist *action = regularize_action (action_list, ic_info);
2890 name = MPLIST_SYMBOL (action);
2891 args = MPLIST_NEXT (action);
2893 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2894 if (name == Minsert)
2896 if (MPLIST_SYMBOL_P (args))
2898 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2899 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2902 if (MPLIST_MTEXT_P (args))
2903 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2904 else /* MPLIST_INTEGER_P (args)) */
2905 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2907 else if (name == M_candidates)
2909 MPlist *plist = get_candidate_list (ic_info, args);
2912 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2914 if (MPLIST_MTEXT_P (plist))
2916 preedit_insert (ic, ic->cursor_pos, NULL,
2917 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2920 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2924 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2926 preedit_insert (ic, ic->cursor_pos, mt, 0);
2927 len = mtext_nchars (mt);
2929 mtext_put_prop (ic->preedit,
2930 ic->cursor_pos - len, ic->cursor_pos,
2931 Mcandidate_list, plist);
2932 mtext_put_prop (ic->preedit,
2933 ic->cursor_pos - len, ic->cursor_pos,
2934 Mcandidate_index, (void *) 0);
2936 else if (name == Mselect)
2939 int code, idx, gindex;
2940 int pos = ic->cursor_pos;
2942 int idx_decided = 0;
2945 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2948 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2949 group = find_candidates_group (mtext_property_value (prop), idx,
2950 &start, &end, &gindex);
2951 if (MPLIST_SYMBOL_P (args))
2953 code = marker_code (MPLIST_SYMBOL (args), 0);
2956 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2957 if (! MPLIST_INTEGER_P (args))
2959 idx = start + MPLIST_INTEGER (args);
2960 if (idx < start || idx >= end)
2968 if (code != '[' && code != ']')
2973 ? new_index (NULL, ic->candidate_index - start,
2974 end - start - 1, MPLIST_SYMBOL (args),
2976 : MPLIST_INTEGER (args)));
2979 find_candidates_group (mtext_property_value (prop), -1,
2984 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2989 int ingroup_index = idx - start;
2992 group = mtext_property_value (prop);
2993 len = mplist_length (group);
3006 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3007 idx += (MPLIST_MTEXT_P (group)
3008 ? mtext_nchars (MPLIST_MTEXT (group))
3009 : mplist_length (MPLIST_PLIST (group)));
3010 len = (MPLIST_MTEXT_P (group)
3011 ? mtext_nchars (MPLIST_MTEXT (group))
3012 : mplist_length (MPLIST_PLIST (group)));
3013 if (ingroup_index >= len)
3014 ingroup_index = len - 1;
3015 idx += ingroup_index;
3017 update_candidate (ic, prop, idx);
3018 MDEBUG_PRINT1 ("(%d)", idx);
3020 else if (name == Mshow)
3021 ic->candidate_show = 1;
3022 else if (name == Mhide)
3023 ic->candidate_show = 0;
3024 else if (name == Mdelete)
3026 int len = mtext_nchars (ic->preedit);
3030 if (MPLIST_SYMBOL_P (args)
3031 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3033 to = ic->cursor_pos + pos;
3036 delete_surrounding_text (ic, to);
3041 delete_surrounding_text (ic, to - len);
3047 to = (MPLIST_SYMBOL_P (args)
3048 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3050 : MPLIST_INTEGER (args));
3056 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3057 if (to < ic->cursor_pos)
3058 preedit_delete (ic, to, ic->cursor_pos);
3059 else if (to > ic->cursor_pos)
3060 preedit_delete (ic, ic->cursor_pos, to);
3062 else if (name == Mmove)
3064 int len = mtext_nchars (ic->preedit);
3066 = (MPLIST_SYMBOL_P (args)
3067 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3069 : MPLIST_INTEGER (args));
3075 if (pos != ic->cursor_pos)
3077 ic->cursor_pos = pos;
3078 ic->preedit_changed = 1;
3080 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3082 else if (name == Mmark)
3084 int code = marker_code (MPLIST_SYMBOL (args), 0);
3088 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3089 (void *) ic->cursor_pos);
3090 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3093 else if (name == Mpushback)
3095 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3099 if (MPLIST_SYMBOL_P (args))
3101 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3102 if (MPLIST_INTEGER_P (args))
3103 num = MPLIST_INTEGER (args);
3108 num = MPLIST_INTEGER (args);
3111 ic_info->key_head -= num;
3113 ic_info->key_head = 0;
3115 ic_info->key_head = - num;
3116 if (ic_info->key_head > ic_info->used)
3117 ic_info->key_head = ic_info->used;
3119 else if (MPLIST_MTEXT_P (args))
3121 MText *mt = MPLIST_MTEXT (args);
3122 int i, len = mtext_nchars (mt);
3125 ic_info->key_head--;
3126 for (i = 0; i < len; i++)
3128 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3129 if (ic_info->key_head + i < ic_info->used)
3130 ic_info->keys[ic_info->key_head + i] = key;
3132 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3137 MPlist *plist = MPLIST_PLIST (args), *pl;
3141 ic_info->key_head--;
3143 MPLIST_DO (pl, plist)
3145 key = MPLIST_SYMBOL (pl);
3146 if (ic_info->key_head < ic_info->used)
3147 ic_info->keys[ic_info->key_head + i] = key;
3149 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3154 else if (name == Mpop)
3156 if (ic_info->key_head < ic_info->used)
3157 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3159 else if (name == Mcall)
3161 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3162 MIMExternalFunc func = NULL;
3163 MSymbol module, func_name;
3164 MPlist *func_args, *val;
3167 module = MPLIST_SYMBOL (args);
3168 args = MPLIST_NEXT (args);
3169 func_name = MPLIST_SYMBOL (args);
3171 if (im_info->externals)
3173 MIMExternalModule *external
3174 = (MIMExternalModule *) mplist_get (im_info->externals,
3177 func = ((MIMExternalFunc)
3178 mplist_get_func (external->func_list, func_name));
3182 func_args = mplist ();
3183 mplist_add (func_args, Mt, ic);
3184 MPLIST_DO (args, MPLIST_NEXT (args))
3188 if (MPLIST_KEY (args) == Msymbol
3189 && MPLIST_KEY (args) != Mnil
3190 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3192 code = new_index (ic, ic->cursor_pos,
3193 mtext_nchars (ic->preedit),
3194 MPLIST_SYMBOL (args), ic->preedit);
3195 mplist_add (func_args, Minteger, (void *) code);
3198 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3200 val = (func) (func_args);
3201 M17N_OBJECT_UNREF (func_args);
3202 if (val && ! MPLIST_TAIL_P (val))
3203 ret = take_action_list (ic, val);
3204 M17N_OBJECT_UNREF (val);
3208 else if (name == Mshift)
3210 shift_state (ic, MPLIST_SYMBOL (args));
3212 else if (name == Mundo)
3214 int intarg = (MPLIST_TAIL_P (args)
3216 : integer_value (ic, args, NULL, 0));
3218 mtext_reset (ic->preedit);
3219 mtext_reset (ic_info->preedit_saved);
3220 mtext_reset (ic->produced);
3221 M17N_OBJECT_UNREF (ic_info->vars);
3222 ic_info->vars = mplist_copy (ic_info->vars_saved);
3223 ic->cursor_pos = ic_info->state_pos = 0;
3224 ic_info->state_key_head = ic_info->key_head
3225 = ic_info->commit_key_head = 0;
3227 shift_state (ic, Mnil);
3230 if (MPLIST_TAIL_P (args))
3235 ic_info->used += intarg;
3238 ic_info->used = intarg;
3241 else if (name == Mset || name == Madd || name == Msub
3242 || name == Mmul || name == Mdiv)
3244 MSymbol sym = MPLIST_SYMBOL (args);
3249 val1 = integer_value (ic, args, &value, 0);
3250 args = MPLIST_NEXT (args);
3251 val2 = resolve_expression (ic, args);
3253 val1 = val2, op = "=";
3254 else if (name == Madd)
3255 val1 += val2, op = "+=";
3256 else if (name == Msub)
3257 val1 -= val2, op = "-=";
3258 else if (name == Mmul)
3259 val1 *= val2, op = "*=";
3261 val1 /= val2, op = "/=";
3262 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3263 MSYMBOL_NAME (sym), op, val1, val1);
3265 mplist_set (value, Minteger, (void *) val1);
3267 else if (name == Mequal || name == Mless || name == Mgreater
3268 || name == Mless_equal || name == Mgreater_equal)
3271 MPlist *actions1, *actions2;
3274 val1 = resolve_expression (ic, args);
3275 args = MPLIST_NEXT (args);
3276 val2 = resolve_expression (ic, args);
3277 args = MPLIST_NEXT (args);
3278 actions1 = MPLIST_PLIST (args);
3279 args = MPLIST_NEXT (args);
3280 if (MPLIST_TAIL_P (args))
3283 actions2 = MPLIST_PLIST (args);
3284 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3285 if (name == Mequal ? val1 == val2
3286 : name == Mless ? val1 < val2
3287 : name == Mgreater ? val1 > val2
3288 : name == Mless_equal ? val1 <= val2
3291 MDEBUG_PRINT ("ok");
3292 ret = take_action_list (ic, actions1);
3296 MDEBUG_PRINT ("no");
3298 ret = take_action_list (ic, actions2);
3303 else if (name == Mcond)
3307 MPLIST_DO (args, args)
3312 if (! MPLIST_PLIST (args))
3314 cond = MPLIST_PLIST (args);
3315 if (resolve_expression (ic, cond) != 0)
3317 MDEBUG_PRINT1 ("(%dth)", idx);
3318 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3324 else if (name == Mcommit)
3326 preedit_commit (ic);
3328 else if (name == Munhandle)
3330 preedit_commit (ic);
3335 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3339 && (actions = mplist_get (im_info->macros, name)))
3341 if (take_action_list (ic, actions) < 0)
3347 if (ic->candidate_list)
3349 M17N_OBJECT_UNREF (ic->candidate_list);
3350 ic->candidate_list = NULL;
3352 if (ic->cursor_pos > 0
3353 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3356 ic->candidate_list = mtext_property_value (prop);
3357 M17N_OBJECT_REF (ic->candidate_list);
3359 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3361 ic->candidate_from = mtext_property_start (prop);
3362 ic->candidate_to = mtext_property_end (prop);
3365 if (candidate_list != ic->candidate_list)
3366 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3367 if (candidate_index != ic->candidate_index)
3368 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3369 if (candidate_show != ic->candidate_show)
3370 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3375 /* Handle the input key KEY in the current state and map specified in
3376 the input context IC. If KEY is handled correctly, return 0.
3377 Otherwise, return -1. */
3380 handle_key (MInputContext *ic)
3382 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3383 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3384 MIMMap *map = ic_info->map;
3385 MIMMap *submap = NULL;
3386 MSymbol key = ic_info->keys[ic_info->key_head];
3387 MSymbol alias = Mnil;
3390 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3391 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3395 submap = mplist_get (map->submaps, key);
3398 && (alias = msymbol_get (alias, M_key_alias))
3400 submap = mplist_get (map->submaps, alias);
3405 if (! alias || alias == key)
3406 MDEBUG_PRINT (" submap-found");
3408 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3409 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3410 ic->preedit_changed = 1;
3411 ic->cursor_pos = ic_info->state_pos;
3412 ic_info->key_head++;
3413 ic_info->map = map = submap;
3414 if (map->map_actions)
3416 MDEBUG_PRINT (" map-actions:");
3417 if (take_action_list (ic, map->map_actions) < 0)
3419 MDEBUG_PRINT ("\n");
3423 else if (map->submaps)
3425 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3427 MSymbol key = ic_info->keys[i];
3428 char *name = msymbol_name (key);
3430 if (! name[0] || ! name[1])
3431 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3435 /* If this is the terminal map or we have shifted to another
3436 state, perform branch actions (if any). */
3437 if (! map->submaps || map != ic_info->map)
3439 if (map->branch_actions)
3441 MDEBUG_PRINT (" branch-actions:");
3442 if (take_action_list (ic, map->branch_actions) < 0)
3444 MDEBUG_PRINT ("\n");
3448 /* If MAP is still not the root map, shift to the current
3450 if (ic_info->map != ic_info->state->map)
3451 shift_state (ic, ic_info->state->name);
3456 /* MAP can not handle KEY. */
3458 /* Perform branch actions if any. */
3459 if (map->branch_actions)
3461 MDEBUG_PRINT (" branch-actions:");
3462 if (take_action_list (ic, map->branch_actions) < 0)
3464 MDEBUG_PRINT ("\n");
3469 if (map == ic_info->map)
3471 /* The above branch actions didn't change the state. */
3473 /* If MAP is the root map of the initial state, and there
3474 still exist an unhandled key, it means that the current
3475 input method can not handle it. */
3476 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3477 && ic_info->key_head < ic_info->used)
3479 MDEBUG_PRINT (" unhandled\n");
3483 if (map != ic_info->state->map)
3485 /* MAP is not the root map. Shift to the root map of the
3487 shift_state (ic, ic_info->state->name);
3489 else if (! map->branch_actions)
3491 /* MAP is the root map without any default branch
3492 actions. Shift to the initial state. */
3493 shift_state (ic, Mnil);
3497 MDEBUG_PRINT ("\n");
3501 /* Initialize IC->ic_info. */
3504 init_ic_info (MInputContext *ic)
3506 MInputMethodInfo *im_info = ic->im->info;
3507 MInputContextInfo *ic_info = ic->info;
3510 MLIST_INIT1 (ic_info, keys, 8);;
3512 ic_info->markers = mplist ();
3514 ic_info->vars = mplist ();
3515 if (im_info->configured_vars)
3516 MPLIST_DO (plist, im_info->configured_vars)
3518 MPlist *pl = MPLIST_PLIST (plist);
3519 MSymbol name = MPLIST_SYMBOL (pl);
3521 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3522 if (MPLIST_KEY (pl) != Mt)
3524 MPlist *p = mplist ();
3526 mplist_push (ic_info->vars, Mplist, p);
3527 M17N_OBJECT_UNREF (p);
3528 mplist_add (p, Msymbol, name);
3529 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3532 ic_info->vars_saved = mplist_copy (ic_info->vars);
3534 if (im_info->externals)
3536 MPlist *func_args = mplist (), *plist;
3538 mplist_add (func_args, Mt, ic);
3539 MPLIST_DO (plist, im_info->externals)
3541 MIMExternalModule *external = MPLIST_VAL (plist);
3542 MIMExternalFunc func
3543 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3548 M17N_OBJECT_UNREF (func_args);
3551 ic_info->preedit_saved = mtext ();
3552 ic_info->tick = im_info->tick;
3555 /* Finalize IC->ic_info. */
3558 fini_ic_info (MInputContext *ic)
3560 MInputMethodInfo *im_info = ic->im->info;
3561 MInputContextInfo *ic_info = ic->info;
3563 if (im_info->externals)
3565 MPlist *func_args = mplist (), *plist;
3567 mplist_add (func_args, Mt, ic);
3568 MPLIST_DO (plist, im_info->externals)
3570 MIMExternalModule *external = MPLIST_VAL (plist);
3571 MIMExternalFunc func
3572 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3577 M17N_OBJECT_UNREF (func_args);
3580 MLIST_FREE1 (ic_info, keys);
3581 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3582 M17N_OBJECT_UNREF (ic_info->markers);
3583 M17N_OBJECT_UNREF (ic_info->vars);
3584 M17N_OBJECT_UNREF (ic_info->vars_saved);
3585 M17N_OBJECT_UNREF (ic_info->preceding_text);
3586 M17N_OBJECT_UNREF (ic_info->following_text);
3588 memset (ic_info, 0, sizeof (MInputContextInfo));
3592 re_init_ic (MInputContext *ic, int reload)
3594 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3595 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3596 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3598 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3599 preedit_changed = mtext_nchars (ic->preedit) > 0;
3600 cursor_pos_changed = ic->cursor_pos > 0;
3601 candidates_changed = 0;
3602 if (ic->candidate_list)
3604 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3605 M17N_OBJECT_UNREF (ic->candidate_list);
3606 ic->candidate_list = NULL;
3608 if (ic->candidate_show)
3610 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3611 ic->candidate_show = 0;
3613 if (ic->candidate_index > 0)
3615 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3616 ic->candidate_index = 0;
3617 ic->candidate_from = ic->candidate_to = 0;
3619 if (mtext_nchars (ic->produced) > 0)
3620 mtext_reset (ic->produced);
3621 if (mtext_nchars (ic->preedit) > 0)
3622 mtext_reset (ic->preedit);
3624 M17N_OBJECT_UNREF (ic->plist);
3625 ic->plist = mplist ();
3629 reload_im_info (im_info);
3631 shift_state (ic, Mnil);
3632 ic->status_changed = status_changed;
3633 ic->preedit_changed = preedit_changed;
3634 ic->cursor_pos_changed = cursor_pos_changed;
3635 ic->candidates_changed = candidates_changed;
3639 reset_ic (MInputContext *ic, MSymbol ignore)
3641 MDEBUG_PRINT ("\n [IM] reset\n");
3646 open_im (MInputMethod *im)
3648 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3651 MERROR (MERROR_IM, -1);
3658 close_im (MInputMethod *im)
3664 create_ic (MInputContext *ic)
3666 MInputContextInfo *ic_info;
3668 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3671 shift_state (ic, Mnil);
3676 destroy_ic (MInputContext *ic)
3683 check_reload (MInputContext *ic, MSymbol key)
3685 MInputMethodInfo *im_info = ic->im->info;
3686 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3690 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3694 MPLIST_DO (plist, plist)
3696 MSymbol this_key, alias;
3698 if (MPLIST_MTEXT_P (plist))
3700 MText *mt = MPLIST_MTEXT (plist);
3701 int c = mtext_ref_char (mt, 0);
3705 this_key = one_char_symbol[c];
3709 MPlist *pl = MPLIST_PLIST (plist);
3711 this_key = MPLIST_SYMBOL (pl);
3715 && (alias = msymbol_get (alias, M_key_alias))
3716 && alias != this_key);
3720 if (MPLIST_TAIL_P (plist))
3723 MDEBUG_PRINT ("\n [IM] reload");
3729 /** Handle the input key KEY in the current state and map of IC->info.
3730 If KEY is handled but no text is produced, return 0, otherwise
3736 filter (MInputContext *ic, MSymbol key, void *arg)
3738 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3739 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3742 if (check_reload (ic, key))
3745 if (! ic_info->state)
3747 ic_info->key_unhandled = 1;
3750 mtext_reset (ic->produced);
3751 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3752 M17N_OBJECT_UNREF (ic_info->preceding_text);
3753 M17N_OBJECT_UNREF (ic_info->following_text);
3754 ic_info->preceding_text = ic_info->following_text = NULL;
3755 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3756 ic_info->key_unhandled = 0;
3759 if (handle_key (ic) < 0)
3761 /* KEY was not handled. Delete it from the current key sequence. */
3762 if (ic_info->used > 0)
3764 memmove (ic_info->keys, ic_info->keys + 1,
3765 sizeof (int) * (ic_info->used - 1));
3767 if (ic_info->state_key_head > 0)
3768 ic_info->state_key_head--;
3769 if (ic_info->commit_key_head > 0)
3770 ic_info->commit_key_head--;
3772 /* This forces returning 1. */
3773 ic_info->key_unhandled = 1;
3779 reset_ic (ic, Mnil);
3780 ic_info->key_unhandled = 1;
3783 /* Break the loop if all keys were handled. */
3784 } while (ic_info->key_head < ic_info->used);
3786 /* If the current map is the root of the initial state, we should
3787 produce any preedit text in ic->produced. */
3788 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3789 preedit_commit (ic);
3791 if (mtext_nchars (ic->produced) > 0)
3793 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3795 if (mdebug__flag & mdebug_mask)
3797 MDEBUG_PRINT (" (produced");
3798 for (i = 0; i < mtext_nchars (ic->produced); i++)
3799 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3804 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3805 Mlanguage, ic->im->language);
3807 if (ic_info->commit_key_head > 0)
3809 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3810 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3811 ic_info->used -= ic_info->commit_key_head;
3812 ic_info->key_head -= ic_info->commit_key_head;
3813 ic_info->state_key_head -= ic_info->commit_key_head;
3814 ic_info->commit_key_head = 0;
3816 if (ic_info->key_unhandled)
3819 ic_info->key_head = ic_info->state_key_head
3820 = ic_info->commit_key_head = 0;
3823 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3827 /** Return 1 if the last event or key was not handled, otherwise
3830 There is no need of looking up because ic->produced should already
3831 contain the produced text (if any).
3836 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3838 mtext_cat (mt, ic->produced);
3839 mtext_reset (ic->produced);
3840 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3844 /* Input method command handler. */
3846 /* List of all (global and local) commands.
3847 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3848 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3849 Global commands are stored as (t (t COMMAND ...)) */
3852 /* Input method variable handler. */
3855 /* Support functions for mdebug_dump_im. */
3858 dump_im_map (MPlist *map_list, int indent)
3861 MSymbol key = MPLIST_KEY (map_list);
3862 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3864 prefix = (char *) alloca (indent + 1);
3865 memset (prefix, 32, indent);
3866 prefix[indent] = '\0';
3868 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3869 if (map->map_actions)
3870 mdebug_dump_plist (map->map_actions, indent + 2);
3873 MPLIST_DO (map_list, map->submaps)
3875 fprintf (stderr, "\n%s ", prefix);
3876 dump_im_map (map_list, indent + 2);
3879 if (map->branch_actions)
3881 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3882 mdebug_dump_plist (map->branch_actions, indent + 4);
3883 fprintf (stderr, ")");
3885 fprintf (stderr, ")");
3890 dump_im_state (MIMState *state, int indent)
3895 prefix = (char *) alloca (indent + 1);
3896 memset (prefix, 32, indent);
3897 prefix[indent] = '\0';
3899 fprintf (stderr, "(%s", msymbol_name (state->name));
3900 if (state->map->submaps)
3902 MPLIST_DO (map_list, state->map->submaps)
3904 fprintf (stderr, "\n%s ", prefix);
3905 dump_im_map (map_list, indent + 2);
3908 fprintf (stderr, ")");
3916 Minput_driver = msymbol ("input-driver");
3918 Minput_preedit_start = msymbol ("input-preedit-start");
3919 Minput_preedit_done = msymbol ("input-preedit-done");
3920 Minput_preedit_draw = msymbol ("input-preedit-draw");
3921 Minput_status_start = msymbol ("input-status-start");
3922 Minput_status_done = msymbol ("input-status-done");
3923 Minput_status_draw = msymbol ("input-status-draw");
3924 Minput_candidates_start = msymbol ("input-candidates-start");
3925 Minput_candidates_done = msymbol ("input-candidates-done");
3926 Minput_candidates_draw = msymbol ("input-candidates-draw");
3927 Minput_set_spot = msymbol ("input-set-spot");
3928 Minput_focus_move = msymbol ("input-focus-move");
3929 Minput_focus_in = msymbol ("input-focus-in");
3930 Minput_focus_out = msymbol ("input-focus-out");
3931 Minput_toggle = msymbol ("input-toggle");
3932 Minput_reset = msymbol ("input-reset");
3933 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3934 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3935 Mcustomized = msymbol ("customized");
3936 Mconfigured = msymbol ("configured");
3937 Minherited = msymbol ("inherited");
3939 minput_default_driver.open_im = open_im;
3940 minput_default_driver.close_im = close_im;
3941 minput_default_driver.create_ic = create_ic;
3942 minput_default_driver.destroy_ic = destroy_ic;
3943 minput_default_driver.filter = filter;
3944 minput_default_driver.lookup = lookup;
3945 minput_default_driver.callback_list = mplist ();
3946 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
3947 M17N_FUNC (reset_ic));
3948 minput_driver = &minput_default_driver;
3950 fully_initialized = 0;
3957 if (fully_initialized)
3959 free_im_list (im_info_list);
3961 free_im_list (im_custom_list);
3963 free_im_list (im_config_list);
3964 M17N_OBJECT_UNREF (load_im_info_keys);
3967 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3968 M17N_OBJECT_UNREF (minput_driver->callback_list);
3973 minput__char_to_key (int c)
3975 if (c < 0 || c >= 0x100)
3978 return one_char_symbol[c];
3982 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3987 /*** @addtogroup m17nInputMethod */
3992 @name Variables: Predefined symbols for callback commands.
3994 These are the predefined symbols that are used as the @c COMMAND
3995 argument of callback functions of an input method driver (see
3996 #MInputDriver::callback_list).
3998 Most of them do not require extra argument nor return any value;
3999 exceptions are these:
4001 Minput_get_surrounding_text: When a callback function assigned for
4002 this command is called, the first element of #MInputContext::plist
4003 has key #Minteger and the value specifies which portion of the
4004 surrounding text should be retrieved. If the value is positive,
4005 it specifies the number of characters following the current cursor
4006 position. If the value is negative, the absolute value specifies
4007 the number of characters preceding the current cursor position.
4008 If the value is zero, it means that the caller just wants to know
4009 if the surrounding text is currently supported or not.
4011 If the surrounding text is currently supported, the callback
4012 function must set the key of this element to #Mtext and the value
4013 to the retrieved M-text. The length of the M-text may be shorter
4014 than the requested number of characters, if the available text is
4015 not that long. The length can be zero in the worst case. Or, the
4016 length may be longer if an application thinks it is more efficient
4017 to return that length.
4019 If the surrounding text is not currently supported, the callback
4020 function should return without changing the first element of
4021 #MInputContext::plist.
4023 Minput_delete_surrounding_text: When a callback function assigned
4024 for this command is called, the first element of
4025 #MInputContext::plist has key #Minteger and the value specifies
4026 which portion of the surrounding text should be deleted in the
4027 same way as the case of Minput_get_surrounding_text. The callback
4028 function must delete the specified text. It should not alter
4029 #MInputContext::plist. */
4031 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4033 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4034 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4036 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4038 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4039 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4040 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4041 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4042 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4043 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4044 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4046 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4047 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4048 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4049 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4050 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4052 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4053 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4055 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4056 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4057 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4058 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4059 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4060 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4064 MSymbol Minput_preedit_start;
4065 MSymbol Minput_preedit_done;
4066 MSymbol Minput_preedit_draw;
4067 MSymbol Minput_status_start;
4068 MSymbol Minput_status_done;
4069 MSymbol Minput_status_draw;
4070 MSymbol Minput_candidates_start;
4071 MSymbol Minput_candidates_done;
4072 MSymbol Minput_candidates_draw;
4073 MSymbol Minput_set_spot;
4074 MSymbol Minput_toggle;
4075 MSymbol Minput_reset;
4076 MSymbol Minput_get_surrounding_text;
4077 MSymbol Minput_delete_surrounding_text;
4083 @name Variables: Predefined symbols for special input events.
4085 These are the predefined symbols that are used as the @c KEY
4086 argument of minput_filter (). */
4088 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4090 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4095 MSymbol Minput_focus_out;
4096 MSymbol Minput_focus_in;
4097 MSymbol Minput_focus_move;
4103 @name Variables: Predefined symbols used in input method information.
4105 These are the predefined symbols describing status of input method
4106 command and variable, and are used in a return value of
4107 minput_get_command () and minput_get_variable (). */
4109 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4111 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4112 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4116 MSymbol Mcustomized;
4117 MSymbol Mconfigured;
4123 @brief The default driver for internal input methods.
4125 The variable #minput_default_driver is the default driver for
4126 internal input methods.
4128 The member MInputDriver::open_im () searches the m17n database for
4129 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4130 $NAME\> and loads it.
4132 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4133 programmers responsibility to set it to a plist of proper callback
4134 functions. Otherwise, no feedback information (e.g. preedit text)
4135 can be shown to users.
4137 The macro M17N_INIT () sets the variable #minput_driver to the
4138 pointer to this driver so that all internal input methods use it.
4140 Therefore, unless @c minput_driver is set differently, the driver
4141 dependent arguments $ARG of the functions whose name begins with
4142 "minput_" are all ignored. */
4144 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4146 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4148 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4149 \< #Minput_method, $LANGUAGE, $NAME\>
4150 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4152 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4153 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4154 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4155 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4157 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4158 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4160 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4161 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4163 MInputDriver minput_default_driver;
4167 @brief The driver for internal input methods.
4169 The variable #minput_driver is a pointer to the input method
4170 driver that is used by internal input methods. The macro
4171 M17N_INIT () initializes it to a pointer to #minput_default_driver
4172 if <m17n<EM></EM>.h> is included. */
4174 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4176 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4177 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4178 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4179 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4181 MInputDriver *minput_driver;
4183 MSymbol Minput_driver;
4198 @brief Open an input method.
4200 The minput_open_im () function opens an input method whose
4201 language and name match $LANGUAGE and $NAME, and returns a pointer
4202 to the input method object newly allocated.
4204 This function at first decides a driver for the input method as
4207 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4208 #minput_driver is used.
4210 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4211 driver pointed to by the property value is used to open the input
4212 method. If $NAME has no such a property, @c NULL is returned.
4214 Then, the member MInputDriver::open_im () of the driver is
4217 $ARG is set in the member @c arg of the structure MInputMethod so
4218 that the driver can refer to it. */
4220 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4222 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4223 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4225 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4227 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4228 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4230 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4231 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4232 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4234 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4236 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4238 @latexonly \IPAlabel{minput_open} @endlatexonly
4243 minput_open_im (MSymbol language, MSymbol name, void *arg)
4246 MInputDriver *driver;
4250 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4251 msymbol_name (language), msymbol_name (name));
4253 driver = minput_driver;
4256 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4258 MERROR (MERROR_IM, NULL);
4261 MSTRUCT_CALLOC (im, MERROR_IM);
4262 im->language = language;
4265 im->driver = *driver;
4266 if ((*im->driver.open_im) (im) < 0)
4268 MDEBUG_PRINT (" failed\n");
4272 MDEBUG_PRINT (" ok\n");
4279 @brief Close an input method.
4281 The minput_close_im () function closes the input method $IM, which
4282 must have been created by minput_open_im (). */
4285 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4287 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4288 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4291 minput_close_im (MInputMethod *im)
4293 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4294 msymbol_name (im->name), msymbol_name (im->language));
4295 (*im->driver.close_im) (im);
4297 MDEBUG_PRINT (" done\n");
4303 @brief Create an input context.
4305 The minput_create_ic () function creates an input context object
4306 associated with input method $IM, and calls callback functions
4307 corresponding to #Minput_preedit_start, #Minput_status_start, and
4308 #Minput_status_draw in this order.
4311 If an input context is successfully created, minput_create_ic ()
4312 returns a pointer to it. Otherwise it returns @c NULL. */
4315 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4317 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4318 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4319 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4320 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4323 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4324 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4328 minput_create_ic (MInputMethod *im, void *arg)
4332 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4333 msymbol_name (im->name), msymbol_name (im->language));
4334 MSTRUCT_CALLOC (ic, MERROR_IM);
4337 ic->preedit = mtext ();
4338 ic->candidate_list = NULL;
4339 ic->produced = mtext ();
4340 ic->spot.x = ic->spot.y = 0;
4342 ic->plist = mplist ();
4343 if ((*im->driver.create_ic) (ic) < 0)
4345 MDEBUG_PRINT (" failed\n");
4346 M17N_OBJECT_UNREF (ic->preedit);
4347 M17N_OBJECT_UNREF (ic->produced);
4348 M17N_OBJECT_UNREF (ic->plist);
4353 if (im->driver.callback_list)
4355 minput_callback (ic, Minput_preedit_start);
4356 minput_callback (ic, Minput_status_start);
4357 minput_callback (ic, Minput_status_draw);
4360 MDEBUG_PRINT (" ok\n");
4367 @brief Destroy an input context.
4369 The minput_destroy_ic () function destroys the input context $IC,
4370 which must have been created by minput_create_ic (). It calls
4371 callback functions corresponding to #Minput_preedit_done,
4372 #Minput_status_done, and #Minput_candidates_done in this order. */
4375 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4377 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4378 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4379 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4380 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4381 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4385 minput_destroy_ic (MInputContext *ic)
4387 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4388 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4389 if (ic->im->driver.callback_list)
4391 minput_callback (ic, Minput_preedit_done);
4392 minput_callback (ic, Minput_status_done);
4393 minput_callback (ic, Minput_candidates_done);
4395 (*ic->im->driver.destroy_ic) (ic);
4396 M17N_OBJECT_UNREF (ic->preedit);
4397 M17N_OBJECT_UNREF (ic->produced);
4398 M17N_OBJECT_UNREF (ic->plist);
4399 MDEBUG_PRINT (" done\n");
4406 @brief Filter an input key.
4408 The minput_filter () function filters input key $KEY according to
4409 input context $IC, and calls callback functions corresponding to
4410 #Minput_preedit_draw, #Minput_status_draw, and
4411 #Minput_candidates_draw if the preedit text, the status, and the
4412 current candidate are changed respectively.
4414 To make the input method commit the current preedit text (if any)
4415 and shift to the initial state, call this function with #Mnil as
4418 To inform the input method about the focus-out event, call this
4419 function with #Minput_focus_out as $KEY.
4421 To inform the input method about the focus-in event, call this
4422 function with #Minput_focus_in as $KEY.
4424 To inform the input method about the focus-move event (i.e. input
4425 spot change within the same input context), call this function
4426 with #Minput_focus_move as $KEY.
4429 If $KEY is filtered out, this function returns 1. In that case,
4430 the caller should discard the key. Otherwise, it returns 0, and
4431 the caller should handle the key, for instance, by calling the
4432 function minput_lookup () with the same key. */
4435 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4437 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4438 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4439 #Minput_preedit_draw, #Minput_status_draw,
4440 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4443 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4444 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4445 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4446 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4448 @latexonly \IPAlabel{minput_filter} @endlatexonly
4452 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4459 if (ic->im->driver.callback_list
4460 && mtext_nchars (ic->preedit) > 0)
4461 minput_callback (ic, Minput_preedit_draw);
4463 ret = (*ic->im->driver.filter) (ic, key, arg);
4465 if (ic->im->driver.callback_list)
4467 if (ic->preedit_changed)
4468 minput_callback (ic, Minput_preedit_draw);
4469 if (ic->status_changed)
4470 minput_callback (ic, Minput_status_draw);
4471 if (ic->candidates_changed)
4472 minput_callback (ic, Minput_candidates_draw);
4481 @brief Look up a text produced in the input context.
4483 The minput_lookup () function looks up a text in the input context
4484 $IC. $KEY must be identical to the one that was used in the previous call of
4487 If a text was produced by the input method, it is concatenated
4490 This function calls #MInputDriver::lookup .
4493 If $KEY was correctly handled by the input method, this function
4494 returns 0. Otherwise, it returns -1, even though some text
4495 might be produced in $MT. */
4498 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4500 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4501 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4503 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4506 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4509 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4510 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4511 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4513 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4516 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4518 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4523 @brief Set the spot of the input context.
4525 The minput_set_spot () function sets the spot of input context $IC
4526 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4527 The semantics of these values depends on the input method driver.
4529 For instance, a driver designed to work in a CUI environment may
4530 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4531 $DESCENT . A driver designed to work in a window system may
4532 interpret $X and $Y as the pixel offsets relative to the origin of the
4533 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4534 descent pixels of the line at ($X . $Y ).
4536 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4538 $MT and $POS are the M-text and the character position at the spot.
4539 $MT may be @c NULL, in which case, the input method cannot get
4540 information about the text around the spot. */
4543 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4545 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4546 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4547 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4549 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4550 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4551 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4552 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4553 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4554 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4556 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4558 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4559 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4563 minput_set_spot (MInputContext *ic, int x, int y,
4564 int ascent, int descent, int fontsize,
4569 ic->spot.ascent = ascent;
4570 ic->spot.descent = descent;
4571 ic->spot.fontsize = fontsize;
4574 if (ic->im->driver.callback_list)
4575 minput_callback (ic, Minput_set_spot);
4580 @brief Toggle input method.
4582 The minput_toggle () function toggles the input method associated
4583 with input context $IC. */
4585 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4587 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4588 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4592 minput_toggle (MInputContext *ic)
4594 if (ic->im->driver.callback_list)
4595 minput_callback (ic, Minput_toggle);
4596 ic->active = ! ic->active;
4602 @brief Reset an input context.
4604 The minput_reset_ic () function resets input context $IC by
4605 calling a callback function corresponding to #Minput_reset. It
4606 resets the status of $IC to its initial one. As the
4607 current preedit text is deleted without commitment, if necessary,
4608 call minput_filter () with the arg @r key #Mnil to force the input
4609 method to commit the preedit in advance. */
4612 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4614 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4615 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4616 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4617 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4618 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4619 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4622 minput_reset_ic (MInputContext *ic)
4624 if (ic->im->driver.callback_list)
4625 minput_callback (ic, Minput_reset);
4631 @brief Get title and icon filename of an input method.
4633 The minput_get_title_icon () function returns a plist containing a
4634 title and icon filename (if any) of an input method specified by
4635 $LANGUAGE and $NAME.
4637 The first element of the plist has key #Mtext and the value is an
4638 M-text of the title for identifying the input method. The second
4639 element (if any) has key #Mtext and the value is an M-text of the
4640 icon image (absolute) filename for the same purpose.
4643 If there exists a specified input method and it defines an title,
4644 a plist is returned. Otherwise, NULL is returned. The caller
4645 must free the plist by m17n_object_unref (). */
4647 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4649 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4650 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4653 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4654 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4655 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4658 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4659 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4660 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4663 minput_get_title_icon (MSymbol language, MSymbol name)
4665 MInputMethodInfo *im_info;
4672 im_info = get_im_info (language, name, Mnil, Mtitle);
4673 if (! im_info || !im_info->title)
4675 mt = mtext_get_prop (im_info->title, 0, Mtext);
4677 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4680 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4683 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4684 (char *) MSYMBOL_NAME (name));
4685 file = mdatabase__find_file (buf);
4686 if (! file && language == Mt)
4688 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4689 file = mdatabase__find_file (buf);
4694 mplist_add (plist, Mtext, im_info->title);
4697 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4699 mplist_add (plist, Mtext, mt);
4700 M17N_OBJECT_UNREF (mt);
4708 @brief Get description text of an input method.
4710 The minput_get_description () function returns an M-text that
4711 describes the input method specified by $LANGUAGE and $NAME.
4714 If the specified input method has a description text, a pointer to
4715 #MText is returned. The caller has to free it by m17n_object_unref ().
4716 If the input method does not have a description text, @c NULL is
4719 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4721 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4722 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4724 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4725 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4726 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4727 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4730 minput_get_description (MSymbol language, MSymbol name)
4732 MInputMethodInfo *im_info;
4740 extra = language, language = Mt;
4742 im_info = get_im_info (language, name, extra, Mdescription);
4743 if (! im_info || ! im_info->description)
4745 M17N_OBJECT_REF (im_info->description);
4746 return im_info->description;
4752 @brief Get information about input method command(s).
4754 The minput_get_command () function returns information about
4755 the command $COMMAND of the input method specified by $LANGUAGE and
4756 $NAME. An input method command is a pseudo key event to which one
4757 or more actual input key sequences are assigned.
4759 There are two kinds of commands, global and local. A global
4760 command has a global definition, and the description and the key
4761 assignment may be inherited by a local command. Each input method
4762 defines a local command which has a local key assignment. It may
4763 also declare a local command that inherits the definition of a
4764 global command of the same name.
4766 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4767 information about a global command. Otherwise information about a
4768 local command is returned.
4770 If $COMMAND is #Mnil, information about all commands is returned.
4772 The return value is a @e well-formed plist (#m17nPlist) of this
4775 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4777 @c NAME is a symbol representing the command name.
4779 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4780 command has no description.
4782 @c STATUS is a symbol representing how the key assignment is decided.
4783 The value is #Mnil (the default key assignment), #Mcustomized (the
4784 key assignment is customized by per-user customization file), or
4785 #Mconfigured (the key assignment is set by the call of
4786 minput_config_command ()). For a local command only, it may also
4787 be #Minherited (the key assignment is inherited from the
4788 corresponding global command).
4790 @c KEYSEQ is a plist of one or more symbols representing a key
4791 sequence assigned to the command. If there's no KEYSEQ, the
4792 command is currently disabled (i.e. no key sequence can trigger
4793 actions of the command).
4795 If $COMMAND is not #Mnil, the first element of the returned plist
4796 contains the information about $COMMAND.
4800 If the requested information was found, a pointer to a non-empty
4801 plist is returned. As the plist is kept in the library, the
4802 caller must not modify nor free it.
4804 Otherwise (the specified input method or the specified command
4805 does not exist), @c NULL is returned. */
4807 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4809 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4810 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4811 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4812 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4814 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4815 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4816 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4817 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4818 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4820 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4821 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4824 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4826 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4829 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4831 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4833 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4836 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4837 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4838 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4839 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4840 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4841 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4843 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4844 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4845 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4846 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4848 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4849 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4853 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4854 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4857 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4862 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4864 /* Return a description of the command COMMAND of the input method
4865 specified by LANGUAGE and NAME. */
4866 MPlist *cmd = minput_get_command (langauge, name, command);
4871 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4872 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4873 return (mplist_key (plist) == Mtext
4874 ? (MText *) mplist_value (plist)
4880 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4882 MInputMethodInfo *im_info;
4886 im_info = get_im_info (language, name, Mnil, Mcommand);
4888 || ! im_info->configured_cmds
4889 || MPLIST_TAIL_P (im_info->configured_cmds))
4891 if (command == Mnil)
4892 return im_info->configured_cmds;
4893 return mplist__assq (im_info->configured_cmds, command);
4899 @brief Configure the key sequence of an input method command.
4901 The minput_config_command () function assigns a list of key
4902 sequences $KEYSEQLIST to the command $COMMAND of the input method
4903 specified by $LANGUAGE and $NAME.
4905 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4906 sequences, and each key sequence must be a plist of symbols.
4908 If $KEYSEQLIST is an empty plist, any configuration and
4909 customization of the command are cancelled, and default key
4910 sequences become effective.
4912 If $KEYSEQLIST is NULL, the configuration of the command is
4913 canceled, and the original key sequences (what saved in per-user
4914 customization file, or the default one) become effective.
4916 In the latter two cases, $COMMAND can be #Mnil to make all the
4917 commands of the input method the target of the operation.
4919 If $NAME is #Mnil, this function configures the key assignment of a
4920 global command, not that of a specific input method.
4922 The configuration takes effect for input methods opened or
4923 re-opened later in the current session. In order to make the
4924 configuration take effect for the future session, it must be saved
4925 in a per-user customization file by the function
4926 minput_save_config ().
4929 If the operation was successful, this function returns 0,
4930 otherwise returns -1. The operation fails in these cases:
4932 <li>$KEYSEQLIST is not in a valid form.
4933 <li>$COMMAND is not available for the input method.
4934 <li>$LANGUAGE and $NAME do not specify an existing input method.
4938 minput_get_commands (), minput_save_config ().
4941 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4943 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4944 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4945 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4947 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4948 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4950 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4952 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4953 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4954 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4957 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4958 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4960 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4961 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4962 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4963 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4967 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4969 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4970 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4971 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4975 minput_get_commands (), minput_save_config ().
4979 /* Add "C-x u" to the "start" command of Unicode input method. */
4981 MSymbol start_command = msymbol ("start");
4982 MSymbol unicode = msymbol ("unicode");
4983 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4985 /* At first get the current key-sequence assignment. */
4986 cmd = minput_get_command (Mt, unicode, start_command);
4989 /* The input method does not have the command "start". Here
4990 should come some error handling code. */
4992 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
4993 Extract the part (KEY-SEQUENCE ...). */
4994 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
4995 /* Copy it because we should not modify it directly. */
4996 key_seq_list = mplist_copy (plist);
4998 key_seq = mplist ();
4999 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5000 mplist_add (key_seq, Msymbol, msymbol ("u"));
5001 mplist_add (key_seq_list, Mplist, key_seq);
5002 m17n_object_unref (key_seq);
5004 minput_config_command (Mt, unicode, start_command, key_seq_list);
5005 m17n_object_unref (key_seq_list);
5010 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5013 MInputMethodInfo *im_info, *config;
5018 im_info = get_im_info (language, name, Mnil, Mcommand);
5020 MERROR (MERROR_IM, -1);
5021 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5023 || ! mplist__assq (im_info->configured_cmds, command)))
5024 MERROR (MERROR_IM, -1);
5025 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5027 MPLIST_DO (plist, keyseqlist)
5028 if (! check_command_keyseq (plist))
5029 MERROR (MERROR_IM, -1);
5032 config = get_config_info (im_info);
5035 if (! im_config_list)
5036 im_config_list = mplist ();
5037 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5038 config->cmds = mplist ();
5039 config->vars = mplist ();
5042 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5043 /* Nothing to do. */
5046 if (command == Mnil)
5050 /* Cancal the configuration. */
5051 if (MPLIST_TAIL_P (config->cmds))
5053 mplist_set (config->cmds, Mnil, NULL);
5057 /* Cancal the customization. */
5058 MInputMethodInfo *custom = get_custom_info (im_info);
5060 if (MPLIST_TAIL_P (config->cmds)
5061 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5062 /* Nothing to do. */
5064 mplist_set (config->cmds, Mnil, NULL);
5065 MPLIST_DO (plist, custom->cmds)
5067 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5069 mplist_add (plist, Msymbol, command);
5070 mplist_push (config->cmds, Mplist, plist);
5071 M17N_OBJECT_UNREF (plist);
5077 plist = mplist__assq (config->cmds, command);
5080 /* Cancel the configuration. */
5083 mplist__pop_unref (plist);
5085 else if (MPLIST_TAIL_P (keyseqlist))
5087 /* Cancel the customization. */
5088 MInputMethodInfo *custom = get_custom_info (im_info);
5089 int no_custom = (! custom || ! custom->cmds
5090 || ! mplist__assq (custom->cmds, command));
5096 mplist_add (config->cmds, Mplist, plist);
5097 M17N_OBJECT_UNREF (plist);
5098 plist = mplist_add (plist, Msymbol, command);
5102 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5103 plist = MPLIST_NEXT (plist);
5104 if (MPLIST_TAIL_P (plist))
5106 mplist_set (plist, Mnil, NULL);
5115 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5116 if (! MPLIST_TAIL_P (plist))
5117 mplist_set (plist, Mnil, NULL);
5122 mplist_add (config->cmds, Mplist, plist);
5123 M17N_OBJECT_UNREF (plist);
5124 plist = mplist_add (plist, Msymbol, command);
5125 plist = MPLIST_NEXT (plist);
5127 MPLIST_DO (keyseqlist, keyseqlist)
5129 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5130 plist = mplist_add (plist, Mplist, pl);
5131 M17N_OBJECT_UNREF (pl);
5135 config_all_commands (im_info);
5136 im_info->tick = time (NULL);
5143 @brief Get information about input method variable(s).
5145 The minput_get_variable () function returns information about
5146 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5147 An input method variable controls behavior of an input method.
5149 There are two kinds of variables, global and local. A global
5150 variable has a global definition, and the description and the value
5151 may be inherited by a local variable. Each input method defines a
5152 local variable which has local value. It may also declare a
5153 local variable that inherits definition of a global variable of
5156 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5157 variable is returned. Otherwise information about a local variable
5160 If $VARIABLE is #Mnil, information about all variables is
5163 The return value is a @e well-formed plist (#m17nPlist) of this
5166 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5168 @c NAME is a symbol representing the variable name.
5170 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5171 variable has no description.
5173 @c STATUS is a symbol representing how the value is decided. The
5174 value is #Mnil (the default value), #Mcustomized (the value is
5175 customized by per-user customization file), or #Mconfigured (the
5176 value is set by the call of minput_config_variable ()). For a
5177 local variable only, it may also be #Minherited (the value is
5178 inherited from the corresponding global variable).
5180 @c VALUE is the initial value of the variable. If the key of this
5181 element is #Mt, the variable has no initial value. Otherwise, the
5182 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5185 @c VALID-VALUEs (if any) specify which values the variable can have.
5186 They have the same type (i.e. having the same key) as @c VALUE except
5187 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5188 may be a plist of two integers specifying the range of possible
5191 If there no @c VALID-VALUE, the variable can have any value as long
5192 as the type is the same as @c VALUE.
5194 If $VARIABLE is not #Mnil, the first element of the returned plist
5195 contains the information about $VARIABLE.
5199 If the requested information was found, a pointer to a non-empty
5200 plist is returned. As the plist is kept in the library, the
5201 caller must not modify nor free it.
5203 Otherwise (the specified input method or the specified variable
5204 does not exist), @c NULL is returned. */
5206 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5208 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5209 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5210 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5212 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5213 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5214 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5215 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5218 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5219 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5221 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5223 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5225 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5228 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5230 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5233 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5234 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5235 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5236 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5237 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5238 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5240 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5241 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5242 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5244 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5245 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5246 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5247 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5249 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5252 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5253 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5257 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5258 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5261 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5265 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5267 MInputMethodInfo *im_info;
5271 im_info = get_im_info (language, name, Mnil, Mvariable);
5272 if (! im_info || ! im_info->configured_vars)
5274 if (variable == Mnil)
5275 return im_info->configured_vars;
5276 return mplist__assq (im_info->configured_vars, variable);
5282 @brief Configure the value of an input method variable.
5284 The minput_config_variable () function assigns $VALUE to the
5285 variable $VARIABLE of the input method specified by $LANGUAGE and
5288 If $VALUE is a non-empty plist, it must be a plist of one element
5289 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5290 the corresponding type. That value is assigned to the variable.
5292 If $VALUE is an empty plist, and configuration and customization
5293 of the variable are canceled, and the default value is assigned to
5296 If $VALUE is NULL, the configuration of the variable is canceled,
5297 and the original value (what saved in per-user customization file,
5298 or the default value) is assigned to the variable.
5300 In the latter two cases, $VARIABLE can be #Mnil to make all the
5301 variables of the input method the target of the operation.
5303 If $NAME is #Mnil, this function configures the value of global
5304 variable, not that of a specific input method.
5306 The configuration takes effect for input methods opened or
5307 re-opened later in the current session. To make the configuration
5308 take effect for the future session, it must be saved in a per-user
5309 customization file by the function minput_save_config ().
5313 If the operation was successful, this function returns 0,
5314 otherwise returns -1. The operation fails in these cases:
5316 <li>$VALUE is not in a valid form, the type does not match the
5317 definition, or the value is our of range.
5318 <li>$VARIABLE is not available for the input method.
5319 <li>$LANGUAGE and $NAME do not specify an existing input method.
5323 minput_get_variable (), minput_save_config (). */
5325 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5327 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5328 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5330 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5331 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5333 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5334 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5335 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5337 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5338 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5340 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5341 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5342 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5343 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5347 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5349 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5350 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5351 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5355 minput_get_commands (), minput_save_config ().
5358 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5361 MInputMethodInfo *im_info, *config;
5366 im_info = get_im_info (language, name, Mnil, Mvariable);
5368 MERROR (MERROR_IM, -1);
5369 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5371 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5372 MERROR (MERROR_IM, -1);
5374 if (value && ! MPLIST_TAIL_P (value))
5376 plist = MPLIST_PLIST (plist);
5377 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5378 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5379 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5380 if (MPLIST_KEY (plist) != Mt
5381 && ! check_variable_value (value, plist))
5382 MERROR (MERROR_IM, -1);
5385 config = get_config_info (im_info);
5388 if (! im_config_list)
5389 im_config_list = mplist ();
5390 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5391 config->cmds = mplist ();
5392 config->vars = mplist ();
5395 if (! value && MPLIST_TAIL_P (config->vars))
5396 /* Nothing to do. */
5399 if (variable == Mnil)
5403 /* Cancel the configuration. */
5404 if (MPLIST_TAIL_P (config->vars))
5406 mplist_set (config->vars, Mnil, NULL);
5410 /* Cancel the customization. */
5411 MInputMethodInfo *custom = get_custom_info (im_info);
5413 if (MPLIST_TAIL_P (config->vars)
5414 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5415 /* Nothing to do. */
5417 mplist_set (config->vars, Mnil, NULL);
5418 MPLIST_DO (plist, custom->vars)
5420 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5422 mplist_add (plist, Msymbol, variable);
5423 mplist_push (config->vars, Mplist, plist);
5424 M17N_OBJECT_UNREF (plist);
5430 plist = mplist__assq (config->vars, variable);
5433 /* Cancel the configuration. */
5436 mplist__pop_unref (plist);
5438 else if (MPLIST_TAIL_P (value))
5440 /* Cancel the customization. */
5441 MInputMethodInfo *custom = get_custom_info (im_info);
5442 int no_custom = (! custom || ! custom->vars
5443 || ! mplist__assq (custom->vars, variable));
5449 mplist_add (config->vars, Mplist, plist);
5450 M17N_OBJECT_UNREF (plist);
5451 plist = mplist_add (plist, Msymbol, variable);
5455 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5456 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5457 if (! MPLIST_TAIL_P (plist))
5459 mplist_set (plist, Mnil ,NULL);
5466 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5467 if (! MPLIST_TAIL_P (plist))
5468 mplist_set (plist, Mnil, NULL);
5473 mplist_add (config->vars, Mplist, plist);
5474 M17N_OBJECT_UNREF (plist);
5475 plist = mplist_add (plist, Msymbol, variable);
5476 plist = MPLIST_NEXT (plist);
5478 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5481 config_all_variables (im_info);
5482 im_info->tick = time (NULL);
5489 @brief Get the name of per-user customization file.
5491 The minput_config_file () function returns the absolute path name
5492 of per-user customization file into which minput_save_config ()
5493 save configurations. It is usually @c "config.mic" under the
5494 directory @c ".m17n.d" of user's home directory. It is not assured
5495 that the file of the returned name exists nor is
5496 readable/writable. If minput_save_config () fails and returns -1,
5497 an application program might check the file, make it
5498 writable (if possible), and try minput_save_config () again.
5502 This function returns a string. As the string is kept in the
5503 library, the caller must not modify nor free it.
5506 minput_save_config ()
5509 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5511 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5512 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5513 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5514 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5515 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5516 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5517 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5522 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5523 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5526 minput_save_config ()
5530 minput_config_file ()
5534 return mdatabase__file (im_custom_mdb);
5540 @brief Save configurations in per-user customization file.
5542 The minput_save_config () function saves the configurations done
5543 so far in the current session into the per-user customization
5548 If the operation was successful, 1 is returned. If the per-user
5549 customization file is currently locked, 0 is returned. In that
5550 case, the caller may wait for a while and try again. If the
5551 configuration file is not writable, -1 is returned. In that case,
5552 the caller may check the name of the file by calling
5553 minput_config_file (), make it writable if possible, and try
5557 minput_config_file () */
5559 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5561 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5562 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5566 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5567 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5568 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5569 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5573 minput_config_file () */
5576 minput_save_config (void)
5578 MPlist *data, *tail, *plist, *p, *elt;
5582 ret = mdatabase__lock (im_custom_mdb);
5585 if (! im_config_list)
5587 update_custom_info ();
5588 if (! im_custom_list)
5589 im_custom_list = mplist ();
5591 /* At first, reflect configuration in customization. */
5592 MPLIST_DO (plist, im_config_list)
5594 MPlist *pl = MPLIST_PLIST (plist);
5595 MSymbol language, name, extra, command, variable;
5596 MInputMethodInfo *custom, *config;
5598 language = MPLIST_SYMBOL (pl);
5599 pl = MPLIST_NEXT (pl);
5600 name = MPLIST_SYMBOL (pl);
5601 pl = MPLIST_NEXT (pl);
5602 extra = MPLIST_SYMBOL (pl);
5603 pl = MPLIST_NEXT (pl);
5604 config = MPLIST_VAL (pl);
5605 custom = get_custom_info (config);
5607 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5609 MPLIST_DO (pl, config->cmds)
5611 elt = MPLIST_PLIST (pl);
5612 command = MPLIST_SYMBOL (elt);
5614 p = mplist__assq (custom->cmds, command);
5616 custom->cmds = mplist (), p = NULL;
5617 elt = MPLIST_NEXT (elt);
5618 if (MPLIST_TAIL_P (elt))
5622 /* Make customization ignored. */
5623 p = MPLIST_NEXT (MPLIST_PLIST (p));
5624 mplist_set (p, Mnil, NULL);
5629 elt = MPLIST_NEXT (elt);
5632 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5633 mplist_set (p, Mnil, NULL);
5634 mplist__conc (p, elt);
5638 p = MPLIST_PLIST (pl);
5639 mplist_add (custom->cmds, Mplist, p);
5644 MPLIST_DO (pl, config->vars)
5646 elt = MPLIST_PLIST (pl);
5647 variable = MPLIST_SYMBOL (elt);
5649 p = mplist__assq (custom->vars, variable);
5651 custom->vars = mplist (), p = NULL;
5652 elt = MPLIST_NEXT (elt);
5653 if (MPLIST_TAIL_P (elt))
5656 mplist__pop_unref (p);
5660 elt = MPLIST_NEXT (elt);
5663 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5664 mplist_set (p, Mnil, NULL);
5665 mplist__conc (p, elt);
5669 p = MPLIST_PLIST (pl);
5670 mplist_add (custom->vars, Mplist, p);
5675 M17N_OBJECT_UNREF (im_config_list);
5677 /* Next, reflect customization to the actual plist to be written. */
5678 data = tail = mplist ();
5679 MPLIST_DO (plist, im_custom_list)
5681 MPlist *pl = MPLIST_PLIST (plist);
5682 MSymbol language, name, extra;
5683 MInputMethodInfo *custom, *im_info;
5685 language = MPLIST_SYMBOL (pl);
5686 pl = MPLIST_NEXT (pl);
5687 name = MPLIST_SYMBOL (pl);
5688 pl = MPLIST_NEXT (pl);
5689 extra = MPLIST_SYMBOL (pl);
5690 pl = MPLIST_NEXT (pl);
5691 custom = MPLIST_VAL (pl);
5692 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5693 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5695 im_info = lookup_im_info (im_info_list, language, name, extra);
5699 config_all_commands (im_info);
5701 config_all_variables (im_info);
5705 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5707 MPLIST_DO (p, custom->cmds)
5708 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5710 if (! MPLIST_TAIL_P (p))
5714 mplist_add (elt, Mplist, pl);
5715 M17N_OBJECT_UNREF (pl);
5716 pl = mplist_add (pl, Msymbol, Mcommand);
5717 MPLIST_DO (p, custom->cmds)
5718 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5719 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5722 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5724 MPLIST_DO (p, custom->vars)
5725 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5727 if (! MPLIST_TAIL_P (p))
5732 mplist_add (elt, Mplist, pl);
5733 M17N_OBJECT_UNREF (pl);
5734 pl = mplist_add (pl, Msymbol, Mvariable);
5735 MPLIST_DO (p, custom->vars)
5736 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5737 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5743 mplist_push (elt, Mplist, pl);
5744 M17N_OBJECT_UNREF (pl);
5745 pl = mplist_add (pl, Msymbol, Minput_method);
5746 pl = mplist_add (pl, Msymbol, language);
5747 pl = mplist_add (pl, Msymbol, name);
5749 pl = mplist_add (pl, Msymbol, extra);
5750 tail = mplist_add (tail, Mplist, elt);
5751 M17N_OBJECT_UNREF (elt);
5755 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5756 ret = mdatabase__save (im_custom_mdb, data);
5757 mdatabase__unlock (im_custom_mdb);
5758 M17N_OBJECT_UNREF (data);
5759 return (ret < 0 ? -1 : 1);
5766 @name Obsolete functions
5769 @name Obsolete ¤Ê´Ø¿ô
5775 @brief Get a list of variables of an input method (obsolete).
5777 This function is obsolete. Use minput_get_variable () instead.
5779 The minput_get_variables () function returns a plist (#MPlist) of
5780 variables used to control the behavior of the input method
5781 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5782 (#m17nPlist) of the following format:
5785 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5786 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5790 @c VARNAME is a symbol representing the variable name.
5792 @c DOC-MTEXT is an M-text describing the variable.
5794 @c DEFAULT-VALUE is the default value of the variable. It is a
5795 symbol, integer, or M-text.
5797 @c VALUEs (if any) specifies the possible values of the variable.
5798 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5799 @c TO), where @c FROM and @c TO specifies a range of possible
5802 For instance, suppose an input method has the variables:
5804 @li name:intvar, description:"value is an integer",
5805 initial value:0, value-range:0..3,10,20
5807 @li name:symvar, description:"value is a symbol",
5808 initial value:nil, value-range:a, b, c, nil
5810 @li name:txtvar, description:"value is an M-text",
5811 initial value:empty text, no value-range (i.e. any text)
5813 Then, the returned plist is as follows.
5816 (intvar ("value is an integer" 0 (0 3) 10 20)
5817 symvar ("value is a symbol" nil a b c nil)
5818 txtvar ("value is an M-text" ""))
5822 If the input method uses any variables, a pointer to #MPlist is
5823 returned. As the plist is kept in the library, the caller must not
5824 modify nor free it. If the input method does not use any
5825 variable, @c NULL is returned. */
5827 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5829 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5830 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5831 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5835 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5836 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5840 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5842 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5844 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5847 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5848 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5849 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5851 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5853 @li name:intvar, ÀâÌÀ:"value is an integer",
5854 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5856 @li name:symvar, ÀâÌÀ:"value is a symbol",
5857 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5859 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5860 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5862 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5865 (intvar ("value is an integer" 0 (0 3) 10 20)
5866 symvar ("value is a symbol" nil a b c nil)
5867 txtvar ("value is an M-text" ""))
5871 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5872 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5873 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5876 minput_get_variables (MSymbol language, MSymbol name)
5878 MInputMethodInfo *im_info;
5883 im_info = get_im_info (language, name, Mnil, Mvariable);
5884 if (! im_info || ! im_info->configured_vars)
5887 M17N_OBJECT_UNREF (im_info->bc_vars);
5888 im_info->bc_vars = mplist ();
5889 MPLIST_DO (vars, im_info->configured_vars)
5891 MPlist *plist = MPLIST_PLIST (vars);
5892 MPlist *elt = mplist ();
5894 mplist_push (im_info->bc_vars, Mplist, elt);
5895 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5896 elt = MPLIST_NEXT (elt);
5897 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5898 M17N_OBJECT_UNREF (elt);
5900 return im_info->bc_vars;
5906 @brief Set the initial value of an input method variable.
5908 The minput_set_variable () function sets the initial value of
5909 input method variable $VARIABLE to $VALUE for the input method
5910 specified by $LANGUAGE and $NAME.
5912 By default, the initial value is 0.
5914 This setting gets effective in a newly opened input method.
5917 If the operation was successful, 0 is returned. Otherwise -1 is
5918 returned, and #merror_code is set to #MERROR_IM. */
5920 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5922 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5923 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5924 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5926 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5928 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5931 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5932 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5935 minput_set_variable (MSymbol language, MSymbol name,
5936 MSymbol variable, void *value)
5939 MInputMethodInfo *im_info;
5944 if (variable == Mnil)
5945 MERROR (MERROR_IM, -1);
5946 plist = minput_get_variable (language, name, variable);
5947 plist = MPLIST_PLIST (plist);
5948 plist = MPLIST_NEXT (plist);
5950 mplist_add (pl, MPLIST_KEY (plist), value);
5951 ret = minput_config_variable (language, name, variable, pl);
5952 M17N_OBJECT_UNREF (pl);
5955 im_info = get_im_info (language, name, Mnil, Mvariable);
5964 @brief Get information about input method commands.
5966 The minput_get_commands () function returns information about
5967 input method commands of the input method specified by $LANGUAGE
5968 and $NAME. An input method command is a pseudo key event to which
5969 one or more actual input key sequences are assigned.
5971 There are two kinds of commands, global and local. Global
5972 commands are used by multiple input methods for the same purpose,
5973 and have global key assignments. Local commands are used only by
5974 a specific input method, and have only local key assignments.
5976 Each input method may locally change key assignments for global
5977 commands. The global key assignment for a global command is
5978 effective only when the current input method does not have local
5979 key assignments for that command.
5981 If $NAME is #Mnil, information about global commands is returned.
5982 In this case $LANGUAGE is ignored.
5984 If $NAME is not #Mnil, information about those commands that have
5985 local key assignments in the input method specified by $LANGUAGE
5986 and $NAME is returned.
5989 If no input method commands are found, this function returns @c NULL.
5991 Otherwise, a pointer to a plist is returned. The key of each
5992 element in the plist is a symbol representing a command, and the
5993 value is a plist of the form COMMAND-INFO described below.
5995 The first element of COMMAND-INFO has the key #Mtext, and the
5996 value is an M-text describing the command.
5998 If there are no more elements, that means no key sequences are
5999 assigned to the command. Otherwise, each of the remaining
6000 elements has the key #Mplist, and the value is a plist whose keys are
6001 #Msymbol and values are symbols representing input keys, which are
6002 currently assigned to the command.
6004 As the returned plist is kept in the library, the caller must not
6005 modify nor free it. */
6007 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6009 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6010 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6011 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6012 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6014 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6015 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6016 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6017 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6019 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6020 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6021 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6024 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6025 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6027 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6028 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6032 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6034 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6035 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6036 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6038 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6039 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6040 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6043 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6044 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6045 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6046 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6047 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6049 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6050 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6053 minput_get_commands (MSymbol language, MSymbol name)
6055 MInputMethodInfo *im_info;
6060 im_info = get_im_info (language, name, Mnil, Mcommand);
6061 if (! im_info || ! im_info->configured_vars)
6063 M17N_OBJECT_UNREF (im_info->bc_cmds);
6064 im_info->bc_cmds = mplist ();
6065 MPLIST_DO (cmds, im_info->configured_cmds)
6067 MPlist *plist = MPLIST_PLIST (cmds);
6068 MPlist *elt = mplist ();
6070 mplist_push (im_info->bc_cmds, Mplist, elt);
6071 mplist_add (elt, MPLIST_SYMBOL (plist),
6072 mplist_copy (MPLIST_NEXT (plist)));
6073 M17N_OBJECT_UNREF (elt);
6075 return im_info->bc_cmds;
6081 @brief Assign a key sequence to an input method command (obsolete).
6083 This function is obsolete. Use minput_config_command () instead.
6085 The minput_assign_command_keys () function assigns input key
6086 sequence $KEYSEQ to input method command $COMMAND for the input
6087 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6088 key sequence is assigned globally no matter what $LANGUAGE is.
6089 Otherwise the key sequence is assigned locally.
6091 Each element of $KEYSEQ must have the key $Msymbol and the value
6092 must be a symbol representing an input key.
6094 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6095 globally or locally.
6097 This assignment gets effective in a newly opened input method.
6100 If the operation was successful, 0 is returned. Otherwise -1 is
6101 returned, and #merror_code is set to #MERROR_IM. */
6103 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6105 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6106 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6107 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6108 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6109 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6111 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6112 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6114 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6115 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6117 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6120 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6121 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6124 minput_assign_command_keys (MSymbol language, MSymbol name,
6125 MSymbol command, MPlist *keyseq)
6131 if (command == Mnil)
6132 MERROR (MERROR_IM, -1);
6137 if (! check_command_keyseq (keyseq))
6138 MERROR (MERROR_IM, -1);
6140 mplist_add (plist, Mplist, keyseq);
6145 ret = minput_config_command (language, name, command, keyseq);
6146 M17N_OBJECT_UNREF (keyseq);
6153 @brief Call a callback function
6155 The minput_callback () functions calls a callback function
6156 $COMMAND assigned for the input context $IC. The caller must set
6157 specific elements in $IC->plist if the callback function requires.
6160 If there exists a specified callback function, 0 is returned.
6161 Otherwise -1 is returned. By side effects, $IC->plist may be
6165 minput_callback (MInputContext *ic, MSymbol command)
6167 MInputCallbackFunc func;
6169 if (! ic->im->driver.callback_list)
6171 func = ((MInputCallbackFunc)
6172 mplist_get_func (ic->im->driver.callback_list, command));
6175 (func) (ic, command);
6182 /*** @addtogroup m17nDebug */
6188 @brief Dump an input method.
6190 The mdebug_dump_im () function prints the input method $IM in a
6191 human readable way to the stderr. $INDENT specifies how many
6192 columns to indent the lines but the first one.
6195 This function returns $IM. */
6197 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6199 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6200 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6203 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6206 mdebug_dump_im (MInputMethod *im, int indent)
6208 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6211 prefix = (char *) alloca (indent + 1);
6212 memset (prefix, 32, indent);
6213 prefix[indent] = '\0';
6215 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6216 msymbol_name (im->name));
6217 mdebug_dump_mtext (im_info->title, 0, 0);
6218 if (im->name != Mnil)
6222 MPLIST_DO (state, im_info->states)
6224 fprintf (stderr, "\n%s ", prefix);
6225 dump_im_state (MPLIST_VAL (state), indent + 2);
6228 fprintf (stderr, ")");