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, 1);
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;
1745 MSymbol name = MPLIST_SYMBOL (plist);
1747 MPlist *description, *keyseq;
1749 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1750 global = MPLIST_NEXT (MPLIST_PLIST (global));
1752 plist = MPLIST_NEXT (plist);
1753 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1755 description = plist;
1756 plist = MPLIST_NEXT (plist);
1760 description = global;
1761 if (! MPLIST_TAIL_P (plist))
1762 plist = MPLIST_NEXT (plist);
1764 if (MPLIST_TAIL_P (plist) && global)
1766 keyseq = MPLIST_NEXT (global);
1767 status = Minherited;
1775 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1777 status = Mconfigured;
1778 config = MPLIST_NEXT (MPLIST_PLIST (config));
1779 if (! MPLIST_TAIL_P (config))
1782 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1784 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1786 if (MPLIST_TAIL_P (this_keyseq))
1787 mplist__pop_unref (custom);
1790 status = Mcustomized;
1791 keyseq = this_keyseq;
1796 mplist_add (plist, Msymbol, name);
1798 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1800 mplist_add (plist, Msymbol, Mnil);
1801 mplist_add (plist, Msymbol, status);
1802 mplist__conc (plist, keyseq);
1807 config_all_commands (MInputMethodInfo *im_info)
1809 MPlist *global_cmds, *custom_cmds, *config_cmds;
1810 MInputMethodInfo *temp;
1811 MPlist *tail, *plist;
1813 M17N_OBJECT_UNREF (im_info->configured_cmds);
1815 if (MPLIST_TAIL_P (im_info->cmds)
1819 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1820 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1821 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1823 im_info->configured_cmds = tail = mplist ();
1824 MPLIST_DO (plist, im_info->cmds)
1826 MPlist *pl = config_command (MPLIST_PLIST (plist),
1827 global_cmds, custom_cmds, config_cmds);
1830 tail = mplist_add (tail, Mplist, pl);
1831 M17N_OBJECT_UNREF (pl);
1836 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1837 valid, return 0 if not. */
1840 check_variable_value (MPlist *val, MPlist *global)
1842 MSymbol type = MPLIST_KEY (val);
1843 MPlist *valids = MPLIST_NEXT (val);
1845 if (type != Minteger && type != Mtext && type != Msymbol)
1849 if (MPLIST_KEY (global) != Mt
1850 && MPLIST_KEY (global) != MPLIST_KEY (val))
1852 if (MPLIST_TAIL_P (valids))
1853 valids = MPLIST_NEXT (global);
1855 if (MPLIST_TAIL_P (valids))
1858 if (type == Minteger)
1860 int n = MPLIST_INTEGER (val);
1862 MPLIST_DO (valids, valids)
1864 if (MPLIST_INTEGER_P (valids))
1866 if (n == MPLIST_INTEGER (valids))
1869 else if (MPLIST_PLIST_P (valids))
1871 MPlist *p = MPLIST_PLIST (valids);
1872 int min_bound, max_bound;
1874 if (! MPLIST_INTEGER_P (p))
1875 MERROR (MERROR_IM, 0);
1876 min_bound = MPLIST_INTEGER (p);
1877 p = MPLIST_NEXT (p);
1878 if (! MPLIST_INTEGER_P (p))
1879 MERROR (MERROR_IM, 0);
1880 max_bound = MPLIST_INTEGER (p);
1881 if (n >= min_bound && n <= max_bound)
1886 else if (type == Msymbol)
1888 MSymbol sym = MPLIST_SYMBOL (val);
1890 MPLIST_DO (valids, valids)
1892 if (! MPLIST_SYMBOL_P (valids))
1893 MERROR (MERROR_IM, 0);
1894 if (sym == MPLIST_SYMBOL (valids))
1900 MText *mt = MPLIST_MTEXT (val);
1902 MPLIST_DO (valids, valids)
1904 if (! MPLIST_MTEXT_P (valids))
1905 MERROR (MERROR_IM, 0);
1906 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1911 return (! MPLIST_TAIL_P (valids));
1914 /* Load variable defitions from PLIST into IM_INFO->vars.
1916 PLIST is well-formed and has this form;
1917 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1919 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1921 The returned list has the same form, but for each element...
1923 (1) If DESCRIPTION and the rest are omitted, the element is not
1924 stored in the returned list.
1926 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1927 description in global_info->vars (if any). */
1930 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1932 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1933 ? global_info->vars : NULL);
1936 im_info->vars = tail = mplist ();
1937 MPLIST_DO (plist, MPLIST_NEXT (plist))
1941 if (MFAILP (MPLIST_PLIST_P (plist)))
1943 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1944 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1946 if (im_info == global_info)
1948 /* Loading a global variable. */
1949 p = MPLIST_NEXT (pl);
1950 if (MPLIST_TAIL_P (p))
1951 mplist_add (p, Msymbol, Mnil);
1954 if (! check_description (p))
1955 mplist_set (p, Msymbol, Mnil);
1956 p = MPLIST_NEXT (p);
1957 if (MFAILP (! MPLIST_TAIL_P (p)
1958 && check_variable_value (p, NULL)))
1959 mplist_set (p, Mt, NULL);
1962 else if (im_info->mdb)
1964 /* Loading a local variable. */
1965 MSymbol name = MPLIST_SYMBOL (pl);
1966 MPlist *global = NULL;
1969 && (p = mplist__assq (global_vars, name)))
1971 /* P ::= ((NAME DESC ...) ...) */
1972 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1973 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1974 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1977 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1978 if (! MPLIST_TAIL_P (p))
1980 if (! check_description (p))
1981 mplist_set (p, Msymbol, Mnil);
1982 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1983 if (MFAILP (! MPLIST_TAIL_P (p)))
1984 mplist_set (p, Mt, NULL);
1987 MPlist *valid_values = MPLIST_NEXT (p);
1989 if (! MPLIST_TAIL_P (valid_values)
1990 ? MFAILP (check_variable_value (p, NULL))
1991 : global && MFAILP (check_variable_value (p, global)))
1992 mplist_set (p, Mt, NULL);
1998 /* Loading a variable customization. */
1999 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2000 if (MFAILP (! MPLIST_TAIL_P (p)))
2002 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2003 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2004 || MPLIST_MTEXT_P (p)))
2007 tail = mplist_add (tail, Mplist, pl);
2012 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2013 MPlist *config_vars)
2015 MPlist *global = NULL, *custom = NULL, *config = NULL;
2016 MSymbol name = MPLIST_SYMBOL (plist);
2018 MPlist *description = NULL, *value, *valids;
2022 global = mplist__assq (global_vars, name);
2024 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2027 plist = MPLIST_NEXT (plist);
2028 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2029 description = plist;
2031 description = global;
2033 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2035 if (MPLIST_TAIL_P (plist))
2037 /* Inherit from global (if any). */
2041 if (MPLIST_KEY (value) == Mt)
2043 valids = MPLIST_NEXT (global);
2044 status = Minherited;
2056 value = plist = MPLIST_NEXT (plist);
2057 valids = MPLIST_NEXT (value);
2058 if (MPLIST_KEY (value) == Mt)
2060 if (! MPLIST_TAIL_P (valids))
2063 valids = MPLIST_NEXT (global);
2067 if (config_vars && (config = mplist__assq (config_vars, name)))
2069 status = Mconfigured;
2070 config = MPLIST_NEXT (MPLIST_PLIST (config));
2071 if (! MPLIST_TAIL_P (config))
2074 if (MFAILP (check_variable_value (value, global ? global : plist)))
2078 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2080 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2082 if (MPLIST_TAIL_P (this_value))
2083 mplist__pop_unref (custom);
2087 if (MFAILP (check_variable_value (value, global ? global : plist)))
2089 status = Mcustomized;
2094 mplist_add (plist, Msymbol, name);
2096 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2098 mplist_add (plist, Msymbol, Mnil);
2099 mplist_add (plist, Msymbol, status);
2101 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2103 mplist_add (plist, Mt, NULL);
2104 if (valids && ! MPLIST_TAIL_P (valids))
2105 mplist__conc (plist, valids);
2109 /* Return a configured variable definition list based on
2110 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2111 get it from global_info->vars. */
2114 config_all_variables (MInputMethodInfo *im_info)
2116 MPlist *global_vars, *custom_vars, *config_vars;
2117 MInputMethodInfo *temp;
2118 MPlist *tail, *plist;
2120 M17N_OBJECT_UNREF (im_info->configured_vars);
2122 if (MPLIST_TAIL_P (im_info->vars)
2126 global_vars = im_info != global_info ? global_info->vars : NULL;
2127 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2128 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2130 im_info->configured_vars = tail = mplist ();
2131 MPLIST_DO (plist, im_info->vars)
2133 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2134 global_vars, custom_vars, config_vars);
2137 tail = mplist_add (tail, Mplist, pl);
2138 M17N_OBJECT_UNREF (pl);
2143 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2144 CONFIG contains configuration information of the input method. */
2147 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2151 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2153 load_commands (im_info, MPLIST_PLIST (pl));
2154 config_all_commands (im_info);
2155 pl = mplist_pop (pl);
2156 M17N_OBJECT_UNREF (pl);
2159 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2161 load_variables (im_info, MPLIST_PLIST (pl));
2162 config_all_variables (im_info);
2163 pl = mplist_pop (pl);
2164 M17N_OBJECT_UNREF (pl);
2167 MPLIST_DO (plist, plist)
2168 if (MPLIST_PLIST_P (plist))
2170 MPlist *elt = MPLIST_PLIST (plist);
2173 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2175 key = MPLIST_SYMBOL (elt);
2180 elt = MPLIST_NEXT (elt);
2181 if (MFAILP (MPLIST_MTEXT_P (elt)))
2183 im_info->title = MPLIST_MTEXT (elt);
2184 M17N_OBJECT_REF (im_info->title);
2186 else if (key == Mmap)
2188 pl = mplist__from_alist (MPLIST_NEXT (elt));
2191 if (! im_info->maps)
2195 mplist__conc (im_info->maps, pl);
2196 M17N_OBJECT_UNREF (pl);
2199 else if (key == Mmacro)
2201 if (! im_info->macros)
2202 im_info->macros = mplist ();
2203 MPLIST_DO (elt, MPLIST_NEXT (elt))
2205 if (MFAILP (MPLIST_PLIST_P (elt)))
2207 load_macros (im_info, MPLIST_PLIST (elt));
2210 else if (key == Mmodule)
2212 if (! im_info->externals)
2213 im_info->externals = mplist ();
2214 MPLIST_DO (elt, MPLIST_NEXT (elt))
2216 if (MFAILP (MPLIST_PLIST_P (elt)))
2218 load_external_module (im_info, MPLIST_PLIST (elt));
2221 else if (key == Mstate)
2223 MPLIST_DO (elt, MPLIST_NEXT (elt))
2227 if (MFAILP (MPLIST_PLIST_P (elt)))
2229 pl = MPLIST_PLIST (elt);
2230 if (! im_info->states)
2231 im_info->states = mplist ();
2232 state = load_state (im_info, MPLIST_PLIST (elt));
2235 mplist_put (im_info->states, state->name, state);
2238 else if (key == Minclude)
2240 /* elt ::= include (tag1 tag2 ...) key item ... */
2242 MInputMethodInfo *temp;
2244 elt = MPLIST_NEXT (elt);
2245 if (MFAILP (MPLIST_PLIST_P (elt)))
2247 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2250 elt = MPLIST_NEXT (elt);
2251 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2253 key = MPLIST_SYMBOL (elt);
2254 elt = MPLIST_NEXT (elt);
2257 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2259 if (! im_info->maps)
2260 im_info->maps = mplist ();
2261 MPLIST_DO (pl, temp->maps)
2263 p = MPLIST_VAL (pl);
2264 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2265 M17N_OBJECT_REF (p);
2268 else if (key == Mmacro)
2270 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2272 if (! im_info->macros)
2273 im_info->macros = mplist ();
2274 MPLIST_DO (pl, temp->macros)
2276 p = MPLIST_VAL (pl);
2277 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2278 M17N_OBJECT_REF (p);
2281 else if (key == Mstate)
2283 if (! temp->states || MPLIST_TAIL_P (temp->states))
2285 if (! im_info->states)
2286 im_info->states = mplist ();
2287 MPLIST_DO (pl, temp->states)
2289 MIMState *state = MPLIST_VAL (pl);
2291 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2292 M17N_OBJECT_REF (state);
2296 else if (key == Mdescription)
2298 if (im_info->description)
2300 elt = MPLIST_NEXT (elt);
2301 if (! check_description (elt))
2303 im_info->description = MPLIST_MTEXT (elt);
2304 M17N_OBJECT_REF (im_info->description);
2307 im_info->tick = time (NULL);
2312 static int take_action_list (MInputContext *ic, MPlist *action_list);
2313 static void preedit_commit (MInputContext *ic);
2316 shift_state (MInputContext *ic, MSymbol state_name)
2318 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2319 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2320 MIMState *orig_state = ic_info->state, *state;
2322 /* Find a state to shift to. If not found, shift to the initial
2324 if (state_name == Mt)
2326 if (! ic_info->prev_state)
2328 state = ic_info->prev_state;
2330 else if (state_name == Mnil)
2332 state = (MIMState *) MPLIST_VAL (im_info->states);
2336 state = (MIMState *) mplist_get (im_info->states, state_name);
2338 state = (MIMState *) MPLIST_VAL (im_info->states);
2341 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2343 /* Enter the new state. */
2344 ic_info->state = state;
2345 ic_info->map = state->map;
2346 ic_info->state_key_head = ic_info->key_head;
2347 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2349 /* We have shifted to the initial state. */
2350 preedit_commit (ic);
2351 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2352 ic_info->state_pos = ic->cursor_pos;
2353 if (state != orig_state)
2355 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2357 /* Shifted to the initial state. */
2358 ic_info->prev_state = NULL;
2359 M17N_OBJECT_UNREF (ic_info->vars_saved);
2360 ic_info->vars_saved = mplist_copy (ic_info->vars);
2363 ic_info->prev_state = orig_state;
2366 ic->status = state->title;
2368 ic->status = im_info->title;
2369 ic->status_changed = 1;
2370 if (ic_info->map == ic_info->state->map
2371 && ic_info->map->map_actions)
2373 MDEBUG_PRINT (" init-actions:");
2374 take_action_list (ic, ic_info->map->map_actions);
2379 /* Find a candidate group that contains a candidate number INDEX from
2380 PLIST. Set START_INDEX to the first candidate number of the group,
2381 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2382 candidate group number if they are non-NULL. If INDEX is -1, find
2383 the last candidate group. */
2386 find_candidates_group (MPlist *plist, int index,
2387 int *start_index, int *end_index, int *group_index)
2389 int i = 0, gidx = 0, len;
2391 MPLIST_DO (plist, plist)
2393 if (MPLIST_MTEXT_P (plist))
2394 len = mtext_nchars (MPLIST_MTEXT (plist));
2396 len = mplist_length (MPLIST_PLIST (plist));
2397 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2403 *end_index = i + len;
2405 *group_index = gidx;
2414 /* Adjust markers for the change of preedit text.
2415 If FROM == TO, the change is insertion of INS chars.
2416 If FROM < TO and INS == 0, the change is deletion of the range.
2417 If FROM < TO and INS > 0, the change is replacement. */
2420 adjust_markers (MInputContext *ic, int from, int to, int ins)
2422 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2427 MPLIST_DO (markers, ic_info->markers)
2428 if (MPLIST_INTEGER (markers) > from)
2429 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2430 if (ic->cursor_pos >= from)
2431 ic->cursor_pos += ins;
2435 MPLIST_DO (markers, ic_info->markers)
2437 if (MPLIST_INTEGER (markers) >= to)
2438 MPLIST_VAL (markers)
2439 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2440 else if (MPLIST_INTEGER (markers) > from)
2441 MPLIST_VAL (markers) = (void *) from;
2443 if (ic->cursor_pos >= to)
2444 ic->cursor_pos += ins - (to - from);
2445 else if (ic->cursor_pos > from)
2446 ic->cursor_pos = from;
2452 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2454 int nchars = mt ? mtext_nchars (mt) : 1;
2457 mtext_ins (ic->preedit, pos, mt);
2459 mtext_ins_char (ic->preedit, pos, c, 1);
2460 adjust_markers (ic, pos, pos, nchars);
2461 ic->preedit_changed = 1;
2466 preedit_delete (MInputContext *ic, int from, int to)
2468 mtext_del (ic->preedit, from, to);
2469 adjust_markers (ic, from, to, 0);
2470 ic->preedit_changed = 1;
2474 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2478 mtext_del (ic->preedit, from, to);
2481 mtext_ins (ic->preedit, from, mt);
2482 ins = mtext_nchars (mt);
2486 mtext_ins_char (ic->preedit, from, c, 1);
2489 adjust_markers (ic, from, to, ins);
2490 ic->preedit_changed = 1;
2495 preedit_commit (MInputContext *ic)
2497 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2498 int preedit_len = mtext_nchars (ic->preedit);
2500 if (preedit_len > 0)
2504 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2505 Mcandidate_list, NULL, 0);
2506 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2507 Mcandidate_index, NULL, 0);
2508 mtext_cat (ic->produced, ic->preedit);
2509 if (mdebug__flag & mdebug_mask)
2513 MDEBUG_PRINT (" (commit");
2514 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2515 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2519 mtext_reset (ic->preedit);
2520 mtext_reset (ic_info->preedit_saved);
2521 MPLIST_DO (p, ic_info->markers)
2523 ic->cursor_pos = ic_info->state_pos = 0;
2524 ic->preedit_changed = 1;
2525 ic_info->commit_key_head = ic_info->key_head;
2527 if (ic->candidate_list)
2529 M17N_OBJECT_UNREF (ic->candidate_list);
2530 ic->candidate_list = NULL;
2531 ic->candidate_index = 0;
2532 ic->candidate_from = ic->candidate_to = 0;
2533 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2534 if (ic->candidate_show)
2536 ic->candidate_show = 0;
2537 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2543 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2545 int code = marker_code (sym, 0);
2547 if (mt && (code == '[' || code == ']'))
2551 if (code == '[' && current > 0)
2553 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2557 else if (code == ']' && current < mtext_nchars (mt))
2559 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2565 return (code == '<' ? 0
2566 : code == '>' ? limit
2567 : code == '-' ? current - 1
2568 : code == '+' ? current + 1
2569 : code == '=' ? current
2570 : code - '0' > limit ? limit
2574 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2578 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2580 int from = mtext_property_start (prop);
2581 int to = mtext_property_end (prop);
2583 MPlist *candidate_list = mtext_property_value (prop);
2584 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2586 int ingroup_index = idx - start;
2589 if (MPLIST_MTEXT_P (group))
2591 mt = MPLIST_MTEXT (group);
2592 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2600 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2601 i++, plist = MPLIST_NEXT (plist));
2602 mt = MPLIST_MTEXT (plist);
2603 preedit_replace (ic, from, to, mt, 0);
2604 to = from + mtext_nchars (mt);
2606 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2607 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2608 ic->cursor_pos = to;
2612 get_select_charset (MInputContextInfo * ic_info)
2614 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2617 if (! MPLIST_VAL (plist))
2619 sym = MPLIST_SYMBOL (plist);
2622 return MCHARSET (sym);
2626 adjust_candidates (MPlist *plist, MCharset *charset)
2630 /* plist ::= MTEXT ... | PLIST ... */
2631 plist = mplist_copy (plist);
2632 if (MPLIST_MTEXT_P (plist))
2635 while (! MPLIST_TAIL_P (pl))
2637 /* pl ::= MTEXT ... */
2638 MText *mt = MPLIST_MTEXT (pl);
2642 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2644 c = mtext_ref_char (mt, i);
2645 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2649 mt = mtext_dup (mt);
2650 mplist_set (pl, Mtext, mt);
2651 M17N_OBJECT_UNREF (mt);
2654 mtext_del (mt, i, i + 1);
2657 if (mtext_len (mt) > 0)
2658 pl = MPLIST_NEXT (pl);
2662 M17N_OBJECT_UNREF (mt);
2666 else /* MPLIST_PLIST_P (plist) */
2669 while (! MPLIST_TAIL_P (pl))
2671 /* pl ::= (MTEXT ...) ... */
2672 MPlist *p = MPLIST_PLIST (pl);
2674 /* p ::= MTEXT ... */
2678 while (! MPLIST_TAIL_P (p0))
2680 MText *mt = MPLIST_MTEXT (p0);
2683 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2685 c = mtext_ref_char (mt, i);
2686 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2691 p0 = MPLIST_NEXT (p0);
2698 p = mplist_copy (p);
2699 mplist_set (pl, Mplist, p);
2700 M17N_OBJECT_UNREF (p);
2704 p0 = MPLIST_NEXT (p0);
2707 M17N_OBJECT_UNREF (mt);
2710 if (! MPLIST_TAIL_P (p))
2711 pl = MPLIST_NEXT (pl);
2715 M17N_OBJECT_UNREF (p);
2719 if (MPLIST_TAIL_P (plist))
2721 M17N_OBJECT_UNREF (plist);
2728 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2730 MCharset *charset = get_select_charset (ic_info);
2735 plist = resolve_variable (ic_info, Mcandidates_group_size);
2736 column = MPLIST_INTEGER (plist);
2738 plist = MPLIST_PLIST (args);
2740 plist = adjust_candidates (plist, charset);
2742 if (plist && column > 0)
2744 if (MPLIST_MTEXT_P (plist))
2746 MText *mt = MPLIST_MTEXT (plist);
2747 MPlist *next = MPLIST_NEXT (plist);
2749 if (MPLIST_TAIL_P (next))
2750 M17N_OBJECT_REF (mt);
2753 mt = mtext_dup (mt);
2754 while (! MPLIST_TAIL_P (next))
2756 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2757 next = MPLIST_NEXT (next);
2761 M17N_OBJECT_UNREF (plist);
2763 len = mtext_nchars (mt);
2765 mplist_add (plist, Mtext, mt);
2768 for (i = 0; i < len; i += column)
2770 int to = (i + column < len ? i + column : len);
2771 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2773 mplist_add (plist, Mtext, sub);
2774 M17N_OBJECT_UNREF (sub);
2777 M17N_OBJECT_UNREF (mt);
2779 else if (! MPLIST_TAIL_P (plist))
2781 MPlist *tail = plist;
2782 MPlist *new = mplist ();
2783 MPlist *this = mplist ();
2786 MPLIST_DO (tail, tail)
2788 MPlist *p = MPLIST_PLIST (tail);
2792 MText *mt = MPLIST_MTEXT (p);
2794 if (count == column)
2796 mplist_add (new, Mplist, this);
2797 M17N_OBJECT_UNREF (this);
2801 mplist_add (this, Mtext, mt);
2805 mplist_add (new, Mplist, this);
2806 M17N_OBJECT_UNREF (this);
2807 mplist_set (plist, Mnil, NULL);
2808 MPLIST_DO (tail, new)
2810 MPlist *elt = MPLIST_PLIST (tail);
2812 mplist_add (plist, Mplist, elt);
2814 M17N_OBJECT_UNREF (new);
2823 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2825 MPlist *action = NULL;
2829 if (MPLIST_SYMBOL_P (action_list))
2831 MSymbol var = MPLIST_SYMBOL (action_list);
2834 MPLIST_DO (p, ic_info->vars)
2835 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2837 if (MPLIST_TAIL_P (p))
2839 action = MPLIST_NEXT (MPLIST_PLIST (p));
2840 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2843 if (MPLIST_PLIST_P (action_list))
2845 action = MPLIST_PLIST (action_list);
2846 if (MPLIST_SYMBOL_P (action))
2848 name = MPLIST_SYMBOL (action);
2849 args = MPLIST_NEXT (action);
2851 && MPLIST_PLIST_P (args))
2852 mplist_set (action, Msymbol, M_candidates);
2854 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2857 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2858 mplist_push (action, Msymbol, M_candidates);
2859 mplist_set (action_list, Mplist, action);
2860 M17N_OBJECT_UNREF (action);
2863 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2866 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2867 mplist_push (action, Msymbol, Minsert);
2868 mplist_set (action_list, Mplist, action);
2869 M17N_OBJECT_UNREF (action);
2874 /* Perform list of actions in ACTION_LIST for the current input
2875 context IC. If unhandle action was not performed, return 0.
2876 Otherwise, return -1. */
2879 take_action_list (MInputContext *ic, MPlist *action_list)
2881 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2882 MPlist *candidate_list = ic->candidate_list;
2883 int candidate_index = ic->candidate_index;
2884 int candidate_show = ic->candidate_show;
2885 MTextProperty *prop;
2887 MPLIST_DO (action_list, action_list)
2889 MPlist *action = regularize_action (action_list, ic_info);
2895 name = MPLIST_SYMBOL (action);
2896 args = MPLIST_NEXT (action);
2898 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2899 if (name == Minsert)
2901 if (MPLIST_SYMBOL_P (args))
2903 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2904 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2907 if (MPLIST_MTEXT_P (args))
2908 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2909 else /* MPLIST_INTEGER_P (args)) */
2910 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2912 else if (name == M_candidates)
2914 MPlist *plist = get_candidate_list (ic_info, args);
2917 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2919 if (MPLIST_MTEXT_P (plist))
2921 preedit_insert (ic, ic->cursor_pos, NULL,
2922 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2925 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2929 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2931 preedit_insert (ic, ic->cursor_pos, mt, 0);
2932 len = mtext_nchars (mt);
2934 mtext_put_prop (ic->preedit,
2935 ic->cursor_pos - len, ic->cursor_pos,
2936 Mcandidate_list, plist);
2937 mtext_put_prop (ic->preedit,
2938 ic->cursor_pos - len, ic->cursor_pos,
2939 Mcandidate_index, (void *) 0);
2941 else if (name == Mselect)
2944 int code, idx, gindex;
2945 int pos = ic->cursor_pos;
2947 int idx_decided = 0;
2950 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2953 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2954 group = find_candidates_group (mtext_property_value (prop), idx,
2955 &start, &end, &gindex);
2956 if (MPLIST_SYMBOL_P (args))
2958 code = marker_code (MPLIST_SYMBOL (args), 0);
2961 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2962 if (! MPLIST_INTEGER_P (args))
2964 idx = start + MPLIST_INTEGER (args);
2965 if (idx < start || idx >= end)
2973 if (code != '[' && code != ']')
2978 ? new_index (NULL, ic->candidate_index - start,
2979 end - start - 1, MPLIST_SYMBOL (args),
2981 : MPLIST_INTEGER (args)));
2984 find_candidates_group (mtext_property_value (prop), -1,
2989 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2994 int ingroup_index = idx - start;
2997 group = mtext_property_value (prop);
2998 len = mplist_length (group);
3011 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3012 idx += (MPLIST_MTEXT_P (group)
3013 ? mtext_nchars (MPLIST_MTEXT (group))
3014 : mplist_length (MPLIST_PLIST (group)));
3015 len = (MPLIST_MTEXT_P (group)
3016 ? mtext_nchars (MPLIST_MTEXT (group))
3017 : mplist_length (MPLIST_PLIST (group)));
3018 if (ingroup_index >= len)
3019 ingroup_index = len - 1;
3020 idx += ingroup_index;
3022 update_candidate (ic, prop, idx);
3023 MDEBUG_PRINT1 ("(%d)", idx);
3025 else if (name == Mshow)
3026 ic->candidate_show = 1;
3027 else if (name == Mhide)
3028 ic->candidate_show = 0;
3029 else if (name == Mdelete)
3031 int len = mtext_nchars (ic->preedit);
3035 if (MPLIST_SYMBOL_P (args)
3036 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3038 to = ic->cursor_pos + pos;
3041 delete_surrounding_text (ic, to);
3046 delete_surrounding_text (ic, to - len);
3052 to = (MPLIST_SYMBOL_P (args)
3053 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3055 : MPLIST_INTEGER (args));
3061 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3062 if (to < ic->cursor_pos)
3063 preedit_delete (ic, to, ic->cursor_pos);
3064 else if (to > ic->cursor_pos)
3065 preedit_delete (ic, ic->cursor_pos, to);
3067 else if (name == Mmove)
3069 int len = mtext_nchars (ic->preedit);
3071 = (MPLIST_SYMBOL_P (args)
3072 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3074 : MPLIST_INTEGER (args));
3080 if (pos != ic->cursor_pos)
3082 ic->cursor_pos = pos;
3083 ic->preedit_changed = 1;
3085 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3087 else if (name == Mmark)
3089 int code = marker_code (MPLIST_SYMBOL (args), 0);
3093 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3094 (void *) ic->cursor_pos);
3095 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3098 else if (name == Mpushback)
3100 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3104 if (MPLIST_SYMBOL_P (args))
3106 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3107 if (MPLIST_INTEGER_P (args))
3108 num = MPLIST_INTEGER (args);
3113 num = MPLIST_INTEGER (args);
3116 ic_info->key_head -= num;
3118 ic_info->key_head = 0;
3120 ic_info->key_head = - num;
3121 if (ic_info->key_head > ic_info->used)
3122 ic_info->key_head = ic_info->used;
3124 else if (MPLIST_MTEXT_P (args))
3126 MText *mt = MPLIST_MTEXT (args);
3127 int i, len = mtext_nchars (mt);
3130 ic_info->key_head--;
3131 for (i = 0; i < len; i++)
3133 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3134 if (ic_info->key_head + i < ic_info->used)
3135 ic_info->keys[ic_info->key_head + i] = key;
3137 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3142 MPlist *plist = MPLIST_PLIST (args), *pl;
3146 ic_info->key_head--;
3148 MPLIST_DO (pl, plist)
3150 key = MPLIST_SYMBOL (pl);
3151 if (ic_info->key_head < ic_info->used)
3152 ic_info->keys[ic_info->key_head + i] = key;
3154 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3159 else if (name == Mpop)
3161 if (ic_info->key_head < ic_info->used)
3162 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3164 else if (name == Mcall)
3166 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3167 MIMExternalFunc func = NULL;
3168 MSymbol module, func_name;
3169 MPlist *func_args, *val;
3172 module = MPLIST_SYMBOL (args);
3173 args = MPLIST_NEXT (args);
3174 func_name = MPLIST_SYMBOL (args);
3176 if (im_info->externals)
3178 MIMExternalModule *external
3179 = (MIMExternalModule *) mplist_get (im_info->externals,
3182 func = ((MIMExternalFunc)
3183 mplist_get_func (external->func_list, func_name));
3187 func_args = mplist ();
3188 mplist_add (func_args, Mt, ic);
3189 MPLIST_DO (args, MPLIST_NEXT (args))
3193 if (MPLIST_KEY (args) == Msymbol
3194 && MPLIST_KEY (args) != Mnil
3195 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3197 code = new_index (ic, ic->cursor_pos,
3198 mtext_nchars (ic->preedit),
3199 MPLIST_SYMBOL (args), ic->preedit);
3200 mplist_add (func_args, Minteger, (void *) code);
3203 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3205 val = (func) (func_args);
3206 M17N_OBJECT_UNREF (func_args);
3207 if (val && ! MPLIST_TAIL_P (val))
3208 ret = take_action_list (ic, val);
3209 M17N_OBJECT_UNREF (val);
3213 else if (name == Mshift)
3215 shift_state (ic, MPLIST_SYMBOL (args));
3217 else if (name == Mundo)
3219 int intarg = (MPLIST_TAIL_P (args)
3221 : integer_value (ic, args, NULL, 0));
3223 mtext_reset (ic->preedit);
3224 mtext_reset (ic_info->preedit_saved);
3225 mtext_reset (ic->produced);
3226 M17N_OBJECT_UNREF (ic_info->vars);
3227 ic_info->vars = mplist_copy (ic_info->vars_saved);
3228 ic->cursor_pos = ic_info->state_pos = 0;
3229 ic_info->state_key_head = ic_info->key_head
3230 = ic_info->commit_key_head = 0;
3232 shift_state (ic, Mnil);
3235 if (MPLIST_TAIL_P (args))
3240 ic_info->used += intarg;
3243 ic_info->used = intarg;
3246 else if (name == Mset || name == Madd || name == Msub
3247 || name == Mmul || name == Mdiv)
3249 MSymbol sym = MPLIST_SYMBOL (args);
3254 val1 = integer_value (ic, args, &value, 0);
3255 args = MPLIST_NEXT (args);
3256 val2 = resolve_expression (ic, args);
3258 val1 = val2, op = "=";
3259 else if (name == Madd)
3260 val1 += val2, op = "+=";
3261 else if (name == Msub)
3262 val1 -= val2, op = "-=";
3263 else if (name == Mmul)
3264 val1 *= val2, op = "*=";
3266 val1 /= val2, op = "/=";
3267 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3268 MSYMBOL_NAME (sym), op, val1, val1);
3270 mplist_set (value, Minteger, (void *) val1);
3272 else if (name == Mequal || name == Mless || name == Mgreater
3273 || name == Mless_equal || name == Mgreater_equal)
3276 MPlist *actions1, *actions2;
3279 val1 = resolve_expression (ic, args);
3280 args = MPLIST_NEXT (args);
3281 val2 = resolve_expression (ic, args);
3282 args = MPLIST_NEXT (args);
3283 actions1 = MPLIST_PLIST (args);
3284 args = MPLIST_NEXT (args);
3285 if (MPLIST_TAIL_P (args))
3288 actions2 = MPLIST_PLIST (args);
3289 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3290 if (name == Mequal ? val1 == val2
3291 : name == Mless ? val1 < val2
3292 : name == Mgreater ? val1 > val2
3293 : name == Mless_equal ? val1 <= val2
3296 MDEBUG_PRINT ("ok");
3297 ret = take_action_list (ic, actions1);
3301 MDEBUG_PRINT ("no");
3303 ret = take_action_list (ic, actions2);
3308 else if (name == Mcond)
3312 MPLIST_DO (args, args)
3317 if (! MPLIST_PLIST (args))
3319 cond = MPLIST_PLIST (args);
3320 if (resolve_expression (ic, cond) != 0)
3322 MDEBUG_PRINT1 ("(%dth)", idx);
3323 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3329 else if (name == Mcommit)
3331 preedit_commit (ic);
3333 else if (name == Munhandle)
3335 preedit_commit (ic);
3340 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3344 && (actions = mplist_get (im_info->macros, name)))
3346 if (take_action_list (ic, actions) < 0)
3352 if (ic->candidate_list)
3354 M17N_OBJECT_UNREF (ic->candidate_list);
3355 ic->candidate_list = NULL;
3357 if (ic->cursor_pos > 0
3358 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3361 ic->candidate_list = mtext_property_value (prop);
3362 M17N_OBJECT_REF (ic->candidate_list);
3364 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3366 ic->candidate_from = mtext_property_start (prop);
3367 ic->candidate_to = mtext_property_end (prop);
3370 if (candidate_list != ic->candidate_list)
3371 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3372 if (candidate_index != ic->candidate_index)
3373 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3374 if (candidate_show != ic->candidate_show)
3375 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3380 /* Handle the input key KEY in the current state and map specified in
3381 the input context IC. If KEY is handled correctly, return 0.
3382 Otherwise, return -1. */
3385 handle_key (MInputContext *ic)
3387 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3388 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3389 MIMMap *map = ic_info->map;
3390 MIMMap *submap = NULL;
3391 MSymbol key = ic_info->keys[ic_info->key_head];
3392 MSymbol alias = Mnil;
3395 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3396 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3400 submap = mplist_get (map->submaps, key);
3403 && (alias = msymbol_get (alias, M_key_alias))
3405 submap = mplist_get (map->submaps, alias);
3410 if (! alias || alias == key)
3411 MDEBUG_PRINT (" submap-found");
3413 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3414 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3415 ic->preedit_changed = 1;
3416 ic->cursor_pos = ic_info->state_pos;
3417 ic_info->key_head++;
3418 ic_info->map = map = submap;
3419 if (map->map_actions)
3421 MDEBUG_PRINT (" map-actions:");
3422 if (take_action_list (ic, map->map_actions) < 0)
3424 MDEBUG_PRINT ("\n");
3428 else if (map->submaps)
3430 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3432 MSymbol key = ic_info->keys[i];
3433 char *name = msymbol_name (key);
3435 if (! name[0] || ! name[1])
3436 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3440 /* If this is the terminal map or we have shifted to another
3441 state, perform branch actions (if any). */
3442 if (! map->submaps || map != ic_info->map)
3444 if (map->branch_actions)
3446 MDEBUG_PRINT (" branch-actions:");
3447 if (take_action_list (ic, map->branch_actions) < 0)
3449 MDEBUG_PRINT ("\n");
3453 /* If MAP is still not the root map, shift to the current
3455 if (ic_info->map != ic_info->state->map)
3456 shift_state (ic, ic_info->state->name);
3461 /* MAP can not handle KEY. */
3463 /* Perform branch actions if any. */
3464 if (map->branch_actions)
3466 MDEBUG_PRINT (" branch-actions:");
3467 if (take_action_list (ic, map->branch_actions) < 0)
3469 MDEBUG_PRINT ("\n");
3474 if (map == ic_info->map)
3476 /* The above branch actions didn't change the state. */
3478 /* If MAP is the root map of the initial state, and there
3479 still exist an unhandled key, it means that the current
3480 input method can not handle it. */
3481 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3482 && ic_info->key_head < ic_info->used)
3484 MDEBUG_PRINT (" unhandled\n");
3488 if (map != ic_info->state->map)
3490 /* MAP is not the root map. Shift to the root map of the
3492 shift_state (ic, ic_info->state->name);
3494 else if (! map->branch_actions)
3496 /* MAP is the root map without any default branch
3497 actions. Shift to the initial state. */
3498 shift_state (ic, Mnil);
3502 MDEBUG_PRINT ("\n");
3506 /* Initialize IC->ic_info. */
3509 init_ic_info (MInputContext *ic)
3511 MInputMethodInfo *im_info = ic->im->info;
3512 MInputContextInfo *ic_info = ic->info;
3515 MLIST_INIT1 (ic_info, keys, 8);;
3517 ic_info->markers = mplist ();
3519 ic_info->vars = mplist ();
3520 if (im_info->configured_vars)
3521 MPLIST_DO (plist, im_info->configured_vars)
3523 MPlist *pl = MPLIST_PLIST (plist);
3524 MSymbol name = MPLIST_SYMBOL (pl);
3526 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3527 if (MPLIST_KEY (pl) != Mt)
3529 MPlist *p = mplist ();
3531 mplist_push (ic_info->vars, Mplist, p);
3532 M17N_OBJECT_UNREF (p);
3533 mplist_add (p, Msymbol, name);
3534 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3537 ic_info->vars_saved = mplist_copy (ic_info->vars);
3539 if (im_info->externals)
3541 MPlist *func_args = mplist (), *plist;
3543 mplist_add (func_args, Mt, ic);
3544 MPLIST_DO (plist, im_info->externals)
3546 MIMExternalModule *external = MPLIST_VAL (plist);
3547 MIMExternalFunc func
3548 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3553 M17N_OBJECT_UNREF (func_args);
3556 ic_info->preedit_saved = mtext ();
3557 ic_info->tick = im_info->tick;
3560 /* Finalize IC->ic_info. */
3563 fini_ic_info (MInputContext *ic)
3565 MInputMethodInfo *im_info = ic->im->info;
3566 MInputContextInfo *ic_info = ic->info;
3568 if (im_info->externals)
3570 MPlist *func_args = mplist (), *plist;
3572 mplist_add (func_args, Mt, ic);
3573 MPLIST_DO (plist, im_info->externals)
3575 MIMExternalModule *external = MPLIST_VAL (plist);
3576 MIMExternalFunc func
3577 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3582 M17N_OBJECT_UNREF (func_args);
3585 MLIST_FREE1 (ic_info, keys);
3586 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3587 M17N_OBJECT_UNREF (ic_info->markers);
3588 M17N_OBJECT_UNREF (ic_info->vars);
3589 M17N_OBJECT_UNREF (ic_info->vars_saved);
3590 M17N_OBJECT_UNREF (ic_info->preceding_text);
3591 M17N_OBJECT_UNREF (ic_info->following_text);
3593 memset (ic_info, 0, sizeof (MInputContextInfo));
3597 re_init_ic (MInputContext *ic, int reload)
3599 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3600 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3601 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3603 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3604 preedit_changed = mtext_nchars (ic->preedit) > 0;
3605 cursor_pos_changed = ic->cursor_pos > 0;
3606 candidates_changed = 0;
3607 if (ic->candidate_list)
3609 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3610 M17N_OBJECT_UNREF (ic->candidate_list);
3611 ic->candidate_list = NULL;
3613 if (ic->candidate_show)
3615 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3616 ic->candidate_show = 0;
3618 if (ic->candidate_index > 0)
3620 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3621 ic->candidate_index = 0;
3622 ic->candidate_from = ic->candidate_to = 0;
3624 if (mtext_nchars (ic->produced) > 0)
3625 mtext_reset (ic->produced);
3626 if (mtext_nchars (ic->preedit) > 0)
3627 mtext_reset (ic->preedit);
3629 M17N_OBJECT_UNREF (ic->plist);
3630 ic->plist = mplist ();
3634 reload_im_info (im_info);
3636 shift_state (ic, Mnil);
3637 ic->status_changed = status_changed;
3638 ic->preedit_changed = preedit_changed;
3639 ic->cursor_pos_changed = cursor_pos_changed;
3640 ic->candidates_changed = candidates_changed;
3644 reset_ic (MInputContext *ic, MSymbol ignore)
3646 MDEBUG_PRINT ("\n [IM] reset\n");
3651 open_im (MInputMethod *im)
3653 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3656 MERROR (MERROR_IM, -1);
3663 close_im (MInputMethod *im)
3669 create_ic (MInputContext *ic)
3671 MInputContextInfo *ic_info;
3673 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3676 shift_state (ic, Mnil);
3681 destroy_ic (MInputContext *ic)
3688 check_reload (MInputContext *ic, MSymbol key)
3690 MInputMethodInfo *im_info = ic->im->info;
3691 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3695 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3699 MPLIST_DO (plist, plist)
3701 MSymbol this_key, alias;
3703 if (MPLIST_MTEXT_P (plist))
3705 MText *mt = MPLIST_MTEXT (plist);
3706 int c = mtext_ref_char (mt, 0);
3710 this_key = one_char_symbol[c];
3714 MPlist *pl = MPLIST_PLIST (plist);
3716 this_key = MPLIST_SYMBOL (pl);
3720 && (alias = msymbol_get (alias, M_key_alias))
3721 && alias != this_key);
3725 if (MPLIST_TAIL_P (plist))
3728 MDEBUG_PRINT ("\n [IM] reload");
3734 /** Handle the input key KEY in the current state and map of IC->info.
3735 If KEY is handled but no text is produced, return 0, otherwise
3741 filter (MInputContext *ic, MSymbol key, void *arg)
3743 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3744 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3747 if (check_reload (ic, key))
3750 if (! ic_info->state)
3752 ic_info->key_unhandled = 1;
3755 mtext_reset (ic->produced);
3756 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3757 M17N_OBJECT_UNREF (ic_info->preceding_text);
3758 M17N_OBJECT_UNREF (ic_info->following_text);
3759 ic_info->preceding_text = ic_info->following_text = NULL;
3760 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3761 ic_info->key_unhandled = 0;
3764 if (handle_key (ic) < 0)
3766 /* KEY was not handled. Delete it from the current key sequence. */
3767 if (ic_info->used > 0)
3769 memmove (ic_info->keys, ic_info->keys + 1,
3770 sizeof (int) * (ic_info->used - 1));
3772 if (ic_info->state_key_head > 0)
3773 ic_info->state_key_head--;
3774 if (ic_info->commit_key_head > 0)
3775 ic_info->commit_key_head--;
3777 /* This forces returning 1. */
3778 ic_info->key_unhandled = 1;
3784 reset_ic (ic, Mnil);
3785 ic_info->key_unhandled = 1;
3788 /* Break the loop if all keys were handled. */
3789 } while (ic_info->key_head < ic_info->used);
3791 /* If the current map is the root of the initial state, we should
3792 produce any preedit text in ic->produced. */
3793 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3794 preedit_commit (ic);
3796 if (mtext_nchars (ic->produced) > 0)
3798 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3800 if (mdebug__flag & mdebug_mask)
3802 MDEBUG_PRINT (" (produced");
3803 for (i = 0; i < mtext_nchars (ic->produced); i++)
3804 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3809 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3810 Mlanguage, ic->im->language);
3812 if (ic_info->commit_key_head > 0)
3814 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3815 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3816 ic_info->used -= ic_info->commit_key_head;
3817 ic_info->key_head -= ic_info->commit_key_head;
3818 ic_info->state_key_head -= ic_info->commit_key_head;
3819 ic_info->commit_key_head = 0;
3821 if (ic_info->key_unhandled)
3824 ic_info->key_head = ic_info->state_key_head
3825 = ic_info->commit_key_head = 0;
3828 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3832 /** Return 1 if the last event or key was not handled, otherwise
3835 There is no need of looking up because ic->produced should already
3836 contain the produced text (if any).
3841 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3843 mtext_cat (mt, ic->produced);
3844 mtext_reset (ic->produced);
3845 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3849 /* Input method command handler. */
3851 /* List of all (global and local) commands.
3852 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3853 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3854 Global commands are stored as (t (t COMMAND ...)) */
3857 /* Input method variable handler. */
3860 /* Support functions for mdebug_dump_im. */
3863 dump_im_map (MPlist *map_list, int indent)
3866 MSymbol key = MPLIST_KEY (map_list);
3867 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3869 prefix = (char *) alloca (indent + 1);
3870 memset (prefix, 32, indent);
3871 prefix[indent] = '\0';
3873 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3874 if (map->map_actions)
3875 mdebug_dump_plist (map->map_actions, indent + 2);
3878 MPLIST_DO (map_list, map->submaps)
3880 fprintf (stderr, "\n%s ", prefix);
3881 dump_im_map (map_list, indent + 2);
3884 if (map->branch_actions)
3886 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3887 mdebug_dump_plist (map->branch_actions, indent + 4);
3888 fprintf (stderr, ")");
3890 fprintf (stderr, ")");
3895 dump_im_state (MIMState *state, int indent)
3900 prefix = (char *) alloca (indent + 1);
3901 memset (prefix, 32, indent);
3902 prefix[indent] = '\0';
3904 fprintf (stderr, "(%s", msymbol_name (state->name));
3905 if (state->map->submaps)
3907 MPLIST_DO (map_list, state->map->submaps)
3909 fprintf (stderr, "\n%s ", prefix);
3910 dump_im_map (map_list, indent + 2);
3913 fprintf (stderr, ")");
3921 Minput_driver = msymbol ("input-driver");
3923 Minput_preedit_start = msymbol ("input-preedit-start");
3924 Minput_preedit_done = msymbol ("input-preedit-done");
3925 Minput_preedit_draw = msymbol ("input-preedit-draw");
3926 Minput_status_start = msymbol ("input-status-start");
3927 Minput_status_done = msymbol ("input-status-done");
3928 Minput_status_draw = msymbol ("input-status-draw");
3929 Minput_candidates_start = msymbol ("input-candidates-start");
3930 Minput_candidates_done = msymbol ("input-candidates-done");
3931 Minput_candidates_draw = msymbol ("input-candidates-draw");
3932 Minput_set_spot = msymbol ("input-set-spot");
3933 Minput_focus_move = msymbol ("input-focus-move");
3934 Minput_focus_in = msymbol ("input-focus-in");
3935 Minput_focus_out = msymbol ("input-focus-out");
3936 Minput_toggle = msymbol ("input-toggle");
3937 Minput_reset = msymbol ("input-reset");
3938 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3939 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3940 Mcustomized = msymbol ("customized");
3941 Mconfigured = msymbol ("configured");
3942 Minherited = msymbol ("inherited");
3944 minput_default_driver.open_im = open_im;
3945 minput_default_driver.close_im = close_im;
3946 minput_default_driver.create_ic = create_ic;
3947 minput_default_driver.destroy_ic = destroy_ic;
3948 minput_default_driver.filter = filter;
3949 minput_default_driver.lookup = lookup;
3950 minput_default_driver.callback_list = mplist ();
3951 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
3952 M17N_FUNC (reset_ic));
3953 minput_driver = &minput_default_driver;
3955 fully_initialized = 0;
3962 if (fully_initialized)
3964 free_im_list (im_info_list);
3966 free_im_list (im_custom_list);
3968 free_im_list (im_config_list);
3969 M17N_OBJECT_UNREF (load_im_info_keys);
3972 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3973 M17N_OBJECT_UNREF (minput_driver->callback_list);
3978 minput__char_to_key (int c)
3980 if (c < 0 || c >= 0x100)
3983 return one_char_symbol[c];
3987 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3992 /*** @addtogroup m17nInputMethod */
3997 @name Variables: Predefined symbols for callback commands.
3999 These are the predefined symbols that are used as the @c COMMAND
4000 argument of callback functions of an input method driver (see
4001 #MInputDriver::callback_list).
4003 Most of them do not require extra argument nor return any value;
4004 exceptions are these:
4006 Minput_get_surrounding_text: When a callback function assigned for
4007 this command is called, the first element of #MInputContext::plist
4008 has key #Minteger and the value specifies which portion of the
4009 surrounding text should be retrieved. If the value is positive,
4010 it specifies the number of characters following the current cursor
4011 position. If the value is negative, the absolute value specifies
4012 the number of characters preceding the current cursor position.
4013 If the value is zero, it means that the caller just wants to know
4014 if the surrounding text is currently supported or not.
4016 If the surrounding text is currently supported, the callback
4017 function must set the key of this element to #Mtext and the value
4018 to the retrieved M-text. The length of the M-text may be shorter
4019 than the requested number of characters, if the available text is
4020 not that long. The length can be zero in the worst case. Or, the
4021 length may be longer if an application thinks it is more efficient
4022 to return that length.
4024 If the surrounding text is not currently supported, the callback
4025 function should return without changing the first element of
4026 #MInputContext::plist.
4028 Minput_delete_surrounding_text: When a callback function assigned
4029 for this command is called, the first element of
4030 #MInputContext::plist has key #Minteger and the value specifies
4031 which portion of the surrounding text should be deleted in the
4032 same way as the case of Minput_get_surrounding_text. The callback
4033 function must delete the specified text. It should not alter
4034 #MInputContext::plist. */
4036 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4038 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4039 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4041 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4043 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4044 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4045 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4046 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4047 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4048 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4049 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4051 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4052 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4053 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4054 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4055 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4057 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4058 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4060 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4061 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4062 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4063 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4064 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4065 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4069 MSymbol Minput_preedit_start;
4070 MSymbol Minput_preedit_done;
4071 MSymbol Minput_preedit_draw;
4072 MSymbol Minput_status_start;
4073 MSymbol Minput_status_done;
4074 MSymbol Minput_status_draw;
4075 MSymbol Minput_candidates_start;
4076 MSymbol Minput_candidates_done;
4077 MSymbol Minput_candidates_draw;
4078 MSymbol Minput_set_spot;
4079 MSymbol Minput_toggle;
4080 MSymbol Minput_reset;
4081 MSymbol Minput_get_surrounding_text;
4082 MSymbol Minput_delete_surrounding_text;
4088 @name Variables: Predefined symbols for special input events.
4090 These are the predefined symbols that are used as the @c KEY
4091 argument of minput_filter (). */
4093 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4095 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4100 MSymbol Minput_focus_out;
4101 MSymbol Minput_focus_in;
4102 MSymbol Minput_focus_move;
4108 @name Variables: Predefined symbols used in input method information.
4110 These are the predefined symbols describing status of input method
4111 command and variable, and are used in a return value of
4112 minput_get_command () and minput_get_variable (). */
4114 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4116 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4117 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4121 MSymbol Mcustomized;
4122 MSymbol Mconfigured;
4128 @brief The default driver for internal input methods.
4130 The variable #minput_default_driver is the default driver for
4131 internal input methods.
4133 The member MInputDriver::open_im () searches the m17n database for
4134 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4135 $NAME\> and loads it.
4137 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4138 programmers responsibility to set it to a plist of proper callback
4139 functions. Otherwise, no feedback information (e.g. preedit text)
4140 can be shown to users.
4142 The macro M17N_INIT () sets the variable #minput_driver to the
4143 pointer to this driver so that all internal input methods use it.
4145 Therefore, unless @c minput_driver is set differently, the driver
4146 dependent arguments $ARG of the functions whose name begins with
4147 "minput_" are all ignored. */
4149 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4151 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4153 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4154 \< #Minput_method, $LANGUAGE, $NAME\>
4155 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4157 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4158 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4159 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4160 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4162 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4163 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4165 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4166 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4168 MInputDriver minput_default_driver;
4172 @brief The driver for internal input methods.
4174 The variable #minput_driver is a pointer to the input method
4175 driver that is used by internal input methods. The macro
4176 M17N_INIT () initializes it to a pointer to #minput_default_driver
4177 if <m17n<EM></EM>.h> is included. */
4179 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4181 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4182 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4183 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4184 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4186 MInputDriver *minput_driver;
4188 MSymbol Minput_driver;
4203 @brief Open an input method.
4205 The minput_open_im () function opens an input method whose
4206 language and name match $LANGUAGE and $NAME, and returns a pointer
4207 to the input method object newly allocated.
4209 This function at first decides a driver for the input method as
4212 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4213 #minput_driver is used.
4215 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4216 driver pointed to by the property value is used to open the input
4217 method. If $NAME has no such a property, @c NULL is returned.
4219 Then, the member MInputDriver::open_im () of the driver is
4222 $ARG is set in the member @c arg of the structure MInputMethod so
4223 that the driver can refer to it. */
4225 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4227 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4228 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4230 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4232 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4233 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4235 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4236 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4237 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4239 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4241 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4243 @latexonly \IPAlabel{minput_open} @endlatexonly
4248 minput_open_im (MSymbol language, MSymbol name, void *arg)
4251 MInputDriver *driver;
4255 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4256 msymbol_name (language), msymbol_name (name));
4258 driver = minput_driver;
4261 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4263 MERROR (MERROR_IM, NULL);
4266 MSTRUCT_CALLOC (im, MERROR_IM);
4267 im->language = language;
4270 im->driver = *driver;
4271 if ((*im->driver.open_im) (im) < 0)
4273 MDEBUG_PRINT (" failed\n");
4277 MDEBUG_PRINT (" ok\n");
4284 @brief Close an input method.
4286 The minput_close_im () function closes the input method $IM, which
4287 must have been created by minput_open_im (). */
4290 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4292 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4293 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4296 minput_close_im (MInputMethod *im)
4298 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4299 msymbol_name (im->name), msymbol_name (im->language));
4300 (*im->driver.close_im) (im);
4302 MDEBUG_PRINT (" done\n");
4308 @brief Create an input context.
4310 The minput_create_ic () function creates an input context object
4311 associated with input method $IM, and calls callback functions
4312 corresponding to #Minput_preedit_start, #Minput_status_start, and
4313 #Minput_status_draw in this order.
4316 If an input context is successfully created, minput_create_ic ()
4317 returns a pointer to it. Otherwise it returns @c NULL. */
4320 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4322 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4323 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4324 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4325 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4328 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4329 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4333 minput_create_ic (MInputMethod *im, void *arg)
4337 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4338 msymbol_name (im->name), msymbol_name (im->language));
4339 MSTRUCT_CALLOC (ic, MERROR_IM);
4342 ic->preedit = mtext ();
4343 ic->candidate_list = NULL;
4344 ic->produced = mtext ();
4345 ic->spot.x = ic->spot.y = 0;
4347 ic->plist = mplist ();
4348 if ((*im->driver.create_ic) (ic) < 0)
4350 MDEBUG_PRINT (" failed\n");
4351 M17N_OBJECT_UNREF (ic->preedit);
4352 M17N_OBJECT_UNREF (ic->produced);
4353 M17N_OBJECT_UNREF (ic->plist);
4358 if (im->driver.callback_list)
4360 minput_callback (ic, Minput_preedit_start);
4361 minput_callback (ic, Minput_status_start);
4362 minput_callback (ic, Minput_status_draw);
4365 MDEBUG_PRINT (" ok\n");
4372 @brief Destroy an input context.
4374 The minput_destroy_ic () function destroys the input context $IC,
4375 which must have been created by minput_create_ic (). It calls
4376 callback functions corresponding to #Minput_preedit_done,
4377 #Minput_status_done, and #Minput_candidates_done in this order. */
4380 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4382 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4383 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4384 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4385 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4386 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4390 minput_destroy_ic (MInputContext *ic)
4392 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4393 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4394 if (ic->im->driver.callback_list)
4396 minput_callback (ic, Minput_preedit_done);
4397 minput_callback (ic, Minput_status_done);
4398 minput_callback (ic, Minput_candidates_done);
4400 (*ic->im->driver.destroy_ic) (ic);
4401 M17N_OBJECT_UNREF (ic->preedit);
4402 M17N_OBJECT_UNREF (ic->produced);
4403 M17N_OBJECT_UNREF (ic->plist);
4404 MDEBUG_PRINT (" done\n");
4411 @brief Filter an input key.
4413 The minput_filter () function filters input key $KEY according to
4414 input context $IC, and calls callback functions corresponding to
4415 #Minput_preedit_draw, #Minput_status_draw, and
4416 #Minput_candidates_draw if the preedit text, the status, and the
4417 current candidate are changed respectively.
4419 To make the input method commit the current preedit text (if any)
4420 and shift to the initial state, call this function with #Mnil as
4423 To inform the input method about the focus-out event, call this
4424 function with #Minput_focus_out as $KEY.
4426 To inform the input method about the focus-in event, call this
4427 function with #Minput_focus_in as $KEY.
4429 To inform the input method about the focus-move event (i.e. input
4430 spot change within the same input context), call this function
4431 with #Minput_focus_move as $KEY.
4434 If $KEY is filtered out, this function returns 1. In that case,
4435 the caller should discard the key. Otherwise, it returns 0, and
4436 the caller should handle the key, for instance, by calling the
4437 function minput_lookup () with the same key. */
4440 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4442 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4443 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4444 #Minput_preedit_draw, #Minput_status_draw,
4445 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4448 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4449 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4450 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4451 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4453 @latexonly \IPAlabel{minput_filter} @endlatexonly
4457 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4464 if (ic->im->driver.callback_list
4465 && mtext_nchars (ic->preedit) > 0)
4466 minput_callback (ic, Minput_preedit_draw);
4468 ret = (*ic->im->driver.filter) (ic, key, arg);
4470 if (ic->im->driver.callback_list)
4472 if (ic->preedit_changed)
4473 minput_callback (ic, Minput_preedit_draw);
4474 if (ic->status_changed)
4475 minput_callback (ic, Minput_status_draw);
4476 if (ic->candidates_changed)
4477 minput_callback (ic, Minput_candidates_draw);
4486 @brief Look up a text produced in the input context.
4488 The minput_lookup () function looks up a text in the input context
4489 $IC. $KEY must be identical to the one that was used in the previous call of
4492 If a text was produced by the input method, it is concatenated
4495 This function calls #MInputDriver::lookup .
4498 If $KEY was correctly handled by the input method, this function
4499 returns 0. Otherwise, it returns -1, even though some text
4500 might be produced in $MT. */
4503 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4505 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4506 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4508 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4511 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4514 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4515 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4516 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4518 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4521 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4523 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4528 @brief Set the spot of the input context.
4530 The minput_set_spot () function sets the spot of input context $IC
4531 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4532 The semantics of these values depends on the input method driver.
4534 For instance, a driver designed to work in a CUI environment may
4535 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4536 $DESCENT . A driver designed to work in a window system may
4537 interpret $X and $Y as the pixel offsets relative to the origin of the
4538 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4539 descent pixels of the line at ($X . $Y ).
4541 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4543 $MT and $POS are the M-text and the character position at the spot.
4544 $MT may be @c NULL, in which case, the input method cannot get
4545 information about the text around the spot. */
4548 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4550 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4551 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4552 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4554 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4555 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4556 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4557 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4558 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4559 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4561 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4563 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4564 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4568 minput_set_spot (MInputContext *ic, int x, int y,
4569 int ascent, int descent, int fontsize,
4574 ic->spot.ascent = ascent;
4575 ic->spot.descent = descent;
4576 ic->spot.fontsize = fontsize;
4579 if (ic->im->driver.callback_list)
4580 minput_callback (ic, Minput_set_spot);
4585 @brief Toggle input method.
4587 The minput_toggle () function toggles the input method associated
4588 with input context $IC. */
4590 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4592 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4593 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4597 minput_toggle (MInputContext *ic)
4599 if (ic->im->driver.callback_list)
4600 minput_callback (ic, Minput_toggle);
4601 ic->active = ! ic->active;
4607 @brief Reset an input context.
4609 The minput_reset_ic () function resets input context $IC by
4610 calling a callback function corresponding to #Minput_reset. It
4611 resets the status of $IC to its initial one. As the
4612 current preedit text is deleted without commitment, if necessary,
4613 call minput_filter () with the arg @r key #Mnil to force the input
4614 method to commit the preedit in advance. */
4617 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4619 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4620 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4621 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4622 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4623 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4624 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4627 minput_reset_ic (MInputContext *ic)
4629 if (ic->im->driver.callback_list)
4630 minput_callback (ic, Minput_reset);
4636 @brief Get title and icon filename of an input method.
4638 The minput_get_title_icon () function returns a plist containing a
4639 title and icon filename (if any) of an input method specified by
4640 $LANGUAGE and $NAME.
4642 The first element of the plist has key #Mtext and the value is an
4643 M-text of the title for identifying the input method. The second
4644 element (if any) has key #Mtext and the value is an M-text of the
4645 icon image (absolute) filename for the same purpose.
4648 If there exists a specified input method and it defines an title,
4649 a plist is returned. Otherwise, NULL is returned. The caller
4650 must free the plist by m17n_object_unref (). */
4652 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4654 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4655 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4658 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4659 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4660 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4663 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4664 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4665 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4668 minput_get_title_icon (MSymbol language, MSymbol name)
4670 MInputMethodInfo *im_info;
4677 im_info = get_im_info (language, name, Mnil, Mtitle);
4678 if (! im_info || !im_info->title)
4680 mt = mtext_get_prop (im_info->title, 0, Mtext);
4682 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4685 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4688 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4689 (char *) MSYMBOL_NAME (name));
4690 file = mdatabase__find_file (buf);
4691 if (! file && language == Mt)
4693 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4694 file = mdatabase__find_file (buf);
4699 mplist_add (plist, Mtext, im_info->title);
4702 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4704 mplist_add (plist, Mtext, mt);
4705 M17N_OBJECT_UNREF (mt);
4713 @brief Get description text of an input method.
4715 The minput_get_description () function returns an M-text that
4716 describes the input method specified by $LANGUAGE and $NAME.
4719 If the specified input method has a description text, a pointer to
4720 #MText is returned. The caller has to free it by m17n_object_unref ().
4721 If the input method does not have a description text, @c NULL is
4724 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4726 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4727 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4729 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4730 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4731 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4732 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4735 minput_get_description (MSymbol language, MSymbol name)
4737 MInputMethodInfo *im_info;
4745 extra = language, language = Mt;
4747 im_info = get_im_info (language, name, extra, Mdescription);
4748 if (! im_info || ! im_info->description)
4750 M17N_OBJECT_REF (im_info->description);
4751 return im_info->description;
4757 @brief Get information about input method command(s).
4759 The minput_get_command () function returns information about
4760 the command $COMMAND of the input method specified by $LANGUAGE and
4761 $NAME. An input method command is a pseudo key event to which one
4762 or more actual input key sequences are assigned.
4764 There are two kinds of commands, global and local. A global
4765 command has a global definition, and the description and the key
4766 assignment may be inherited by a local command. Each input method
4767 defines a local command which has a local key assignment. It may
4768 also declare a local command that inherits the definition of a
4769 global command of the same name.
4771 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4772 information about a global command. Otherwise information about a
4773 local command is returned.
4775 If $COMMAND is #Mnil, information about all commands is returned.
4777 The return value is a @e well-formed plist (#m17nPlist) of this
4780 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4782 @c NAME is a symbol representing the command name.
4784 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4785 command has no description.
4787 @c STATUS is a symbol representing how the key assignment is decided.
4788 The value is #Mnil (the default key assignment), #Mcustomized (the
4789 key assignment is customized by per-user customization file), or
4790 #Mconfigured (the key assignment is set by the call of
4791 minput_config_command ()). For a local command only, it may also
4792 be #Minherited (the key assignment is inherited from the
4793 corresponding global command).
4795 @c KEYSEQ is a plist of one or more symbols representing a key
4796 sequence assigned to the command. If there's no KEYSEQ, the
4797 command is currently disabled (i.e. no key sequence can trigger
4798 actions of the command).
4800 If $COMMAND is not #Mnil, the first element of the returned plist
4801 contains the information about $COMMAND.
4805 If the requested information was found, a pointer to a non-empty
4806 plist is returned. As the plist is kept in the library, the
4807 caller must not modify nor free it.
4809 Otherwise (the specified input method or the specified command
4810 does not exist), @c NULL is returned. */
4812 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4814 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4815 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4816 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4817 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4819 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4820 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4821 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4822 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4823 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4825 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4826 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4829 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4831 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4834 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4836 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4838 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4841 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4842 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4843 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4844 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4845 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4846 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4849 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4850 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4851 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4852 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4854 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4855 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4859 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4860 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4863 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4868 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4870 /* Return a description of the command COMMAND of the input method
4871 specified by LANGUAGE and NAME. */
4872 MPlist *cmd = minput_get_command (langauge, name, command);
4877 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4878 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4879 return (mplist_key (plist) == Mtext
4880 ? (MText *) mplist_value (plist)
4886 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4888 MInputMethodInfo *im_info;
4892 im_info = get_im_info (language, name, Mnil, Mcommand);
4894 || ! im_info->configured_cmds
4895 || MPLIST_TAIL_P (im_info->configured_cmds))
4897 if (command == Mnil)
4898 return im_info->configured_cmds;
4899 return mplist__assq (im_info->configured_cmds, command);
4905 @brief Configure the key sequence of an input method command.
4907 The minput_config_command () function assigns a list of key
4908 sequences $KEYSEQLIST to the command $COMMAND of the input method
4909 specified by $LANGUAGE and $NAME.
4911 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4912 sequences, and each key sequence must be a plist of symbols.
4914 If $KEYSEQLIST is an empty plist, any configuration and
4915 customization of the command are cancelled, and default key
4916 sequences become effective.
4918 If $KEYSEQLIST is NULL, the configuration of the command is
4919 canceled, and the original key sequences (what saved in per-user
4920 customization file, or the default one) become effective.
4922 In the latter two cases, $COMMAND can be #Mnil to make all the
4923 commands of the input method the target of the operation.
4925 If $NAME is #Mnil, this function configures the key assignment of a
4926 global command, not that of a specific input method.
4928 The configuration takes effect for input methods opened or
4929 re-opened later in the current session. In order to make the
4930 configuration take effect for the future session, it must be saved
4931 in a per-user customization file by the function
4932 minput_save_config ().
4935 If the operation was successful, this function returns 0,
4936 otherwise returns -1. The operation fails in these cases:
4938 <li>$KEYSEQLIST is not in a valid form.
4939 <li>$COMMAND is not available for the input method.
4940 <li>$LANGUAGE and $NAME do not specify an existing input method.
4944 minput_get_commands (), minput_save_config ().
4947 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4949 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4950 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4951 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4953 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4954 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4956 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
4957 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
4959 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
4960 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
4961 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
4963 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
4964 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
4966 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4967 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4969 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4970 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4971 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
4972 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4976 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4978 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4979 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4980 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4984 minput_get_commands (), minput_save_config ().
4988 /* Add "C-x u" to the "start" command of Unicode input method. */
4990 MSymbol start_command = msymbol ("start");
4991 MSymbol unicode = msymbol ("unicode");
4992 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4994 /* At first get the current key-sequence assignment. */
4995 cmd = minput_get_command (Mt, unicode, start_command);
4998 /* The input method does not have the command "start". Here
4999 should come some error handling code. */
5001 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5002 Extract the part (KEY-SEQUENCE ...). */
5003 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5004 /* Copy it because we should not modify it directly. */
5005 key_seq_list = mplist_copy (plist);
5007 key_seq = mplist ();
5008 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5009 mplist_add (key_seq, Msymbol, msymbol ("u"));
5010 mplist_add (key_seq_list, Mplist, key_seq);
5011 m17n_object_unref (key_seq);
5013 minput_config_command (Mt, unicode, start_command, key_seq_list);
5014 m17n_object_unref (key_seq_list);
5019 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5022 MInputMethodInfo *im_info, *config;
5027 im_info = get_im_info (language, name, Mnil, Mcommand);
5029 MERROR (MERROR_IM, -1);
5030 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5032 || ! mplist__assq (im_info->configured_cmds, command)))
5033 MERROR (MERROR_IM, -1);
5034 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5036 MPLIST_DO (plist, keyseqlist)
5037 if (! check_command_keyseq (plist))
5038 MERROR (MERROR_IM, -1);
5041 config = get_config_info (im_info);
5044 if (! im_config_list)
5045 im_config_list = mplist ();
5046 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5047 config->cmds = mplist ();
5048 config->vars = mplist ();
5051 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5052 /* Nothing to do. */
5055 if (command == Mnil)
5059 /* Cancal the configuration. */
5060 if (MPLIST_TAIL_P (config->cmds))
5062 mplist_set (config->cmds, Mnil, NULL);
5066 /* Cancal the customization. */
5067 MInputMethodInfo *custom = get_custom_info (im_info);
5069 if (MPLIST_TAIL_P (config->cmds)
5070 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5071 /* Nothing to do. */
5073 mplist_set (config->cmds, Mnil, NULL);
5074 MPLIST_DO (plist, custom->cmds)
5076 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5078 mplist_add (plist, Msymbol, command);
5079 mplist_push (config->cmds, Mplist, plist);
5080 M17N_OBJECT_UNREF (plist);
5086 plist = mplist__assq (config->cmds, command);
5089 /* Cancel the configuration. */
5092 mplist__pop_unref (plist);
5094 else if (MPLIST_TAIL_P (keyseqlist))
5096 /* Cancel the customization. */
5097 MInputMethodInfo *custom = get_custom_info (im_info);
5098 int no_custom = (! custom || ! custom->cmds
5099 || ! mplist__assq (custom->cmds, command));
5105 mplist_add (config->cmds, Mplist, plist);
5106 M17N_OBJECT_UNREF (plist);
5107 plist = mplist_add (plist, Msymbol, command);
5112 mplist__pop_unref (plist);
5115 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5116 plist = MPLIST_NEXT (plist);
5117 mplist_set (plist, Mnil, NULL);
5127 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5128 if (! MPLIST_TAIL_P (plist))
5129 mplist_set (plist, Mnil, NULL);
5134 mplist_add (config->cmds, Mplist, plist);
5135 M17N_OBJECT_UNREF (plist);
5136 plist = mplist_add (plist, Msymbol, command);
5137 plist = MPLIST_NEXT (plist);
5139 MPLIST_DO (keyseqlist, keyseqlist)
5141 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5142 plist = mplist_add (plist, Mplist, pl);
5143 M17N_OBJECT_UNREF (pl);
5147 config_all_commands (im_info);
5148 im_info->tick = time (NULL);
5155 @brief Get information about input method variable(s).
5157 The minput_get_variable () function returns information about
5158 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5159 An input method variable controls behavior of an input method.
5161 There are two kinds of variables, global and local. A global
5162 variable has a global definition, and the description and the value
5163 may be inherited by a local variable. Each input method defines a
5164 local variable which has local value. It may also declare a
5165 local variable that inherits definition of a global variable of
5168 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5169 variable is returned. Otherwise information about a local variable
5172 If $VARIABLE is #Mnil, information about all variables is
5175 The return value is a @e well-formed plist (#m17nPlist) of this
5178 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5180 @c NAME is a symbol representing the variable name.
5182 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5183 variable has no description.
5185 @c STATUS is a symbol representing how the value is decided. The
5186 value is #Mnil (the default value), #Mcustomized (the value is
5187 customized by per-user customization file), or #Mconfigured (the
5188 value is set by the call of minput_config_variable ()). For a
5189 local variable only, it may also be #Minherited (the value is
5190 inherited from the corresponding global variable).
5192 @c VALUE is the initial value of the variable. If the key of this
5193 element is #Mt, the variable has no initial value. Otherwise, the
5194 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5197 @c VALID-VALUEs (if any) specify which values the variable can have.
5198 They have the same type (i.e. having the same key) as @c VALUE except
5199 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5200 may be a plist of two integers specifying the range of possible
5203 If there no @c VALID-VALUE, the variable can have any value as long
5204 as the type is the same as @c VALUE.
5206 If $VARIABLE is not #Mnil, the first element of the returned plist
5207 contains the information about $VARIABLE.
5211 If the requested information was found, a pointer to a non-empty
5212 plist is returned. As the plist is kept in the library, the
5213 caller must not modify nor free it.
5215 Otherwise (the specified input method or the specified variable
5216 does not exist), @c NULL is returned. */
5218 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5220 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5221 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5222 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5224 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5225 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5226 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5227 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5230 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5231 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5233 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5235 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5237 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5240 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5242 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5245 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5246 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5247 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5248 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5249 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5250 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5252 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5253 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5254 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5256 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5257 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5258 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5259 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5261 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5264 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5265 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5269 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5270 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5273 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5277 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5279 MInputMethodInfo *im_info;
5283 im_info = get_im_info (language, name, Mnil, Mvariable);
5284 if (! im_info || ! im_info->configured_vars)
5286 if (variable == Mnil)
5287 return im_info->configured_vars;
5288 return mplist__assq (im_info->configured_vars, variable);
5294 @brief Configure the value of an input method variable.
5296 The minput_config_variable () function assigns $VALUE to the
5297 variable $VARIABLE of the input method specified by $LANGUAGE and
5300 If $VALUE is a non-empty plist, it must be a plist of one element
5301 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5302 the corresponding type. That value is assigned to the variable.
5304 If $VALUE is an empty plist, any configuration and customization
5305 of the variable are canceled, and the default value is assigned to
5308 If $VALUE is NULL, the configuration of the variable is canceled,
5309 and the original value (what saved in per-user customization file,
5310 or the default value) is assigned to the variable.
5312 In the latter two cases, $VARIABLE can be #Mnil to make all the
5313 variables of the input method the target of the operation.
5315 If $NAME is #Mnil, this function configures the value of global
5316 variable, not that of a specific input method.
5318 The configuration takes effect for input methods opened or
5319 re-opened later in the current session. To make the configuration
5320 take effect for the future session, it must be saved in a per-user
5321 customization file by the function minput_save_config ().
5325 If the operation was successful, this function returns 0,
5326 otherwise returns -1. The operation fails in these cases:
5328 <li>$VALUE is not in a valid form, the type does not match the
5329 definition, or the value is our of range.
5330 <li>$VARIABLE is not available for the input method.
5331 <li>$LANGUAGE and $NAME do not specify an existing input method.
5335 minput_get_variable (), minput_save_config (). */
5337 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5339 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5340 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5342 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5343 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5344 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5346 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5347 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5349 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5350 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5352 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5353 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5355 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5356 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5358 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5359 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5360 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5361 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5365 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5367 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5368 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5369 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5373 minput_get_commands (), minput_save_config ().
5376 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5379 MInputMethodInfo *im_info, *config;
5384 im_info = get_im_info (language, name, Mnil, Mvariable);
5386 MERROR (MERROR_IM, -1);
5387 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5389 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5390 MERROR (MERROR_IM, -1);
5392 if (value && ! MPLIST_TAIL_P (value))
5394 plist = MPLIST_PLIST (plist);
5395 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5396 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5397 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5398 if (MPLIST_KEY (plist) != Mt
5399 && ! check_variable_value (value, plist))
5400 MERROR (MERROR_IM, -1);
5403 config = get_config_info (im_info);
5406 if (! im_config_list)
5407 im_config_list = mplist ();
5408 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5409 config->cmds = mplist ();
5410 config->vars = mplist ();
5413 if (! value && MPLIST_TAIL_P (config->vars))
5414 /* Nothing to do. */
5417 if (variable == Mnil)
5421 /* Cancel the configuration. */
5422 if (MPLIST_TAIL_P (config->vars))
5424 mplist_set (config->vars, Mnil, NULL);
5428 /* Cancel the customization. */
5429 MInputMethodInfo *custom = get_custom_info (im_info);
5431 if (MPLIST_TAIL_P (config->vars)
5432 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5433 /* Nothing to do. */
5435 mplist_set (config->vars, Mnil, NULL);
5436 MPLIST_DO (plist, custom->vars)
5438 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5440 mplist_add (plist, Msymbol, variable);
5441 mplist_push (config->vars, Mplist, plist);
5442 M17N_OBJECT_UNREF (plist);
5448 plist = mplist__assq (config->vars, variable);
5451 /* Cancel the configuration. */
5454 mplist__pop_unref (plist);
5456 else if (MPLIST_TAIL_P (value))
5458 /* Cancel the customization. */
5459 MInputMethodInfo *custom = get_custom_info (im_info);
5460 int no_custom = (! custom || ! custom->vars
5461 || ! mplist__assq (custom->vars, variable));
5467 mplist_add (config->vars, Mplist, plist);
5468 M17N_OBJECT_UNREF (plist);
5469 plist = mplist_add (plist, Msymbol, variable);
5474 mplist__pop_unref (plist);
5477 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5478 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5479 mplist_set (plist, Mnil ,NULL);
5487 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5488 if (! MPLIST_TAIL_P (plist))
5489 mplist_set (plist, Mnil, NULL);
5494 mplist_add (config->vars, Mplist, plist);
5495 M17N_OBJECT_UNREF (plist);
5496 plist = mplist_add (plist, Msymbol, variable);
5497 plist = MPLIST_NEXT (plist);
5499 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5502 config_all_variables (im_info);
5503 im_info->tick = time (NULL);
5510 @brief Get the name of per-user customization file.
5512 The minput_config_file () function returns the absolute path name
5513 of per-user customization file into which minput_save_config ()
5514 save configurations. It is usually @c "config.mic" under the
5515 directory @c ".m17n.d" of user's home directory. It is not assured
5516 that the file of the returned name exists nor is
5517 readable/writable. If minput_save_config () fails and returns -1,
5518 an application program might check the file, make it
5519 writable (if possible), and try minput_save_config () again.
5523 This function returns a string. As the string is kept in the
5524 library, the caller must not modify nor free it.
5527 minput_save_config ()
5530 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5532 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5533 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5534 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5535 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5536 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5537 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5538 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5543 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5544 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5547 minput_save_config ()
5551 minput_config_file ()
5555 return mdatabase__file (im_custom_mdb);
5561 @brief Save configurations in per-user customization file.
5563 The minput_save_config () function saves the configurations done
5564 so far in the current session into the per-user customization
5569 If the operation was successful, 1 is returned. If the per-user
5570 customization file is currently locked, 0 is returned. In that
5571 case, the caller may wait for a while and try again. If the
5572 configuration file is not writable, -1 is returned. In that case,
5573 the caller may check the name of the file by calling
5574 minput_config_file (), make it writable if possible, and try
5578 minput_config_file () */
5580 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5582 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5583 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5587 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5588 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5589 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5590 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5594 minput_config_file () */
5597 minput_save_config (void)
5599 MPlist *data, *tail, *plist, *p, *elt;
5603 ret = mdatabase__lock (im_custom_mdb);
5606 if (! im_config_list)
5608 update_custom_info ();
5609 if (! im_custom_list)
5610 im_custom_list = mplist ();
5612 /* At first, reflect configuration in customization. */
5613 MPLIST_DO (plist, im_config_list)
5615 MPlist *pl = MPLIST_PLIST (plist);
5616 MSymbol language, name, extra, command, variable;
5617 MInputMethodInfo *custom, *config;
5619 language = MPLIST_SYMBOL (pl);
5620 pl = MPLIST_NEXT (pl);
5621 name = MPLIST_SYMBOL (pl);
5622 pl = MPLIST_NEXT (pl);
5623 extra = MPLIST_SYMBOL (pl);
5624 pl = MPLIST_NEXT (pl);
5625 config = MPLIST_VAL (pl);
5626 custom = get_custom_info (config);
5628 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5630 MPLIST_DO (pl, config->cmds)
5632 elt = MPLIST_PLIST (pl);
5633 command = MPLIST_SYMBOL (elt);
5635 p = mplist__assq (custom->cmds, command);
5637 custom->cmds = mplist (), p = NULL;
5638 elt = MPLIST_NEXT (elt);
5641 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5642 mplist_set (p, Mnil, NULL);
5647 mplist_add (custom->cmds, Mplist, p);
5648 M17N_OBJECT_UNREF (p);
5649 mplist_add (p, Msymbol, command);
5650 p = mplist_add (p, Msymbol, Mnil);
5651 p = MPLIST_NEXT (p);
5653 mplist__conc (p, elt);
5656 MPLIST_DO (pl, config->vars)
5658 elt = MPLIST_PLIST (pl);
5659 variable = MPLIST_SYMBOL (elt);
5661 p = mplist__assq (custom->vars, variable);
5663 custom->vars = mplist (), p = NULL;
5664 elt = MPLIST_NEXT (elt);
5667 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5668 mplist_set (p, Mnil, NULL);
5673 mplist_add (custom->vars, Mplist, p);
5674 M17N_OBJECT_UNREF (p);
5675 mplist_add (p, Msymbol, variable);
5676 p = mplist_add (p, Msymbol, Mnil);
5677 p = MPLIST_NEXT (p);
5679 mplist__conc (p, elt);
5682 free_im_list (im_config_list);
5683 im_config_list = NULL;
5685 /* Next, reflect customization to the actual plist to be written. */
5686 data = tail = mplist ();
5687 MPLIST_DO (plist, im_custom_list)
5689 MPlist *pl = MPLIST_PLIST (plist);
5690 MSymbol language, name, extra;
5691 MInputMethodInfo *custom, *im_info;
5693 language = MPLIST_SYMBOL (pl);
5694 pl = MPLIST_NEXT (pl);
5695 name = MPLIST_SYMBOL (pl);
5696 pl = MPLIST_NEXT (pl);
5697 extra = MPLIST_SYMBOL (pl);
5698 pl = MPLIST_NEXT (pl);
5699 custom = MPLIST_VAL (pl);
5700 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5701 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5703 im_info = lookup_im_info (im_info_list, language, name, extra);
5707 config_all_commands (im_info);
5709 config_all_variables (im_info);
5713 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5715 MPLIST_DO (p, custom->cmds)
5716 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5718 if (! MPLIST_TAIL_P (p))
5722 mplist_add (elt, Mplist, pl);
5723 M17N_OBJECT_UNREF (pl);
5724 pl = mplist_add (pl, Msymbol, Mcommand);
5725 MPLIST_DO (p, custom->cmds)
5726 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5727 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5730 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5732 MPLIST_DO (p, custom->vars)
5733 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5735 if (! MPLIST_TAIL_P (p))
5740 mplist_add (elt, Mplist, pl);
5741 M17N_OBJECT_UNREF (pl);
5742 pl = mplist_add (pl, Msymbol, Mvariable);
5743 MPLIST_DO (p, custom->vars)
5744 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5745 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5751 mplist_push (elt, Mplist, pl);
5752 M17N_OBJECT_UNREF (pl);
5753 pl = mplist_add (pl, Msymbol, Minput_method);
5754 pl = mplist_add (pl, Msymbol, language);
5755 pl = mplist_add (pl, Msymbol, name);
5757 pl = mplist_add (pl, Msymbol, extra);
5758 tail = mplist_add (tail, Mplist, elt);
5759 M17N_OBJECT_UNREF (elt);
5763 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5764 ret = mdatabase__save (im_custom_mdb, data);
5765 mdatabase__unlock (im_custom_mdb);
5766 M17N_OBJECT_UNREF (data);
5767 return (ret < 0 ? -1 : 1);
5774 @name Obsolete functions
5777 @name Obsolete ¤Ê´Ø¿ô
5783 @brief Get a list of variables of an input method (obsolete).
5785 This function is obsolete. Use minput_get_variable () instead.
5787 The minput_get_variables () function returns a plist (#MPlist) of
5788 variables used to control the behavior of the input method
5789 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5790 (#m17nPlist) of the following format:
5793 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5794 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5798 @c VARNAME is a symbol representing the variable name.
5800 @c DOC-MTEXT is an M-text describing the variable.
5802 @c DEFAULT-VALUE is the default value of the variable. It is a
5803 symbol, integer, or M-text.
5805 @c VALUEs (if any) specifies the possible values of the variable.
5806 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5807 @c TO), where @c FROM and @c TO specifies a range of possible
5810 For instance, suppose an input method has the variables:
5812 @li name:intvar, description:"value is an integer",
5813 initial value:0, value-range:0..3,10,20
5815 @li name:symvar, description:"value is a symbol",
5816 initial value:nil, value-range:a, b, c, nil
5818 @li name:txtvar, description:"value is an M-text",
5819 initial value:empty text, no value-range (i.e. any text)
5821 Then, the returned plist is as follows.
5824 (intvar ("value is an integer" 0 (0 3) 10 20)
5825 symvar ("value is a symbol" nil a b c nil)
5826 txtvar ("value is an M-text" ""))
5830 If the input method uses any variables, a pointer to #MPlist is
5831 returned. As the plist is kept in the library, the caller must not
5832 modify nor free it. If the input method does not use any
5833 variable, @c NULL is returned. */
5835 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5837 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5838 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5839 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5843 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5844 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5848 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5850 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5852 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5855 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5856 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5857 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5859 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5861 @li name:intvar, ÀâÌÀ:"value is an integer",
5862 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5864 @li name:symvar, ÀâÌÀ:"value is a symbol",
5865 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5867 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5868 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5870 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5873 (intvar ("value is an integer" 0 (0 3) 10 20)
5874 symvar ("value is a symbol" nil a b c nil)
5875 txtvar ("value is an M-text" ""))
5879 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5880 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5881 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5884 minput_get_variables (MSymbol language, MSymbol name)
5886 MInputMethodInfo *im_info;
5891 im_info = get_im_info (language, name, Mnil, Mvariable);
5892 if (! im_info || ! im_info->configured_vars)
5895 M17N_OBJECT_UNREF (im_info->bc_vars);
5896 im_info->bc_vars = mplist ();
5897 MPLIST_DO (vars, im_info->configured_vars)
5899 MPlist *plist = MPLIST_PLIST (vars);
5900 MPlist *elt = mplist ();
5902 mplist_push (im_info->bc_vars, Mplist, elt);
5903 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5904 elt = MPLIST_NEXT (elt);
5905 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5906 M17N_OBJECT_UNREF (elt);
5908 return im_info->bc_vars;
5914 @brief Set the initial value of an input method variable.
5916 The minput_set_variable () function sets the initial value of
5917 input method variable $VARIABLE to $VALUE for the input method
5918 specified by $LANGUAGE and $NAME.
5920 By default, the initial value is 0.
5922 This setting gets effective in a newly opened input method.
5925 If the operation was successful, 0 is returned. Otherwise -1 is
5926 returned, and #merror_code is set to #MERROR_IM. */
5928 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5930 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5931 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5932 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5934 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5936 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5939 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5940 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5943 minput_set_variable (MSymbol language, MSymbol name,
5944 MSymbol variable, void *value)
5947 MInputMethodInfo *im_info;
5952 if (variable == Mnil)
5953 MERROR (MERROR_IM, -1);
5954 plist = minput_get_variable (language, name, variable);
5955 plist = MPLIST_PLIST (plist);
5956 plist = MPLIST_NEXT (plist);
5958 mplist_add (pl, MPLIST_KEY (plist), value);
5959 ret = minput_config_variable (language, name, variable, pl);
5960 M17N_OBJECT_UNREF (pl);
5963 im_info = get_im_info (language, name, Mnil, Mvariable);
5972 @brief Get information about input method commands.
5974 The minput_get_commands () function returns information about
5975 input method commands of the input method specified by $LANGUAGE
5976 and $NAME. An input method command is a pseudo key event to which
5977 one or more actual input key sequences are assigned.
5979 There are two kinds of commands, global and local. Global
5980 commands are used by multiple input methods for the same purpose,
5981 and have global key assignments. Local commands are used only by
5982 a specific input method, and have only local key assignments.
5984 Each input method may locally change key assignments for global
5985 commands. The global key assignment for a global command is
5986 effective only when the current input method does not have local
5987 key assignments for that command.
5989 If $NAME is #Mnil, information about global commands is returned.
5990 In this case $LANGUAGE is ignored.
5992 If $NAME is not #Mnil, information about those commands that have
5993 local key assignments in the input method specified by $LANGUAGE
5994 and $NAME is returned.
5997 If no input method commands are found, this function returns @c NULL.
5999 Otherwise, a pointer to a plist is returned. The key of each
6000 element in the plist is a symbol representing a command, and the
6001 value is a plist of the form COMMAND-INFO described below.
6003 The first element of COMMAND-INFO has the key #Mtext, and the
6004 value is an M-text describing the command.
6006 If there are no more elements, that means no key sequences are
6007 assigned to the command. Otherwise, each of the remaining
6008 elements has the key #Mplist, and the value is a plist whose keys are
6009 #Msymbol and values are symbols representing input keys, which are
6010 currently assigned to the command.
6012 As the returned plist is kept in the library, the caller must not
6013 modify nor free it. */
6015 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6017 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6018 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6019 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6020 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6022 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6023 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6024 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6025 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6027 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6028 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6029 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6032 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6033 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6035 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6036 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6040 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6042 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6043 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6044 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6046 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6047 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6048 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6051 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6052 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6053 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6054 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6055 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6057 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6058 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6061 minput_get_commands (MSymbol language, MSymbol name)
6063 MInputMethodInfo *im_info;
6068 im_info = get_im_info (language, name, Mnil, Mcommand);
6069 if (! im_info || ! im_info->configured_vars)
6071 M17N_OBJECT_UNREF (im_info->bc_cmds);
6072 im_info->bc_cmds = mplist ();
6073 MPLIST_DO (cmds, im_info->configured_cmds)
6075 MPlist *plist = MPLIST_PLIST (cmds);
6076 MPlist *elt = mplist ();
6078 mplist_push (im_info->bc_cmds, Mplist, elt);
6079 mplist_add (elt, MPLIST_SYMBOL (plist),
6080 mplist_copy (MPLIST_NEXT (plist)));
6081 M17N_OBJECT_UNREF (elt);
6083 return im_info->bc_cmds;
6089 @brief Assign a key sequence to an input method command (obsolete).
6091 This function is obsolete. Use minput_config_command () instead.
6093 The minput_assign_command_keys () function assigns input key
6094 sequence $KEYSEQ to input method command $COMMAND for the input
6095 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6096 key sequence is assigned globally no matter what $LANGUAGE is.
6097 Otherwise the key sequence is assigned locally.
6099 Each element of $KEYSEQ must have the key $Msymbol and the value
6100 must be a symbol representing an input key.
6102 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6103 globally or locally.
6105 This assignment gets effective in a newly opened input method.
6108 If the operation was successful, 0 is returned. Otherwise -1 is
6109 returned, and #merror_code is set to #MERROR_IM. */
6111 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6113 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6114 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6115 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6116 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6117 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6119 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6120 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6122 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6123 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6125 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6128 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6129 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6132 minput_assign_command_keys (MSymbol language, MSymbol name,
6133 MSymbol command, MPlist *keyseq)
6139 if (command == Mnil)
6140 MERROR (MERROR_IM, -1);
6145 if (! check_command_keyseq (keyseq))
6146 MERROR (MERROR_IM, -1);
6148 mplist_add (plist, Mplist, keyseq);
6153 ret = minput_config_command (language, name, command, keyseq);
6154 M17N_OBJECT_UNREF (keyseq);
6161 @brief Call a callback function
6163 The minput_callback () functions calls a callback function
6164 $COMMAND assigned for the input context $IC. The caller must set
6165 specific elements in $IC->plist if the callback function requires.
6168 If there exists a specified callback function, 0 is returned.
6169 Otherwise -1 is returned. By side effects, $IC->plist may be
6173 minput_callback (MInputContext *ic, MSymbol command)
6175 MInputCallbackFunc func;
6177 if (! ic->im->driver.callback_list)
6179 func = ((MInputCallbackFunc)
6180 mplist_get_func (ic->im->driver.callback_list, command));
6183 (func) (ic, command);
6190 /*** @addtogroup m17nDebug */
6196 @brief Dump an input method.
6198 The mdebug_dump_im () function prints the input method $IM in a
6199 human readable way to the stderr. $INDENT specifies how many
6200 columns to indent the lines but the first one.
6203 This function returns $IM. */
6205 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6207 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6208 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6211 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6214 mdebug_dump_im (MInputMethod *im, int indent)
6216 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6219 prefix = (char *) alloca (indent + 1);
6220 memset (prefix, 32, indent);
6221 prefix[indent] = '\0';
6223 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6224 msymbol_name (im->name));
6225 mdebug_dump_mtext (im_info->title, 0, 0);
6226 if (im->name != Mnil)
6230 MPLIST_DO (state, im_info->states)
6232 fprintf (stderr, "\n%s ", prefix);
6233 dump_im_state (MPLIST_VAL (state), indent + 2);
6236 fprintf (stderr, ")");