1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
156 #include "m17n-gui.h"
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_mask = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mpop = msymbol ("pop");
406 Mundo = msymbol ("undo");
407 Mcall = msymbol ("call");
408 Mshift = msymbol ("shift");
409 Mselect = msymbol ("select");
410 Mshow = msymbol ("show");
411 Mhide = msymbol ("hide");
412 Mcommit = msymbol ("commit");
413 Munhandle = msymbol ("unhandle");
414 Mset = msymbol ("set");
415 Madd = msymbol ("add");
416 Msub = msymbol ("sub");
417 Mmul = msymbol ("mul");
418 Mdiv = msymbol ("div");
419 Mequal = msymbol ("=");
420 Mless = msymbol ("<");
421 Mgreater = msymbol (">");
422 Mless_equal = msymbol ("<=");
423 Mgreater_equal = msymbol (">=");
424 Mcond = msymbol ("cond");
425 Mplus = msymbol ("+");
426 Mminus = msymbol ("-");
427 Mstar = msymbol ("*");
428 Mslash = msymbol ("/");
429 Mand = msymbol ("&");
431 Mnot = msymbol ("!");
433 Mat_reload = msymbol ("@reload");
435 Mcandidates_group_size = msymbol ("candidates-group-size");
436 Mcandidates_charset = msymbol ("candidates-charset");
438 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
439 Mcandidate_index = msymbol (" candidate-index");
441 Minit = msymbol ("init");
442 Mfini = msymbol ("fini");
444 Mdescription = msymbol ("description");
445 Mcommand = msymbol ("command");
446 Mvariable = msymbol ("variable");
447 Mglobal = msymbol ("global");
448 Mconfig = msymbol ("config");
449 M_gettext = msymbol ("_");
451 load_im_info_keys = mplist ();
452 mplist_add (load_im_info_keys, Mstate, Mnil);
453 mplist_push (load_im_info_keys, Mmap, Mnil);
455 im_info_list = mplist ();
456 im_config_list = im_custom_list = NULL;
457 im_custom_mdb = NULL;
458 update_custom_info ();
460 update_global_info ();
462 fully_initialized = 1;
465 #define MINPUT__INIT() \
467 if (! fully_initialized) \
468 fully_initialize (); \
473 marker_code (MSymbol sym, int surrounding)
479 name = MSYMBOL_NAME (sym);
480 return (name[0] != '@' ? -1
481 : (((name[1] >= '0' && name[1] <= '9')
482 || name[1] == '<' || name[1] == '>' || name[1] == '='
483 || name[1] == '[' || name[1] == ']'
485 && name[2] == '\0') ? name[1]
486 : (name[1] != '+' && name[1] != '-') ? -1
487 : (name[2] == '\0' || surrounding) ? name[1]
493 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
495 MPlist *plist = mplist__assq (ic_info->vars, var);
499 plist = MPLIST_PLIST (plist);
500 return MPLIST_NEXT (plist);
504 mplist_push (ic_info->vars, Mplist, plist);
505 M17N_OBJECT_UNREF (plist);
506 plist = mplist_add (plist, Msymbol, var);
507 plist = mplist_add (plist, Minteger, (void *) 0);
512 get_surrounding_text (MInputContext *ic, int len)
516 mplist_push (ic->plist, Minteger, (void *) len);
517 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
518 && MPLIST_MTEXT_P (ic->plist))
519 mt = MPLIST_MTEXT (ic->plist);
520 mplist_pop (ic->plist);
525 delete_surrounding_text (MInputContext *ic, int pos)
527 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
529 mplist_push (ic->plist, Minteger, (void *) pos);
530 minput_callback (ic, Minput_delete_surrounding_text);
531 mplist_pop (ic->plist);
534 M17N_OBJECT_UNREF (ic_info->preceding_text);
535 ic_info->preceding_text = NULL;
539 M17N_OBJECT_UNREF (ic_info->following_text);
540 ic_info->following_text = NULL;
545 get_preceding_char (MInputContext *ic, int pos)
547 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
551 if (pos && ic_info->preceding_text)
553 len = mtext_nchars (ic_info->preceding_text);
555 return mtext_ref_char (ic_info->preceding_text, len - pos);
557 mt = get_surrounding_text (ic, - pos);
560 len = mtext_nchars (mt);
561 if (ic_info->preceding_text)
563 if (mtext_nchars (ic_info->preceding_text) < len)
565 M17N_OBJECT_UNREF (ic_info->preceding_text);
566 ic_info->preceding_text = mt;
569 M17N_OBJECT_UNREF (mt);
572 ic_info->preceding_text = mt;
575 return mtext_ref_char (ic_info->preceding_text, len - pos);
579 get_following_char (MInputContext *ic, int pos)
581 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
585 if (ic_info->following_text)
587 len = mtext_nchars (ic_info->following_text);
589 return mtext_ref_char (ic_info->following_text, pos - 1);
591 mt = get_surrounding_text (ic, pos);
594 len = mtext_nchars (mt);
595 if (ic_info->following_text)
597 if (mtext_nchars (ic_info->following_text) < len)
599 M17N_OBJECT_UNREF (ic_info->following_text);
600 ic_info->following_text = mt;
603 M17N_OBJECT_UNREF (mt);
606 ic_info->following_text = mt;
609 return mtext_ref_char (ic_info->following_text, pos - 1);
613 surrounding_pos (MSymbol sym)
619 name = MSYMBOL_NAME (sym);
621 && (name[1] == '-' || name[1] == '+')
622 && name[2] >= '1' && name[2] <= '9')
623 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
628 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
630 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
632 MText *preedit = ic->preedit;
633 int len = mtext_nchars (preedit);
637 if (MPLIST_INTEGER_P (arg))
638 return MPLIST_INTEGER (arg);
640 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
643 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
647 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
650 return ic_info->key_head;
651 if ((code == '-' || code == '+'))
653 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
657 pos = atoi (name + 1);
659 return get_preceding_char (ic, 0);
660 pos = ic->cursor_pos + pos;
663 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
664 return mtext_ref_char (ic->produced,
665 mtext_len (ic->produced) + pos);
666 return get_preceding_char (ic, - pos);
669 return get_following_char (ic, pos - len + 1);
672 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
674 else if (code >= '0' && code <= '9')
676 else if (code == '=')
677 pos = ic->cursor_pos;
678 else if (code == '[')
679 pos = ic->cursor_pos - 1;
680 else if (code == ']')
681 pos = ic->cursor_pos + 1;
682 else if (code == '<')
684 else if (code == '>')
686 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
690 parse_expression (MPlist *plist)
694 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
696 if (! MPLIST_PLIST_P (plist))
698 plist = MPLIST_PLIST (plist);
699 op = MPLIST_SYMBOL (plist);
700 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
701 && op != Mand && op != Mor && op != Mnot
702 && op != Mless && op != Mgreater && op != Mequal
703 && op != Mless_equal && op != Mgreater_equal)
704 MERROR (MERROR_IM, -1);
705 MPLIST_DO (plist, MPLIST_NEXT (plist))
706 if (parse_expression (plist) < 0)
712 resolve_expression (MInputContext *ic, MPlist *plist)
717 if (MPLIST_INTEGER_P (plist))
718 return MPLIST_INTEGER (plist);
719 if (MPLIST_SYMBOL_P (plist))
720 return integer_value (ic, plist, NULL, 1);
721 if (! MPLIST_PLIST_P (plist))
723 plist = MPLIST_PLIST (plist);
724 if (! MPLIST_SYMBOL_P (plist))
726 op = MPLIST_SYMBOL (plist);
727 plist = MPLIST_NEXT (plist);
728 val = resolve_expression (ic, plist);
730 MPLIST_DO (plist, MPLIST_NEXT (plist))
731 val += resolve_expression (ic, plist);
732 else if (op == Mminus)
733 MPLIST_DO (plist, MPLIST_NEXT (plist))
734 val -= resolve_expression (ic, plist);
735 else if (op == Mstar)
736 MPLIST_DO (plist, MPLIST_NEXT (plist))
737 val *= resolve_expression (ic, plist);
738 else if (op == Mslash)
739 MPLIST_DO (plist, MPLIST_NEXT (plist))
740 val /= resolve_expression (ic, plist);
742 MPLIST_DO (plist, MPLIST_NEXT (plist))
743 val &= resolve_expression (ic, plist);
745 MPLIST_DO (plist, MPLIST_NEXT (plist))
746 val |= resolve_expression (ic, plist);
749 else if (op == Mless)
750 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
751 else if (op == Mequal)
752 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
753 else if (op == Mgreater)
754 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
755 else if (op == Mless_equal)
756 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
757 else if (op == Mgreater_equal)
758 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
762 /* Parse PLIST as an action list. PLIST should have this form:
763 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
764 Return 0 if successfully parsed, otherwise return -1. */
767 parse_action_list (MPlist *plist, MPlist *macros)
769 MPLIST_DO (plist, plist)
771 if (MPLIST_MTEXT_P (plist))
773 /* This is a short form of (insert MTEXT). */
774 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
775 MERROR (MERROR_IM, -1); */
777 else if (MPLIST_PLIST_P (plist)
778 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
779 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
783 /* This is a short form of (insert (GROUPS *)). */
784 MPLIST_DO (pl, MPLIST_PLIST (plist))
786 if (MPLIST_PLIST_P (pl))
790 MPLIST_DO (elt, MPLIST_PLIST (pl))
791 if (! MPLIST_MTEXT_P (elt)
792 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
793 MERROR (MERROR_IM, -1);
797 if (! MPLIST_MTEXT_P (pl)
798 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
799 MERROR (MERROR_IM, -1);
803 else if (MPLIST_INTEGER_P (plist))
805 int c = MPLIST_INTEGER (plist);
807 if (c < 0 || c > MCHAR_MAX)
808 MERROR (MERROR_IM, -1);
810 else if (MPLIST_PLIST_P (plist)
811 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
813 MPlist *pl = MPLIST_PLIST (plist);
814 MSymbol action_name = MPLIST_SYMBOL (pl);
816 pl = MPLIST_NEXT (pl);
818 if (action_name == Minsert)
820 if (MPLIST_MTEXT_P (pl))
822 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
823 MERROR (MERROR_IM, -1);
825 else if (MPLIST_PLIST_P (pl))
827 MPLIST_DO (pl, MPLIST_PLIST (pl))
829 if (MPLIST_PLIST_P (pl))
833 MPLIST_DO (elt, MPLIST_PLIST (pl))
834 if (! MPLIST_MTEXT_P (elt)
835 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
836 MERROR (MERROR_IM, -1);
840 if (! MPLIST_MTEXT_P (pl)
841 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
842 MERROR (MERROR_IM, -1);
846 else if (! MPLIST_SYMBOL_P (pl))
847 MERROR (MERROR_IM, -1);
849 else if (action_name == Mselect
850 || action_name == Mdelete
851 || action_name == Mmove)
853 if (parse_expression (pl) < 0)
856 else if (action_name == Mmark
857 || action_name == Mcall
858 || action_name == Mshift)
860 if (! MPLIST_SYMBOL_P (pl))
861 MERROR (MERROR_IM, -1);
863 else if (action_name == Mundo)
865 if (! MPLIST_TAIL_P (pl))
867 if (! MPLIST_SYMBOL_P (pl)
868 && ! MPLIST_INTEGER_P (pl))
869 MERROR (MERROR_IM, -1);
872 else if (action_name == Mpushback)
874 if (MPLIST_MTEXT_P (pl))
876 MText *mt = MPLIST_MTEXT (pl);
878 if (mtext_nchars (mt) != mtext_nbytes (mt))
879 MERROR (MERROR_IM, -1);
881 else if (MPLIST_PLIST_P (pl))
885 MPLIST_DO (p, MPLIST_PLIST (pl))
886 if (! MPLIST_SYMBOL_P (p))
887 MERROR (MERROR_IM, -1);
889 else if (! MPLIST_INTEGER_P (pl))
890 MERROR (MERROR_IM, -1);
892 else if (action_name == Mset || action_name == Madd
893 || action_name == Msub || action_name == Mmul
894 || action_name == Mdiv)
896 if (! MPLIST_SYMBOL_P (pl))
897 MERROR (MERROR_IM, -1);
898 if (parse_expression (MPLIST_NEXT (pl)) < 0)
901 else if (action_name == Mequal || action_name == Mless
902 || action_name == Mgreater || action_name == Mless_equal
903 || action_name == Mgreater_equal)
905 if (parse_expression (pl) < 0
906 || parse_expression (MPLIST_NEXT (pl)) < 0)
908 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
909 if (! MPLIST_PLIST_P (pl))
910 MERROR (MERROR_IM, -1);
911 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
912 MERROR (MERROR_IM, -1);
913 pl = MPLIST_NEXT (pl);
914 if (MPLIST_PLIST_P (pl)
915 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
916 MERROR (MERROR_IM, -1);
918 else if (action_name == Mshow || action_name == Mhide
919 || action_name == Mcommit || action_name == Munhandle
920 || action_name == Mpop)
922 else if (action_name == Mcond)
925 if (! MPLIST_PLIST_P (pl))
926 MERROR (MERROR_IM, -1);
928 else if (! macros || ! mplist_get (macros, action_name))
929 MERROR (MERROR_IM, -1);
931 else if (! MPLIST_SYMBOL_P (plist))
932 MERROR (MERROR_IM, -1);
939 resolve_command (MPlist *cmds, MSymbol command)
943 if (! cmds || ! (plist = mplist__assq (cmds, command)))
945 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
946 plist = MPLIST_NEXT (plist);
947 plist = MPLIST_NEXT (plist);
948 plist = MPLIST_NEXT (plist);
952 /* Load a translation into MAP from PLIST.
954 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
957 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
958 MPlist *branch_actions, MPlist *macros)
963 if (MPLIST_MTEXT_P (keylist))
965 MText *mt = MPLIST_MTEXT (keylist);
967 len = mtext_nchars (mt);
968 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
970 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
971 for (i = 0; i < len; i++)
972 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
978 if (MFAILP (MPLIST_PLIST_P (keylist)))
980 elt = MPLIST_PLIST (keylist);
981 len = MPLIST_LENGTH (elt);
982 if (MFAILP (len > 0))
984 keyseq = (MSymbol *) alloca (sizeof (int) * len);
985 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
987 if (MPLIST_INTEGER_P (elt))
989 int c = MPLIST_INTEGER (elt);
991 if (MFAILP (c >= 0 && c < 0x100))
993 keyseq[i] = one_char_symbol[c];
997 if (MFAILP (MPLIST_SYMBOL_P (elt)))
999 keyseq[i] = MPLIST_SYMBOL (elt);
1004 for (i = 0; i < len; i++)
1006 MIMMap *deeper = NULL;
1009 deeper = mplist_get (map->submaps, keyseq[i]);
1011 map->submaps = mplist ();
1014 /* Fixme: It is better to make all deeper maps at once. */
1015 MSTRUCT_CALLOC (deeper, MERROR_IM);
1016 mplist_put (map->submaps, keyseq[i], deeper);
1021 /* We reach a terminal map. */
1022 if (map->map_actions
1023 || map->branch_actions)
1024 /* This map is already defined. We avoid overriding it. */
1027 if (! MPLIST_TAIL_P (map_actions))
1029 if (parse_action_list (map_actions, macros) < 0)
1030 MERROR (MERROR_IM, -1);
1031 map->map_actions = map_actions;
1035 map->branch_actions = branch_actions;
1036 M17N_OBJECT_REF (branch_actions);
1042 /* Load a branch from PLIST into MAP. PLIST has this form:
1043 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1046 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1049 MPlist *branch_actions;
1051 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1053 map_name = MPLIST_SYMBOL (plist);
1054 plist = MPLIST_NEXT (plist);
1055 if (MPLIST_TAIL_P (plist))
1056 branch_actions = NULL;
1057 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1060 branch_actions = plist;
1061 if (map_name == Mnil)
1063 map->branch_actions = branch_actions;
1065 M17N_OBJECT_REF (branch_actions);
1067 else if (map_name == Mt)
1069 map->map_actions = branch_actions;
1071 M17N_OBJECT_REF (branch_actions);
1073 else if (im_info->maps
1074 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1076 MPLIST_DO (plist, plist)
1078 MPlist *keylist, *map_actions;
1080 if (! MPLIST_PLIST_P (plist))
1081 MERROR (MERROR_IM, -1);
1082 keylist = MPLIST_PLIST (plist);
1083 map_actions = MPLIST_NEXT (keylist);
1084 if (MPLIST_SYMBOL_P (keylist))
1086 MSymbol command = MPLIST_SYMBOL (keylist);
1089 if (MFAILP (command != Mat_reload))
1091 pl = resolve_command (im_info->configured_cmds, command);
1095 load_translation (map, pl, map_actions, branch_actions,
1099 load_translation (map, keylist, map_actions, branch_actions,
1107 /* Load a macro from PLIST into IM_INFO->macros.
1108 PLIST has this from:
1109 PLIST ::= ( MACRO-NAME ACTION * )
1110 IM_INFO->macros is a plist of macro names vs action list. */
1113 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1118 if (! MPLIST_SYMBOL_P (plist))
1119 MERROR (MERROR_IM, -1);
1120 name = MPLIST_SYMBOL (plist);
1121 plist = MPLIST_NEXT (plist);
1122 if (MPLIST_TAIL_P (plist)
1123 || parse_action_list (plist, im_info->macros) < 0)
1124 MERROR (MERROR_IM, -1);
1125 pl = mplist_get (im_info->macros, name);
1126 M17N_OBJECT_UNREF (pl);
1127 mplist_put (im_info->macros, name, plist);
1128 M17N_OBJECT_REF (plist);
1132 /* Load an external module from PLIST into IM_INFO->externals.
1133 PLIST has this form:
1134 PLIST ::= ( MODULE-NAME FUNCTION * )
1135 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1138 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1143 MIMExternalModule *external;
1147 if (MPLIST_MTEXT_P (plist))
1148 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1149 else if (MPLIST_SYMBOL_P (plist))
1150 module = MPLIST_SYMBOL (plist);
1151 module_file = alloca (strlen (MSYMBOL_NAME (module))
1152 + strlen (DLOPEN_SHLIB_EXT) + 1);
1153 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1155 handle = dlopen (module_file, RTLD_NOW);
1156 if (MFAILP (handle))
1158 fprintf (stderr, "%s\n", dlerror ());
1161 func_list = mplist ();
1162 MPLIST_DO (plist, MPLIST_NEXT (plist))
1164 if (! MPLIST_SYMBOL_P (plist))
1165 MERROR_GOTO (MERROR_IM, err_label);
1166 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1169 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1172 MSTRUCT_MALLOC (external, MERROR_IM);
1173 external->handle = handle;
1174 external->func_list = func_list;
1175 mplist_add (im_info->externals, module, external);
1180 M17N_OBJECT_UNREF (func_list);
1185 free_map (MIMMap *map, int top)
1190 M17N_OBJECT_UNREF (map->map_actions);
1193 MPLIST_DO (plist, map->submaps)
1194 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1195 M17N_OBJECT_UNREF (map->submaps);
1197 M17N_OBJECT_UNREF (map->branch_actions);
1202 free_state (void *object)
1204 MIMState *state = object;
1206 M17N_OBJECT_UNREF (state->title);
1208 free_map (state->map, 1);
1212 /** Load a state from PLIST into a newly allocated state object.
1213 PLIST has this form:
1214 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1215 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1216 Return the state object. */
1219 load_state (MInputMethodInfo *im_info, MPlist *plist)
1223 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1225 M17N_OBJECT (state, free_state, MERROR_IM);
1226 state->name = MPLIST_SYMBOL (plist);
1227 plist = MPLIST_NEXT (plist);
1228 if (MPLIST_MTEXT_P (plist))
1230 state->title = MPLIST_MTEXT (plist);
1231 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1232 Mlanguage, im_info->language);
1233 M17N_OBJECT_REF (state->title);
1234 plist = MPLIST_NEXT (plist);
1236 MSTRUCT_CALLOC (state->map, MERROR_IM);
1237 MPLIST_DO (plist, plist)
1239 if (MFAILP (MPLIST_PLIST_P (plist)))
1241 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1246 /* Return a newly created IM_INFO for an input method specified by
1247 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1249 static MInputMethodInfo *
1250 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1253 MInputMethodInfo *im_info;
1256 if (name == Mnil && extra == Mnil)
1257 language = Mt, extra = Mglobal;
1258 MSTRUCT_CALLOC (im_info, MERROR_IM);
1260 im_info->language = language;
1261 im_info->name = name;
1262 im_info->extra = extra;
1265 mplist_add (plist, Mplist, elt);
1266 M17N_OBJECT_UNREF (elt);
1267 elt = mplist_add (elt, Msymbol, language);
1268 elt = mplist_add (elt, Msymbol, name);
1269 elt = mplist_add (elt, Msymbol, extra);
1270 mplist_add (elt, Mt, im_info);
1276 fini_im_info (MInputMethodInfo *im_info)
1280 M17N_OBJECT_UNREF (im_info->cmds);
1281 M17N_OBJECT_UNREF (im_info->configured_cmds);
1282 M17N_OBJECT_UNREF (im_info->bc_cmds);
1283 M17N_OBJECT_UNREF (im_info->vars);
1284 M17N_OBJECT_UNREF (im_info->configured_vars);
1285 M17N_OBJECT_UNREF (im_info->bc_vars);
1286 M17N_OBJECT_UNREF (im_info->description);
1287 M17N_OBJECT_UNREF (im_info->title);
1288 if (im_info->states)
1290 MPLIST_DO (plist, im_info->states)
1292 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1294 M17N_OBJECT_UNREF (state);
1296 M17N_OBJECT_UNREF (im_info->states);
1299 if (im_info->macros)
1301 MPLIST_DO (plist, im_info->macros)
1302 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1303 M17N_OBJECT_UNREF (im_info->macros);
1306 if (im_info->externals)
1308 MPLIST_DO (plist, im_info->externals)
1310 MIMExternalModule *external = MPLIST_VAL (plist);
1312 dlclose (external->handle);
1313 M17N_OBJECT_UNREF (external->func_list);
1315 MPLIST_KEY (plist) = Mt;
1317 M17N_OBJECT_UNREF (im_info->externals);
1321 MPLIST_DO (plist, im_info->maps)
1323 MPlist *p = MPLIST_PLIST (plist);
1325 M17N_OBJECT_UNREF (p);
1327 M17N_OBJECT_UNREF (im_info->maps);
1334 free_im_info (MInputMethodInfo *im_info)
1336 fini_im_info (im_info);
1341 free_im_list (MPlist *plist)
1345 MPLIST_DO (pl, plist)
1347 MInputMethodInfo *im_info;
1349 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1350 im_info = MPLIST_VAL (elt);
1351 free_im_info (im_info);
1353 M17N_OBJECT_UNREF (plist);
1356 static MInputMethodInfo *
1357 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1359 if (name == Mnil && extra == Mnil)
1360 language = Mt, extra = Mglobal;
1361 while ((plist = mplist__assq (plist, language)))
1363 MPlist *elt = MPLIST_PLIST (plist);
1365 plist = MPLIST_NEXT (plist);
1366 elt = MPLIST_NEXT (elt);
1367 if (MPLIST_SYMBOL (elt) != name)
1369 elt = MPLIST_NEXT (elt);
1370 if (MPLIST_SYMBOL (elt) != extra)
1372 elt = MPLIST_NEXT (elt);
1373 return MPLIST_VAL (elt);
1378 static void load_im_info (MPlist *, MInputMethodInfo *);
1380 #define get_custom_info(im_info) \
1382 ? lookup_im_info (im_custom_list, (im_info)->language, \
1383 (im_info)->name, (im_info)->extra) \
1386 #define get_config_info(im_info) \
1388 ? lookup_im_info (im_config_list, (im_info)->language, \
1389 (im_info)->name, (im_info)->extra) \
1393 update_custom_info (void)
1399 if (mdatabase__check (im_custom_mdb) > 0)
1404 MDatabaseInfo *custom_dir_info;
1405 char custom_path[PATH_MAX + 1];
1407 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1408 if (! custom_dir_info->filename
1409 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1411 strcpy (custom_path, custom_dir_info->filename);
1412 strcat (custom_path, CUSTOM_FILE);
1413 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1419 free_im_list (im_custom_list);
1420 im_custom_list = NULL;
1422 plist = mdatabase_load (im_custom_mdb);
1425 im_custom_list = mplist ();
1427 MPLIST_DO (pl, plist)
1429 MSymbol language, name, extra;
1430 MInputMethodInfo *im_info;
1431 MPlist *im_data, *p;
1433 if (! MPLIST_PLIST_P (pl))
1435 p = MPLIST_PLIST (pl);
1436 im_data = MPLIST_NEXT (p);
1437 if (! MPLIST_PLIST_P (p))
1439 p = MPLIST_PLIST (p);
1440 if (! MPLIST_SYMBOL_P (p)
1441 || MPLIST_SYMBOL (p) != Minput_method)
1443 p = MPLIST_NEXT (p);
1444 if (! MPLIST_SYMBOL_P (p))
1446 language = MPLIST_SYMBOL (p);
1447 p = MPLIST_NEXT (p);
1448 if (! MPLIST_SYMBOL_P (p))
1450 name = MPLIST_SYMBOL (p);
1451 p = MPLIST_NEXT (p);
1452 if (MPLIST_TAIL_P (p))
1454 else if (MPLIST_SYMBOL_P (p))
1455 extra = MPLIST_SYMBOL (p);
1456 if (language == Mnil || (name == Mnil && extra == Mnil))
1458 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1459 load_im_info (im_data, im_info);
1461 M17N_OBJECT_UNREF (plist);
1466 update_global_info (void)
1472 int ret = mdatabase__check (global_info->mdb);
1476 fini_im_info (global_info);
1480 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1482 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1484 if (! global_info->mdb
1485 || ! (plist = mdatabase_load (global_info->mdb)))
1488 load_im_info (plist, global_info);
1489 M17N_OBJECT_UNREF (plist);
1494 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1495 and EXTRA. KEY, if not Mnil, tells which kind of information about
1496 the input method is necessary, and the returned IM_INFO may contain
1497 only that information. */
1499 static MInputMethodInfo *
1500 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1503 MInputMethodInfo *im_info;
1506 if (name == Mnil && extra == Mnil)
1507 language = Mt, extra = Mglobal;
1508 im_info = lookup_im_info (im_info_list, language, name, extra);
1511 if (key == Mnil ? im_info->states != NULL
1512 : key == Mcommand ? im_info->cmds != NULL
1513 : key == Mvariable ? im_info->vars != NULL
1514 : key == Mtitle ? im_info->title != NULL
1515 : key == Mdescription ? im_info->description != NULL
1517 /* IM_INFO already contains required information. */
1519 /* We have not yet loaded required information. */
1523 mdb = mdatabase_find (Minput_method, language, name, extra);
1526 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1531 plist = mdatabase_load (im_info->mdb);
1535 mplist_push (load_im_info_keys, key, Mt);
1536 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1537 mplist_pop (load_im_info_keys);
1541 MERROR (MERROR_IM, im_info);
1542 update_global_info ();
1543 load_im_info (plist, im_info);
1544 M17N_OBJECT_UNREF (plist);
1547 if (! im_info->cmds)
1548 im_info->cmds = mplist ();
1549 if (! im_info->vars)
1550 im_info->vars = mplist ();
1552 if (! im_info->title
1553 && (key == Mnil || key == Mtitle))
1554 im_info->title = (name == Mnil ? mtext ()
1555 : mtext_from_data (MSYMBOL_NAME (name),
1556 MSYMBOL_NAMELEN (name),
1557 MTEXT_FORMAT_US_ASCII));
1561 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1562 If updated, but got unloadable, return -1. Otherwise, update
1563 contents of IM_INFO from the new database, and return 1. */
1566 reload_im_info (MInputMethodInfo *im_info)
1571 update_custom_info ();
1572 update_global_info ();
1573 check = mdatabase__check (im_info->mdb);
1576 plist = mdatabase_load (im_info->mdb);
1579 fini_im_info (im_info);
1580 load_im_info (plist, im_info);
1581 M17N_OBJECT_UNREF (plist);
1582 if (! im_info->cmds)
1583 im_info->cmds = mplist ();
1584 if (! im_info->vars)
1585 im_info->vars = mplist ();
1586 if (! im_info->title)
1588 MSymbol name = im_info->name;
1590 im_info->title = (name == Mnil ? mtext ()
1591 : mtext_from_data (MSYMBOL_NAME (name),
1592 MSYMBOL_NAMELEN (name),
1593 MTEXT_FORMAT_US_ASCII));
1598 static MInputMethodInfo *
1599 get_im_info_by_tags (MPlist *plist)
1604 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1605 i++, plist = MPLIST_NEXT (plist))
1606 tag[i] = MPLIST_SYMBOL (plist);
1611 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1616 check_description (MPlist *plist)
1620 if (MPLIST_MTEXT_P (plist))
1622 if (MPLIST_PLIST_P (plist))
1624 MPlist *pl = MPLIST_PLIST (plist);
1626 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1628 pl =MPLIST_NEXT (pl);
1629 if (MFAILP (MPLIST_MTEXT_P (pl)))
1631 mt = MPLIST_MTEXT (pl);
1632 M17N_OBJECT_REF (mt);
1635 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1637 if (translated == (char *) MTEXT_DATA (mt))
1638 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1639 if (translated != (char *) MTEXT_DATA (mt))
1641 M17N_OBJECT_UNREF (mt);
1642 mt = mtext__from_data (translated, strlen (translated),
1643 MTEXT_FORMAT_UTF_8, 0);
1647 mplist_set (plist, Mtext, mt);
1648 M17N_OBJECT_UNREF (mt);
1651 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1657 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1661 check_command_keyseq (MPlist *keyseq)
1663 if (MPLIST_PLIST_P (keyseq))
1665 MPlist *p = MPLIST_PLIST (keyseq);
1668 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1672 if (MPLIST_MTEXT_P (keyseq))
1674 MText *mt = MPLIST_MTEXT (keyseq);
1677 for (i = 0; i < mtext_nchars (mt); i++)
1678 if (mtext_ref_char (mt, i) >= 256)
1685 /* Load command defitions from PLIST into IM_INFO->cmds.
1687 PLIST is well-formed and has this form;
1688 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1689 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1690 M-text or a plist of symbols.
1692 The returned list has the same form, but for each element...
1694 (1) If DESCRIPTION and the rest are omitted, the element is not
1695 stored in the returned list.
1697 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1698 description in global_info->cmds (if any). */
1701 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1705 im_info->cmds = tail = mplist ();
1707 MPLIST_DO (plist, MPLIST_NEXT (plist))
1709 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1712 if (MFAILP (MPLIST_PLIST_P (plist)))
1714 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1715 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1717 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1718 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1720 if (MFAILP (im_info != global_info))
1721 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1725 if (! check_description (p))
1726 mplist_set (p, Msymbol, Mnil);
1727 p = MPLIST_NEXT (p);
1728 while (! MPLIST_TAIL_P (p))
1730 if (MFAILP (check_command_keyseq (p)))
1731 mplist__pop_unref (p);
1733 p = MPLIST_NEXT (p);
1736 tail = mplist_add (tail, Mplist, pl);
1741 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1742 MPlist *config_cmds)
1744 MPlist *global = NULL, *custom = NULL, *config = NULL;
1747 MPlist *description, *keyseq;
1749 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1750 global = MPLIST_NEXT (MPLIST_PLIST (global));
1752 name = MPLIST_SYMBOL (plist);
1753 plist = MPLIST_NEXT (plist);
1754 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1756 description = plist;
1757 plist = MPLIST_NEXT (plist);
1761 description = global;
1762 if (! MPLIST_TAIL_P (plist))
1763 plist = MPLIST_NEXT (plist);
1765 if (MPLIST_TAIL_P (plist) && global)
1767 keyseq = MPLIST_NEXT (global);
1768 status = Minherited;
1776 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1778 status = Mconfigured;
1779 config = MPLIST_NEXT (MPLIST_PLIST (config));
1780 if (! MPLIST_TAIL_P (config))
1781 keyseq = MPLIST_NEXT (config);
1783 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1785 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1786 if (! MPLIST_TAIL_P (custom))
1788 status = Mcustomized;
1789 keyseq = MPLIST_NEXT (custom);
1794 mplist_add (plist, Msymbol, name);
1796 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1798 mplist_add (plist, Msymbol, Mnil);
1799 mplist_add (plist, Msymbol, status);
1800 mplist__conc (plist, keyseq);
1805 config_all_commands (MInputMethodInfo *im_info)
1807 MPlist *global_cmds, *custom_cmds, *config_cmds;
1808 MInputMethodInfo *temp;
1809 MPlist *tail, *plist;
1811 M17N_OBJECT_UNREF (im_info->configured_cmds);
1813 if (MPLIST_TAIL_P (im_info->cmds)
1817 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1818 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1819 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1821 im_info->configured_cmds = tail = mplist ();
1822 MPLIST_DO (plist, im_info->cmds)
1824 MPlist *pl = config_command (MPLIST_PLIST (plist),
1825 global_cmds, custom_cmds, config_cmds);
1828 tail = mplist_add (tail, Mplist, pl);
1829 M17N_OBJECT_UNREF (pl);
1834 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1835 valid, return 0 if not. */
1838 check_variable_value (MPlist *val, MPlist *global)
1840 MSymbol type = MPLIST_KEY (val);
1841 MPlist *valids = MPLIST_NEXT (val);
1843 if (type != Minteger && type != Mtext && type != Msymbol)
1847 if (MPLIST_KEY (global) != Mt
1848 && MPLIST_KEY (global) != MPLIST_KEY (val))
1850 if (MPLIST_TAIL_P (valids))
1851 valids = MPLIST_NEXT (global);
1853 if (MPLIST_TAIL_P (valids))
1856 if (type == Minteger)
1858 int n = MPLIST_INTEGER (val);
1860 MPLIST_DO (valids, valids)
1862 if (MPLIST_INTEGER_P (valids))
1864 if (n == MPLIST_INTEGER (valids))
1867 else if (MPLIST_PLIST_P (valids))
1869 MPlist *p = MPLIST_PLIST (valids);
1870 int min_bound, max_bound;
1872 if (! MPLIST_INTEGER_P (p))
1873 MERROR (MERROR_IM, 0);
1874 min_bound = MPLIST_INTEGER (p);
1875 p = MPLIST_NEXT (p);
1876 if (! MPLIST_INTEGER_P (p))
1877 MERROR (MERROR_IM, 0);
1878 max_bound = MPLIST_INTEGER (p);
1879 if (n >= min_bound && n <= max_bound)
1884 else if (type == Msymbol)
1886 MSymbol sym = MPLIST_SYMBOL (val);
1888 MPLIST_DO (valids, valids)
1890 if (! MPLIST_SYMBOL_P (valids))
1891 MERROR (MERROR_IM, 0);
1892 if (sym == MPLIST_SYMBOL (valids))
1898 MText *mt = MPLIST_MTEXT (val);
1900 MPLIST_DO (valids, valids)
1902 if (! MPLIST_MTEXT_P (valids))
1903 MERROR (MERROR_IM, 0);
1904 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1909 return (! MPLIST_TAIL_P (valids));
1912 /* Load variable defitions from PLIST into IM_INFO->vars.
1914 PLIST is well-formed and has this form;
1915 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1917 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1919 The returned list has the same form, but for each element...
1921 (1) If DESCRIPTION and the rest are omitted, the element is not
1922 stored in the returned list.
1924 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1925 description in global_info->vars (if any). */
1928 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1930 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1931 ? global_info->vars : NULL);
1934 im_info->vars = tail = mplist ();
1935 MPLIST_DO (plist, MPLIST_NEXT (plist))
1939 if (MFAILP (MPLIST_PLIST_P (plist)))
1941 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1942 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1944 if (im_info == global_info)
1946 /* Loading a global variable. */
1947 p = MPLIST_NEXT (pl);
1948 if (MPLIST_TAIL_P (p))
1949 mplist_add (p, Msymbol, Mnil);
1952 if (! check_description (p))
1953 mplist_set (p, Msymbol, Mnil);
1954 p = MPLIST_NEXT (p);
1955 if (MFAILP (! MPLIST_TAIL_P (p)
1956 && check_variable_value (p, NULL)))
1957 mplist_set (p, Mt, NULL);
1960 else if (im_info->mdb)
1962 /* Loading a local variable. */
1963 MSymbol name = MPLIST_SYMBOL (pl);
1964 MPlist *global = NULL;
1967 && (p = mplist__assq (global_vars, name)))
1969 /* P ::= ((NAME DESC ...) ...) */
1970 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1971 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1972 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1975 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1976 if (! MPLIST_TAIL_P (p))
1978 if (! check_description (p))
1979 mplist_set (p, Msymbol, Mnil);
1980 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1981 if (MFAILP (! MPLIST_TAIL_P (p)))
1982 mplist_set (p, Mt, NULL);
1985 MPlist *valid_values = MPLIST_NEXT (p);
1987 if (! MPLIST_TAIL_P (valid_values)
1988 ? MFAILP (check_variable_value (p, NULL))
1989 : global && MFAILP (check_variable_value (p, global)))
1990 mplist_set (p, Mt, NULL);
1996 /* Loading a variable customization. */
1997 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1998 if (MFAILP (! MPLIST_TAIL_P (p)))
2000 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2001 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2002 || MPLIST_MTEXT_P (p)))
2005 tail = mplist_add (tail, Mplist, pl);
2010 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2011 MPlist *config_vars)
2013 MPlist *global = NULL, *custom = NULL, *config = NULL;
2014 MSymbol name = MPLIST_SYMBOL (plist);
2016 MPlist *description = NULL, *value, *valids;
2020 global = mplist__assq (global_vars, name);
2022 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2025 plist = MPLIST_NEXT (plist);
2026 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2027 description = plist;
2029 description = global;
2031 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2033 if (MPLIST_TAIL_P (plist))
2035 /* Inherit from global (if any). */
2039 if (MPLIST_KEY (value) == Mt)
2041 valids = MPLIST_NEXT (global);
2042 status = Minherited;
2054 value = plist = MPLIST_NEXT (plist);
2055 valids = MPLIST_NEXT (value);
2056 if (MPLIST_KEY (value) == Mt)
2058 if (! MPLIST_TAIL_P (valids))
2061 valids = MPLIST_NEXT (global);
2065 if (config_vars && (config = mplist__assq (config_vars, name)))
2067 status = Mconfigured;
2068 config = MPLIST_NEXT (MPLIST_PLIST (config));
2069 if (! MPLIST_TAIL_P (config))
2071 value = MPLIST_NEXT (config);
2072 if (MFAILP (check_variable_value (value, global ? global : plist)))
2076 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2078 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2079 if (! MPLIST_TAIL_P (custom))
2081 value = MPLIST_NEXT (custom);
2082 if (MFAILP (check_variable_value (value, global ? global : plist)))
2084 status = Mcustomized;
2089 mplist_add (plist, Msymbol, name);
2091 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2093 mplist_add (plist, Msymbol, Mnil);
2094 mplist_add (plist, Msymbol, status);
2096 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2098 mplist_add (plist, Mt, NULL);
2099 if (valids && ! MPLIST_TAIL_P (valids))
2100 mplist__conc (plist, valids);
2104 /* Return a configured variable definition list based on
2105 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2106 get it from global_info->vars. */
2109 config_all_variables (MInputMethodInfo *im_info)
2111 MPlist *global_vars, *custom_vars, *config_vars;
2112 MInputMethodInfo *temp;
2113 MPlist *tail, *plist;
2115 M17N_OBJECT_UNREF (im_info->configured_vars);
2117 if (MPLIST_TAIL_P (im_info->vars)
2121 global_vars = im_info != global_info ? global_info->vars : NULL;
2122 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2123 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2125 im_info->configured_vars = tail = mplist ();
2126 MPLIST_DO (plist, im_info->vars)
2128 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2129 global_vars, custom_vars, config_vars);
2132 tail = mplist_add (tail, Mplist, pl);
2133 M17N_OBJECT_UNREF (pl);
2138 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2139 CONFIG contains configuration information of the input method. */
2142 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2146 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2148 load_commands (im_info, MPLIST_PLIST (pl));
2149 config_all_commands (im_info);
2150 pl = mplist_pop (pl);
2151 M17N_OBJECT_UNREF (pl);
2154 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2156 load_variables (im_info, MPLIST_PLIST (pl));
2157 config_all_variables (im_info);
2158 pl = mplist_pop (pl);
2159 M17N_OBJECT_UNREF (pl);
2162 MPLIST_DO (plist, plist)
2163 if (MPLIST_PLIST_P (plist))
2165 MPlist *elt = MPLIST_PLIST (plist);
2168 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2170 key = MPLIST_SYMBOL (elt);
2175 elt = MPLIST_NEXT (elt);
2176 if (MFAILP (MPLIST_MTEXT_P (elt)))
2178 im_info->title = MPLIST_MTEXT (elt);
2179 M17N_OBJECT_REF (im_info->title);
2181 else if (key == Mmap)
2183 pl = mplist__from_alist (MPLIST_NEXT (elt));
2186 if (! im_info->maps)
2190 mplist__conc (im_info->maps, pl);
2191 M17N_OBJECT_UNREF (pl);
2194 else if (key == Mmacro)
2196 if (! im_info->macros)
2197 im_info->macros = mplist ();
2198 MPLIST_DO (elt, MPLIST_NEXT (elt))
2200 if (MFAILP (MPLIST_PLIST_P (elt)))
2202 load_macros (im_info, MPLIST_PLIST (elt));
2205 else if (key == Mmodule)
2207 if (! im_info->externals)
2208 im_info->externals = mplist ();
2209 MPLIST_DO (elt, MPLIST_NEXT (elt))
2211 if (MFAILP (MPLIST_PLIST_P (elt)))
2213 load_external_module (im_info, MPLIST_PLIST (elt));
2216 else if (key == Mstate)
2218 MPLIST_DO (elt, MPLIST_NEXT (elt))
2222 if (MFAILP (MPLIST_PLIST_P (elt)))
2224 pl = MPLIST_PLIST (elt);
2225 if (! im_info->states)
2226 im_info->states = mplist ();
2227 state = load_state (im_info, MPLIST_PLIST (elt));
2230 mplist_put (im_info->states, state->name, state);
2233 else if (key == Minclude)
2235 /* elt ::= include (tag1 tag2 ...) key item ... */
2237 MInputMethodInfo *temp;
2239 elt = MPLIST_NEXT (elt);
2240 if (MFAILP (MPLIST_PLIST_P (elt)))
2242 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2245 elt = MPLIST_NEXT (elt);
2246 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2248 key = MPLIST_SYMBOL (elt);
2249 elt = MPLIST_NEXT (elt);
2252 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2254 if (! im_info->maps)
2255 im_info->maps = mplist ();
2256 MPLIST_DO (pl, temp->maps)
2258 p = MPLIST_VAL (pl);
2259 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2260 M17N_OBJECT_REF (p);
2263 else if (key == Mmacro)
2265 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2267 if (! im_info->macros)
2268 im_info->macros = mplist ();
2269 MPLIST_DO (pl, temp->macros)
2271 p = MPLIST_VAL (pl);
2272 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2273 M17N_OBJECT_REF (p);
2276 else if (key == Mstate)
2278 if (! temp->states || MPLIST_TAIL_P (temp->states))
2280 if (! im_info->states)
2281 im_info->states = mplist ();
2282 MPLIST_DO (pl, temp->states)
2284 MIMState *state = MPLIST_VAL (pl);
2286 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2287 M17N_OBJECT_REF (state);
2291 else if (key == Mdescription)
2293 if (im_info->description)
2295 elt = MPLIST_NEXT (elt);
2296 if (! check_description (elt))
2298 im_info->description = MPLIST_MTEXT (elt);
2299 M17N_OBJECT_REF (im_info->description);
2302 im_info->tick = time (NULL);
2307 static int take_action_list (MInputContext *ic, MPlist *action_list);
2308 static void preedit_commit (MInputContext *ic);
2311 shift_state (MInputContext *ic, MSymbol state_name)
2313 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2314 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2315 MIMState *orig_state = ic_info->state, *state;
2317 /* Find a state to shift to. If not found, shift to the initial
2319 if (state_name == Mt)
2321 if (! ic_info->prev_state)
2323 state = ic_info->prev_state;
2325 else if (state_name == Mnil)
2327 state = (MIMState *) MPLIST_VAL (im_info->states);
2331 state = (MIMState *) mplist_get (im_info->states, state_name);
2333 state = (MIMState *) MPLIST_VAL (im_info->states);
2336 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2338 /* Enter the new state. */
2339 ic_info->state = state;
2340 ic_info->map = state->map;
2341 ic_info->state_key_head = ic_info->key_head;
2342 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2344 /* We have shifted to the initial state. */
2345 preedit_commit (ic);
2346 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2347 ic_info->state_pos = ic->cursor_pos;
2348 if (state != orig_state)
2350 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2352 /* Shifted to the initial state. */
2353 ic_info->prev_state = NULL;
2354 M17N_OBJECT_UNREF (ic_info->vars_saved);
2355 ic_info->vars_saved = mplist_copy (ic_info->vars);
2358 ic_info->prev_state = orig_state;
2361 ic->status = state->title;
2363 ic->status = im_info->title;
2364 ic->status_changed = 1;
2365 if (ic_info->map == ic_info->state->map
2366 && ic_info->map->map_actions)
2368 MDEBUG_PRINT (" init-actions:");
2369 take_action_list (ic, ic_info->map->map_actions);
2374 /* Find a candidate group that contains a candidate number INDEX from
2375 PLIST. Set START_INDEX to the first candidate number of the group,
2376 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2377 candidate group number if they are non-NULL. If INDEX is -1, find
2378 the last candidate group. */
2381 find_candidates_group (MPlist *plist, int index,
2382 int *start_index, int *end_index, int *group_index)
2384 int i = 0, gidx = 0, len;
2386 MPLIST_DO (plist, plist)
2388 if (MPLIST_MTEXT_P (plist))
2389 len = mtext_nchars (MPLIST_MTEXT (plist));
2391 len = mplist_length (MPLIST_PLIST (plist));
2392 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2398 *end_index = i + len;
2400 *group_index = gidx;
2409 /* Adjust markers for the change of preedit text.
2410 If FROM == TO, the change is insertion of INS chars.
2411 If FROM < TO and INS == 0, the change is deletion of the range.
2412 If FROM < TO and INS > 0, the change is replacement. */
2415 adjust_markers (MInputContext *ic, int from, int to, int ins)
2417 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2422 MPLIST_DO (markers, ic_info->markers)
2423 if (MPLIST_INTEGER (markers) > from)
2424 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2425 if (ic->cursor_pos >= from)
2426 ic->cursor_pos += ins;
2430 MPLIST_DO (markers, ic_info->markers)
2432 if (MPLIST_INTEGER (markers) >= to)
2433 MPLIST_VAL (markers)
2434 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2435 else if (MPLIST_INTEGER (markers) > from)
2436 MPLIST_VAL (markers) = (void *) from;
2438 if (ic->cursor_pos >= to)
2439 ic->cursor_pos += ins - (to - from);
2440 else if (ic->cursor_pos > from)
2441 ic->cursor_pos = from;
2447 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2449 int nchars = mt ? mtext_nchars (mt) : 1;
2452 mtext_ins (ic->preedit, pos, mt);
2454 mtext_ins_char (ic->preedit, pos, c, 1);
2455 adjust_markers (ic, pos, pos, nchars);
2456 ic->preedit_changed = 1;
2461 preedit_delete (MInputContext *ic, int from, int to)
2463 mtext_del (ic->preedit, from, to);
2464 adjust_markers (ic, from, to, 0);
2465 ic->preedit_changed = 1;
2469 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2473 mtext_del (ic->preedit, from, to);
2476 mtext_ins (ic->preedit, from, mt);
2477 ins = mtext_nchars (mt);
2481 mtext_ins_char (ic->preedit, from, c, 1);
2484 adjust_markers (ic, from, to, ins);
2485 ic->preedit_changed = 1;
2490 preedit_commit (MInputContext *ic)
2492 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2493 int preedit_len = mtext_nchars (ic->preedit);
2495 if (preedit_len > 0)
2499 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2500 Mcandidate_list, NULL, 0);
2501 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2502 Mcandidate_index, NULL, 0);
2503 mtext_cat (ic->produced, ic->preedit);
2504 if (mdebug__flag & mdebug_mask)
2508 MDEBUG_PRINT (" (commit");
2509 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2510 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2514 mtext_reset (ic->preedit);
2515 mtext_reset (ic_info->preedit_saved);
2516 MPLIST_DO (p, ic_info->markers)
2518 ic->cursor_pos = ic_info->state_pos = 0;
2519 ic->preedit_changed = 1;
2520 ic_info->commit_key_head = ic_info->key_head;
2522 if (ic->candidate_list)
2524 M17N_OBJECT_UNREF (ic->candidate_list);
2525 ic->candidate_list = NULL;
2526 ic->candidate_index = 0;
2527 ic->candidate_from = ic->candidate_to = 0;
2528 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2529 if (ic->candidate_show)
2531 ic->candidate_show = 0;
2532 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2538 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2540 int code = marker_code (sym, 0);
2542 if (mt && (code == '[' || code == ']'))
2546 if (code == '[' && current > 0)
2548 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2552 else if (code == ']' && current < mtext_nchars (mt))
2554 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2560 return (code == '<' ? 0
2561 : code == '>' ? limit
2562 : code == '-' ? current - 1
2563 : code == '+' ? current + 1
2564 : code == '=' ? current
2565 : code - '0' > limit ? limit
2569 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2573 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2575 int from = mtext_property_start (prop);
2576 int to = mtext_property_end (prop);
2578 MPlist *candidate_list = mtext_property_value (prop);
2579 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2581 int ingroup_index = idx - start;
2584 if (MPLIST_MTEXT_P (group))
2586 mt = MPLIST_MTEXT (group);
2587 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2595 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2596 i++, plist = MPLIST_NEXT (plist));
2597 mt = MPLIST_MTEXT (plist);
2598 preedit_replace (ic, from, to, mt, 0);
2599 to = from + mtext_nchars (mt);
2601 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2602 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2603 ic->cursor_pos = to;
2607 get_select_charset (MInputContextInfo * ic_info)
2609 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2612 if (! MPLIST_VAL (plist))
2614 sym = MPLIST_SYMBOL (plist);
2617 return MCHARSET (sym);
2621 adjust_candidates (MPlist *plist, MCharset *charset)
2625 /* plist ::= MTEXT ... | PLIST ... */
2626 plist = mplist_copy (plist);
2627 if (MPLIST_MTEXT_P (plist))
2630 while (! MPLIST_TAIL_P (pl))
2632 /* pl ::= MTEXT ... */
2633 MText *mt = MPLIST_MTEXT (pl);
2637 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2639 c = mtext_ref_char (mt, i);
2640 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2644 mt = mtext_dup (mt);
2645 mplist_set (pl, Mtext, mt);
2646 M17N_OBJECT_UNREF (mt);
2649 mtext_del (mt, i, i + 1);
2652 if (mtext_len (mt) > 0)
2653 pl = MPLIST_NEXT (pl);
2657 M17N_OBJECT_UNREF (mt);
2661 else /* MPLIST_PLIST_P (plist) */
2664 while (! MPLIST_TAIL_P (pl))
2666 /* pl ::= (MTEXT ...) ... */
2667 MPlist *p = MPLIST_PLIST (pl);
2669 /* p ::= MTEXT ... */
2673 while (! MPLIST_TAIL_P (p0))
2675 MText *mt = MPLIST_MTEXT (p0);
2678 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2680 c = mtext_ref_char (mt, i);
2681 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2686 p0 = MPLIST_NEXT (p0);
2693 p = mplist_copy (p);
2694 mplist_set (pl, Mplist, p);
2695 M17N_OBJECT_UNREF (p);
2699 p0 = MPLIST_NEXT (p0);
2702 M17N_OBJECT_UNREF (mt);
2705 if (! MPLIST_TAIL_P (p))
2706 pl = MPLIST_NEXT (pl);
2710 M17N_OBJECT_UNREF (p);
2714 if (MPLIST_TAIL_P (plist))
2716 M17N_OBJECT_UNREF (plist);
2723 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2725 MCharset *charset = get_select_charset (ic_info);
2730 plist = resolve_variable (ic_info, Mcandidates_group_size);
2731 column = MPLIST_INTEGER (plist);
2733 plist = MPLIST_PLIST (args);
2735 plist = adjust_candidates (plist, charset);
2737 if (plist && column > 0)
2739 if (MPLIST_MTEXT_P (plist))
2741 MText *mt = MPLIST_MTEXT (plist);
2742 MPlist *next = MPLIST_NEXT (plist);
2744 if (MPLIST_TAIL_P (next))
2745 M17N_OBJECT_REF (mt);
2748 mt = mtext_dup (mt);
2749 while (! MPLIST_TAIL_P (next))
2751 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2752 next = MPLIST_NEXT (next);
2755 M17N_OBJECT_UNREF (plist);
2757 len = mtext_nchars (mt);
2759 mplist_add (plist, Mtext, mt);
2762 for (i = 0; i < len; i += column)
2764 int to = (i + column < len ? i + column : len);
2765 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2767 mplist_add (plist, Mtext, sub);
2768 M17N_OBJECT_UNREF (sub);
2771 M17N_OBJECT_UNREF (mt);
2773 else if (! MPLIST_TAIL_P (plist))
2775 MPlist *tail = plist;
2776 MPlist *new = mplist ();
2777 MPlist *this = mplist ();
2780 MPLIST_DO (tail, tail)
2782 MPlist *p = MPLIST_PLIST (tail);
2786 MText *mt = MPLIST_MTEXT (p);
2788 if (count == column)
2790 mplist_add (new, Mplist, this);
2791 M17N_OBJECT_UNREF (this);
2795 mplist_add (this, Mtext, mt);
2799 mplist_add (new, Mplist, this);
2800 M17N_OBJECT_UNREF (this);
2801 mplist_set (plist, Mnil, NULL);
2802 MPLIST_DO (tail, new)
2804 MPlist *elt = MPLIST_PLIST (tail);
2806 mplist_add (plist, Mplist, elt);
2808 M17N_OBJECT_UNREF (new);
2817 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2819 MPlist *action = NULL;
2823 if (MPLIST_SYMBOL_P (action_list))
2825 MSymbol var = MPLIST_SYMBOL (action_list);
2828 MPLIST_DO (p, ic_info->vars)
2829 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2831 if (MPLIST_TAIL_P (p))
2833 action = MPLIST_NEXT (MPLIST_PLIST (p));
2834 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2837 if (MPLIST_PLIST_P (action_list))
2839 action = MPLIST_PLIST (action_list);
2840 if (MPLIST_SYMBOL_P (action))
2842 name = MPLIST_SYMBOL (action);
2843 args = MPLIST_NEXT (action);
2845 && MPLIST_PLIST_P (args))
2846 mplist_set (action, Msymbol, M_candidates);
2848 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2851 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2852 mplist_push (action, Msymbol, M_candidates);
2853 mplist_set (action_list, Mplist, action);
2854 M17N_OBJECT_UNREF (action);
2857 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2860 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2861 mplist_push (action, Msymbol, Minsert);
2862 mplist_set (action_list, Mplist, action);
2863 M17N_OBJECT_UNREF (action);
2868 /* Perform list of actions in ACTION_LIST for the current input
2869 context IC. If unhandle action was not performed, return 0.
2870 Otherwise, return -1. */
2873 take_action_list (MInputContext *ic, MPlist *action_list)
2875 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2876 MPlist *candidate_list = ic->candidate_list;
2877 int candidate_index = ic->candidate_index;
2878 int candidate_show = ic->candidate_show;
2879 MTextProperty *prop;
2881 MPLIST_DO (action_list, action_list)
2883 MPlist *action = regularize_action (action_list, ic_info);
2889 name = MPLIST_SYMBOL (action);
2890 args = MPLIST_NEXT (action);
2892 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2893 if (name == Minsert)
2895 if (MPLIST_SYMBOL_P (args))
2897 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2898 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2901 if (MPLIST_MTEXT_P (args))
2902 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2903 else /* MPLIST_INTEGER_P (args)) */
2904 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2906 else if (name == M_candidates)
2908 MPlist *plist = get_candidate_list (ic_info, args);
2911 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2913 if (MPLIST_MTEXT_P (plist))
2915 preedit_insert (ic, ic->cursor_pos, NULL,
2916 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2919 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2923 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2925 preedit_insert (ic, ic->cursor_pos, mt, 0);
2926 len = mtext_nchars (mt);
2928 mtext_put_prop (ic->preedit,
2929 ic->cursor_pos - len, ic->cursor_pos,
2930 Mcandidate_list, plist);
2931 mtext_put_prop (ic->preedit,
2932 ic->cursor_pos - len, ic->cursor_pos,
2933 Mcandidate_index, (void *) 0);
2935 else if (name == Mselect)
2938 int code, idx, gindex;
2939 int pos = ic->cursor_pos;
2941 int idx_decided = 0;
2944 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2947 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2948 group = find_candidates_group (mtext_property_value (prop), idx,
2949 &start, &end, &gindex);
2950 if (MPLIST_SYMBOL_P (args))
2952 code = marker_code (MPLIST_SYMBOL (args), 0);
2955 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2956 if (! MPLIST_INTEGER_P (args))
2958 idx = start + MPLIST_INTEGER (args);
2959 if (idx < start || idx >= end)
2967 if (code != '[' && code != ']')
2972 ? new_index (NULL, ic->candidate_index - start,
2973 end - start - 1, MPLIST_SYMBOL (args),
2975 : MPLIST_INTEGER (args)));
2978 find_candidates_group (mtext_property_value (prop), -1,
2983 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2988 int ingroup_index = idx - start;
2991 group = mtext_property_value (prop);
2992 len = mplist_length (group);
3005 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3006 idx += (MPLIST_MTEXT_P (group)
3007 ? mtext_nchars (MPLIST_MTEXT (group))
3008 : mplist_length (MPLIST_PLIST (group)));
3009 len = (MPLIST_MTEXT_P (group)
3010 ? mtext_nchars (MPLIST_MTEXT (group))
3011 : mplist_length (MPLIST_PLIST (group)));
3012 if (ingroup_index >= len)
3013 ingroup_index = len - 1;
3014 idx += ingroup_index;
3016 update_candidate (ic, prop, idx);
3017 MDEBUG_PRINT1 ("(%d)", idx);
3019 else if (name == Mshow)
3020 ic->candidate_show = 1;
3021 else if (name == Mhide)
3022 ic->candidate_show = 0;
3023 else if (name == Mdelete)
3025 int len = mtext_nchars (ic->preedit);
3029 if (MPLIST_SYMBOL_P (args)
3030 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3032 to = ic->cursor_pos + pos;
3035 delete_surrounding_text (ic, to);
3040 delete_surrounding_text (ic, to - len);
3046 to = (MPLIST_SYMBOL_P (args)
3047 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3049 : MPLIST_INTEGER (args));
3055 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3056 if (to < ic->cursor_pos)
3057 preedit_delete (ic, to, ic->cursor_pos);
3058 else if (to > ic->cursor_pos)
3059 preedit_delete (ic, ic->cursor_pos, to);
3061 else if (name == Mmove)
3063 int len = mtext_nchars (ic->preedit);
3065 = (MPLIST_SYMBOL_P (args)
3066 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3068 : MPLIST_INTEGER (args));
3074 if (pos != ic->cursor_pos)
3076 ic->cursor_pos = pos;
3077 ic->preedit_changed = 1;
3079 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3081 else if (name == Mmark)
3083 int code = marker_code (MPLIST_SYMBOL (args), 0);
3087 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3088 (void *) ic->cursor_pos);
3089 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3092 else if (name == Mpushback)
3094 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3098 if (MPLIST_SYMBOL_P (args))
3100 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3101 if (MPLIST_INTEGER_P (args))
3102 num = MPLIST_INTEGER (args);
3107 num = MPLIST_INTEGER (args);
3110 ic_info->key_head -= num;
3112 ic_info->key_head = 0;
3114 ic_info->key_head = - num;
3115 if (ic_info->key_head > ic_info->used)
3116 ic_info->key_head = ic_info->used;
3118 else if (MPLIST_MTEXT_P (args))
3120 MText *mt = MPLIST_MTEXT (args);
3121 int i, len = mtext_nchars (mt);
3124 ic_info->key_head--;
3125 for (i = 0; i < len; i++)
3127 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3128 if (ic_info->key_head + i < ic_info->used)
3129 ic_info->keys[ic_info->key_head + i] = key;
3131 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3136 MPlist *plist = MPLIST_PLIST (args), *pl;
3140 ic_info->key_head--;
3142 MPLIST_DO (pl, plist)
3144 key = MPLIST_SYMBOL (pl);
3145 if (ic_info->key_head < ic_info->used)
3146 ic_info->keys[ic_info->key_head + i] = key;
3148 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3153 else if (name == Mpop)
3155 if (ic_info->key_head < ic_info->used)
3156 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3158 else if (name == Mcall)
3160 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3161 MIMExternalFunc func = NULL;
3162 MSymbol module, func_name;
3163 MPlist *func_args, *val;
3166 module = MPLIST_SYMBOL (args);
3167 args = MPLIST_NEXT (args);
3168 func_name = MPLIST_SYMBOL (args);
3170 if (im_info->externals)
3172 MIMExternalModule *external
3173 = (MIMExternalModule *) mplist_get (im_info->externals,
3176 func = (MIMExternalFunc) mplist_get (external->func_list,
3181 func_args = mplist ();
3182 mplist_add (func_args, Mt, ic);
3183 MPLIST_DO (args, MPLIST_NEXT (args))
3187 if (MPLIST_KEY (args) == Msymbol
3188 && MPLIST_KEY (args) != Mnil
3189 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3191 code = new_index (ic, ic->cursor_pos,
3192 mtext_nchars (ic->preedit),
3193 MPLIST_SYMBOL (args), ic->preedit);
3194 mplist_add (func_args, Minteger, (void *) code);
3197 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3199 val = (func) (func_args);
3200 M17N_OBJECT_UNREF (func_args);
3201 if (val && ! MPLIST_TAIL_P (val))
3202 ret = take_action_list (ic, val);
3203 M17N_OBJECT_UNREF (val);
3207 else if (name == Mshift)
3209 shift_state (ic, MPLIST_SYMBOL (args));
3211 else if (name == Mundo)
3213 int intarg = (MPLIST_TAIL_P (args)
3215 : integer_value (ic, args, NULL, 0));
3217 mtext_reset (ic->preedit);
3218 mtext_reset (ic_info->preedit_saved);
3219 mtext_reset (ic->produced);
3220 M17N_OBJECT_UNREF (ic_info->vars);
3221 ic_info->vars = mplist_copy (ic_info->vars_saved);
3222 ic->cursor_pos = ic_info->state_pos = 0;
3223 ic_info->state_key_head = ic_info->key_head
3224 = ic_info->commit_key_head = 0;
3226 shift_state (ic, Mnil);
3229 if (MPLIST_TAIL_P (args))
3234 ic_info->used += intarg;
3237 ic_info->used = intarg;
3240 else if (name == Mset || name == Madd || name == Msub
3241 || name == Mmul || name == Mdiv)
3243 MSymbol sym = MPLIST_SYMBOL (args);
3248 val1 = integer_value (ic, args, &value, 0);
3249 args = MPLIST_NEXT (args);
3250 val2 = resolve_expression (ic, args);
3252 val1 = val2, op = "=";
3253 else if (name == Madd)
3254 val1 += val2, op = "+=";
3255 else if (name == Msub)
3256 val1 -= val2, op = "-=";
3257 else if (name == Mmul)
3258 val1 *= val2, op = "*=";
3260 val1 /= val2, op = "/=";
3261 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3262 MSYMBOL_NAME (sym), op, val1, val1);
3264 mplist_set (value, Minteger, (void *) val1);
3266 else if (name == Mequal || name == Mless || name == Mgreater
3267 || name == Mless_equal || name == Mgreater_equal)
3270 MPlist *actions1, *actions2;
3273 val1 = resolve_expression (ic, args);
3274 args = MPLIST_NEXT (args);
3275 val2 = resolve_expression (ic, args);
3276 args = MPLIST_NEXT (args);
3277 actions1 = MPLIST_PLIST (args);
3278 args = MPLIST_NEXT (args);
3279 if (MPLIST_TAIL_P (args))
3282 actions2 = MPLIST_PLIST (args);
3283 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3284 if (name == Mequal ? val1 == val2
3285 : name == Mless ? val1 < val2
3286 : name == Mgreater ? val1 > val2
3287 : name == Mless_equal ? val1 <= val2
3290 MDEBUG_PRINT ("ok");
3291 ret = take_action_list (ic, actions1);
3295 MDEBUG_PRINT ("no");
3297 ret = take_action_list (ic, actions2);
3302 else if (name == Mcond)
3306 MPLIST_DO (args, args)
3311 if (! MPLIST_PLIST (args))
3313 cond = MPLIST_PLIST (args);
3314 if (resolve_expression (ic, cond) != 0)
3316 MDEBUG_PRINT1 ("(%dth)", idx);
3317 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3323 else if (name == Mcommit)
3325 preedit_commit (ic);
3327 else if (name == Munhandle)
3329 preedit_commit (ic);
3334 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3338 && (actions = mplist_get (im_info->macros, name)))
3340 if (take_action_list (ic, actions) < 0)
3346 if (ic->candidate_list)
3348 M17N_OBJECT_UNREF (ic->candidate_list);
3349 ic->candidate_list = NULL;
3351 if (ic->cursor_pos > 0
3352 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3355 ic->candidate_list = mtext_property_value (prop);
3356 M17N_OBJECT_REF (ic->candidate_list);
3358 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3360 ic->candidate_from = mtext_property_start (prop);
3361 ic->candidate_to = mtext_property_end (prop);
3364 if (candidate_list != ic->candidate_list)
3365 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3366 if (candidate_index != ic->candidate_index)
3367 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3368 if (candidate_show != ic->candidate_show)
3369 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3374 /* Handle the input key KEY in the current state and map specified in
3375 the input context IC. If KEY is handled correctly, return 0.
3376 Otherwise, return -1. */
3379 handle_key (MInputContext *ic)
3381 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3382 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3383 MIMMap *map = ic_info->map;
3384 MIMMap *submap = NULL;
3385 MSymbol key = ic_info->keys[ic_info->key_head];
3386 MSymbol alias = Mnil;
3389 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3390 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3394 submap = mplist_get (map->submaps, key);
3397 && (alias = msymbol_get (alias, M_key_alias))
3399 submap = mplist_get (map->submaps, alias);
3404 if (! alias || alias == key)
3405 MDEBUG_PRINT (" submap-found");
3407 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3408 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3409 ic->preedit_changed = 1;
3410 ic->cursor_pos = ic_info->state_pos;
3411 ic_info->key_head++;
3412 ic_info->map = map = submap;
3413 if (map->map_actions)
3415 MDEBUG_PRINT (" map-actions:");
3416 if (take_action_list (ic, map->map_actions) < 0)
3418 MDEBUG_PRINT ("\n");
3422 else if (map->submaps)
3424 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3426 MSymbol key = ic_info->keys[i];
3427 char *name = msymbol_name (key);
3429 if (! name[0] || ! name[1])
3430 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3434 /* If this is the terminal map or we have shifted to another
3435 state, perform branch actions (if any). */
3436 if (! map->submaps || map != ic_info->map)
3438 if (map->branch_actions)
3440 MDEBUG_PRINT (" branch-actions:");
3441 if (take_action_list (ic, map->branch_actions) < 0)
3443 MDEBUG_PRINT ("\n");
3447 /* If MAP is still not the root map, shift to the current
3449 if (ic_info->map != ic_info->state->map)
3450 shift_state (ic, ic_info->state->name);
3455 /* MAP can not handle KEY. */
3457 /* Perform branch actions if any. */
3458 if (map->branch_actions)
3460 MDEBUG_PRINT (" branch-actions:");
3461 if (take_action_list (ic, map->branch_actions) < 0)
3463 MDEBUG_PRINT ("\n");
3468 if (map == ic_info->map)
3470 /* The above branch actions didn't change the state. */
3472 /* If MAP is the root map of the initial state, and there
3473 still exist an unhandled key, it means that the current
3474 input method can not handle it. */
3475 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3476 && ic_info->key_head < ic_info->used)
3478 MDEBUG_PRINT (" unhandled\n");
3482 if (map != ic_info->state->map)
3484 /* MAP is not the root map. Shift to the root map of the
3486 shift_state (ic, ic_info->state->name);
3488 else if (! map->branch_actions)
3490 /* MAP is the root map without any default branch
3491 actions. Shift to the initial state. */
3492 shift_state (ic, Mnil);
3496 MDEBUG_PRINT ("\n");
3500 /* Initialize IC->ic_info. */
3503 init_ic_info (MInputContext *ic)
3505 MInputMethodInfo *im_info = ic->im->info;
3506 MInputContextInfo *ic_info = ic->info;
3509 MLIST_INIT1 (ic_info, keys, 8);;
3511 ic_info->markers = mplist ();
3513 ic_info->vars = mplist ();
3514 if (im_info->configured_vars)
3515 MPLIST_DO (plist, im_info->configured_vars)
3517 MPlist *pl = MPLIST_PLIST (plist);
3518 MSymbol name = MPLIST_SYMBOL (pl);
3520 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3521 if (MPLIST_KEY (pl) != Mt)
3523 MPlist *p = mplist ();
3525 mplist_push (ic_info->vars, Mplist, p);
3526 M17N_OBJECT_UNREF (p);
3527 mplist_add (p, Msymbol, name);
3528 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3531 ic_info->vars_saved = mplist_copy (ic_info->vars);
3533 if (im_info->externals)
3535 MPlist *func_args = mplist (), *plist;
3537 mplist_add (func_args, Mt, ic);
3538 MPLIST_DO (plist, im_info->externals)
3540 MIMExternalModule *external = MPLIST_VAL (plist);
3541 MIMExternalFunc func
3542 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3547 M17N_OBJECT_UNREF (func_args);
3550 ic_info->preedit_saved = mtext ();
3551 ic_info->tick = im_info->tick;
3554 /* Finalize IC->ic_info. */
3557 fini_ic_info (MInputContext *ic)
3559 MInputMethodInfo *im_info = ic->im->info;
3560 MInputContextInfo *ic_info = ic->info;
3562 if (im_info->externals)
3564 MPlist *func_args = mplist (), *plist;
3566 mplist_add (func_args, Mt, ic);
3567 MPLIST_DO (plist, im_info->externals)
3569 MIMExternalModule *external = MPLIST_VAL (plist);
3570 MIMExternalFunc func
3571 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3576 M17N_OBJECT_UNREF (func_args);
3579 MLIST_FREE1 (ic_info, keys);
3580 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3581 M17N_OBJECT_UNREF (ic_info->markers);
3582 M17N_OBJECT_UNREF (ic_info->vars);
3583 M17N_OBJECT_UNREF (ic_info->vars_saved);
3584 M17N_OBJECT_UNREF (ic_info->preceding_text);
3585 M17N_OBJECT_UNREF (ic_info->following_text);
3587 memset (ic_info, 0, sizeof (MInputContextInfo));
3591 re_init_ic (MInputContext *ic, int reload)
3593 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3594 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3595 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3597 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3598 preedit_changed = mtext_nchars (ic->preedit) > 0;
3599 cursor_pos_changed = ic->cursor_pos > 0;
3600 candidates_changed = 0;
3601 if (ic->candidate_list)
3603 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3604 M17N_OBJECT_UNREF (ic->candidate_list);
3605 ic->candidate_list = NULL;
3607 if (ic->candidate_show)
3609 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3610 ic->candidate_show = 0;
3612 if (ic->candidate_index > 0)
3614 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3615 ic->candidate_index = 0;
3616 ic->candidate_from = ic->candidate_to = 0;
3618 if (mtext_nchars (ic->produced) > 0)
3619 mtext_reset (ic->produced);
3620 if (mtext_nchars (ic->preedit) > 0)
3621 mtext_reset (ic->preedit);
3623 M17N_OBJECT_UNREF (ic->plist);
3624 ic->plist = mplist ();
3628 reload_im_info (im_info);
3630 shift_state (ic, Mnil);
3631 ic->status_changed = status_changed;
3632 ic->preedit_changed = preedit_changed;
3633 ic->cursor_pos_changed = cursor_pos_changed;
3634 ic->candidates_changed = candidates_changed;
3638 reset_ic (MInputContext *ic, MSymbol ignore)
3640 MDEBUG_PRINT ("\n [IM] reset\n");
3645 open_im (MInputMethod *im)
3647 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3650 MERROR (MERROR_IM, -1);
3657 close_im (MInputMethod *im)
3663 create_ic (MInputContext *ic)
3665 MInputContextInfo *ic_info;
3667 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3670 shift_state (ic, Mnil);
3675 destroy_ic (MInputContext *ic)
3682 check_reload (MInputContext *ic, MSymbol key)
3684 MInputMethodInfo *im_info = ic->im->info;
3685 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3689 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3693 MPLIST_DO (plist, plist)
3695 MSymbol this_key, alias;
3697 if (MPLIST_MTEXT_P (plist))
3699 MText *mt = MPLIST_MTEXT (plist);
3700 int c = mtext_ref_char (mt, 0);
3704 this_key = one_char_symbol[c];
3708 MPlist *pl = MPLIST_PLIST (plist);
3710 this_key = MPLIST_SYMBOL (pl);
3714 && (alias = msymbol_get (alias, M_key_alias))
3715 && alias != this_key);
3719 if (MPLIST_TAIL_P (plist))
3722 MDEBUG_PRINT ("\n [IM] reload");
3728 /** Handle the input key KEY in the current state and map of IC->info.
3729 If KEY is handled but no text is produced, return 0, otherwise
3735 filter (MInputContext *ic, MSymbol key, void *arg)
3737 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3738 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3741 if (check_reload (ic, key))
3744 if (! ic_info->state)
3746 ic_info->key_unhandled = 1;
3749 mtext_reset (ic->produced);
3750 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3751 M17N_OBJECT_UNREF (ic_info->preceding_text);
3752 M17N_OBJECT_UNREF (ic_info->following_text);
3753 ic_info->preceding_text = ic_info->following_text = NULL;
3754 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3755 ic_info->key_unhandled = 0;
3758 if (handle_key (ic) < 0)
3760 /* KEY was not handled. Delete it from the current key sequence. */
3761 if (ic_info->used > 0)
3763 memmove (ic_info->keys, ic_info->keys + 1,
3764 sizeof (int) * (ic_info->used - 1));
3766 if (ic_info->state_key_head > 0)
3767 ic_info->state_key_head--;
3768 if (ic_info->commit_key_head > 0)
3769 ic_info->commit_key_head--;
3771 /* This forces returning 1. */
3772 ic_info->key_unhandled = 1;
3778 reset_ic (ic, Mnil);
3779 ic_info->key_unhandled = 1;
3782 /* Break the loop if all keys were handled. */
3783 } while (ic_info->key_head < ic_info->used);
3785 /* If the current map is the root of the initial state, we should
3786 produce any preedit text in ic->produced. */
3787 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3788 preedit_commit (ic);
3790 if (mtext_nchars (ic->produced) > 0)
3792 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3794 if (mdebug__flag & mdebug_mask)
3796 MDEBUG_PRINT (" (produced");
3797 for (i = 0; i < mtext_nchars (ic->produced); i++)
3798 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3803 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3804 Mlanguage, ic->im->language);
3806 if (ic_info->commit_key_head > 0)
3808 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3809 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3810 ic_info->used -= ic_info->commit_key_head;
3811 ic_info->key_head -= ic_info->commit_key_head;
3812 ic_info->state_key_head -= ic_info->commit_key_head;
3813 ic_info->commit_key_head = 0;
3815 if (ic_info->key_unhandled)
3818 ic_info->key_head = ic_info->state_key_head
3819 = ic_info->commit_key_head = 0;
3822 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3826 /** Return 1 if the last event or key was not handled, otherwise
3829 There is no need of looking up because ic->produced should already
3830 contain the produced text (if any).
3835 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3837 mtext_cat (mt, ic->produced);
3838 mtext_reset (ic->produced);
3839 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3843 /* Input method command handler. */
3845 /* List of all (global and local) commands.
3846 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3847 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3848 Global commands are stored as (t (t COMMAND ...)) */
3851 /* Input method variable handler. */
3854 /* Support functions for mdebug_dump_im. */
3857 dump_im_map (MPlist *map_list, int indent)
3860 MSymbol key = MPLIST_KEY (map_list);
3861 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3863 prefix = (char *) alloca (indent + 1);
3864 memset (prefix, 32, indent);
3865 prefix[indent] = '\0';
3867 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3868 if (map->map_actions)
3869 mdebug_dump_plist (map->map_actions, indent + 2);
3872 MPLIST_DO (map_list, map->submaps)
3874 fprintf (stderr, "\n%s ", prefix);
3875 dump_im_map (map_list, indent + 2);
3878 if (map->branch_actions)
3880 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3881 mdebug_dump_plist (map->branch_actions, indent + 4);
3882 fprintf (stderr, ")");
3884 fprintf (stderr, ")");
3889 dump_im_state (MIMState *state, int indent)
3894 prefix = (char *) alloca (indent + 1);
3895 memset (prefix, 32, indent);
3896 prefix[indent] = '\0';
3898 fprintf (stderr, "(%s", msymbol_name (state->name));
3899 if (state->map->submaps)
3901 MPLIST_DO (map_list, state->map->submaps)
3903 fprintf (stderr, "\n%s ", prefix);
3904 dump_im_map (map_list, indent + 2);
3907 fprintf (stderr, ")");
3915 Minput_driver = msymbol ("input-driver");
3917 Minput_preedit_start = msymbol ("input-preedit-start");
3918 Minput_preedit_done = msymbol ("input-preedit-done");
3919 Minput_preedit_draw = msymbol ("input-preedit-draw");
3920 Minput_status_start = msymbol ("input-status-start");
3921 Minput_status_done = msymbol ("input-status-done");
3922 Minput_status_draw = msymbol ("input-status-draw");
3923 Minput_candidates_start = msymbol ("input-candidates-start");
3924 Minput_candidates_done = msymbol ("input-candidates-done");
3925 Minput_candidates_draw = msymbol ("input-candidates-draw");
3926 Minput_set_spot = msymbol ("input-set-spot");
3927 Minput_focus_move = msymbol ("input-focus-move");
3928 Minput_focus_in = msymbol ("input-focus-in");
3929 Minput_focus_out = msymbol ("input-focus-out");
3930 Minput_toggle = msymbol ("input-toggle");
3931 Minput_reset = msymbol ("input-reset");
3932 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3933 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3934 Mcustomized = msymbol ("customized");
3935 Mconfigured = msymbol ("configured");
3936 Minherited = msymbol ("inherited");
3938 minput_default_driver.open_im = open_im;
3939 minput_default_driver.close_im = close_im;
3940 minput_default_driver.create_ic = create_ic;
3941 minput_default_driver.destroy_ic = destroy_ic;
3942 minput_default_driver.filter = filter;
3943 minput_default_driver.lookup = lookup;
3944 minput_default_driver.callback_list = mplist ();
3945 mplist_put (minput_default_driver.callback_list, Minput_reset,
3947 minput_driver = &minput_default_driver;
3949 fully_initialized = 0;
3956 if (fully_initialized)
3958 free_im_list (im_info_list);
3960 free_im_list (im_custom_list);
3962 free_im_list (im_config_list);
3963 M17N_OBJECT_UNREF (load_im_info_keys);
3966 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3967 M17N_OBJECT_UNREF (minput_driver->callback_list);
3972 minput__char_to_key (int c)
3974 if (c < 0 || c >= 0x100)
3977 return one_char_symbol[c];
3981 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3986 /*** @addtogroup m17nInputMethod */
3991 @name Variables: Predefined symbols for callback commands.
3993 These are the predefined symbols that are used as the @c COMMAND
3994 argument of callback functions of an input method driver (see
3995 #MInputDriver::callback_list).
3997 Most of them do not require extra argument nor return any value;
3998 exceptions are these:
4000 Minput_get_surrounding_text: When a callback function assigned for
4001 this command is called, the first element of #MInputContext::plist
4002 has key #Minteger and the value specifies which portion of the
4003 surrounding text should be retrieved. If the value is positive,
4004 it specifies the number of characters following the current cursor
4005 position. If the value is negative, the absolute value specifies
4006 the number of characters preceding the current cursor position.
4007 If the value is zero, it means that the caller just wants to know
4008 if the surrounding text is currently supported or not.
4010 If the surrounding text is currently supported, the callback
4011 function must set the key of this element to #Mtext and the value
4012 to the retrieved M-text. The length of the M-text may be shorter
4013 than the requested number of characters, if the available text is
4014 not that long. The length can be zero in the worst case. Or, the
4015 length may be longer if an application thinks it is more efficient
4016 to return that length.
4018 If the surrounding text is not currently supported, the callback
4019 function should return without changing the first element of
4020 #MInputContext::plist.
4022 Minput_delete_surrounding_text: When a callback function assigned
4023 for this command is called, the first element of
4024 #MInputContext::plist has key #Minteger and the value specifies
4025 which portion of the surrounding text should be deleted in the
4026 same way as the case of Minput_get_surrounding_text. The callback
4027 function must delete the specified text. It should not alter
4028 #MInputContext::plist. */
4030 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4032 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4033 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4035 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4037 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4038 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4039 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4040 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4041 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4042 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4043 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4045 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4046 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4047 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4048 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4049 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4051 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4052 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4054 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4055 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4056 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4057 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4058 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4059 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4063 MSymbol Minput_preedit_start;
4064 MSymbol Minput_preedit_done;
4065 MSymbol Minput_preedit_draw;
4066 MSymbol Minput_status_start;
4067 MSymbol Minput_status_done;
4068 MSymbol Minput_status_draw;
4069 MSymbol Minput_candidates_start;
4070 MSymbol Minput_candidates_done;
4071 MSymbol Minput_candidates_draw;
4072 MSymbol Minput_set_spot;
4073 MSymbol Minput_toggle;
4074 MSymbol Minput_reset;
4075 MSymbol Minput_get_surrounding_text;
4076 MSymbol Minput_delete_surrounding_text;
4082 @name Variables: Predefined symbols for special input events.
4084 These are the predefined symbols that are used as the @c KEY
4085 argument of minput_filter (). */
4087 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4089 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4094 MSymbol Minput_focus_out;
4095 MSymbol Minput_focus_in;
4096 MSymbol Minput_focus_move;
4102 @name Variables: Predefined symbols used in input method information.
4104 These are the predefined symbols describing status of input method
4105 command and variable, and are used in a return value of
4106 minput_get_command () and minput_get_variable (). */
4108 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4110 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4111 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4115 MSymbol Mcustomized;
4116 MSymbol Mconfigured;
4122 @brief The default driver for internal input methods.
4124 The variable #minput_default_driver is the default driver for
4125 internal input methods.
4127 The member MInputDriver::open_im () searches the m17n database for
4128 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4129 $NAME\> and loads it.
4131 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4132 programmers responsibility to set it to a plist of proper callback
4133 functions. Otherwise, no feedback information (e.g. preedit text)
4134 can be shown to users.
4136 The macro M17N_INIT () sets the variable #minput_driver to the
4137 pointer to this driver so that all internal input methods use it.
4139 Therefore, unless @c minput_driver is set differently, the driver
4140 dependent arguments $ARG of the functions whose name begins with
4141 "minput_" are all ignored. */
4143 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4145 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4147 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4148 \< #Minput_method, $LANGUAGE, $NAME\>
4149 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4151 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4152 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4153 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4154 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4156 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4157 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4159 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4160 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4162 MInputDriver minput_default_driver;
4166 @brief The driver for internal input methods.
4168 The variable #minput_driver is a pointer to the input method
4169 driver that is used by internal input methods. The macro
4170 M17N_INIT () initializes it to a pointer to #minput_default_driver
4171 if <m17n<EM></EM>.h> is included. */
4173 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4175 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4176 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4177 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4178 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4180 MInputDriver *minput_driver;
4182 MSymbol Minput_driver;
4197 @brief Open an input method.
4199 The minput_open_im () function opens an input method whose
4200 language and name match $LANGUAGE and $NAME, and returns a pointer
4201 to the input method object newly allocated.
4203 This function at first decides a driver for the input method as
4206 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4207 #minput_driver is used.
4209 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4210 driver pointed to by the property value is used to open the input
4211 method. If $NAME has no such a property, @c NULL is returned.
4213 Then, the member MInputDriver::open_im () of the driver is
4216 $ARG is set in the member @c arg of the structure MInputMethod so
4217 that the driver can refer to it. */
4219 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4221 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4222 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4224 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4226 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4227 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4229 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4230 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4231 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4233 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4235 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4237 @latexonly \IPAlabel{minput_open} @endlatexonly
4242 minput_open_im (MSymbol language, MSymbol name, void *arg)
4245 MInputDriver *driver;
4249 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4250 msymbol_name (language), msymbol_name (name));
4252 driver = minput_driver;
4255 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4257 MERROR (MERROR_IM, NULL);
4260 MSTRUCT_CALLOC (im, MERROR_IM);
4261 im->language = language;
4264 im->driver = *driver;
4265 if ((*im->driver.open_im) (im) < 0)
4267 MDEBUG_PRINT (" failed\n");
4271 MDEBUG_PRINT (" ok\n");
4278 @brief Close an input method.
4280 The minput_close_im () function closes the input method $IM, which
4281 must have been created by minput_open_im (). */
4284 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4286 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4287 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4290 minput_close_im (MInputMethod *im)
4292 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4293 msymbol_name (im->name), msymbol_name (im->language));
4294 (*im->driver.close_im) (im);
4296 MDEBUG_PRINT (" done\n");
4302 @brief Create an input context.
4304 The minput_create_ic () function creates an input context object
4305 associated with input method $IM, and calls callback functions
4306 corresponding to #Minput_preedit_start, #Minput_status_start, and
4307 #Minput_status_draw in this order.
4310 If an input context is successfully created, minput_create_ic ()
4311 returns a pointer to it. Otherwise it returns @c NULL. */
4314 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4316 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4317 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4318 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4319 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4322 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4323 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4327 minput_create_ic (MInputMethod *im, void *arg)
4331 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4332 msymbol_name (im->name), msymbol_name (im->language));
4333 MSTRUCT_CALLOC (ic, MERROR_IM);
4336 ic->preedit = mtext ();
4337 ic->candidate_list = NULL;
4338 ic->produced = mtext ();
4339 ic->spot.x = ic->spot.y = 0;
4341 ic->plist = mplist ();
4342 if ((*im->driver.create_ic) (ic) < 0)
4344 MDEBUG_PRINT (" failed\n");
4345 M17N_OBJECT_UNREF (ic->preedit);
4346 M17N_OBJECT_UNREF (ic->produced);
4347 M17N_OBJECT_UNREF (ic->plist);
4352 if (im->driver.callback_list)
4354 minput_callback (ic, Minput_preedit_start);
4355 minput_callback (ic, Minput_status_start);
4356 minput_callback (ic, Minput_status_draw);
4359 MDEBUG_PRINT (" ok\n");
4366 @brief Destroy an input context.
4368 The minput_destroy_ic () function destroys the input context $IC,
4369 which must have been created by minput_create_ic (). It calls
4370 callback functions corresponding to #Minput_preedit_done,
4371 #Minput_status_done, and #Minput_candidates_done in this order. */
4374 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4376 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4377 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4378 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4379 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4380 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4384 minput_destroy_ic (MInputContext *ic)
4386 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4387 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4388 if (ic->im->driver.callback_list)
4390 minput_callback (ic, Minput_preedit_done);
4391 minput_callback (ic, Minput_status_done);
4392 minput_callback (ic, Minput_candidates_done);
4394 (*ic->im->driver.destroy_ic) (ic);
4395 M17N_OBJECT_UNREF (ic->preedit);
4396 M17N_OBJECT_UNREF (ic->produced);
4397 M17N_OBJECT_UNREF (ic->plist);
4398 MDEBUG_PRINT (" done\n");
4405 @brief Filter an input key.
4407 The minput_filter () function filters input key $KEY according to
4408 input context $IC, and calls callback functions corresponding to
4409 #Minput_preedit_draw, #Minput_status_draw, and
4410 #Minput_candidates_draw if the preedit text, the status, and the
4411 current candidate are changed respectively.
4413 To make the input method commit the current preedit text (if any)
4414 and shift to the initial state, call this function with #Mnil as
4417 To inform the input method about the focus-out event, call this
4418 function with #Minput_focus_out as $KEY.
4420 To inform the input method about the focus-in event, call this
4421 function with #Minput_focus_in as $KEY.
4423 To inform the input method about the focus-move event (i.e. input
4424 spot change within the same input context), call this function
4425 with #Minput_focus_move as $KEY.
4428 If $KEY is filtered out, this function returns 1. In that case,
4429 the caller should discard the key. Otherwise, it returns 0, and
4430 the caller should handle the key, for instance, by calling the
4431 function minput_lookup () with the same key. */
4434 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4436 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4437 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4438 #Minput_preedit_draw, #Minput_status_draw,
4439 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4442 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4443 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4444 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4445 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4447 @latexonly \IPAlabel{minput_filter} @endlatexonly
4451 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4458 if (ic->im->driver.callback_list
4459 && mtext_nchars (ic->preedit) > 0)
4460 minput_callback (ic, Minput_preedit_draw);
4462 ret = (*ic->im->driver.filter) (ic, key, arg);
4464 if (ic->im->driver.callback_list)
4466 if (ic->preedit_changed)
4467 minput_callback (ic, Minput_preedit_draw);
4468 if (ic->status_changed)
4469 minput_callback (ic, Minput_status_draw);
4470 if (ic->candidates_changed)
4471 minput_callback (ic, Minput_candidates_draw);
4480 @brief Look up a text produced in the input context.
4482 The minput_lookup () function looks up a text in the input context
4483 $IC. $KEY must be identical to the one that was used in the previous call of
4486 If a text was produced by the input method, it is concatenated
4489 This function calls #MInputDriver::lookup .
4492 If $KEY was correctly handled by the input method, this function
4493 returns 0. Otherwise, it returns -1, even though some text
4494 might be produced in $MT. */
4497 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4499 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4500 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4502 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4505 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4508 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4509 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4510 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4512 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4515 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4517 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4522 @brief Set the spot of the input context.
4524 The minput_set_spot () function sets the spot of input context $IC
4525 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4526 The semantics of these values depends on the input method driver.
4528 For instance, a driver designed to work in a CUI environment may
4529 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4530 $DESCENT . A driver designed to work in a window system may
4531 interpret $X and $Y as the pixel offsets relative to the origin of the
4532 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4533 descent pixels of the line at ($X . $Y ).
4535 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4537 $MT and $POS are the M-text and the character position at the spot.
4538 $MT may be @c NULL, in which case, the input method cannot get
4539 information about the text around the spot. */
4542 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4544 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4545 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4546 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4548 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4549 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4550 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4551 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4552 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4553 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4555 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4557 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4558 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4562 minput_set_spot (MInputContext *ic, int x, int y,
4563 int ascent, int descent, int fontsize,
4568 ic->spot.ascent = ascent;
4569 ic->spot.descent = descent;
4570 ic->spot.fontsize = fontsize;
4573 if (ic->im->driver.callback_list)
4574 minput_callback (ic, Minput_set_spot);
4579 @brief Toggle input method.
4581 The minput_toggle () function toggles the input method associated
4582 with input context $IC. */
4584 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4586 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4587 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4591 minput_toggle (MInputContext *ic)
4593 if (ic->im->driver.callback_list)
4594 minput_callback (ic, Minput_toggle);
4595 ic->active = ! ic->active;
4601 @brief Reset an input context.
4603 The minput_reset_ic () function resets input context $IC by
4604 calling a callback function corresponding to #Minput_reset. It
4605 resets the status of $IC to its initial one. As the
4606 current preedit text is deleted without commitment, if necessary,
4607 call minput_filter () with the arg @r key #Mnil to force the input
4608 method to commit the preedit in advance. */
4611 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4613 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4614 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4615 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4616 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4617 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4618 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4621 minput_reset_ic (MInputContext *ic)
4623 if (ic->im->driver.callback_list)
4624 minput_callback (ic, Minput_reset);
4630 @brief Get title and icon filename of an input method.
4632 The minput_get_title_icon () function returns a plist containing a
4633 title and icon filename (if any) of an input method specified by
4634 $LANGUAGE and $NAME.
4636 The first element of the plist has key #Mtext and the value is an
4637 M-text of the title for identifying the input method. The second
4638 element (if any) has key #Mtext and the value is an M-text of the
4639 icon image (absolute) filename for the same purpose.
4642 If there exists a specified input method and it defines an title,
4643 a plist is returned. Otherwise, NULL is returned. The caller
4644 must free the plist by m17n_object_unref (). */
4646 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4648 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4649 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4652 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4653 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4654 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4657 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4658 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4659 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4662 minput_get_title_icon (MSymbol language, MSymbol name)
4664 MInputMethodInfo *im_info;
4671 im_info = get_im_info (language, name, Mnil, Mtitle);
4672 if (! im_info || !im_info->title)
4674 mt = mtext_get_prop (im_info->title, 0, Mtext);
4676 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4679 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4682 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4683 (char *) MSYMBOL_NAME (name));
4684 file = mdatabase__find_file (buf);
4685 if (! file && language == Mt)
4687 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4688 file = mdatabase__find_file (buf);
4693 mplist_add (plist, Mtext, im_info->title);
4696 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4698 mplist_add (plist, Mtext, mt);
4699 M17N_OBJECT_UNREF (mt);
4707 @brief Get description text of an input method.
4709 The minput_get_description () function returns an M-text that
4710 describes the input method specified by $LANGUAGE and $NAME.
4713 If the specified input method has a description text, a pointer to
4714 #MText is returned. The caller has to free it by m17n_object_unref ().
4715 If the input method does not have a description text, @c NULL is
4718 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4720 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4721 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4723 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4724 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4725 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4726 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4729 minput_get_description (MSymbol language, MSymbol name)
4731 MInputMethodInfo *im_info;
4739 extra = language, language = Mt;
4741 im_info = get_im_info (language, name, extra, Mdescription);
4742 if (! im_info || ! im_info->description)
4744 M17N_OBJECT_REF (im_info->description);
4745 return im_info->description;
4751 @brief Get information about input method command(s).
4753 The minput_get_command () function returns information about
4754 the command $COMMAND of the input method specified by $LANGUAGE and
4755 $NAME. An input method command is a pseudo key event to which one
4756 or more actual input key sequences are assigned.
4758 There are two kinds of commands, global and local. A global
4759 command has a global definition, and the description and the key
4760 assignment may be inherited by a local command. Each input method
4761 defines a local command which has a local key assignment. It may
4762 also declare a local command that inherits the definition of a
4763 global command of the same name.
4765 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4766 information about a global command. Otherwise information about a
4767 local command is returned.
4769 If $COMMAND is #Mnil, information about all commands is returned.
4771 The return value is a @e well-formed plist (#m17nPlist) of this
4774 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4776 @c NAME is a symbol representing the command name.
4778 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4779 command has no description.
4781 @c STATUS is a symbol representing how the key assignment is decided.
4782 The value is #Mnil (the default key assignment), #Mcustomized (the
4783 key assignment is customized by per-user configuration file), or
4784 #Mconfigured (the key assignment is set by the call of
4785 minput_config_command ()). For a local command only, it may also
4786 be #Minherited (the key assignment is inherited from the
4787 corresponding global command).
4789 @c KEYSEQ is a plist of one or more symbols representing a key
4790 sequence assigned to the command. If there's no KEYSEQ, the
4791 command is currently disabled (i.e. no key sequence can trigger
4792 actions of the command).
4794 If $COMMAND is not #Mnil, the first element of the returned plist
4795 contains the information about $COMMAND.
4799 If the requested information was found, a pointer to a non-empty
4800 plist is returned. As the plist is kept in the library, the
4801 caller must not modify nor free it.
4803 Otherwise (the specified input method or the specified command
4804 does not exist), @c NULL is returned. */
4806 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4808 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4809 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4810 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4811 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4813 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4814 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4815 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4816 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4817 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4819 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4820 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4823 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4825 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4828 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4830 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4832 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4835 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4836 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4837 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4838 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4839 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4840 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4842 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4843 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4844 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4845 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4847 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4848 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4852 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4853 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4856 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4861 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4863 /* Return a description of the command COMMAND of the input method
4864 specified by LANGUAGE and NAME. */
4865 MPlist *cmd = minput_get_command (langauge, name, command);
4870 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4871 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4872 return (mplist_key (plist) == Mtext
4873 ? (MText *) mplist_value (plist)
4879 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4881 MInputMethodInfo *im_info;
4885 im_info = get_im_info (language, name, Mnil, Mcommand);
4887 || ! im_info->configured_cmds
4888 || MPLIST_TAIL_P (im_info->configured_cmds))
4890 if (command == Mnil)
4891 return im_info->configured_cmds;
4892 return mplist__assq (im_info->configured_cmds, command);
4898 @brief Configure the key sequence of an input method command.
4900 The minput_config_command () function assigns a list of key
4901 sequences $KEYSEQLIST to the command $COMMAND of the input method
4902 specified by $LANGUAGE and $NAME.
4904 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4905 sequences, and each key sequence must be a plist of symbols.
4907 If $KEYSEQLIST is an empty plist, the default key sequences of the
4908 command for the input method is assigned to $COMMAND.
4910 If $KEYSEQLIST is NULL, the configuration of the command for the
4911 input method is canceled, and the default key sequences become
4912 effective. In such case, if $COMMAND is #Mnil, configurations for
4913 all commands of the input method are canceled.
4915 If $NAME is #Mnil, this function configures the key assignment of a
4916 global command, not that of a specific input method.
4918 The configuration takes effect for input methods opened or
4919 re-opened later in the current session. In order to make the
4920 configuration take effect for the future session, it must be saved
4921 in a per-user configuration file by the function
4922 minput_save_config ().
4926 If the operation was successful, this function returns 0,
4927 otherwise returns -1. The operation fails in these cases:
4929 <li>$KEYSEQLIST is not in a valid form.
4930 <li>$COMMAND is not available for the input method.
4931 <li>$LANGUAGE and $NAME do not specify an existing input method.
4935 minput_get_commands (), minput_save_config ().
4938 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4940 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4941 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4942 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4944 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4945 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4947 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4949 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4950 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4951 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4954 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4955 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4957 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4958 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4959 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4960 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4964 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4966 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4967 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4968 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4972 minput_get_commands (), minput_save_config ().
4976 /* Add "C-x u" to the "start" command of Unicode input method. */
4978 MSymbol start_command = msymbol ("start");
4979 MSymbol unicode = msymbol ("unicode");
4980 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4982 /* At first get the current key-sequence assignment. */
4983 cmd = mplist_get_command (Mt, unicode, start_command);
4986 /* The input method does not have the command "start". Here
4987 should come some error handling code. */
4989 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4990 the part (KEY-SEQUENCE ...). */
4991 plist = mplist_next (mplist_next (mplist_value (cmd)));
4992 /* Copy it because we should not modify it directly. */
4993 key_seq_list = mplist_copy (plist);
4994 m17n_object_unref (cmds);
4996 key_seq = mplist ();
4997 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4998 mplist_add (key_seq, Msymbol, msymbol ("u"));
4999 mplist_add (key_seq_list, Mplist, key_seq);
5000 m17n_object_unref (key_seq);
5002 minput_config_command (Mt, unicode, start_command, key_seq_list);
5003 m17n_object_unref (key_seq_list);
5008 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5011 MInputMethodInfo *im_info, *config;
5016 im_info = get_im_info (language, name, Mnil, Mcommand);
5018 MERROR (MERROR_IM, -1);
5019 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5021 || ! mplist__assq (im_info->configured_cmds, command)))
5022 MERROR (MERROR_IM, -1);
5023 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5025 MPLIST_DO (plist, keyseqlist)
5026 if (! check_command_keyseq (plist))
5027 MERROR (MERROR_IM, -1);
5030 config = get_config_info (im_info);
5033 if (! im_config_list)
5034 im_config_list = mplist ();
5035 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5036 config->cmds = mplist ();
5037 config->vars = mplist ();
5040 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5041 /* Nothing to do. */
5044 if (command == Mnil)
5048 /* Cancal the configuration. */
5049 if (MPLIST_TAIL_P (config->cmds))
5051 mplist_set (config->cmds, Mnil, NULL);
5055 /* Cancal the customization. */
5056 MInputMethodInfo *custom = get_custom_info (im_info);
5058 if (MPLIST_TAIL_P (config->cmds)
5059 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5060 /* Nothing to do. */
5062 mplist_set (config->cmds, Mnil, NULL);
5063 MPLIST_DO (plist, custom->cmds)
5065 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5067 mplist_add (plist, Msymbol, command);
5068 mplist_push (config->cmds, Mplist, plist);
5069 M17N_OBJECT_UNREF (plist);
5075 plist = mplist__assq (config->cmds, command);
5078 /* Cancel the configuration. */
5081 mplist__pop_unref (plist);
5083 else if (MPLIST_TAIL_P (keyseqlist))
5085 /* Cancel the customization. */
5086 MInputMethodInfo *custom = get_custom_info (im_info);
5087 int no_custom = (! custom || ! custom->cmds
5088 || ! mplist__assq (custom->cmds, command));
5094 mplist_add (config->cmds, Mplist, plist);
5095 M17N_OBJECT_UNREF (plist);
5096 plist = mplist_add (plist, Msymbol, command);
5100 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5101 plist = MPLIST_NEXT (plist);
5102 if (MPLIST_TAIL_P (plist))
5104 mplist_set (plist, Mnil, NULL);
5113 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5114 if (! MPLIST_TAIL_P (plist))
5115 mplist_set (plist, Mnil, NULL);
5120 mplist_add (config->cmds, Mplist, plist);
5121 M17N_OBJECT_UNREF (plist);
5122 plist = mplist_add (plist, Msymbol, command);
5123 plist = MPLIST_NEXT (plist);
5125 MPLIST_DO (keyseqlist, keyseqlist)
5127 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5128 plist = mplist_add (plist, Mplist, pl);
5129 M17N_OBJECT_UNREF (pl);
5133 config_all_commands (im_info);
5134 im_info->tick = time (NULL);
5141 @brief Get information about input method variable(s).
5143 The minput_get_variable () function returns information about
5144 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5145 An input method variable controls behavior of an input method.
5147 There are two kinds of variables, global and local. A global
5148 variable has a global definition, and the description and the value
5149 may be inherited by a local variable. Each input method defines a
5150 local variable which has local value. It may also declare a
5151 local variable that inherits definition of a global variable of
5154 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5155 variable is returned. Otherwise information about a local variable
5158 If $VARIABLE is #Mnil, information about all variables is
5161 The return value is a @e well-formed plist (#m17nPlist) of this
5164 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5166 @c NAME is a symbol representing the variable name.
5168 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5169 variable has no description.
5171 @c STATUS is a symbol representing how the value is decided. The
5172 value is #Mnil (the default value), #Mcustomized (the value is
5173 customized by per-user configuration file), or #Mconfigured (the
5174 value is set by the call of minput_config_variable ()). For a
5175 local variable only, it may also be #Minherited (the value is
5176 inherited from the corresponding global variable).
5178 @c VALUE is the initial value of the variable. If the key of this
5179 element is #Mt, the variable has no initial value. Otherwise, the
5180 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5183 @c VALID-VALUEs (if any) specify which values the variable can have.
5184 They have the same type (i.e. having the same key) as @c VALUE except
5185 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5186 may be a plist of two integers specifying the range of possible
5189 If there no @c VALID-VALUE, the variable can have any value as long
5190 as the type is the same as @c VALUE.
5192 If $VARIABLE is not #Mnil, the first element of the returned plist
5193 contains the information about $VARIABLE.
5197 If the requested information was found, a pointer to a non-empty
5198 plist is returned. As the plist is kept in the library, the
5199 caller must not modify nor free it.
5201 Otherwise (the specified input method or the specified variable
5202 does not exist), @c NULL is returned. */
5204 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5206 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5207 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5208 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5210 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5211 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5212 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5213 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5216 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5217 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5219 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5221 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5223 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5226 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5228 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5231 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5232 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5233 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5234 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5235 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5236 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5238 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5239 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5240 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5242 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5243 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5244 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5245 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5247 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5250 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5251 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5255 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5256 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5259 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5263 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5265 MInputMethodInfo *im_info;
5269 im_info = get_im_info (language, name, Mnil, Mvariable);
5270 if (! im_info || ! im_info->configured_vars)
5272 if (variable == Mnil)
5273 return im_info->configured_vars;
5274 return mplist__assq (im_info->configured_vars, variable);
5280 @brief Configure the value of an input method variable.
5282 The minput_config_variable () function assigns $VALUE to the
5283 variable $VARIABLE of the input method specified by $LANGUAGE and
5286 If $VALUE is not NULL, it must be a plist of one element whose key
5287 is #Minteger, #Msymbol, or #Mtext, or an empty plist. In the
5288 former case, the value must be of the corresponding type, and it
5289 is assinged to $VARIABLE. In the latter case, the default value
5290 for the input method is assigned to $VARIABLE.
5292 If $VALUE is NULL, a configuration for the variable for the input
5293 method is canceled, and the variable is initialized to the
5294 original value (it may be what saved in per-user configuration
5295 file, or the default value of the input method).
5297 If $VALUE is an empty plist or NULL, $VARIABLE can be #Mnil. In
5298 that case, it is applied to all the variables of the input method
5301 If $NAME is #Mnil, this function configure the value of global
5302 variable, not that of a specific input method.
5304 The configuration takes effect for input methods opened or
5305 re-opened later in the current session. To make the configuration
5306 take effect for the future session, it must be saved in a per-user
5307 configuration file by the function minput_save_config ().
5311 If the operation was successful, this function returns 0,
5312 otherwise returns -1. The operation fails in these cases:
5314 <li>$VALUE is not in a valid form, the type does not match the
5315 definition, or the value is our of range.
5316 <li>$VARIABLE is not available for the input method.
5317 <li>$LANGUAGE and $NAME do not specify an existing input method.
5321 minput_get_variable (), minput_save_config (). */
5323 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5325 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5326 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5328 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5329 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5331 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5332 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5333 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5335 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5336 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5338 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5339 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5340 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5341 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5345 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5347 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5348 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5349 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5353 minput_get_commands (), minput_save_config ().
5356 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5359 MInputMethodInfo *im_info, *config;
5364 im_info = get_im_info (language, name, Mnil, Mvariable);
5366 MERROR (MERROR_IM, -1);
5367 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5369 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5370 MERROR (MERROR_IM, -1);
5372 if (value && ! MPLIST_TAIL_P (value))
5374 plist = MPLIST_PLIST (plist);
5375 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5376 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5377 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5378 if (MPLIST_KEY (plist) != Mt
5379 && ! check_variable_value (value, plist))
5380 MERROR (MERROR_IM, -1);
5383 config = get_config_info (im_info);
5386 if (! im_config_list)
5387 im_config_list = mplist ();
5388 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5389 config->cmds = mplist ();
5390 config->vars = mplist ();
5393 if (! value && MPLIST_TAIL_P (config->vars))
5394 /* Nothing to do. */
5397 if (variable == Mnil)
5401 /* Cancel the configuration. */
5402 if (MPLIST_TAIL_P (config->vars))
5404 mplist_set (config->vars, Mnil, NULL);
5408 /* Cancel the customization. */
5409 MInputMethodInfo *custom = get_custom_info (im_info);
5411 if (MPLIST_TAIL_P (config->vars)
5412 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5413 /* Nothing to do. */
5415 mplist_set (config->vars, Mnil, NULL);
5416 MPLIST_DO (plist, custom->vars)
5418 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5420 mplist_add (plist, Msymbol, variable);
5421 mplist_push (config->vars, Mplist, plist);
5422 M17N_OBJECT_UNREF (plist);
5428 plist = mplist__assq (config->vars, variable);
5431 /* Cancel the configuration. */
5434 mplist__pop_unref (plist);
5436 else if (MPLIST_TAIL_P (value))
5438 /* Cancel the customization. */
5439 MInputMethodInfo *custom = get_custom_info (im_info);
5440 int no_custom = (! custom || ! custom->vars
5441 || ! mplist__assq (custom->vars, variable));
5447 mplist_add (config->vars, Mplist, plist);
5448 M17N_OBJECT_UNREF (plist);
5449 plist = mplist_add (plist, Msymbol, variable);
5453 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5454 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5455 if (! MPLIST_TAIL_P (plist))
5457 mplist_set (plist, Mnil ,NULL);
5464 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5465 if (! MPLIST_TAIL_P (plist))
5466 mplist_set (plist, Mnil, NULL);
5471 mplist_add (config->vars, Mplist, plist);
5472 M17N_OBJECT_UNREF (plist);
5473 plist = mplist_add (plist, Msymbol, variable);
5474 plist = MPLIST_NEXT (plist);
5476 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5479 config_all_variables (im_info);
5480 im_info->tick = time (NULL);
5487 @brief Get the name of per-user configuration file.
5489 The minput_config_file () function returns the absolute path name
5490 of per-user configuration file into which minput_save_config ()
5491 save configurations. It is usually @c "config.mic" under the
5492 directory @c ".m17n.d" of user's home directory. It is not assured
5493 that the file of the returned name exists nor is
5494 readable/writable. If minput_save_config () fails and returns -1,
5495 an application program might check the file, make it
5496 writable (if possible), and try minput_save_config () again.
5500 This function returns a string. As the string is kept in the
5501 library, the caller must not modify nor free it.
5504 minput_save_config ()
5507 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5509 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5510 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5511 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5512 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5513 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5514 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5515 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5520 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5521 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5524 minput_save_config ()
5528 minput_config_file ()
5532 return mdatabase__file (im_custom_mdb);
5538 @brief Save configurations in per-user configuration file.
5540 The minput_save_config () function saves the configurations done
5541 so far in the current session into the per-user configuration
5546 If the operation was successful, 1 is returned. If the per-user
5547 configuration file is currently locked, 0 is returned. In that
5548 case, the caller may wait for a while and try again. If the
5549 configuration file is not writable, -1 is returned. In that case,
5550 the caller may check the name of the file by calling
5551 minput_config_file (), make it writable if possible, and try
5555 minput_config_file () */
5557 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5559 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5560 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5564 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5565 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5566 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5567 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5571 minput_config_file () */
5574 minput_save_config (void)
5576 MPlist *data, *tail, *plist, *p, *elt;
5580 ret = mdatabase__lock (im_custom_mdb);
5583 if (! im_config_list)
5585 update_custom_info ();
5586 if (! im_custom_list)
5587 im_custom_list = mplist ();
5589 /* At first, reflect configuration in customization. */
5590 MPLIST_DO (plist, im_config_list)
5592 MPlist *pl = MPLIST_PLIST (plist);
5593 MSymbol language, name, extra, command, variable;
5594 MInputMethodInfo *custom, *config;
5596 language = MPLIST_SYMBOL (pl);
5597 pl = MPLIST_NEXT (pl);
5598 name = MPLIST_SYMBOL (pl);
5599 pl = MPLIST_NEXT (pl);
5600 extra = MPLIST_SYMBOL (pl);
5601 pl = MPLIST_NEXT (pl);
5602 config = MPLIST_VAL (pl);
5603 custom = get_custom_info (config);
5605 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5607 MPLIST_DO (pl, config->cmds)
5609 elt = MPLIST_PLIST (pl);
5610 command = MPLIST_SYMBOL (elt);
5612 p = mplist__assq (custom->cmds, command);
5614 custom->cmds = mplist (), p = NULL;
5615 elt = MPLIST_NEXT (elt);
5616 if (MPLIST_TAIL_P (elt))
5620 /* Make customization ignored. */
5621 p = MPLIST_NEXT (MPLIST_PLIST (p));
5622 mplist_set (p, Mnil, NULL);
5627 elt = MPLIST_NEXT (elt);
5630 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5631 mplist_set (p, Mnil, NULL);
5632 mplist__conc (p, elt);
5636 p = MPLIST_PLIST (pl);
5637 mplist_add (custom->cmds, Mplist, p);
5642 MPLIST_DO (pl, config->vars)
5644 elt = MPLIST_PLIST (pl);
5645 variable = MPLIST_SYMBOL (elt);
5647 p = mplist__assq (custom->vars, variable);
5649 custom->vars = mplist (), p = NULL;
5650 elt = MPLIST_NEXT (elt);
5651 if (MPLIST_TAIL_P (elt))
5654 mplist__pop_unref (p);
5658 elt = MPLIST_NEXT (elt);
5661 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5662 mplist_set (p, Mnil, NULL);
5663 mplist__conc (p, elt);
5667 p = MPLIST_PLIST (pl);
5668 mplist_add (custom->vars, Mplist, p);
5673 M17N_OBJECT_UNREF (im_config_list);
5675 /* Next, reflect customization to the actual plist to be written. */
5676 data = tail = mplist ();
5677 MPLIST_DO (plist, im_custom_list)
5679 MPlist *pl = MPLIST_PLIST (plist);
5680 MSymbol language, name, extra;
5681 MInputMethodInfo *custom, *im_info;
5683 language = MPLIST_SYMBOL (pl);
5684 pl = MPLIST_NEXT (pl);
5685 name = MPLIST_SYMBOL (pl);
5686 pl = MPLIST_NEXT (pl);
5687 extra = MPLIST_SYMBOL (pl);
5688 pl = MPLIST_NEXT (pl);
5689 custom = MPLIST_VAL (pl);
5690 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5691 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5693 im_info = lookup_im_info (im_info_list, language, name, extra);
5697 config_all_commands (im_info);
5699 config_all_variables (im_info);
5703 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5705 MPLIST_DO (p, custom->cmds)
5706 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5708 if (! MPLIST_TAIL_P (p))
5712 mplist_add (elt, Mplist, pl);
5713 M17N_OBJECT_UNREF (pl);
5714 pl = mplist_add (pl, Msymbol, Mcommand);
5715 MPLIST_DO (p, custom->cmds)
5716 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5717 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5720 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5722 MPLIST_DO (p, custom->vars)
5723 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5725 if (! MPLIST_TAIL_P (p))
5730 mplist_add (elt, Mplist, pl);
5731 M17N_OBJECT_UNREF (pl);
5732 pl = mplist_add (pl, Msymbol, Mvariable);
5733 MPLIST_DO (p, custom->vars)
5734 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5735 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5741 mplist_push (elt, Mplist, pl);
5742 M17N_OBJECT_UNREF (pl);
5743 pl = mplist_add (pl, Msymbol, Minput_method);
5744 pl = mplist_add (pl, Msymbol, language);
5745 pl = mplist_add (pl, Msymbol, name);
5747 pl = mplist_add (pl, Msymbol, extra);
5748 tail = mplist_add (tail, Mplist, elt);
5749 M17N_OBJECT_UNREF (elt);
5753 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5754 ret = mdatabase__save (im_custom_mdb, data);
5755 mdatabase__unlock (im_custom_mdb);
5756 M17N_OBJECT_UNREF (data);
5757 return (ret < 0 ? -1 : 1);
5764 @name Obsolete functions
5767 @name Obsolete ¤Ê´Ø¿ô
5773 @brief Get a list of variables of an input method (obsolete).
5775 This function is obsolete. Use minput_get_variable () instead.
5777 The minput_get_variables () function returns a plist (#MPlist) of
5778 variables used to control the behavior of the input method
5779 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5780 (#m17nPlist) of the following format:
5783 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5784 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5788 @c VARNAME is a symbol representing the variable name.
5790 @c DOC-MTEXT is an M-text describing the variable.
5792 @c DEFAULT-VALUE is the default value of the variable. It is a
5793 symbol, integer, or M-text.
5795 @c VALUEs (if any) specifies the possible values of the variable.
5796 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5797 @c TO), where @c FROM and @c TO specifies a range of possible
5800 For instance, suppose an input method has the variables:
5802 @li name:intvar, description:"value is an integer",
5803 initial value:0, value-range:0..3,10,20
5805 @li name:symvar, description:"value is a symbol",
5806 initial value:nil, value-range:a, b, c, nil
5808 @li name:txtvar, description:"value is an M-text",
5809 initial value:empty text, no value-range (i.e. any text)
5811 Then, the returned plist is as follows.
5814 (intvar ("value is an integer" 0 (0 3) 10 20)
5815 symvar ("value is a symbol" nil a b c nil)
5816 txtvar ("value is an M-text" ""))
5820 If the input method uses any variables, a pointer to #MPlist is
5821 returned. As the plist is kept in the library, the caller must not
5822 modify nor free it. If the input method does not use any
5823 variable, @c NULL is returned. */
5825 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5827 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5828 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5829 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5833 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5834 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5838 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5840 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5842 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5845 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5846 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5847 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5849 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5851 @li name:intvar, ÀâÌÀ:"value is an integer",
5852 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5854 @li name:symvar, ÀâÌÀ:"value is a symbol",
5855 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5857 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5858 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5860 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5863 (intvar ("value is an integer" 0 (0 3) 10 20)
5864 symvar ("value is a symbol" nil a b c nil)
5865 txtvar ("value is an M-text" ""))
5869 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5870 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5871 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5874 minput_get_variables (MSymbol language, MSymbol name)
5876 MInputMethodInfo *im_info;
5881 im_info = get_im_info (language, name, Mnil, Mvariable);
5882 if (! im_info || ! im_info->configured_vars)
5885 M17N_OBJECT_UNREF (im_info->bc_vars);
5886 im_info->bc_vars = mplist ();
5887 MPLIST_DO (vars, im_info->configured_vars)
5889 MPlist *plist = MPLIST_PLIST (vars);
5890 MPlist *elt = mplist ();
5892 mplist_push (im_info->bc_vars, Mplist, elt);
5893 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5894 elt = MPLIST_NEXT (elt);
5895 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5896 M17N_OBJECT_UNREF (elt);
5898 return im_info->bc_vars;
5904 @brief Set the initial value of an input method variable.
5906 The minput_set_variable () function sets the initial value of
5907 input method variable $VARIABLE to $VALUE for the input method
5908 specified by $LANGUAGE and $NAME.
5910 By default, the initial value is 0.
5912 This setting gets effective in a newly opened input method.
5915 If the operation was successful, 0 is returned. Otherwise -1 is
5916 returned, and #merror_code is set to #MERROR_IM. */
5918 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5920 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5921 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5922 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5924 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5926 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5929 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5930 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5933 minput_set_variable (MSymbol language, MSymbol name,
5934 MSymbol variable, void *value)
5937 MInputMethodInfo *im_info;
5942 if (variable == Mnil)
5943 MERROR (MERROR_IM, -1);
5944 plist = minput_get_variable (language, name, variable);
5945 plist = MPLIST_PLIST (plist);
5946 plist = MPLIST_NEXT (plist);
5948 mplist_add (pl, MPLIST_KEY (plist), value);
5949 ret = minput_config_variable (language, name, variable, pl);
5950 M17N_OBJECT_UNREF (pl);
5953 im_info = get_im_info (language, name, Mnil, Mvariable);
5962 @brief Get information about input method commands.
5964 The minput_get_commands () function returns information about
5965 input method commands of the input method specified by $LANGUAGE
5966 and $NAME. An input method command is a pseudo key event to which
5967 one or more actual input key sequences are assigned.
5969 There are two kinds of commands, global and local. Global
5970 commands are used by multiple input methods for the same purpose,
5971 and have global key assignments. Local commands are used only by
5972 a specific input method, and have only local key assignments.
5974 Each input method may locally change key assignments for global
5975 commands. The global key assignment for a global command is
5976 effective only when the current input method does not have local
5977 key assignments for that command.
5979 If $NAME is #Mnil, information about global commands is returned.
5980 In this case $LANGUAGE is ignored.
5982 If $NAME is not #Mnil, information about those commands that have
5983 local key assignments in the input method specified by $LANGUAGE
5984 and $NAME is returned.
5987 If no input method commands are found, this function returns @c NULL.
5989 Otherwise, a pointer to a plist is returned. The key of each
5990 element in the plist is a symbol representing a command, and the
5991 value is a plist of the form COMMAND-INFO described below.
5993 The first element of COMMAND-INFO has the key #Mtext, and the
5994 value is an M-text describing the command.
5996 If there are no more elements, that means no key sequences are
5997 assigned to the command. Otherwise, each of the remaining
5998 elements has the key #Mplist, and the value is a plist whose keys are
5999 #Msymbol and values are symbols representing input keys, which are
6000 currently assigned to the command.
6002 As the returned plist is kept in the library, the caller must not
6003 modify nor free it. */
6005 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6007 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6008 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6009 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6010 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6012 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6013 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6014 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6015 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6017 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6018 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6019 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6022 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6023 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6025 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6026 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6030 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6032 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6033 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6034 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6036 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6037 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6038 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6041 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6042 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6043 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6044 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6045 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6047 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6048 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6051 minput_get_commands (MSymbol language, MSymbol name)
6053 MInputMethodInfo *im_info;
6058 im_info = get_im_info (language, name, Mnil, Mcommand);
6059 if (! im_info || ! im_info->configured_vars)
6061 M17N_OBJECT_UNREF (im_info->bc_cmds);
6062 im_info->bc_cmds = mplist ();
6063 MPLIST_DO (cmds, im_info->configured_cmds)
6065 MPlist *plist = MPLIST_PLIST (cmds);
6066 MPlist *elt = mplist ();
6068 mplist_push (im_info->bc_cmds, Mplist, elt);
6069 mplist_add (elt, MPLIST_SYMBOL (plist),
6070 mplist_copy (MPLIST_NEXT (plist)));
6071 M17N_OBJECT_UNREF (elt);
6073 return im_info->bc_cmds;
6079 @brief Assign a key sequence to an input method command (obsolete).
6081 This function is obsolete. Use minput_config_command () instead.
6083 The minput_assign_command_keys () function assigns input key
6084 sequence $KEYSEQ to input method command $COMMAND for the input
6085 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6086 key sequence is assigned globally no matter what $LANGUAGE is.
6087 Otherwise the key sequence is assigned locally.
6089 Each element of $KEYSEQ must have the key $Msymbol and the value
6090 must be a symbol representing an input key.
6092 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6093 globally or locally.
6095 This assignment gets effective in a newly opened input method.
6098 If the operation was successful, 0 is returned. Otherwise -1 is
6099 returned, and #merror_code is set to #MERROR_IM. */
6101 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6103 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6104 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6105 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6106 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6107 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6109 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6110 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6112 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6113 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6115 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6118 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6119 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6122 minput_assign_command_keys (MSymbol language, MSymbol name,
6123 MSymbol command, MPlist *keyseq)
6129 if (command == Mnil)
6130 MERROR (MERROR_IM, -1);
6135 if (! check_command_keyseq (keyseq))
6136 MERROR (MERROR_IM, -1);
6138 mplist_add (plist, Mplist, keyseq);
6143 ret = minput_config_command (language, name, command, keyseq);
6144 M17N_OBJECT_UNREF (keyseq);
6151 @brief Call a callback function
6153 The minput_callback () functions calls a callback function
6154 $COMMAND assigned for the input context $IC. The caller must set
6155 specific elements in $IC->plist if the callback function requires.
6158 If there exists a specified callback function, 0 is returned.
6159 Otherwise -1 is returned. By side effects, $IC->plist may be
6163 minput_callback (MInputContext *ic, MSymbol command)
6165 MInputCallbackFunc func;
6167 if (! ic->im->driver.callback_list)
6169 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
6173 (func) (ic, command);
6180 /*** @addtogroup m17nDebug */
6186 @brief Dump an input method.
6188 The mdebug_dump_im () function prints the input method $IM in a
6189 human readable way to the stderr. $INDENT specifies how many
6190 columns to indent the lines but the first one.
6193 This function returns $IM. */
6195 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6197 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6198 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6201 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6204 mdebug_dump_im (MInputMethod *im, int indent)
6206 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6209 prefix = (char *) alloca (indent + 1);
6210 memset (prefix, 32, indent);
6211 prefix[indent] = '\0';
6213 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6214 msymbol_name (im->name));
6215 mdebug_dump_mtext (im_info->title, 0, 0);
6216 if (im->name != Mnil)
6220 MPLIST_DO (state, im_info->states)
6222 fprintf (stderr, "\n%s ", prefix);
6223 dump_im_state (MPLIST_VAL (state), indent + 2);
6226 fprintf (stderr, ")");