1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
156 #include "m17n-gui.h"
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_mask = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle, Mpop;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mpop = msymbol ("pop");
406 Mundo = msymbol ("undo");
407 Mcall = msymbol ("call");
408 Mshift = msymbol ("shift");
409 Mselect = msymbol ("select");
410 Mshow = msymbol ("show");
411 Mhide = msymbol ("hide");
412 Mcommit = msymbol ("commit");
413 Munhandle = msymbol ("unhandle");
414 Mset = msymbol ("set");
415 Madd = msymbol ("add");
416 Msub = msymbol ("sub");
417 Mmul = msymbol ("mul");
418 Mdiv = msymbol ("div");
419 Mequal = msymbol ("=");
420 Mless = msymbol ("<");
421 Mgreater = msymbol (">");
422 Mless_equal = msymbol ("<=");
423 Mgreater_equal = msymbol (">=");
424 Mcond = msymbol ("cond");
425 Mplus = msymbol ("+");
426 Mminus = msymbol ("-");
427 Mstar = msymbol ("*");
428 Mslash = msymbol ("/");
429 Mand = msymbol ("&");
431 Mnot = msymbol ("!");
433 Mat_reload = msymbol ("@reload");
435 Mcandidates_group_size = msymbol ("candidates-group-size");
436 Mcandidates_charset = msymbol ("candidates-charset");
438 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
439 Mcandidate_index = msymbol (" candidate-index");
441 Minit = msymbol ("init");
442 Mfini = msymbol ("fini");
444 Mdescription = msymbol ("description");
445 Mcommand = msymbol ("command");
446 Mvariable = msymbol ("variable");
447 Mglobal = msymbol ("global");
448 Mconfig = msymbol ("config");
449 M_gettext = msymbol ("_");
451 load_im_info_keys = mplist ();
452 mplist_add (load_im_info_keys, Mstate, Mnil);
453 mplist_push (load_im_info_keys, Mmap, Mnil);
455 im_info_list = mplist ();
456 im_config_list = im_custom_list = NULL;
457 im_custom_mdb = NULL;
458 update_custom_info ();
460 update_global_info ();
462 fully_initialized = 1;
465 #define MINPUT__INIT() \
467 if (! fully_initialized) \
468 fully_initialize (); \
473 marker_code (MSymbol sym, int surrounding)
479 name = MSYMBOL_NAME (sym);
480 return (name[0] != '@' ? -1
481 : (((name[1] >= '0' && name[1] <= '9')
482 || name[1] == '<' || name[1] == '>' || name[1] == '='
483 || name[1] == '[' || name[1] == ']'
485 && name[2] == '\0') ? name[1]
486 : (name[1] != '+' && name[1] != '-') ? -1
487 : (name[2] == '\0' || surrounding) ? name[1]
493 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
495 MPlist *plist = mplist__assq (ic_info->vars, var);
499 plist = MPLIST_PLIST (plist);
500 return MPLIST_NEXT (plist);
504 mplist_push (ic_info->vars, Mplist, plist);
505 M17N_OBJECT_UNREF (plist);
506 plist = mplist_add (plist, Msymbol, var);
507 plist = mplist_add (plist, Minteger, (void *) 0);
512 get_surrounding_text (MInputContext *ic, int len)
516 mplist_push (ic->plist, Minteger, (void *) len);
517 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
518 && MPLIST_MTEXT_P (ic->plist))
519 mt = MPLIST_MTEXT (ic->plist);
520 mplist_pop (ic->plist);
525 delete_surrounding_text (MInputContext *ic, int pos)
527 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
529 mplist_push (ic->plist, Minteger, (void *) pos);
530 minput_callback (ic, Minput_delete_surrounding_text);
531 mplist_pop (ic->plist);
534 M17N_OBJECT_UNREF (ic_info->preceding_text);
535 ic_info->preceding_text = NULL;
539 M17N_OBJECT_UNREF (ic_info->following_text);
540 ic_info->following_text = NULL;
545 get_preceding_char (MInputContext *ic, int pos)
547 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
551 if (pos && ic_info->preceding_text)
553 len = mtext_nchars (ic_info->preceding_text);
555 return mtext_ref_char (ic_info->preceding_text, len - pos);
557 mt = get_surrounding_text (ic, - pos);
560 len = mtext_nchars (mt);
561 if (ic_info->preceding_text)
563 if (mtext_nchars (ic_info->preceding_text) < len)
565 M17N_OBJECT_UNREF (ic_info->preceding_text);
566 ic_info->preceding_text = mt;
569 M17N_OBJECT_UNREF (mt);
572 ic_info->preceding_text = mt;
575 return mtext_ref_char (ic_info->preceding_text, len - pos);
579 get_following_char (MInputContext *ic, int pos)
581 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
585 if (ic_info->following_text)
587 len = mtext_nchars (ic_info->following_text);
589 return mtext_ref_char (ic_info->following_text, pos - 1);
591 mt = get_surrounding_text (ic, pos);
594 len = mtext_nchars (mt);
595 if (ic_info->following_text)
597 if (mtext_nchars (ic_info->following_text) < len)
599 M17N_OBJECT_UNREF (ic_info->following_text);
600 ic_info->following_text = mt;
603 M17N_OBJECT_UNREF (mt);
606 ic_info->following_text = mt;
609 return mtext_ref_char (ic_info->following_text, pos - 1);
613 surrounding_pos (MSymbol sym)
619 name = MSYMBOL_NAME (sym);
621 && (name[1] == '-' || name[1] == '+')
622 && name[2] >= '1' && name[2] <= '9')
623 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
628 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
630 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
632 MText *preedit = ic->preedit;
633 int len = mtext_nchars (preedit);
637 if (MPLIST_INTEGER_P (arg))
638 return MPLIST_INTEGER (arg);
640 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
643 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
647 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
650 return ic_info->key_head;
651 if ((code == '-' || code == '+'))
653 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
657 pos = atoi (name + 1);
659 return get_preceding_char (ic, 0);
660 pos = ic->cursor_pos + pos;
663 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
664 return mtext_ref_char (ic->produced,
665 mtext_len (ic->produced) + pos);
666 return get_preceding_char (ic, - pos);
669 return get_following_char (ic, pos - len + 1);
672 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
674 else if (code >= '0' && code <= '9')
676 else if (code == '=')
677 pos = ic->cursor_pos;
678 else if (code == '[')
679 pos = ic->cursor_pos - 1;
680 else if (code == ']')
681 pos = ic->cursor_pos + 1;
682 else if (code == '<')
684 else if (code == '>')
686 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
690 parse_expression (MPlist *plist)
694 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
696 if (! MPLIST_PLIST_P (plist))
698 plist = MPLIST_PLIST (plist);
699 op = MPLIST_SYMBOL (plist);
700 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
701 && op != Mand && op != Mor && op != Mnot
702 && op != Mless && op != Mgreater && op != Mequal
703 && op != Mless_equal && op != Mgreater_equal)
704 MERROR (MERROR_IM, -1);
705 MPLIST_DO (plist, MPLIST_NEXT (plist))
706 if (parse_expression (plist) < 0)
712 resolve_expression (MInputContext *ic, MPlist *plist)
717 if (MPLIST_INTEGER_P (plist))
718 return MPLIST_INTEGER (plist);
719 if (MPLIST_SYMBOL_P (plist))
720 return integer_value (ic, plist, NULL, 1);
721 if (! MPLIST_PLIST_P (plist))
723 plist = MPLIST_PLIST (plist);
724 if (! MPLIST_SYMBOL_P (plist))
726 op = MPLIST_SYMBOL (plist);
727 plist = MPLIST_NEXT (plist);
728 val = resolve_expression (ic, plist);
730 MPLIST_DO (plist, MPLIST_NEXT (plist))
731 val += resolve_expression (ic, plist);
732 else if (op == Mminus)
733 MPLIST_DO (plist, MPLIST_NEXT (plist))
734 val -= resolve_expression (ic, plist);
735 else if (op == Mstar)
736 MPLIST_DO (plist, MPLIST_NEXT (plist))
737 val *= resolve_expression (ic, plist);
738 else if (op == Mslash)
739 MPLIST_DO (plist, MPLIST_NEXT (plist))
740 val /= resolve_expression (ic, plist);
742 MPLIST_DO (plist, MPLIST_NEXT (plist))
743 val &= resolve_expression (ic, plist);
745 MPLIST_DO (plist, MPLIST_NEXT (plist))
746 val |= resolve_expression (ic, plist);
749 else if (op == Mless)
750 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
751 else if (op == Mequal)
752 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
753 else if (op == Mgreater)
754 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
755 else if (op == Mless_equal)
756 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
757 else if (op == Mgreater_equal)
758 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
762 /* Parse PLIST as an action list. PLIST should have this form:
763 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
764 Return 0 if successfully parsed, otherwise return -1. */
767 parse_action_list (MPlist *plist, MPlist *macros)
769 MPLIST_DO (plist, plist)
771 if (MPLIST_MTEXT_P (plist))
773 /* This is a short form of (insert MTEXT). */
774 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
775 MERROR (MERROR_IM, -1); */
777 else if (MPLIST_PLIST_P (plist)
778 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
779 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
783 /* This is a short form of (insert (GROUPS *)). */
784 MPLIST_DO (pl, MPLIST_PLIST (plist))
786 if (MPLIST_PLIST_P (pl))
790 MPLIST_DO (elt, MPLIST_PLIST (pl))
791 if (! MPLIST_MTEXT_P (elt)
792 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
793 MERROR (MERROR_IM, -1);
797 if (! MPLIST_MTEXT_P (pl)
798 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
799 MERROR (MERROR_IM, -1);
803 else if (MPLIST_INTEGER_P (plist))
805 int c = MPLIST_INTEGER (plist);
807 if (c < 0 || c > MCHAR_MAX)
808 MERROR (MERROR_IM, -1);
810 else if (MPLIST_PLIST_P (plist)
811 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
813 MPlist *pl = MPLIST_PLIST (plist);
814 MSymbol action_name = MPLIST_SYMBOL (pl);
816 pl = MPLIST_NEXT (pl);
818 if (action_name == Minsert)
820 if (MPLIST_MTEXT_P (pl))
822 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
823 MERROR (MERROR_IM, -1);
825 else if (MPLIST_PLIST_P (pl))
827 MPLIST_DO (pl, MPLIST_PLIST (pl))
829 if (MPLIST_PLIST_P (pl))
833 MPLIST_DO (elt, MPLIST_PLIST (pl))
834 if (! MPLIST_MTEXT_P (elt)
835 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
836 MERROR (MERROR_IM, -1);
840 if (! MPLIST_MTEXT_P (pl)
841 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
842 MERROR (MERROR_IM, -1);
846 else if (! MPLIST_SYMBOL_P (pl))
847 MERROR (MERROR_IM, -1);
849 else if (action_name == Mselect
850 || action_name == Mdelete
851 || action_name == Mmove)
853 if (parse_expression (pl) < 0)
856 else if (action_name == Mmark
857 || action_name == Mcall
858 || action_name == Mshift)
860 if (! MPLIST_SYMBOL_P (pl))
861 MERROR (MERROR_IM, -1);
863 else if (action_name == Mundo)
865 if (! MPLIST_TAIL_P (pl))
867 if (! MPLIST_SYMBOL_P (pl)
868 && ! MPLIST_INTEGER_P (pl))
869 MERROR (MERROR_IM, -1);
872 else if (action_name == Mpushback)
874 if (MPLIST_MTEXT_P (pl))
876 MText *mt = MPLIST_MTEXT (pl);
878 if (mtext_nchars (mt) != mtext_nbytes (mt))
879 MERROR (MERROR_IM, -1);
881 else if (MPLIST_PLIST_P (pl))
885 MPLIST_DO (p, MPLIST_PLIST (pl))
886 if (! MPLIST_SYMBOL_P (p))
887 MERROR (MERROR_IM, -1);
889 else if (! MPLIST_INTEGER_P (pl))
890 MERROR (MERROR_IM, -1);
892 else if (action_name == Mset || action_name == Madd
893 || action_name == Msub || action_name == Mmul
894 || action_name == Mdiv)
896 if (! MPLIST_SYMBOL_P (pl))
897 MERROR (MERROR_IM, -1);
898 if (parse_expression (MPLIST_NEXT (pl)) < 0)
901 else if (action_name == Mequal || action_name == Mless
902 || action_name == Mgreater || action_name == Mless_equal
903 || action_name == Mgreater_equal)
905 if (parse_expression (pl) < 0
906 || parse_expression (MPLIST_NEXT (pl)) < 0)
908 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
909 if (! MPLIST_PLIST_P (pl))
910 MERROR (MERROR_IM, -1);
911 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
912 MERROR (MERROR_IM, -1);
913 pl = MPLIST_NEXT (pl);
914 if (MPLIST_PLIST_P (pl)
915 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
916 MERROR (MERROR_IM, -1);
918 else if (action_name == Mshow || action_name == Mhide
919 || action_name == Mcommit || action_name == Munhandle
920 || action_name == Mpop)
922 else if (action_name == Mcond)
925 if (! MPLIST_PLIST_P (pl))
926 MERROR (MERROR_IM, -1);
928 else if (! macros || ! mplist_get (macros, action_name))
929 MERROR (MERROR_IM, -1);
931 else if (! MPLIST_SYMBOL_P (plist))
932 MERROR (MERROR_IM, -1);
939 resolve_command (MPlist *cmds, MSymbol command)
943 if (! cmds || ! (plist = mplist__assq (cmds, command)))
945 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
946 plist = MPLIST_NEXT (plist);
947 plist = MPLIST_NEXT (plist);
948 plist = MPLIST_NEXT (plist);
952 /* Load a translation into MAP from PLIST.
954 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
957 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
958 MPlist *branch_actions, MPlist *macros)
963 if (MPLIST_MTEXT_P (keylist))
965 MText *mt = MPLIST_MTEXT (keylist);
967 len = mtext_nchars (mt);
968 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
970 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
971 for (i = 0; i < len; i++)
972 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
978 if (MFAILP (MPLIST_PLIST_P (keylist)))
980 elt = MPLIST_PLIST (keylist);
981 len = MPLIST_LENGTH (elt);
982 if (MFAILP (len > 0))
984 keyseq = (MSymbol *) alloca (sizeof (int) * len);
985 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
987 if (MPLIST_INTEGER_P (elt))
989 int c = MPLIST_INTEGER (elt);
991 if (MFAILP (c >= 0 && c < 0x100))
993 keyseq[i] = one_char_symbol[c];
997 if (MFAILP (MPLIST_SYMBOL_P (elt)))
999 keyseq[i] = MPLIST_SYMBOL (elt);
1004 for (i = 0; i < len; i++)
1006 MIMMap *deeper = NULL;
1009 deeper = mplist_get (map->submaps, keyseq[i]);
1011 map->submaps = mplist ();
1014 /* Fixme: It is better to make all deeper maps at once. */
1015 MSTRUCT_CALLOC (deeper, MERROR_IM);
1016 mplist_put (map->submaps, keyseq[i], deeper);
1021 /* We reach a terminal map. */
1022 if (map->map_actions
1023 || map->branch_actions)
1024 /* This map is already defined. We avoid overriding it. */
1027 if (! MPLIST_TAIL_P (map_actions))
1029 if (parse_action_list (map_actions, macros) < 0)
1030 MERROR (MERROR_IM, -1);
1031 map->map_actions = map_actions;
1035 map->branch_actions = branch_actions;
1036 M17N_OBJECT_REF (branch_actions);
1042 /* Load a branch from PLIST into MAP. PLIST has this form:
1043 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1046 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1049 MPlist *branch_actions;
1051 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1053 map_name = MPLIST_SYMBOL (plist);
1054 plist = MPLIST_NEXT (plist);
1055 if (MPLIST_TAIL_P (plist))
1056 branch_actions = NULL;
1057 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1060 branch_actions = plist;
1061 if (map_name == Mnil)
1063 map->branch_actions = branch_actions;
1065 M17N_OBJECT_REF (branch_actions);
1067 else if (map_name == Mt)
1069 map->map_actions = branch_actions;
1071 M17N_OBJECT_REF (branch_actions);
1073 else if (im_info->maps
1074 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1076 MPLIST_DO (plist, plist)
1078 MPlist *keylist, *map_actions;
1080 if (! MPLIST_PLIST_P (plist))
1081 MERROR (MERROR_IM, -1);
1082 keylist = MPLIST_PLIST (plist);
1083 map_actions = MPLIST_NEXT (keylist);
1084 if (MPLIST_SYMBOL_P (keylist))
1086 MSymbol command = MPLIST_SYMBOL (keylist);
1089 if (MFAILP (command != Mat_reload))
1091 pl = resolve_command (im_info->configured_cmds, command);
1095 load_translation (map, pl, map_actions, branch_actions,
1099 load_translation (map, keylist, map_actions, branch_actions,
1107 /* Load a macro from PLIST into IM_INFO->macros.
1108 PLIST has this from:
1109 PLIST ::= ( MACRO-NAME ACTION * )
1110 IM_INFO->macros is a plist of macro names vs action list. */
1113 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1118 if (! MPLIST_SYMBOL_P (plist))
1119 MERROR (MERROR_IM, -1);
1120 name = MPLIST_SYMBOL (plist);
1121 plist = MPLIST_NEXT (plist);
1122 if (MPLIST_TAIL_P (plist)
1123 || parse_action_list (plist, im_info->macros) < 0)
1124 MERROR (MERROR_IM, -1);
1125 pl = mplist_get (im_info->macros, name);
1126 M17N_OBJECT_UNREF (pl);
1127 mplist_put (im_info->macros, name, plist);
1128 M17N_OBJECT_REF (plist);
1132 /* Load an external module from PLIST into IM_INFO->externals.
1133 PLIST has this form:
1134 PLIST ::= ( MODULE-NAME FUNCTION * )
1135 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1138 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1143 MIMExternalModule *external;
1147 if (MPLIST_MTEXT_P (plist))
1148 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1149 else if (MPLIST_SYMBOL_P (plist))
1150 module = MPLIST_SYMBOL (plist);
1151 module_file = alloca (strlen (MSYMBOL_NAME (module))
1152 + strlen (DLOPEN_SHLIB_EXT) + 1);
1153 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1155 handle = dlopen (module_file, RTLD_NOW);
1156 if (MFAILP (handle))
1158 fprintf (stderr, "%s\n", dlerror ());
1161 func_list = mplist ();
1162 MPLIST_DO (plist, MPLIST_NEXT (plist))
1164 if (! MPLIST_SYMBOL_P (plist))
1165 MERROR_GOTO (MERROR_IM, err_label);
1166 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1169 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1172 MSTRUCT_MALLOC (external, MERROR_IM);
1173 external->handle = handle;
1174 external->func_list = func_list;
1175 mplist_add (im_info->externals, module, external);
1180 M17N_OBJECT_UNREF (func_list);
1185 free_map (MIMMap *map, int top)
1190 M17N_OBJECT_UNREF (map->map_actions);
1193 MPLIST_DO (plist, map->submaps)
1194 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1195 M17N_OBJECT_UNREF (map->submaps);
1197 M17N_OBJECT_UNREF (map->branch_actions);
1202 free_state (void *object)
1204 MIMState *state = object;
1206 M17N_OBJECT_UNREF (state->title);
1208 free_map (state->map, 1);
1212 /** Load a state from PLIST into a newly allocated state object.
1213 PLIST has this form:
1214 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1215 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1216 Return the state object. */
1219 load_state (MInputMethodInfo *im_info, MPlist *plist)
1223 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1225 M17N_OBJECT (state, free_state, MERROR_IM);
1226 state->name = MPLIST_SYMBOL (plist);
1227 plist = MPLIST_NEXT (plist);
1228 if (MPLIST_MTEXT_P (plist))
1230 state->title = MPLIST_MTEXT (plist);
1231 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1232 Mlanguage, im_info->language);
1233 M17N_OBJECT_REF (state->title);
1234 plist = MPLIST_NEXT (plist);
1236 MSTRUCT_CALLOC (state->map, MERROR_IM);
1237 MPLIST_DO (plist, plist)
1239 if (MFAILP (MPLIST_PLIST_P (plist)))
1241 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1246 /* Return a newly created IM_INFO for an input method specified by
1247 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1249 static MInputMethodInfo *
1250 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1253 MInputMethodInfo *im_info;
1256 if (name == Mnil && extra == Mnil)
1257 language = Mt, extra = Mglobal;
1258 MSTRUCT_CALLOC (im_info, MERROR_IM);
1260 im_info->language = language;
1261 im_info->name = name;
1262 im_info->extra = extra;
1265 mplist_add (plist, Mplist, elt);
1266 M17N_OBJECT_UNREF (elt);
1267 elt = mplist_add (elt, Msymbol, language);
1268 elt = mplist_add (elt, Msymbol, name);
1269 elt = mplist_add (elt, Msymbol, extra);
1270 mplist_add (elt, Mt, im_info);
1276 fini_im_info (MInputMethodInfo *im_info)
1280 M17N_OBJECT_UNREF (im_info->cmds);
1281 M17N_OBJECT_UNREF (im_info->configured_cmds);
1282 M17N_OBJECT_UNREF (im_info->bc_cmds);
1283 M17N_OBJECT_UNREF (im_info->vars);
1284 M17N_OBJECT_UNREF (im_info->configured_vars);
1285 M17N_OBJECT_UNREF (im_info->bc_vars);
1286 M17N_OBJECT_UNREF (im_info->description);
1287 M17N_OBJECT_UNREF (im_info->title);
1288 if (im_info->states)
1290 MPLIST_DO (plist, im_info->states)
1292 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1294 M17N_OBJECT_UNREF (state);
1296 M17N_OBJECT_UNREF (im_info->states);
1299 if (im_info->macros)
1301 MPLIST_DO (plist, im_info->macros)
1302 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1303 M17N_OBJECT_UNREF (im_info->macros);
1306 if (im_info->externals)
1308 MPLIST_DO (plist, im_info->externals)
1310 MIMExternalModule *external = MPLIST_VAL (plist);
1312 dlclose (external->handle);
1313 M17N_OBJECT_UNREF (external->func_list);
1315 MPLIST_KEY (plist) = Mt;
1317 M17N_OBJECT_UNREF (im_info->externals);
1321 MPLIST_DO (plist, im_info->maps)
1323 MPlist *p = MPLIST_PLIST (plist);
1325 M17N_OBJECT_UNREF (p);
1327 M17N_OBJECT_UNREF (im_info->maps);
1334 free_im_info (MInputMethodInfo *im_info)
1336 fini_im_info (im_info);
1341 free_im_list (MPlist *plist)
1345 MPLIST_DO (pl, plist)
1347 MInputMethodInfo *im_info;
1349 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1350 im_info = MPLIST_VAL (elt);
1351 free_im_info (im_info);
1353 M17N_OBJECT_UNREF (plist);
1356 static MInputMethodInfo *
1357 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1359 if (name == Mnil && extra == Mnil)
1360 language = Mt, extra = Mglobal;
1361 while ((plist = mplist__assq (plist, language)))
1363 MPlist *elt = MPLIST_PLIST (plist);
1365 plist = MPLIST_NEXT (plist);
1366 elt = MPLIST_NEXT (elt);
1367 if (MPLIST_SYMBOL (elt) != name)
1369 elt = MPLIST_NEXT (elt);
1370 if (MPLIST_SYMBOL (elt) != extra)
1372 elt = MPLIST_NEXT (elt);
1373 return MPLIST_VAL (elt);
1378 static void load_im_info (MPlist *, MInputMethodInfo *);
1380 #define get_custom_info(im_info) \
1382 ? lookup_im_info (im_custom_list, (im_info)->language, \
1383 (im_info)->name, (im_info)->extra) \
1386 #define get_config_info(im_info) \
1388 ? lookup_im_info (im_config_list, (im_info)->language, \
1389 (im_info)->name, (im_info)->extra) \
1393 update_custom_info (void)
1399 if (mdatabase__check (im_custom_mdb) > 0)
1404 MDatabaseInfo *custom_dir_info;
1405 char custom_path[PATH_MAX + 1];
1407 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1408 if (! custom_dir_info->filename
1409 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1411 strcpy (custom_path, custom_dir_info->filename);
1412 strcat (custom_path, CUSTOM_FILE);
1413 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1419 free_im_list (im_custom_list);
1420 im_custom_list = NULL;
1422 plist = mdatabase_load (im_custom_mdb);
1425 im_custom_list = mplist ();
1427 MPLIST_DO (pl, plist)
1429 MSymbol language, name, extra;
1430 MInputMethodInfo *im_info;
1431 MPlist *im_data, *p;
1433 if (! MPLIST_PLIST_P (pl))
1435 p = MPLIST_PLIST (pl);
1436 im_data = MPLIST_NEXT (p);
1437 if (! MPLIST_PLIST_P (p))
1439 p = MPLIST_PLIST (p);
1440 if (! MPLIST_SYMBOL_P (p)
1441 || MPLIST_SYMBOL (p) != Minput_method)
1443 p = MPLIST_NEXT (p);
1444 if (! MPLIST_SYMBOL_P (p))
1446 language = MPLIST_SYMBOL (p);
1447 p = MPLIST_NEXT (p);
1448 if (! MPLIST_SYMBOL_P (p))
1450 name = MPLIST_SYMBOL (p);
1451 p = MPLIST_NEXT (p);
1452 if (MPLIST_TAIL_P (p))
1454 else if (MPLIST_SYMBOL_P (p))
1455 extra = MPLIST_SYMBOL (p);
1456 if (language == Mnil || (name == Mnil && extra == Mnil))
1458 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1459 load_im_info (im_data, im_info);
1461 M17N_OBJECT_UNREF (plist);
1466 update_global_info (void)
1472 int ret = mdatabase__check (global_info->mdb);
1476 fini_im_info (global_info);
1480 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1482 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1484 if (! global_info->mdb
1485 || ! (plist = mdatabase_load (global_info->mdb)))
1488 load_im_info (plist, global_info);
1489 M17N_OBJECT_UNREF (plist);
1494 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1495 and EXTRA. KEY, if not Mnil, tells which kind of information about
1496 the input method is necessary, and the returned IM_INFO may contain
1497 only that information. */
1499 static MInputMethodInfo *
1500 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1503 MInputMethodInfo *im_info;
1506 if (name == Mnil && extra == Mnil)
1507 language = Mt, extra = Mglobal;
1508 im_info = lookup_im_info (im_info_list, language, name, extra);
1511 if (key == Mnil ? im_info->states != NULL
1512 : key == Mcommand ? im_info->cmds != NULL
1513 : key == Mvariable ? im_info->vars != NULL
1514 : key == Mtitle ? im_info->title != NULL
1515 : key == Mdescription ? im_info->description != NULL
1517 /* IM_INFO already contains required information. */
1519 /* We have not yet loaded required information. */
1523 mdb = mdatabase_find (Minput_method, language, name, extra);
1526 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1531 plist = mdatabase_load (im_info->mdb);
1535 mplist_push (load_im_info_keys, key, Mt);
1536 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1537 mplist_pop (load_im_info_keys);
1541 MERROR (MERROR_IM, im_info);
1542 update_global_info ();
1543 load_im_info (plist, im_info);
1544 M17N_OBJECT_UNREF (plist);
1547 if (! im_info->cmds)
1548 im_info->cmds = mplist ();
1549 if (! im_info->vars)
1550 im_info->vars = mplist ();
1552 if (! im_info->title
1553 && (key == Mnil || key == Mtitle))
1554 im_info->title = (name == Mnil ? mtext ()
1555 : mtext_from_data (MSYMBOL_NAME (name),
1556 MSYMBOL_NAMELEN (name),
1557 MTEXT_FORMAT_US_ASCII));
1561 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1562 If updated, but got unloadable, return -1. Otherwise, update
1563 contents of IM_INFO from the new database, and return 1. */
1566 reload_im_info (MInputMethodInfo *im_info)
1571 update_custom_info ();
1572 update_global_info ();
1573 check = mdatabase__check (im_info->mdb);
1576 plist = mdatabase_load (im_info->mdb);
1579 fini_im_info (im_info);
1580 load_im_info (plist, im_info);
1581 M17N_OBJECT_UNREF (plist);
1582 if (! im_info->cmds)
1583 im_info->cmds = mplist ();
1584 if (! im_info->vars)
1585 im_info->vars = mplist ();
1586 if (! im_info->title)
1588 MSymbol name = im_info->name;
1590 im_info->title = (name == Mnil ? mtext ()
1591 : mtext_from_data (MSYMBOL_NAME (name),
1592 MSYMBOL_NAMELEN (name),
1593 MTEXT_FORMAT_US_ASCII));
1598 static MInputMethodInfo *
1599 get_im_info_by_tags (MPlist *plist)
1604 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1605 i++, plist = MPLIST_NEXT (plist))
1606 tag[i] = MPLIST_SYMBOL (plist);
1611 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1616 check_description (MPlist *plist)
1620 if (MPLIST_MTEXT_P (plist))
1622 if (MPLIST_PLIST_P (plist))
1624 MPlist *pl = MPLIST_PLIST (plist);
1626 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1628 pl =MPLIST_NEXT (pl);
1629 if (MFAILP (MPLIST_MTEXT_P (pl)))
1631 mt = MPLIST_MTEXT (pl);
1632 M17N_OBJECT_REF (mt);
1635 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1637 if (translated == (char *) MTEXT_DATA (mt))
1638 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1639 if (translated != (char *) MTEXT_DATA (mt))
1641 M17N_OBJECT_UNREF (mt);
1642 mt = mtext__from_data (translated, strlen (translated),
1643 MTEXT_FORMAT_UTF_8, 0);
1647 mplist_set (plist, Mtext, mt);
1648 M17N_OBJECT_UNREF (mt);
1651 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1657 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1661 check_command_keyseq (MPlist *keyseq)
1663 if (MPLIST_PLIST_P (keyseq))
1665 MPlist *p = MPLIST_PLIST (keyseq);
1668 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1672 if (MPLIST_MTEXT_P (keyseq))
1674 MText *mt = MPLIST_MTEXT (keyseq);
1677 for (i = 0; i < mtext_nchars (mt); i++)
1678 if (mtext_ref_char (mt, i) >= 256)
1685 /* Load command defitions from PLIST into IM_INFO->cmds.
1687 PLIST is well-formed and has this form;
1688 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1689 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1690 M-text or a plist of symbols.
1692 The returned list has the same form, but for each element...
1694 (1) If DESCRIPTION and the rest are omitted, the element is not
1695 stored in the returned list.
1697 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1698 description in global_info->cmds (if any). */
1701 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1705 im_info->cmds = tail = mplist ();
1707 MPLIST_DO (plist, MPLIST_NEXT (plist))
1709 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1712 if (MFAILP (MPLIST_PLIST_P (plist)))
1714 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1715 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1717 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1718 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1720 if (MFAILP (im_info != global_info))
1721 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1725 if (! check_description (p))
1726 mplist_set (p, Msymbol, Mnil);
1727 p = MPLIST_NEXT (p);
1728 while (! MPLIST_TAIL_P (p))
1730 if (MFAILP (check_command_keyseq (p)))
1731 mplist__pop_unref (p);
1733 p = MPLIST_NEXT (p);
1736 tail = mplist_add (tail, Mplist, pl);
1741 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1742 MPlist *config_cmds)
1744 MPlist *global = NULL, *custom = NULL, *config = NULL;
1747 MPlist *description, *keyseq;
1749 if (global_cmds && (global = mplist__assq (global_cmds, name)))
1750 global = MPLIST_NEXT (MPLIST_PLIST (global));
1752 name = MPLIST_SYMBOL (plist);
1753 plist = MPLIST_NEXT (plist);
1754 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1756 description = plist;
1757 plist = MPLIST_NEXT (plist);
1761 description = global;
1762 if (! MPLIST_TAIL_P (plist))
1763 plist = MPLIST_NEXT (plist);
1765 if (MPLIST_TAIL_P (plist) && global)
1767 keyseq = MPLIST_NEXT (global);
1768 status = Minherited;
1776 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1778 status = Mconfigured;
1779 config = MPLIST_NEXT (MPLIST_PLIST (config));
1780 if (! MPLIST_TAIL_P (config))
1783 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1785 MPlist *this_keyseq = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
1787 if (MPLIST_TAIL_P (this_keyseq))
1788 mplist__pop_unref (custom);
1791 status = Mcustomized;
1792 keyseq = this_keyseq;
1797 mplist_add (plist, Msymbol, name);
1799 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1801 mplist_add (plist, Msymbol, Mnil);
1802 mplist_add (plist, Msymbol, status);
1803 mplist__conc (plist, keyseq);
1808 config_all_commands (MInputMethodInfo *im_info)
1810 MPlist *global_cmds, *custom_cmds, *config_cmds;
1811 MInputMethodInfo *temp;
1812 MPlist *tail, *plist;
1814 M17N_OBJECT_UNREF (im_info->configured_cmds);
1816 if (MPLIST_TAIL_P (im_info->cmds)
1820 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1821 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1822 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1824 im_info->configured_cmds = tail = mplist ();
1825 MPLIST_DO (plist, im_info->cmds)
1827 MPlist *pl = config_command (MPLIST_PLIST (plist),
1828 global_cmds, custom_cmds, config_cmds);
1831 tail = mplist_add (tail, Mplist, pl);
1832 M17N_OBJECT_UNREF (pl);
1837 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1838 valid, return 0 if not. */
1841 check_variable_value (MPlist *val, MPlist *global)
1843 MSymbol type = MPLIST_KEY (val);
1844 MPlist *valids = MPLIST_NEXT (val);
1846 if (type != Minteger && type != Mtext && type != Msymbol)
1850 if (MPLIST_KEY (global) != Mt
1851 && MPLIST_KEY (global) != MPLIST_KEY (val))
1853 if (MPLIST_TAIL_P (valids))
1854 valids = MPLIST_NEXT (global);
1856 if (MPLIST_TAIL_P (valids))
1859 if (type == Minteger)
1861 int n = MPLIST_INTEGER (val);
1863 MPLIST_DO (valids, valids)
1865 if (MPLIST_INTEGER_P (valids))
1867 if (n == MPLIST_INTEGER (valids))
1870 else if (MPLIST_PLIST_P (valids))
1872 MPlist *p = MPLIST_PLIST (valids);
1873 int min_bound, max_bound;
1875 if (! MPLIST_INTEGER_P (p))
1876 MERROR (MERROR_IM, 0);
1877 min_bound = MPLIST_INTEGER (p);
1878 p = MPLIST_NEXT (p);
1879 if (! MPLIST_INTEGER_P (p))
1880 MERROR (MERROR_IM, 0);
1881 max_bound = MPLIST_INTEGER (p);
1882 if (n >= min_bound && n <= max_bound)
1887 else if (type == Msymbol)
1889 MSymbol sym = MPLIST_SYMBOL (val);
1891 MPLIST_DO (valids, valids)
1893 if (! MPLIST_SYMBOL_P (valids))
1894 MERROR (MERROR_IM, 0);
1895 if (sym == MPLIST_SYMBOL (valids))
1901 MText *mt = MPLIST_MTEXT (val);
1903 MPLIST_DO (valids, valids)
1905 if (! MPLIST_MTEXT_P (valids))
1906 MERROR (MERROR_IM, 0);
1907 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1912 return (! MPLIST_TAIL_P (valids));
1915 /* Load variable defitions from PLIST into IM_INFO->vars.
1917 PLIST is well-formed and has this form;
1918 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1920 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1922 The returned list has the same form, but for each element...
1924 (1) If DESCRIPTION and the rest are omitted, the element is not
1925 stored in the returned list.
1927 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1928 description in global_info->vars (if any). */
1931 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1933 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1934 ? global_info->vars : NULL);
1937 im_info->vars = tail = mplist ();
1938 MPLIST_DO (plist, MPLIST_NEXT (plist))
1942 if (MFAILP (MPLIST_PLIST_P (plist)))
1944 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1945 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1947 if (im_info == global_info)
1949 /* Loading a global variable. */
1950 p = MPLIST_NEXT (pl);
1951 if (MPLIST_TAIL_P (p))
1952 mplist_add (p, Msymbol, Mnil);
1955 if (! check_description (p))
1956 mplist_set (p, Msymbol, Mnil);
1957 p = MPLIST_NEXT (p);
1958 if (MFAILP (! MPLIST_TAIL_P (p)
1959 && check_variable_value (p, NULL)))
1960 mplist_set (p, Mt, NULL);
1963 else if (im_info->mdb)
1965 /* Loading a local variable. */
1966 MSymbol name = MPLIST_SYMBOL (pl);
1967 MPlist *global = NULL;
1970 && (p = mplist__assq (global_vars, name)))
1972 /* P ::= ((NAME DESC ...) ...) */
1973 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1974 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1975 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1978 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1979 if (! MPLIST_TAIL_P (p))
1981 if (! check_description (p))
1982 mplist_set (p, Msymbol, Mnil);
1983 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1984 if (MFAILP (! MPLIST_TAIL_P (p)))
1985 mplist_set (p, Mt, NULL);
1988 MPlist *valid_values = MPLIST_NEXT (p);
1990 if (! MPLIST_TAIL_P (valid_values)
1991 ? MFAILP (check_variable_value (p, NULL))
1992 : global && MFAILP (check_variable_value (p, global)))
1993 mplist_set (p, Mt, NULL);
1999 /* Loading a variable customization. */
2000 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2001 if (MFAILP (! MPLIST_TAIL_P (p)))
2003 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2004 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2005 || MPLIST_MTEXT_P (p)))
2008 tail = mplist_add (tail, Mplist, pl);
2013 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2014 MPlist *config_vars)
2016 MPlist *global = NULL, *custom = NULL, *config = NULL;
2017 MSymbol name = MPLIST_SYMBOL (plist);
2019 MPlist *description = NULL, *value, *valids;
2023 global = mplist__assq (global_vars, name);
2025 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2028 plist = MPLIST_NEXT (plist);
2029 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2030 description = plist;
2032 description = global;
2034 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2036 if (MPLIST_TAIL_P (plist))
2038 /* Inherit from global (if any). */
2042 if (MPLIST_KEY (value) == Mt)
2044 valids = MPLIST_NEXT (global);
2045 status = Minherited;
2057 value = plist = MPLIST_NEXT (plist);
2058 valids = MPLIST_NEXT (value);
2059 if (MPLIST_KEY (value) == Mt)
2061 if (! MPLIST_TAIL_P (valids))
2064 valids = MPLIST_NEXT (global);
2068 if (config_vars && (config = mplist__assq (config_vars, name)))
2070 status = Mconfigured;
2071 config = MPLIST_NEXT (MPLIST_PLIST (config));
2072 if (! MPLIST_TAIL_P (config))
2075 if (MFAILP (check_variable_value (value, global ? global : plist)))
2079 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2081 MPlist *this_value = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (custom)));
2083 if (MPLIST_TAIL_P (this_value))
2084 mplist__pop_unref (custom);
2088 if (MFAILP (check_variable_value (value, global ? global : plist)))
2090 status = Mcustomized;
2095 mplist_add (plist, Msymbol, name);
2097 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2099 mplist_add (plist, Msymbol, Mnil);
2100 mplist_add (plist, Msymbol, status);
2102 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2104 mplist_add (plist, Mt, NULL);
2105 if (valids && ! MPLIST_TAIL_P (valids))
2106 mplist__conc (plist, valids);
2110 /* Return a configured variable definition list based on
2111 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2112 get it from global_info->vars. */
2115 config_all_variables (MInputMethodInfo *im_info)
2117 MPlist *global_vars, *custom_vars, *config_vars;
2118 MInputMethodInfo *temp;
2119 MPlist *tail, *plist;
2121 M17N_OBJECT_UNREF (im_info->configured_vars);
2123 if (MPLIST_TAIL_P (im_info->vars)
2127 global_vars = im_info != global_info ? global_info->vars : NULL;
2128 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2129 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2131 im_info->configured_vars = tail = mplist ();
2132 MPLIST_DO (plist, im_info->vars)
2134 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2135 global_vars, custom_vars, config_vars);
2138 tail = mplist_add (tail, Mplist, pl);
2139 M17N_OBJECT_UNREF (pl);
2144 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2145 CONFIG contains configuration information of the input method. */
2148 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2152 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2154 load_commands (im_info, MPLIST_PLIST (pl));
2155 config_all_commands (im_info);
2156 pl = mplist_pop (pl);
2157 M17N_OBJECT_UNREF (pl);
2160 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2162 load_variables (im_info, MPLIST_PLIST (pl));
2163 config_all_variables (im_info);
2164 pl = mplist_pop (pl);
2165 M17N_OBJECT_UNREF (pl);
2168 MPLIST_DO (plist, plist)
2169 if (MPLIST_PLIST_P (plist))
2171 MPlist *elt = MPLIST_PLIST (plist);
2174 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2176 key = MPLIST_SYMBOL (elt);
2181 elt = MPLIST_NEXT (elt);
2182 if (MFAILP (MPLIST_MTEXT_P (elt)))
2184 im_info->title = MPLIST_MTEXT (elt);
2185 M17N_OBJECT_REF (im_info->title);
2187 else if (key == Mmap)
2189 pl = mplist__from_alist (MPLIST_NEXT (elt));
2192 if (! im_info->maps)
2196 mplist__conc (im_info->maps, pl);
2197 M17N_OBJECT_UNREF (pl);
2200 else if (key == Mmacro)
2202 if (! im_info->macros)
2203 im_info->macros = mplist ();
2204 MPLIST_DO (elt, MPLIST_NEXT (elt))
2206 if (MFAILP (MPLIST_PLIST_P (elt)))
2208 load_macros (im_info, MPLIST_PLIST (elt));
2211 else if (key == Mmodule)
2213 if (! im_info->externals)
2214 im_info->externals = mplist ();
2215 MPLIST_DO (elt, MPLIST_NEXT (elt))
2217 if (MFAILP (MPLIST_PLIST_P (elt)))
2219 load_external_module (im_info, MPLIST_PLIST (elt));
2222 else if (key == Mstate)
2224 MPLIST_DO (elt, MPLIST_NEXT (elt))
2228 if (MFAILP (MPLIST_PLIST_P (elt)))
2230 pl = MPLIST_PLIST (elt);
2231 if (! im_info->states)
2232 im_info->states = mplist ();
2233 state = load_state (im_info, MPLIST_PLIST (elt));
2236 mplist_put (im_info->states, state->name, state);
2239 else if (key == Minclude)
2241 /* elt ::= include (tag1 tag2 ...) key item ... */
2243 MInputMethodInfo *temp;
2245 elt = MPLIST_NEXT (elt);
2246 if (MFAILP (MPLIST_PLIST_P (elt)))
2248 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2251 elt = MPLIST_NEXT (elt);
2252 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2254 key = MPLIST_SYMBOL (elt);
2255 elt = MPLIST_NEXT (elt);
2258 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2260 if (! im_info->maps)
2261 im_info->maps = mplist ();
2262 MPLIST_DO (pl, temp->maps)
2264 p = MPLIST_VAL (pl);
2265 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2266 M17N_OBJECT_REF (p);
2269 else if (key == Mmacro)
2271 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2273 if (! im_info->macros)
2274 im_info->macros = mplist ();
2275 MPLIST_DO (pl, temp->macros)
2277 p = MPLIST_VAL (pl);
2278 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2279 M17N_OBJECT_REF (p);
2282 else if (key == Mstate)
2284 if (! temp->states || MPLIST_TAIL_P (temp->states))
2286 if (! im_info->states)
2287 im_info->states = mplist ();
2288 MPLIST_DO (pl, temp->states)
2290 MIMState *state = MPLIST_VAL (pl);
2292 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2293 M17N_OBJECT_REF (state);
2297 else if (key == Mdescription)
2299 if (im_info->description)
2301 elt = MPLIST_NEXT (elt);
2302 if (! check_description (elt))
2304 im_info->description = MPLIST_MTEXT (elt);
2305 M17N_OBJECT_REF (im_info->description);
2308 im_info->tick = time (NULL);
2313 static int take_action_list (MInputContext *ic, MPlist *action_list);
2314 static void preedit_commit (MInputContext *ic);
2317 shift_state (MInputContext *ic, MSymbol state_name)
2319 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2320 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2321 MIMState *orig_state = ic_info->state, *state;
2323 /* Find a state to shift to. If not found, shift to the initial
2325 if (state_name == Mt)
2327 if (! ic_info->prev_state)
2329 state = ic_info->prev_state;
2331 else if (state_name == Mnil)
2333 state = (MIMState *) MPLIST_VAL (im_info->states);
2337 state = (MIMState *) mplist_get (im_info->states, state_name);
2339 state = (MIMState *) MPLIST_VAL (im_info->states);
2342 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2344 /* Enter the new state. */
2345 ic_info->state = state;
2346 ic_info->map = state->map;
2347 ic_info->state_key_head = ic_info->key_head;
2348 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2350 /* We have shifted to the initial state. */
2351 preedit_commit (ic);
2352 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2353 ic_info->state_pos = ic->cursor_pos;
2354 if (state != orig_state)
2356 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2358 /* Shifted to the initial state. */
2359 ic_info->prev_state = NULL;
2360 M17N_OBJECT_UNREF (ic_info->vars_saved);
2361 ic_info->vars_saved = mplist_copy (ic_info->vars);
2364 ic_info->prev_state = orig_state;
2367 ic->status = state->title;
2369 ic->status = im_info->title;
2370 ic->status_changed = 1;
2371 if (ic_info->map == ic_info->state->map
2372 && ic_info->map->map_actions)
2374 MDEBUG_PRINT (" init-actions:");
2375 take_action_list (ic, ic_info->map->map_actions);
2380 /* Find a candidate group that contains a candidate number INDEX from
2381 PLIST. Set START_INDEX to the first candidate number of the group,
2382 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2383 candidate group number if they are non-NULL. If INDEX is -1, find
2384 the last candidate group. */
2387 find_candidates_group (MPlist *plist, int index,
2388 int *start_index, int *end_index, int *group_index)
2390 int i = 0, gidx = 0, len;
2392 MPLIST_DO (plist, plist)
2394 if (MPLIST_MTEXT_P (plist))
2395 len = mtext_nchars (MPLIST_MTEXT (plist));
2397 len = mplist_length (MPLIST_PLIST (plist));
2398 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2404 *end_index = i + len;
2406 *group_index = gidx;
2415 /* Adjust markers for the change of preedit text.
2416 If FROM == TO, the change is insertion of INS chars.
2417 If FROM < TO and INS == 0, the change is deletion of the range.
2418 If FROM < TO and INS > 0, the change is replacement. */
2421 adjust_markers (MInputContext *ic, int from, int to, int ins)
2423 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2428 MPLIST_DO (markers, ic_info->markers)
2429 if (MPLIST_INTEGER (markers) > from)
2430 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2431 if (ic->cursor_pos >= from)
2432 ic->cursor_pos += ins;
2436 MPLIST_DO (markers, ic_info->markers)
2438 if (MPLIST_INTEGER (markers) >= to)
2439 MPLIST_VAL (markers)
2440 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2441 else if (MPLIST_INTEGER (markers) > from)
2442 MPLIST_VAL (markers) = (void *) from;
2444 if (ic->cursor_pos >= to)
2445 ic->cursor_pos += ins - (to - from);
2446 else if (ic->cursor_pos > from)
2447 ic->cursor_pos = from;
2453 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2455 int nchars = mt ? mtext_nchars (mt) : 1;
2458 mtext_ins (ic->preedit, pos, mt);
2460 mtext_ins_char (ic->preedit, pos, c, 1);
2461 adjust_markers (ic, pos, pos, nchars);
2462 ic->preedit_changed = 1;
2467 preedit_delete (MInputContext *ic, int from, int to)
2469 mtext_del (ic->preedit, from, to);
2470 adjust_markers (ic, from, to, 0);
2471 ic->preedit_changed = 1;
2475 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2479 mtext_del (ic->preedit, from, to);
2482 mtext_ins (ic->preedit, from, mt);
2483 ins = mtext_nchars (mt);
2487 mtext_ins_char (ic->preedit, from, c, 1);
2490 adjust_markers (ic, from, to, ins);
2491 ic->preedit_changed = 1;
2496 preedit_commit (MInputContext *ic)
2498 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2499 int preedit_len = mtext_nchars (ic->preedit);
2501 if (preedit_len > 0)
2505 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2506 Mcandidate_list, NULL, 0);
2507 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2508 Mcandidate_index, NULL, 0);
2509 mtext_cat (ic->produced, ic->preedit);
2510 if (mdebug__flag & mdebug_mask)
2514 MDEBUG_PRINT (" (commit");
2515 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2516 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2520 mtext_reset (ic->preedit);
2521 mtext_reset (ic_info->preedit_saved);
2522 MPLIST_DO (p, ic_info->markers)
2524 ic->cursor_pos = ic_info->state_pos = 0;
2525 ic->preedit_changed = 1;
2526 ic_info->commit_key_head = ic_info->key_head;
2528 if (ic->candidate_list)
2530 M17N_OBJECT_UNREF (ic->candidate_list);
2531 ic->candidate_list = NULL;
2532 ic->candidate_index = 0;
2533 ic->candidate_from = ic->candidate_to = 0;
2534 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2535 if (ic->candidate_show)
2537 ic->candidate_show = 0;
2538 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2544 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2546 int code = marker_code (sym, 0);
2548 if (mt && (code == '[' || code == ']'))
2552 if (code == '[' && current > 0)
2554 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2558 else if (code == ']' && current < mtext_nchars (mt))
2560 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2566 return (code == '<' ? 0
2567 : code == '>' ? limit
2568 : code == '-' ? current - 1
2569 : code == '+' ? current + 1
2570 : code == '=' ? current
2571 : code - '0' > limit ? limit
2575 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2579 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2581 int from = mtext_property_start (prop);
2582 int to = mtext_property_end (prop);
2584 MPlist *candidate_list = mtext_property_value (prop);
2585 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2587 int ingroup_index = idx - start;
2590 if (MPLIST_MTEXT_P (group))
2592 mt = MPLIST_MTEXT (group);
2593 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2601 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2602 i++, plist = MPLIST_NEXT (plist));
2603 mt = MPLIST_MTEXT (plist);
2604 preedit_replace (ic, from, to, mt, 0);
2605 to = from + mtext_nchars (mt);
2607 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2608 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2609 ic->cursor_pos = to;
2613 get_select_charset (MInputContextInfo * ic_info)
2615 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2618 if (! MPLIST_VAL (plist))
2620 sym = MPLIST_SYMBOL (plist);
2623 return MCHARSET (sym);
2627 adjust_candidates (MPlist *plist, MCharset *charset)
2631 /* plist ::= MTEXT ... | PLIST ... */
2632 plist = mplist_copy (plist);
2633 if (MPLIST_MTEXT_P (plist))
2636 while (! MPLIST_TAIL_P (pl))
2638 /* pl ::= MTEXT ... */
2639 MText *mt = MPLIST_MTEXT (pl);
2643 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2645 c = mtext_ref_char (mt, i);
2646 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2650 mt = mtext_dup (mt);
2651 mplist_set (pl, Mtext, mt);
2652 M17N_OBJECT_UNREF (mt);
2655 mtext_del (mt, i, i + 1);
2658 if (mtext_len (mt) > 0)
2659 pl = MPLIST_NEXT (pl);
2663 M17N_OBJECT_UNREF (mt);
2667 else /* MPLIST_PLIST_P (plist) */
2670 while (! MPLIST_TAIL_P (pl))
2672 /* pl ::= (MTEXT ...) ... */
2673 MPlist *p = MPLIST_PLIST (pl);
2675 /* p ::= MTEXT ... */
2679 while (! MPLIST_TAIL_P (p0))
2681 MText *mt = MPLIST_MTEXT (p0);
2684 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2686 c = mtext_ref_char (mt, i);
2687 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2692 p0 = MPLIST_NEXT (p0);
2699 p = mplist_copy (p);
2700 mplist_set (pl, Mplist, p);
2701 M17N_OBJECT_UNREF (p);
2705 p0 = MPLIST_NEXT (p0);
2708 M17N_OBJECT_UNREF (mt);
2711 if (! MPLIST_TAIL_P (p))
2712 pl = MPLIST_NEXT (pl);
2716 M17N_OBJECT_UNREF (p);
2720 if (MPLIST_TAIL_P (plist))
2722 M17N_OBJECT_UNREF (plist);
2729 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2731 MCharset *charset = get_select_charset (ic_info);
2736 plist = resolve_variable (ic_info, Mcandidates_group_size);
2737 column = MPLIST_INTEGER (plist);
2739 plist = MPLIST_PLIST (args);
2741 plist = adjust_candidates (plist, charset);
2743 if (plist && column > 0)
2745 if (MPLIST_MTEXT_P (plist))
2747 MText *mt = MPLIST_MTEXT (plist);
2748 MPlist *next = MPLIST_NEXT (plist);
2750 if (MPLIST_TAIL_P (next))
2751 M17N_OBJECT_REF (mt);
2754 mt = mtext_dup (mt);
2755 while (! MPLIST_TAIL_P (next))
2757 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2758 next = MPLIST_NEXT (next);
2762 M17N_OBJECT_UNREF (plist);
2764 len = mtext_nchars (mt);
2766 mplist_add (plist, Mtext, mt);
2769 for (i = 0; i < len; i += column)
2771 int to = (i + column < len ? i + column : len);
2772 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2774 mplist_add (plist, Mtext, sub);
2775 M17N_OBJECT_UNREF (sub);
2778 M17N_OBJECT_UNREF (mt);
2780 else if (! MPLIST_TAIL_P (plist))
2782 MPlist *tail = plist;
2783 MPlist *new = mplist ();
2784 MPlist *this = mplist ();
2787 MPLIST_DO (tail, tail)
2789 MPlist *p = MPLIST_PLIST (tail);
2793 MText *mt = MPLIST_MTEXT (p);
2795 if (count == column)
2797 mplist_add (new, Mplist, this);
2798 M17N_OBJECT_UNREF (this);
2802 mplist_add (this, Mtext, mt);
2806 mplist_add (new, Mplist, this);
2807 M17N_OBJECT_UNREF (this);
2808 mplist_set (plist, Mnil, NULL);
2809 MPLIST_DO (tail, new)
2811 MPlist *elt = MPLIST_PLIST (tail);
2813 mplist_add (plist, Mplist, elt);
2815 M17N_OBJECT_UNREF (new);
2824 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2826 MPlist *action = NULL;
2830 if (MPLIST_SYMBOL_P (action_list))
2832 MSymbol var = MPLIST_SYMBOL (action_list);
2835 MPLIST_DO (p, ic_info->vars)
2836 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2838 if (MPLIST_TAIL_P (p))
2840 action = MPLIST_NEXT (MPLIST_PLIST (p));
2841 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2844 if (MPLIST_PLIST_P (action_list))
2846 action = MPLIST_PLIST (action_list);
2847 if (MPLIST_SYMBOL_P (action))
2849 name = MPLIST_SYMBOL (action);
2850 args = MPLIST_NEXT (action);
2852 && MPLIST_PLIST_P (args))
2853 mplist_set (action, Msymbol, M_candidates);
2855 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2858 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2859 mplist_push (action, Msymbol, M_candidates);
2860 mplist_set (action_list, Mplist, action);
2861 M17N_OBJECT_UNREF (action);
2864 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2867 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2868 mplist_push (action, Msymbol, Minsert);
2869 mplist_set (action_list, Mplist, action);
2870 M17N_OBJECT_UNREF (action);
2875 /* Perform list of actions in ACTION_LIST for the current input
2876 context IC. If unhandle action was not performed, return 0.
2877 Otherwise, return -1. */
2880 take_action_list (MInputContext *ic, MPlist *action_list)
2882 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2883 MPlist *candidate_list = ic->candidate_list;
2884 int candidate_index = ic->candidate_index;
2885 int candidate_show = ic->candidate_show;
2886 MTextProperty *prop;
2888 MPLIST_DO (action_list, action_list)
2890 MPlist *action = regularize_action (action_list, ic_info);
2896 name = MPLIST_SYMBOL (action);
2897 args = MPLIST_NEXT (action);
2899 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2900 if (name == Minsert)
2902 if (MPLIST_SYMBOL_P (args))
2904 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2905 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2908 if (MPLIST_MTEXT_P (args))
2909 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2910 else /* MPLIST_INTEGER_P (args)) */
2911 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2913 else if (name == M_candidates)
2915 MPlist *plist = get_candidate_list (ic_info, args);
2918 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2920 if (MPLIST_MTEXT_P (plist))
2922 preedit_insert (ic, ic->cursor_pos, NULL,
2923 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2926 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2930 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2932 preedit_insert (ic, ic->cursor_pos, mt, 0);
2933 len = mtext_nchars (mt);
2935 mtext_put_prop (ic->preedit,
2936 ic->cursor_pos - len, ic->cursor_pos,
2937 Mcandidate_list, plist);
2938 mtext_put_prop (ic->preedit,
2939 ic->cursor_pos - len, ic->cursor_pos,
2940 Mcandidate_index, (void *) 0);
2942 else if (name == Mselect)
2945 int code, idx, gindex;
2946 int pos = ic->cursor_pos;
2948 int idx_decided = 0;
2951 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2954 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2955 group = find_candidates_group (mtext_property_value (prop), idx,
2956 &start, &end, &gindex);
2957 if (MPLIST_SYMBOL_P (args))
2959 code = marker_code (MPLIST_SYMBOL (args), 0);
2962 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2963 if (! MPLIST_INTEGER_P (args))
2965 idx = start + MPLIST_INTEGER (args);
2966 if (idx < start || idx >= end)
2974 if (code != '[' && code != ']')
2979 ? new_index (NULL, ic->candidate_index - start,
2980 end - start - 1, MPLIST_SYMBOL (args),
2982 : MPLIST_INTEGER (args)));
2985 find_candidates_group (mtext_property_value (prop), -1,
2990 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2995 int ingroup_index = idx - start;
2998 group = mtext_property_value (prop);
2999 len = mplist_length (group);
3012 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3013 idx += (MPLIST_MTEXT_P (group)
3014 ? mtext_nchars (MPLIST_MTEXT (group))
3015 : mplist_length (MPLIST_PLIST (group)));
3016 len = (MPLIST_MTEXT_P (group)
3017 ? mtext_nchars (MPLIST_MTEXT (group))
3018 : mplist_length (MPLIST_PLIST (group)));
3019 if (ingroup_index >= len)
3020 ingroup_index = len - 1;
3021 idx += ingroup_index;
3023 update_candidate (ic, prop, idx);
3024 MDEBUG_PRINT1 ("(%d)", idx);
3026 else if (name == Mshow)
3027 ic->candidate_show = 1;
3028 else if (name == Mhide)
3029 ic->candidate_show = 0;
3030 else if (name == Mdelete)
3032 int len = mtext_nchars (ic->preedit);
3036 if (MPLIST_SYMBOL_P (args)
3037 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3039 to = ic->cursor_pos + pos;
3042 delete_surrounding_text (ic, to);
3047 delete_surrounding_text (ic, to - len);
3053 to = (MPLIST_SYMBOL_P (args)
3054 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3056 : MPLIST_INTEGER (args));
3062 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3063 if (to < ic->cursor_pos)
3064 preedit_delete (ic, to, ic->cursor_pos);
3065 else if (to > ic->cursor_pos)
3066 preedit_delete (ic, ic->cursor_pos, to);
3068 else if (name == Mmove)
3070 int len = mtext_nchars (ic->preedit);
3072 = (MPLIST_SYMBOL_P (args)
3073 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3075 : MPLIST_INTEGER (args));
3081 if (pos != ic->cursor_pos)
3083 ic->cursor_pos = pos;
3084 ic->preedit_changed = 1;
3086 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3088 else if (name == Mmark)
3090 int code = marker_code (MPLIST_SYMBOL (args), 0);
3094 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3095 (void *) ic->cursor_pos);
3096 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3099 else if (name == Mpushback)
3101 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3105 if (MPLIST_SYMBOL_P (args))
3107 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3108 if (MPLIST_INTEGER_P (args))
3109 num = MPLIST_INTEGER (args);
3114 num = MPLIST_INTEGER (args);
3117 ic_info->key_head -= num;
3119 ic_info->key_head = 0;
3121 ic_info->key_head = - num;
3122 if (ic_info->key_head > ic_info->used)
3123 ic_info->key_head = ic_info->used;
3125 else if (MPLIST_MTEXT_P (args))
3127 MText *mt = MPLIST_MTEXT (args);
3128 int i, len = mtext_nchars (mt);
3131 ic_info->key_head--;
3132 for (i = 0; i < len; i++)
3134 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3135 if (ic_info->key_head + i < ic_info->used)
3136 ic_info->keys[ic_info->key_head + i] = key;
3138 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3143 MPlist *plist = MPLIST_PLIST (args), *pl;
3147 ic_info->key_head--;
3149 MPLIST_DO (pl, plist)
3151 key = MPLIST_SYMBOL (pl);
3152 if (ic_info->key_head < ic_info->used)
3153 ic_info->keys[ic_info->key_head + i] = key;
3155 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3160 else if (name == Mpop)
3162 if (ic_info->key_head < ic_info->used)
3163 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3165 else if (name == Mcall)
3167 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3168 MIMExternalFunc func = NULL;
3169 MSymbol module, func_name;
3170 MPlist *func_args, *val;
3173 module = MPLIST_SYMBOL (args);
3174 args = MPLIST_NEXT (args);
3175 func_name = MPLIST_SYMBOL (args);
3177 if (im_info->externals)
3179 MIMExternalModule *external
3180 = (MIMExternalModule *) mplist_get (im_info->externals,
3183 func = ((MIMExternalFunc)
3184 mplist_get_func (external->func_list, func_name));
3188 func_args = mplist ();
3189 mplist_add (func_args, Mt, ic);
3190 MPLIST_DO (args, MPLIST_NEXT (args))
3194 if (MPLIST_KEY (args) == Msymbol
3195 && MPLIST_KEY (args) != Mnil
3196 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3198 code = new_index (ic, ic->cursor_pos,
3199 mtext_nchars (ic->preedit),
3200 MPLIST_SYMBOL (args), ic->preedit);
3201 mplist_add (func_args, Minteger, (void *) code);
3204 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3206 val = (func) (func_args);
3207 M17N_OBJECT_UNREF (func_args);
3208 if (val && ! MPLIST_TAIL_P (val))
3209 ret = take_action_list (ic, val);
3210 M17N_OBJECT_UNREF (val);
3214 else if (name == Mshift)
3216 shift_state (ic, MPLIST_SYMBOL (args));
3218 else if (name == Mundo)
3220 int intarg = (MPLIST_TAIL_P (args)
3222 : integer_value (ic, args, NULL, 0));
3224 mtext_reset (ic->preedit);
3225 mtext_reset (ic_info->preedit_saved);
3226 mtext_reset (ic->produced);
3227 M17N_OBJECT_UNREF (ic_info->vars);
3228 ic_info->vars = mplist_copy (ic_info->vars_saved);
3229 ic->cursor_pos = ic_info->state_pos = 0;
3230 ic_info->state_key_head = ic_info->key_head
3231 = ic_info->commit_key_head = 0;
3233 shift_state (ic, Mnil);
3236 if (MPLIST_TAIL_P (args))
3241 ic_info->used += intarg;
3244 ic_info->used = intarg;
3247 else if (name == Mset || name == Madd || name == Msub
3248 || name == Mmul || name == Mdiv)
3250 MSymbol sym = MPLIST_SYMBOL (args);
3255 val1 = integer_value (ic, args, &value, 0);
3256 args = MPLIST_NEXT (args);
3257 val2 = resolve_expression (ic, args);
3259 val1 = val2, op = "=";
3260 else if (name == Madd)
3261 val1 += val2, op = "+=";
3262 else if (name == Msub)
3263 val1 -= val2, op = "-=";
3264 else if (name == Mmul)
3265 val1 *= val2, op = "*=";
3267 val1 /= val2, op = "/=";
3268 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3269 MSYMBOL_NAME (sym), op, val1, val1);
3271 mplist_set (value, Minteger, (void *) val1);
3273 else if (name == Mequal || name == Mless || name == Mgreater
3274 || name == Mless_equal || name == Mgreater_equal)
3277 MPlist *actions1, *actions2;
3280 val1 = resolve_expression (ic, args);
3281 args = MPLIST_NEXT (args);
3282 val2 = resolve_expression (ic, args);
3283 args = MPLIST_NEXT (args);
3284 actions1 = MPLIST_PLIST (args);
3285 args = MPLIST_NEXT (args);
3286 if (MPLIST_TAIL_P (args))
3289 actions2 = MPLIST_PLIST (args);
3290 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3291 if (name == Mequal ? val1 == val2
3292 : name == Mless ? val1 < val2
3293 : name == Mgreater ? val1 > val2
3294 : name == Mless_equal ? val1 <= val2
3297 MDEBUG_PRINT ("ok");
3298 ret = take_action_list (ic, actions1);
3302 MDEBUG_PRINT ("no");
3304 ret = take_action_list (ic, actions2);
3309 else if (name == Mcond)
3313 MPLIST_DO (args, args)
3318 if (! MPLIST_PLIST (args))
3320 cond = MPLIST_PLIST (args);
3321 if (resolve_expression (ic, cond) != 0)
3323 MDEBUG_PRINT1 ("(%dth)", idx);
3324 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3330 else if (name == Mcommit)
3332 preedit_commit (ic);
3334 else if (name == Munhandle)
3336 preedit_commit (ic);
3341 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3345 && (actions = mplist_get (im_info->macros, name)))
3347 if (take_action_list (ic, actions) < 0)
3353 if (ic->candidate_list)
3355 M17N_OBJECT_UNREF (ic->candidate_list);
3356 ic->candidate_list = NULL;
3358 if (ic->cursor_pos > 0
3359 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3362 ic->candidate_list = mtext_property_value (prop);
3363 M17N_OBJECT_REF (ic->candidate_list);
3365 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3367 ic->candidate_from = mtext_property_start (prop);
3368 ic->candidate_to = mtext_property_end (prop);
3371 if (candidate_list != ic->candidate_list)
3372 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3373 if (candidate_index != ic->candidate_index)
3374 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3375 if (candidate_show != ic->candidate_show)
3376 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3381 /* Handle the input key KEY in the current state and map specified in
3382 the input context IC. If KEY is handled correctly, return 0.
3383 Otherwise, return -1. */
3386 handle_key (MInputContext *ic)
3388 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3389 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3390 MIMMap *map = ic_info->map;
3391 MIMMap *submap = NULL;
3392 MSymbol key = ic_info->keys[ic_info->key_head];
3393 MSymbol alias = Mnil;
3396 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3397 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3401 submap = mplist_get (map->submaps, key);
3404 && (alias = msymbol_get (alias, M_key_alias))
3406 submap = mplist_get (map->submaps, alias);
3411 if (! alias || alias == key)
3412 MDEBUG_PRINT (" submap-found");
3414 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3415 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3416 ic->preedit_changed = 1;
3417 ic->cursor_pos = ic_info->state_pos;
3418 ic_info->key_head++;
3419 ic_info->map = map = submap;
3420 if (map->map_actions)
3422 MDEBUG_PRINT (" map-actions:");
3423 if (take_action_list (ic, map->map_actions) < 0)
3425 MDEBUG_PRINT ("\n");
3429 else if (map->submaps)
3431 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3433 MSymbol key = ic_info->keys[i];
3434 char *name = msymbol_name (key);
3436 if (! name[0] || ! name[1])
3437 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3441 /* If this is the terminal map or we have shifted to another
3442 state, perform branch actions (if any). */
3443 if (! map->submaps || map != ic_info->map)
3445 if (map->branch_actions)
3447 MDEBUG_PRINT (" branch-actions:");
3448 if (take_action_list (ic, map->branch_actions) < 0)
3450 MDEBUG_PRINT ("\n");
3454 /* If MAP is still not the root map, shift to the current
3456 if (ic_info->map != ic_info->state->map)
3457 shift_state (ic, ic_info->state->name);
3462 /* MAP can not handle KEY. */
3464 /* Perform branch actions if any. */
3465 if (map->branch_actions)
3467 MDEBUG_PRINT (" branch-actions:");
3468 if (take_action_list (ic, map->branch_actions) < 0)
3470 MDEBUG_PRINT ("\n");
3475 if (map == ic_info->map)
3477 /* The above branch actions didn't change the state. */
3479 /* If MAP is the root map of the initial state, and there
3480 still exist an unhandled key, it means that the current
3481 input method can not handle it. */
3482 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3483 && ic_info->key_head < ic_info->used)
3485 MDEBUG_PRINT (" unhandled\n");
3489 if (map != ic_info->state->map)
3491 /* MAP is not the root map. Shift to the root map of the
3493 shift_state (ic, ic_info->state->name);
3495 else if (! map->branch_actions)
3497 /* MAP is the root map without any default branch
3498 actions. Shift to the initial state. */
3499 shift_state (ic, Mnil);
3503 MDEBUG_PRINT ("\n");
3507 /* Initialize IC->ic_info. */
3510 init_ic_info (MInputContext *ic)
3512 MInputMethodInfo *im_info = ic->im->info;
3513 MInputContextInfo *ic_info = ic->info;
3516 MLIST_INIT1 (ic_info, keys, 8);;
3518 ic_info->markers = mplist ();
3520 ic_info->vars = mplist ();
3521 if (im_info->configured_vars)
3522 MPLIST_DO (plist, im_info->configured_vars)
3524 MPlist *pl = MPLIST_PLIST (plist);
3525 MSymbol name = MPLIST_SYMBOL (pl);
3527 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3528 if (MPLIST_KEY (pl) != Mt)
3530 MPlist *p = mplist ();
3532 mplist_push (ic_info->vars, Mplist, p);
3533 M17N_OBJECT_UNREF (p);
3534 mplist_add (p, Msymbol, name);
3535 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3538 ic_info->vars_saved = mplist_copy (ic_info->vars);
3540 if (im_info->externals)
3542 MPlist *func_args = mplist (), *plist;
3544 mplist_add (func_args, Mt, ic);
3545 MPLIST_DO (plist, im_info->externals)
3547 MIMExternalModule *external = MPLIST_VAL (plist);
3548 MIMExternalFunc func
3549 = (MIMExternalFunc) mplist_get_func (external->func_list, Minit);
3554 M17N_OBJECT_UNREF (func_args);
3557 ic_info->preedit_saved = mtext ();
3558 ic_info->tick = im_info->tick;
3561 /* Finalize IC->ic_info. */
3564 fini_ic_info (MInputContext *ic)
3566 MInputMethodInfo *im_info = ic->im->info;
3567 MInputContextInfo *ic_info = ic->info;
3569 if (im_info->externals)
3571 MPlist *func_args = mplist (), *plist;
3573 mplist_add (func_args, Mt, ic);
3574 MPLIST_DO (plist, im_info->externals)
3576 MIMExternalModule *external = MPLIST_VAL (plist);
3577 MIMExternalFunc func
3578 = (MIMExternalFunc) mplist_get_func (external->func_list, Mfini);
3583 M17N_OBJECT_UNREF (func_args);
3586 MLIST_FREE1 (ic_info, keys);
3587 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3588 M17N_OBJECT_UNREF (ic_info->markers);
3589 M17N_OBJECT_UNREF (ic_info->vars);
3590 M17N_OBJECT_UNREF (ic_info->vars_saved);
3591 M17N_OBJECT_UNREF (ic_info->preceding_text);
3592 M17N_OBJECT_UNREF (ic_info->following_text);
3594 memset (ic_info, 0, sizeof (MInputContextInfo));
3598 re_init_ic (MInputContext *ic, int reload)
3600 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3601 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3602 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3604 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3605 preedit_changed = mtext_nchars (ic->preedit) > 0;
3606 cursor_pos_changed = ic->cursor_pos > 0;
3607 candidates_changed = 0;
3608 if (ic->candidate_list)
3610 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3611 M17N_OBJECT_UNREF (ic->candidate_list);
3612 ic->candidate_list = NULL;
3614 if (ic->candidate_show)
3616 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3617 ic->candidate_show = 0;
3619 if (ic->candidate_index > 0)
3621 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3622 ic->candidate_index = 0;
3623 ic->candidate_from = ic->candidate_to = 0;
3625 if (mtext_nchars (ic->produced) > 0)
3626 mtext_reset (ic->produced);
3627 if (mtext_nchars (ic->preedit) > 0)
3628 mtext_reset (ic->preedit);
3630 M17N_OBJECT_UNREF (ic->plist);
3631 ic->plist = mplist ();
3635 reload_im_info (im_info);
3637 shift_state (ic, Mnil);
3638 ic->status_changed = status_changed;
3639 ic->preedit_changed = preedit_changed;
3640 ic->cursor_pos_changed = cursor_pos_changed;
3641 ic->candidates_changed = candidates_changed;
3645 reset_ic (MInputContext *ic, MSymbol ignore)
3647 MDEBUG_PRINT ("\n [IM] reset\n");
3652 open_im (MInputMethod *im)
3654 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3657 MERROR (MERROR_IM, -1);
3664 close_im (MInputMethod *im)
3670 create_ic (MInputContext *ic)
3672 MInputContextInfo *ic_info;
3674 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3677 shift_state (ic, Mnil);
3682 destroy_ic (MInputContext *ic)
3689 check_reload (MInputContext *ic, MSymbol key)
3691 MInputMethodInfo *im_info = ic->im->info;
3692 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3696 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3700 MPLIST_DO (plist, plist)
3702 MSymbol this_key, alias;
3704 if (MPLIST_MTEXT_P (plist))
3706 MText *mt = MPLIST_MTEXT (plist);
3707 int c = mtext_ref_char (mt, 0);
3711 this_key = one_char_symbol[c];
3715 MPlist *pl = MPLIST_PLIST (plist);
3717 this_key = MPLIST_SYMBOL (pl);
3721 && (alias = msymbol_get (alias, M_key_alias))
3722 && alias != this_key);
3726 if (MPLIST_TAIL_P (plist))
3729 MDEBUG_PRINT ("\n [IM] reload");
3735 /** Handle the input key KEY in the current state and map of IC->info.
3736 If KEY is handled but no text is produced, return 0, otherwise
3742 filter (MInputContext *ic, MSymbol key, void *arg)
3744 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3745 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3748 if (check_reload (ic, key))
3751 if (! ic_info->state)
3753 ic_info->key_unhandled = 1;
3756 mtext_reset (ic->produced);
3757 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3758 M17N_OBJECT_UNREF (ic_info->preceding_text);
3759 M17N_OBJECT_UNREF (ic_info->following_text);
3760 ic_info->preceding_text = ic_info->following_text = NULL;
3761 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3762 ic_info->key_unhandled = 0;
3765 if (handle_key (ic) < 0)
3767 /* KEY was not handled. Delete it from the current key sequence. */
3768 if (ic_info->used > 0)
3770 memmove (ic_info->keys, ic_info->keys + 1,
3771 sizeof (int) * (ic_info->used - 1));
3773 if (ic_info->state_key_head > 0)
3774 ic_info->state_key_head--;
3775 if (ic_info->commit_key_head > 0)
3776 ic_info->commit_key_head--;
3778 /* This forces returning 1. */
3779 ic_info->key_unhandled = 1;
3785 reset_ic (ic, Mnil);
3786 ic_info->key_unhandled = 1;
3789 /* Break the loop if all keys were handled. */
3790 } while (ic_info->key_head < ic_info->used);
3792 /* If the current map is the root of the initial state, we should
3793 produce any preedit text in ic->produced. */
3794 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3795 preedit_commit (ic);
3797 if (mtext_nchars (ic->produced) > 0)
3799 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3801 if (mdebug__flag & mdebug_mask)
3803 MDEBUG_PRINT (" (produced");
3804 for (i = 0; i < mtext_nchars (ic->produced); i++)
3805 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3810 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3811 Mlanguage, ic->im->language);
3813 if (ic_info->commit_key_head > 0)
3815 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3816 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3817 ic_info->used -= ic_info->commit_key_head;
3818 ic_info->key_head -= ic_info->commit_key_head;
3819 ic_info->state_key_head -= ic_info->commit_key_head;
3820 ic_info->commit_key_head = 0;
3822 if (ic_info->key_unhandled)
3825 ic_info->key_head = ic_info->state_key_head
3826 = ic_info->commit_key_head = 0;
3829 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3833 /** Return 1 if the last event or key was not handled, otherwise
3836 There is no need of looking up because ic->produced should already
3837 contain the produced text (if any).
3842 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3844 mtext_cat (mt, ic->produced);
3845 mtext_reset (ic->produced);
3846 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3850 /* Input method command handler. */
3852 /* List of all (global and local) commands.
3853 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3854 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3855 Global commands are stored as (t (t COMMAND ...)) */
3858 /* Input method variable handler. */
3861 /* Support functions for mdebug_dump_im. */
3864 dump_im_map (MPlist *map_list, int indent)
3867 MSymbol key = MPLIST_KEY (map_list);
3868 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3870 prefix = (char *) alloca (indent + 1);
3871 memset (prefix, 32, indent);
3872 prefix[indent] = '\0';
3874 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3875 if (map->map_actions)
3876 mdebug_dump_plist (map->map_actions, indent + 2);
3879 MPLIST_DO (map_list, map->submaps)
3881 fprintf (stderr, "\n%s ", prefix);
3882 dump_im_map (map_list, indent + 2);
3885 if (map->branch_actions)
3887 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3888 mdebug_dump_plist (map->branch_actions, indent + 4);
3889 fprintf (stderr, ")");
3891 fprintf (stderr, ")");
3896 dump_im_state (MIMState *state, int indent)
3901 prefix = (char *) alloca (indent + 1);
3902 memset (prefix, 32, indent);
3903 prefix[indent] = '\0';
3905 fprintf (stderr, "(%s", msymbol_name (state->name));
3906 if (state->map->submaps)
3908 MPLIST_DO (map_list, state->map->submaps)
3910 fprintf (stderr, "\n%s ", prefix);
3911 dump_im_map (map_list, indent + 2);
3914 fprintf (stderr, ")");
3922 Minput_driver = msymbol ("input-driver");
3924 Minput_preedit_start = msymbol ("input-preedit-start");
3925 Minput_preedit_done = msymbol ("input-preedit-done");
3926 Minput_preedit_draw = msymbol ("input-preedit-draw");
3927 Minput_status_start = msymbol ("input-status-start");
3928 Minput_status_done = msymbol ("input-status-done");
3929 Minput_status_draw = msymbol ("input-status-draw");
3930 Minput_candidates_start = msymbol ("input-candidates-start");
3931 Minput_candidates_done = msymbol ("input-candidates-done");
3932 Minput_candidates_draw = msymbol ("input-candidates-draw");
3933 Minput_set_spot = msymbol ("input-set-spot");
3934 Minput_focus_move = msymbol ("input-focus-move");
3935 Minput_focus_in = msymbol ("input-focus-in");
3936 Minput_focus_out = msymbol ("input-focus-out");
3937 Minput_toggle = msymbol ("input-toggle");
3938 Minput_reset = msymbol ("input-reset");
3939 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3940 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3941 Mcustomized = msymbol ("customized");
3942 Mconfigured = msymbol ("configured");
3943 Minherited = msymbol ("inherited");
3945 minput_default_driver.open_im = open_im;
3946 minput_default_driver.close_im = close_im;
3947 minput_default_driver.create_ic = create_ic;
3948 minput_default_driver.destroy_ic = destroy_ic;
3949 minput_default_driver.filter = filter;
3950 minput_default_driver.lookup = lookup;
3951 minput_default_driver.callback_list = mplist ();
3952 mplist_put_func (minput_default_driver.callback_list, Minput_reset,
3953 M17N_FUNC (reset_ic));
3954 minput_driver = &minput_default_driver;
3956 fully_initialized = 0;
3963 if (fully_initialized)
3965 free_im_list (im_info_list);
3967 free_im_list (im_custom_list);
3969 free_im_list (im_config_list);
3970 M17N_OBJECT_UNREF (load_im_info_keys);
3973 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3974 M17N_OBJECT_UNREF (minput_driver->callback_list);
3979 minput__char_to_key (int c)
3981 if (c < 0 || c >= 0x100)
3984 return one_char_symbol[c];
3988 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3993 /*** @addtogroup m17nInputMethod */
3998 @name Variables: Predefined symbols for callback commands.
4000 These are the predefined symbols that are used as the @c COMMAND
4001 argument of callback functions of an input method driver (see
4002 #MInputDriver::callback_list).
4004 Most of them do not require extra argument nor return any value;
4005 exceptions are these:
4007 Minput_get_surrounding_text: When a callback function assigned for
4008 this command is called, the first element of #MInputContext::plist
4009 has key #Minteger and the value specifies which portion of the
4010 surrounding text should be retrieved. If the value is positive,
4011 it specifies the number of characters following the current cursor
4012 position. If the value is negative, the absolute value specifies
4013 the number of characters preceding the current cursor position.
4014 If the value is zero, it means that the caller just wants to know
4015 if the surrounding text is currently supported or not.
4017 If the surrounding text is currently supported, the callback
4018 function must set the key of this element to #Mtext and the value
4019 to the retrieved M-text. The length of the M-text may be shorter
4020 than the requested number of characters, if the available text is
4021 not that long. The length can be zero in the worst case. Or, the
4022 length may be longer if an application thinks it is more efficient
4023 to return that length.
4025 If the surrounding text is not currently supported, the callback
4026 function should return without changing the first element of
4027 #MInputContext::plist.
4029 Minput_delete_surrounding_text: When a callback function assigned
4030 for this command is called, the first element of
4031 #MInputContext::plist has key #Minteger and the value specifies
4032 which portion of the surrounding text should be deleted in the
4033 same way as the case of Minput_get_surrounding_text. The callback
4034 function must delete the specified text. It should not alter
4035 #MInputContext::plist. */
4037 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4039 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4040 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4042 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4044 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4045 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4046 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4047 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4048 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4049 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4050 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4052 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4053 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4054 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4055 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4056 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4058 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4059 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4061 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4062 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4063 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4064 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4065 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4066 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4070 MSymbol Minput_preedit_start;
4071 MSymbol Minput_preedit_done;
4072 MSymbol Minput_preedit_draw;
4073 MSymbol Minput_status_start;
4074 MSymbol Minput_status_done;
4075 MSymbol Minput_status_draw;
4076 MSymbol Minput_candidates_start;
4077 MSymbol Minput_candidates_done;
4078 MSymbol Minput_candidates_draw;
4079 MSymbol Minput_set_spot;
4080 MSymbol Minput_toggle;
4081 MSymbol Minput_reset;
4082 MSymbol Minput_get_surrounding_text;
4083 MSymbol Minput_delete_surrounding_text;
4089 @name Variables: Predefined symbols for special input events.
4091 These are the predefined symbols that are used as the @c KEY
4092 argument of minput_filter (). */
4094 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4096 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4101 MSymbol Minput_focus_out;
4102 MSymbol Minput_focus_in;
4103 MSymbol Minput_focus_move;
4109 @name Variables: Predefined symbols used in input method information.
4111 These are the predefined symbols describing status of input method
4112 command and variable, and are used in a return value of
4113 minput_get_command () and minput_get_variable (). */
4115 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4117 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4118 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4122 MSymbol Mcustomized;
4123 MSymbol Mconfigured;
4129 @brief The default driver for internal input methods.
4131 The variable #minput_default_driver is the default driver for
4132 internal input methods.
4134 The member MInputDriver::open_im () searches the m17n database for
4135 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4136 $NAME\> and loads it.
4138 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4139 programmers responsibility to set it to a plist of proper callback
4140 functions. Otherwise, no feedback information (e.g. preedit text)
4141 can be shown to users.
4143 The macro M17N_INIT () sets the variable #minput_driver to the
4144 pointer to this driver so that all internal input methods use it.
4146 Therefore, unless @c minput_driver is set differently, the driver
4147 dependent arguments $ARG of the functions whose name begins with
4148 "minput_" are all ignored. */
4150 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4152 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4154 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4155 \< #Minput_method, $LANGUAGE, $NAME\>
4156 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4158 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4159 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4160 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4161 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4163 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4164 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4166 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4167 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4169 MInputDriver minput_default_driver;
4173 @brief The driver for internal input methods.
4175 The variable #minput_driver is a pointer to the input method
4176 driver that is used by internal input methods. The macro
4177 M17N_INIT () initializes it to a pointer to #minput_default_driver
4178 if <m17n<EM></EM>.h> is included. */
4180 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4182 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4183 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4184 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4185 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4187 MInputDriver *minput_driver;
4189 MSymbol Minput_driver;
4204 @brief Open an input method.
4206 The minput_open_im () function opens an input method whose
4207 language and name match $LANGUAGE and $NAME, and returns a pointer
4208 to the input method object newly allocated.
4210 This function at first decides a driver for the input method as
4213 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4214 #minput_driver is used.
4216 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4217 driver pointed to by the property value is used to open the input
4218 method. If $NAME has no such a property, @c NULL is returned.
4220 Then, the member MInputDriver::open_im () of the driver is
4223 $ARG is set in the member @c arg of the structure MInputMethod so
4224 that the driver can refer to it. */
4226 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4228 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4229 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4231 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4233 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4234 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4236 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4237 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4238 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4240 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4242 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4244 @latexonly \IPAlabel{minput_open} @endlatexonly
4249 minput_open_im (MSymbol language, MSymbol name, void *arg)
4252 MInputDriver *driver;
4256 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4257 msymbol_name (language), msymbol_name (name));
4259 driver = minput_driver;
4262 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4264 MERROR (MERROR_IM, NULL);
4267 MSTRUCT_CALLOC (im, MERROR_IM);
4268 im->language = language;
4271 im->driver = *driver;
4272 if ((*im->driver.open_im) (im) < 0)
4274 MDEBUG_PRINT (" failed\n");
4278 MDEBUG_PRINT (" ok\n");
4285 @brief Close an input method.
4287 The minput_close_im () function closes the input method $IM, which
4288 must have been created by minput_open_im (). */
4291 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4293 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4294 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4297 minput_close_im (MInputMethod *im)
4299 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4300 msymbol_name (im->name), msymbol_name (im->language));
4301 (*im->driver.close_im) (im);
4303 MDEBUG_PRINT (" done\n");
4309 @brief Create an input context.
4311 The minput_create_ic () function creates an input context object
4312 associated with input method $IM, and calls callback functions
4313 corresponding to #Minput_preedit_start, #Minput_status_start, and
4314 #Minput_status_draw in this order.
4317 If an input context is successfully created, minput_create_ic ()
4318 returns a pointer to it. Otherwise it returns @c NULL. */
4321 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4323 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4324 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4325 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4326 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4329 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4330 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4334 minput_create_ic (MInputMethod *im, void *arg)
4338 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4339 msymbol_name (im->name), msymbol_name (im->language));
4340 MSTRUCT_CALLOC (ic, MERROR_IM);
4343 ic->preedit = mtext ();
4344 ic->candidate_list = NULL;
4345 ic->produced = mtext ();
4346 ic->spot.x = ic->spot.y = 0;
4348 ic->plist = mplist ();
4349 if ((*im->driver.create_ic) (ic) < 0)
4351 MDEBUG_PRINT (" failed\n");
4352 M17N_OBJECT_UNREF (ic->preedit);
4353 M17N_OBJECT_UNREF (ic->produced);
4354 M17N_OBJECT_UNREF (ic->plist);
4359 if (im->driver.callback_list)
4361 minput_callback (ic, Minput_preedit_start);
4362 minput_callback (ic, Minput_status_start);
4363 minput_callback (ic, Minput_status_draw);
4366 MDEBUG_PRINT (" ok\n");
4373 @brief Destroy an input context.
4375 The minput_destroy_ic () function destroys the input context $IC,
4376 which must have been created by minput_create_ic (). It calls
4377 callback functions corresponding to #Minput_preedit_done,
4378 #Minput_status_done, and #Minput_candidates_done in this order. */
4381 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4383 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4384 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4385 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4386 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4387 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4391 minput_destroy_ic (MInputContext *ic)
4393 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4394 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4395 if (ic->im->driver.callback_list)
4397 minput_callback (ic, Minput_preedit_done);
4398 minput_callback (ic, Minput_status_done);
4399 minput_callback (ic, Minput_candidates_done);
4401 (*ic->im->driver.destroy_ic) (ic);
4402 M17N_OBJECT_UNREF (ic->preedit);
4403 M17N_OBJECT_UNREF (ic->produced);
4404 M17N_OBJECT_UNREF (ic->plist);
4405 MDEBUG_PRINT (" done\n");
4412 @brief Filter an input key.
4414 The minput_filter () function filters input key $KEY according to
4415 input context $IC, and calls callback functions corresponding to
4416 #Minput_preedit_draw, #Minput_status_draw, and
4417 #Minput_candidates_draw if the preedit text, the status, and the
4418 current candidate are changed respectively.
4420 To make the input method commit the current preedit text (if any)
4421 and shift to the initial state, call this function with #Mnil as
4424 To inform the input method about the focus-out event, call this
4425 function with #Minput_focus_out as $KEY.
4427 To inform the input method about the focus-in event, call this
4428 function with #Minput_focus_in as $KEY.
4430 To inform the input method about the focus-move event (i.e. input
4431 spot change within the same input context), call this function
4432 with #Minput_focus_move as $KEY.
4435 If $KEY is filtered out, this function returns 1. In that case,
4436 the caller should discard the key. Otherwise, it returns 0, and
4437 the caller should handle the key, for instance, by calling the
4438 function minput_lookup () with the same key. */
4441 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4443 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4444 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4445 #Minput_preedit_draw, #Minput_status_draw,
4446 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4449 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4450 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4451 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4452 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4454 @latexonly \IPAlabel{minput_filter} @endlatexonly
4458 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4465 if (ic->im->driver.callback_list
4466 && mtext_nchars (ic->preedit) > 0)
4467 minput_callback (ic, Minput_preedit_draw);
4469 ret = (*ic->im->driver.filter) (ic, key, arg);
4471 if (ic->im->driver.callback_list)
4473 if (ic->preedit_changed)
4474 minput_callback (ic, Minput_preedit_draw);
4475 if (ic->status_changed)
4476 minput_callback (ic, Minput_status_draw);
4477 if (ic->candidates_changed)
4478 minput_callback (ic, Minput_candidates_draw);
4487 @brief Look up a text produced in the input context.
4489 The minput_lookup () function looks up a text in the input context
4490 $IC. $KEY must be identical to the one that was used in the previous call of
4493 If a text was produced by the input method, it is concatenated
4496 This function calls #MInputDriver::lookup .
4499 If $KEY was correctly handled by the input method, this function
4500 returns 0. Otherwise, it returns -1, even though some text
4501 might be produced in $MT. */
4504 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4506 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4507 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4509 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4512 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4515 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4516 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4517 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4519 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4522 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4524 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4529 @brief Set the spot of the input context.
4531 The minput_set_spot () function sets the spot of input context $IC
4532 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4533 The semantics of these values depends on the input method driver.
4535 For instance, a driver designed to work in a CUI environment may
4536 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4537 $DESCENT . A driver designed to work in a window system may
4538 interpret $X and $Y as the pixel offsets relative to the origin of the
4539 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4540 descent pixels of the line at ($X . $Y ).
4542 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4544 $MT and $POS are the M-text and the character position at the spot.
4545 $MT may be @c NULL, in which case, the input method cannot get
4546 information about the text around the spot. */
4549 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4551 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4552 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4553 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4555 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4556 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4557 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4558 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4559 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4560 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4562 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4564 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4565 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4569 minput_set_spot (MInputContext *ic, int x, int y,
4570 int ascent, int descent, int fontsize,
4575 ic->spot.ascent = ascent;
4576 ic->spot.descent = descent;
4577 ic->spot.fontsize = fontsize;
4580 if (ic->im->driver.callback_list)
4581 minput_callback (ic, Minput_set_spot);
4586 @brief Toggle input method.
4588 The minput_toggle () function toggles the input method associated
4589 with input context $IC. */
4591 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4593 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4594 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4598 minput_toggle (MInputContext *ic)
4600 if (ic->im->driver.callback_list)
4601 minput_callback (ic, Minput_toggle);
4602 ic->active = ! ic->active;
4608 @brief Reset an input context.
4610 The minput_reset_ic () function resets input context $IC by
4611 calling a callback function corresponding to #Minput_reset. It
4612 resets the status of $IC to its initial one. As the
4613 current preedit text is deleted without commitment, if necessary,
4614 call minput_filter () with the arg @r key #Mnil to force the input
4615 method to commit the preedit in advance. */
4618 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4620 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4621 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4622 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4623 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4624 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4625 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4628 minput_reset_ic (MInputContext *ic)
4630 if (ic->im->driver.callback_list)
4631 minput_callback (ic, Minput_reset);
4637 @brief Get title and icon filename of an input method.
4639 The minput_get_title_icon () function returns a plist containing a
4640 title and icon filename (if any) of an input method specified by
4641 $LANGUAGE and $NAME.
4643 The first element of the plist has key #Mtext and the value is an
4644 M-text of the title for identifying the input method. The second
4645 element (if any) has key #Mtext and the value is an M-text of the
4646 icon image (absolute) filename for the same purpose.
4649 If there exists a specified input method and it defines an title,
4650 a plist is returned. Otherwise, NULL is returned. The caller
4651 must free the plist by m17n_object_unref (). */
4653 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4655 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4656 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4659 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4660 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4661 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4664 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4665 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4666 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4669 minput_get_title_icon (MSymbol language, MSymbol name)
4671 MInputMethodInfo *im_info;
4678 im_info = get_im_info (language, name, Mnil, Mtitle);
4679 if (! im_info || !im_info->title)
4681 mt = mtext_get_prop (im_info->title, 0, Mtext);
4683 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4686 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4689 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4690 (char *) MSYMBOL_NAME (name));
4691 file = mdatabase__find_file (buf);
4692 if (! file && language == Mt)
4694 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4695 file = mdatabase__find_file (buf);
4700 mplist_add (plist, Mtext, im_info->title);
4703 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4705 mplist_add (plist, Mtext, mt);
4706 M17N_OBJECT_UNREF (mt);
4714 @brief Get description text of an input method.
4716 The minput_get_description () function returns an M-text that
4717 describes the input method specified by $LANGUAGE and $NAME.
4720 If the specified input method has a description text, a pointer to
4721 #MText is returned. The caller has to free it by m17n_object_unref ().
4722 If the input method does not have a description text, @c NULL is
4725 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4727 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4728 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4730 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4731 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4732 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4733 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4736 minput_get_description (MSymbol language, MSymbol name)
4738 MInputMethodInfo *im_info;
4746 extra = language, language = Mt;
4748 im_info = get_im_info (language, name, extra, Mdescription);
4749 if (! im_info || ! im_info->description)
4751 M17N_OBJECT_REF (im_info->description);
4752 return im_info->description;
4758 @brief Get information about input method command(s).
4760 The minput_get_command () function returns information about
4761 the command $COMMAND of the input method specified by $LANGUAGE and
4762 $NAME. An input method command is a pseudo key event to which one
4763 or more actual input key sequences are assigned.
4765 There are two kinds of commands, global and local. A global
4766 command has a global definition, and the description and the key
4767 assignment may be inherited by a local command. Each input method
4768 defines a local command which has a local key assignment. It may
4769 also declare a local command that inherits the definition of a
4770 global command of the same name.
4772 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4773 information about a global command. Otherwise information about a
4774 local command is returned.
4776 If $COMMAND is #Mnil, information about all commands is returned.
4778 The return value is a @e well-formed plist (#m17nPlist) of this
4781 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4783 @c NAME is a symbol representing the command name.
4785 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4786 command has no description.
4788 @c STATUS is a symbol representing how the key assignment is decided.
4789 The value is #Mnil (the default key assignment), #Mcustomized (the
4790 key assignment is customized by per-user customization file), or
4791 #Mconfigured (the key assignment is set by the call of
4792 minput_config_command ()). For a local command only, it may also
4793 be #Minherited (the key assignment is inherited from the
4794 corresponding global command).
4796 @c KEYSEQ is a plist of one or more symbols representing a key
4797 sequence assigned to the command. If there's no KEYSEQ, the
4798 command is currently disabled (i.e. no key sequence can trigger
4799 actions of the command).
4801 If $COMMAND is not #Mnil, the first element of the returned plist
4802 contains the information about $COMMAND.
4806 If the requested information was found, a pointer to a non-empty
4807 plist is returned. As the plist is kept in the library, the
4808 caller must not modify nor free it.
4810 Otherwise (the specified input method or the specified command
4811 does not exist), @c NULL is returned. */
4813 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4815 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4816 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4817 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4818 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4820 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4821 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4822 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4823 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4824 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4826 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4827 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4830 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4832 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4835 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4837 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4839 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4842 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë
4843 ¤Ç¤¢¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼
4844 ¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë,
4845 #Mconfigured ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë
4846 ³ä¤êÅö¤Æ¡Ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢
4847 #Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë
4850 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4851 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4852 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4853 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4855 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4856 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4860 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4861 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4864 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4869 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4871 /* Return a description of the command COMMAND of the input method
4872 specified by LANGUAGE and NAME. */
4873 MPlist *cmd = minput_get_command (langauge, name, command);
4878 plist = mplist_value (cmds); /* (NAME DESCRIPTION STATUS KEY-SEQ ...) */
4879 plist = mplist_next (plist); /* (DESCRIPTION STATUS KEY-SEQ ...) */
4880 return (mplist_key (plist) == Mtext
4881 ? (MText *) mplist_value (plist)
4887 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4889 MInputMethodInfo *im_info;
4893 im_info = get_im_info (language, name, Mnil, Mcommand);
4895 || ! im_info->configured_cmds
4896 || MPLIST_TAIL_P (im_info->configured_cmds))
4898 if (command == Mnil)
4899 return im_info->configured_cmds;
4900 return mplist__assq (im_info->configured_cmds, command);
4906 @brief Configure the key sequence of an input method command.
4908 The minput_config_command () function assigns a list of key
4909 sequences $KEYSEQLIST to the command $COMMAND of the input method
4910 specified by $LANGUAGE and $NAME.
4912 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4913 sequences, and each key sequence must be a plist of symbols.
4915 If $KEYSEQLIST is an empty plist, any configuration and
4916 customization of the command are cancelled, and default key
4917 sequences become effective.
4919 If $KEYSEQLIST is NULL, the configuration of the command is
4920 canceled, and the original key sequences (what saved in per-user
4921 customization file, or the default one) become effective.
4923 In the latter two cases, $COMMAND can be #Mnil to make all the
4924 commands of the input method the target of the operation.
4926 If $NAME is #Mnil, this function configures the key assignment of a
4927 global command, not that of a specific input method.
4929 The configuration takes effect for input methods opened or
4930 re-opened later in the current session. In order to make the
4931 configuration take effect for the future session, it must be saved
4932 in a per-user customization file by the function
4933 minput_save_config ().
4936 If the operation was successful, this function returns 0,
4937 otherwise returns -1. The operation fails in these cases:
4939 <li>$KEYSEQLIST is not in a valid form.
4940 <li>$COMMAND is not available for the input method.
4941 <li>$LANGUAGE and $NAME do not specify an existing input method.
4945 minput_get_commands (), minput_save_config ().
4948 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4950 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4951 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4952 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4954 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4955 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4957 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤ä¥«¥¹¥¿¥Þ¥¤¥º¤Ï
4958 ¤¹¤Ù¤Æ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£
4960 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢¤½¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢
4961 ¸µ¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¡Ê¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Æ¤¤
4962 ¤ë¤â¤Î¡¢¤¢¤ë¤¤¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¤â¤Î¡Ë¤¬Í¸ú¤Ë¤Ê¤ë¡£
4964 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$COMMAND ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄê¤ÎÆþ
4965 Îϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥ÉÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
4967 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4968 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4970 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4971 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4972 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
4973 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4977 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4979 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4980 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4981 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4985 minput_get_commands (), minput_save_config ().
4989 /* Add "C-x u" to the "start" command of Unicode input method. */
4991 MSymbol start_command = msymbol ("start");
4992 MSymbol unicode = msymbol ("unicode");
4993 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4995 /* At first get the current key-sequence assignment. */
4996 cmd = minput_get_command (Mt, unicode, start_command);
4999 /* The input method does not have the command "start". Here
5000 should come some error handling code. */
5002 /* Now CMD == ((start DESCRIPTION STATUS KEY-SEQUENCE ...) ...).
5003 Extract the part (KEY-SEQUENCE ...). */
5004 plist = mplist_next (mplist_next (mplist_next (mplist_value (cmd))));
5005 /* Copy it because we should not modify it directly. */
5006 key_seq_list = mplist_copy (plist);
5008 key_seq = mplist ();
5009 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5010 mplist_add (key_seq, Msymbol, msymbol ("u"));
5011 mplist_add (key_seq_list, Mplist, key_seq);
5012 m17n_object_unref (key_seq);
5014 minput_config_command (Mt, unicode, start_command, key_seq_list);
5015 m17n_object_unref (key_seq_list);
5020 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5023 MInputMethodInfo *im_info, *config;
5028 im_info = get_im_info (language, name, Mnil, Mcommand);
5030 MERROR (MERROR_IM, -1);
5031 if (command == Mnil ? (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5033 || ! mplist__assq (im_info->configured_cmds, command)))
5034 MERROR (MERROR_IM, -1);
5035 if (keyseqlist && ! MPLIST_TAIL_P (keyseqlist))
5037 MPLIST_DO (plist, keyseqlist)
5038 if (! check_command_keyseq (plist))
5039 MERROR (MERROR_IM, -1);
5042 config = get_config_info (im_info);
5045 if (! im_config_list)
5046 im_config_list = mplist ();
5047 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5048 config->cmds = mplist ();
5049 config->vars = mplist ();
5052 if (! keyseqlist && MPLIST_TAIL_P (config->cmds))
5053 /* Nothing to do. */
5056 if (command == Mnil)
5060 /* Cancal the configuration. */
5061 if (MPLIST_TAIL_P (config->cmds))
5063 mplist_set (config->cmds, Mnil, NULL);
5067 /* Cancal the customization. */
5068 MInputMethodInfo *custom = get_custom_info (im_info);
5070 if (MPLIST_TAIL_P (config->cmds)
5071 && (! custom || ! custom->cmds || MPLIST_TAIL_P (custom->cmds)))
5072 /* Nothing to do. */
5074 mplist_set (config->cmds, Mnil, NULL);
5075 MPLIST_DO (plist, custom->cmds)
5077 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5079 mplist_add (plist, Msymbol, command);
5080 mplist_push (config->cmds, Mplist, plist);
5081 M17N_OBJECT_UNREF (plist);
5087 plist = mplist__assq (config->cmds, command);
5090 /* Cancel the configuration. */
5093 mplist__pop_unref (plist);
5095 else if (MPLIST_TAIL_P (keyseqlist))
5097 /* Cancel the customization. */
5098 MInputMethodInfo *custom = get_custom_info (im_info);
5099 int no_custom = (! custom || ! custom->cmds
5100 || ! mplist__assq (custom->cmds, command));
5106 mplist_add (config->cmds, Mplist, plist);
5107 M17N_OBJECT_UNREF (plist);
5108 plist = mplist_add (plist, Msymbol, command);
5113 mplist__pop_unref (plist);
5116 plist = MPLIST_PLIST (plist); /* (NAME nil KEYSEQ ...) */
5117 plist = MPLIST_NEXT (plist);
5118 mplist_set (plist, Mnil, NULL);
5128 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5129 if (! MPLIST_TAIL_P (plist))
5130 mplist_set (plist, Mnil, NULL);
5135 mplist_add (config->cmds, Mplist, plist);
5136 M17N_OBJECT_UNREF (plist);
5137 plist = mplist_add (plist, Msymbol, command);
5138 plist = MPLIST_NEXT (plist);
5140 MPLIST_DO (keyseqlist, keyseqlist)
5142 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5143 plist = mplist_add (plist, Mplist, pl);
5144 M17N_OBJECT_UNREF (pl);
5148 config_all_commands (im_info);
5149 im_info->tick = time (NULL);
5156 @brief Get information about input method variable(s).
5158 The minput_get_variable () function returns information about
5159 variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5160 An input method variable controls behavior of an input method.
5162 There are two kinds of variables, global and local. A global
5163 variable has a global definition, and the description and the value
5164 may be inherited by a local variable. Each input method defines a
5165 local variable which has local value. It may also declare a
5166 local variable that inherits definition of a global variable of
5169 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5170 variable is returned. Otherwise information about a local variable
5173 If $VARIABLE is #Mnil, information about all variables is
5176 The return value is a @e well-formed plist (#m17nPlist) of this
5179 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5181 @c NAME is a symbol representing the variable name.
5183 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5184 variable has no description.
5186 @c STATUS is a symbol representing how the value is decided. The
5187 value is #Mnil (the default value), #Mcustomized (the value is
5188 customized by per-user customization file), or #Mconfigured (the
5189 value is set by the call of minput_config_variable ()). For a
5190 local variable only, it may also be #Minherited (the value is
5191 inherited from the corresponding global variable).
5193 @c VALUE is the initial value of the variable. If the key of this
5194 element is #Mt, the variable has no initial value. Otherwise, the
5195 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5198 @c VALID-VALUEs (if any) specify which values the variable can have.
5199 They have the same type (i.e. having the same key) as @c VALUE except
5200 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5201 may be a plist of two integers specifying the range of possible
5204 If there no @c VALID-VALUE, the variable can have any value as long
5205 as the type is the same as @c VALUE.
5207 If $VARIABLE is not #Mnil, the first element of the returned plist
5208 contains the information about $VARIABLE.
5212 If the requested information was found, a pointer to a non-empty
5213 plist is returned. As the plist is kept in the library, the
5214 caller must not modify nor free it.
5216 Otherwise (the specified input method or the specified variable
5217 does not exist), @c NULL is returned. */
5219 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5221 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5222 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5223 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5225 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5226 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5227 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5228 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5231 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5232 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5234 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5236 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5238 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5241 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5243 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5246 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5247 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤Î
5248 ¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5249 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5250 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5251 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5253 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5254 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5255 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5257 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5258 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5259 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5260 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5262 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5265 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5266 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5270 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5271 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5274 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5278 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5280 MInputMethodInfo *im_info;
5284 im_info = get_im_info (language, name, Mnil, Mvariable);
5285 if (! im_info || ! im_info->configured_vars)
5287 if (variable == Mnil)
5288 return im_info->configured_vars;
5289 return mplist__assq (im_info->configured_vars, variable);
5295 @brief Configure the value of an input method variable.
5297 The minput_config_variable () function assigns $VALUE to the
5298 variable $VARIABLE of the input method specified by $LANGUAGE and
5301 If $VALUE is a non-empty plist, it must be a plist of one element
5302 whose key is #Minteger, #Msymbol, or #Mtext, and the value is of
5303 the corresponding type. That value is assigned to the variable.
5305 If $VALUE is an empty plist, any configuration and customization
5306 of the variable are canceled, and the default value is assigned to
5309 If $VALUE is NULL, the configuration of the variable is canceled,
5310 and the original value (what saved in per-user customization file,
5311 or the default value) is assigned to the variable.
5313 In the latter two cases, $VARIABLE can be #Mnil to make all the
5314 variables of the input method the target of the operation.
5316 If $NAME is #Mnil, this function configures the value of global
5317 variable, not that of a specific input method.
5319 The configuration takes effect for input methods opened or
5320 re-opened later in the current session. To make the configuration
5321 take effect for the future session, it must be saved in a per-user
5322 customization file by the function minput_save_config ().
5326 If the operation was successful, this function returns 0,
5327 otherwise returns -1. The operation fails in these cases:
5329 <li>$VALUE is not in a valid form, the type does not match the
5330 definition, or the value is our of range.
5331 <li>$VARIABLE is not available for the input method.
5332 <li>$LANGUAGE and $NAME do not specify an existing input method.
5336 minput_get_variable (), minput_save_config (). */
5338 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5340 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5341 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5343 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5344 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5345 ¤³¤ÎÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5347 $VALUE ¤¬ ¶õ¥ê¥¹¥È¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤È¥«¥¹¥¿¥Þ¥¤¥º¤¬¥¥ã¥ó¥»¥ë¤µ
5348 ¤ì¡¢¥Ç¥Õ¥©¥ë¥ÈÃͤ¬ÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5350 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢ÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¸µ¤ÎÃ͡ʥ桼¥¶
5351 Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ëÃæ¤ÎÃÍ¡¢¤Þ¤¿¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÃ͡ˤ¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
5353 ¸å¤Î¤Õ¤¿¤Ä¤Î¾ì¹ç¤Ë¤Ï¡¢$VARIABLE ¤Ï #Mnil ¤ò¤È¤ë¤³¤È¤¬¤Ç¤¡¢»ØÄꤵ¤ì
5354 ¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ôÀßÄê¤Î¥¥ã¥ó¥»¥ë¤ò°ÕÌ£¤¹¤ë¡£
5356 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5357 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5359 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5360 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5361 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤
5362 ¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5366 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5368 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5369 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5370 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5374 minput_get_commands (), minput_save_config ().
5377 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5380 MInputMethodInfo *im_info, *config;
5385 im_info = get_im_info (language, name, Mnil, Mvariable);
5387 MERROR (MERROR_IM, -1);
5388 if (variable == Mnil ? (value && ! MPLIST_TAIL_P (value))
5390 || ! (plist = mplist__assq (im_info->configured_vars, variable))))
5391 MERROR (MERROR_IM, -1);
5393 if (value && ! MPLIST_TAIL_P (value))
5395 plist = MPLIST_PLIST (plist);
5396 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5397 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5398 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5399 if (MPLIST_KEY (plist) != Mt
5400 && ! check_variable_value (value, plist))
5401 MERROR (MERROR_IM, -1);
5404 config = get_config_info (im_info);
5407 if (! im_config_list)
5408 im_config_list = mplist ();
5409 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5410 config->cmds = mplist ();
5411 config->vars = mplist ();
5414 if (! value && MPLIST_TAIL_P (config->vars))
5415 /* Nothing to do. */
5418 if (variable == Mnil)
5422 /* Cancel the configuration. */
5423 if (MPLIST_TAIL_P (config->vars))
5425 mplist_set (config->vars, Mnil, NULL);
5429 /* Cancel the customization. */
5430 MInputMethodInfo *custom = get_custom_info (im_info);
5432 if (MPLIST_TAIL_P (config->vars)
5433 && (! custom || ! custom->vars || MPLIST_TAIL_P (custom->vars)))
5434 /* Nothing to do. */
5436 mplist_set (config->vars, Mnil, NULL);
5437 MPLIST_DO (plist, custom->vars)
5439 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5441 mplist_add (plist, Msymbol, variable);
5442 mplist_push (config->vars, Mplist, plist);
5443 M17N_OBJECT_UNREF (plist);
5449 plist = mplist__assq (config->vars, variable);
5452 /* Cancel the configuration. */
5455 mplist__pop_unref (plist);
5457 else if (MPLIST_TAIL_P (value))
5459 /* Cancel the customization. */
5460 MInputMethodInfo *custom = get_custom_info (im_info);
5461 int no_custom = (! custom || ! custom->vars
5462 || ! mplist__assq (custom->vars, variable));
5468 mplist_add (config->vars, Mplist, plist);
5469 M17N_OBJECT_UNREF (plist);
5470 plist = mplist_add (plist, Msymbol, variable);
5475 mplist__pop_unref (plist);
5478 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5479 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5480 mplist_set (plist, Mnil ,NULL);
5488 plist = MPLIST_NEXT (MPLIST_PLIST (plist));
5489 if (! MPLIST_TAIL_P (plist))
5490 mplist_set (plist, Mnil, NULL);
5495 mplist_add (config->vars, Mplist, plist);
5496 M17N_OBJECT_UNREF (plist);
5497 plist = mplist_add (plist, Msymbol, variable);
5498 plist = MPLIST_NEXT (plist);
5500 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5503 config_all_variables (im_info);
5504 im_info->tick = time (NULL);
5511 @brief Get the name of per-user customization file.
5513 The minput_config_file () function returns the absolute path name
5514 of per-user customization file into which minput_save_config ()
5515 save configurations. It is usually @c "config.mic" under the
5516 directory @c ".m17n.d" of user's home directory. It is not assured
5517 that the file of the returned name exists nor is
5518 readable/writable. If minput_save_config () fails and returns -1,
5519 an application program might check the file, make it
5520 writable (if possible), and try minput_save_config () again.
5524 This function returns a string. As the string is kept in the
5525 library, the caller must not modify nor free it.
5528 minput_save_config ()
5531 @brief ¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5533 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5534 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5535 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5536 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5537 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5538 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5539 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5544 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5545 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5548 minput_save_config ()
5552 minput_config_file ()
5556 return mdatabase__file (im_custom_mdb);
5562 @brief Save configurations in per-user customization file.
5564 The minput_save_config () function saves the configurations done
5565 so far in the current session into the per-user customization
5570 If the operation was successful, 1 is returned. If the per-user
5571 customization file is currently locked, 0 is returned. In that
5572 case, the caller may wait for a while and try again. If the
5573 configuration file is not writable, -1 is returned. In that case,
5574 the caller may check the name of the file by calling
5575 minput_config_file (), make it writable if possible, and try
5579 minput_config_file () */
5581 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5583 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5584 ¤ò¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5588 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤Î¥«¥¹¥¿¥Þ¥¤¥º¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤
5589 ¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡
5590 ¥¤¥ë¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file
5591 () ¤ò¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô
5595 minput_config_file () */
5598 minput_save_config (void)
5600 MPlist *data, *tail, *plist, *p, *elt;
5604 ret = mdatabase__lock (im_custom_mdb);
5607 if (! im_config_list)
5609 update_custom_info ();
5610 if (! im_custom_list)
5611 im_custom_list = mplist ();
5613 /* At first, reflect configuration in customization. */
5614 MPLIST_DO (plist, im_config_list)
5616 MPlist *pl = MPLIST_PLIST (plist);
5617 MSymbol language, name, extra, command, variable;
5618 MInputMethodInfo *custom, *config;
5620 language = MPLIST_SYMBOL (pl);
5621 pl = MPLIST_NEXT (pl);
5622 name = MPLIST_SYMBOL (pl);
5623 pl = MPLIST_NEXT (pl);
5624 extra = MPLIST_SYMBOL (pl);
5625 pl = MPLIST_NEXT (pl);
5626 config = MPLIST_VAL (pl);
5627 custom = get_custom_info (config);
5629 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5631 MPLIST_DO (pl, config->cmds)
5633 elt = MPLIST_PLIST (pl);
5634 command = MPLIST_SYMBOL (elt);
5636 p = mplist__assq (custom->cmds, command);
5638 custom->cmds = mplist (), p = NULL;
5639 elt = MPLIST_NEXT (elt);
5642 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5643 mplist_set (p, Mnil, NULL);
5648 mplist_add (custom->cmds, Mplist, p);
5649 mplist_add (p, Msymbol, command);
5650 p = mplist_add (p, Msymbol, Mnil);
5651 p = MPLIST_NEXT (p);
5653 mplist__conc (p, elt);
5656 MPLIST_DO (pl, config->vars)
5658 elt = MPLIST_PLIST (pl);
5659 variable = MPLIST_SYMBOL (elt);
5661 p = mplist__assq (custom->vars, variable);
5663 custom->vars = mplist (), p = NULL;
5664 elt = MPLIST_NEXT (elt);
5667 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5668 mplist_set (p, Mnil, NULL);
5673 mplist_add (custom->vars, Mplist, p);
5674 mplist_add (p, Msymbol, variable);
5675 p = mplist_add (p, Msymbol, Mnil);
5676 p = MPLIST_NEXT (p);
5678 mplist__conc (p, elt);
5681 M17N_OBJECT_UNREF (im_config_list);
5683 /* Next, reflect customization to the actual plist to be written. */
5684 data = tail = mplist ();
5685 MPLIST_DO (plist, im_custom_list)
5687 MPlist *pl = MPLIST_PLIST (plist);
5688 MSymbol language, name, extra;
5689 MInputMethodInfo *custom, *im_info;
5691 language = MPLIST_SYMBOL (pl);
5692 pl = MPLIST_NEXT (pl);
5693 name = MPLIST_SYMBOL (pl);
5694 pl = MPLIST_NEXT (pl);
5695 extra = MPLIST_SYMBOL (pl);
5696 pl = MPLIST_NEXT (pl);
5697 custom = MPLIST_VAL (pl);
5698 if ((! custom->cmds || MPLIST_TAIL_P (custom->cmds))
5699 && (! custom->vars || MPLIST_TAIL_P (custom->vars)))
5701 im_info = lookup_im_info (im_info_list, language, name, extra);
5705 config_all_commands (im_info);
5707 config_all_variables (im_info);
5711 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5713 MPLIST_DO (p, custom->cmds)
5714 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5716 if (! MPLIST_TAIL_P (p))
5720 mplist_add (elt, Mplist, pl);
5721 M17N_OBJECT_UNREF (pl);
5722 pl = mplist_add (pl, Msymbol, Mcommand);
5723 MPLIST_DO (p, custom->cmds)
5724 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5725 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5728 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5730 MPLIST_DO (p, custom->vars)
5731 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5733 if (! MPLIST_TAIL_P (p))
5738 mplist_add (elt, Mplist, pl);
5739 M17N_OBJECT_UNREF (pl);
5740 pl = mplist_add (pl, Msymbol, Mvariable);
5741 MPLIST_DO (p, custom->vars)
5742 if (! MPLIST_TAIL_P (MPLIST_NEXT (MPLIST_PLIST (p))))
5743 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5749 mplist_push (elt, Mplist, pl);
5750 M17N_OBJECT_UNREF (pl);
5751 pl = mplist_add (pl, Msymbol, Minput_method);
5752 pl = mplist_add (pl, Msymbol, language);
5753 pl = mplist_add (pl, Msymbol, name);
5755 pl = mplist_add (pl, Msymbol, extra);
5756 tail = mplist_add (tail, Mplist, elt);
5757 M17N_OBJECT_UNREF (elt);
5761 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5762 ret = mdatabase__save (im_custom_mdb, data);
5763 mdatabase__unlock (im_custom_mdb);
5764 M17N_OBJECT_UNREF (data);
5765 return (ret < 0 ? -1 : 1);
5772 @name Obsolete functions
5775 @name Obsolete ¤Ê´Ø¿ô
5781 @brief Get a list of variables of an input method (obsolete).
5783 This function is obsolete. Use minput_get_variable () instead.
5785 The minput_get_variables () function returns a plist (#MPlist) of
5786 variables used to control the behavior of the input method
5787 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5788 (#m17nPlist) of the following format:
5791 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5792 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5796 @c VARNAME is a symbol representing the variable name.
5798 @c DOC-MTEXT is an M-text describing the variable.
5800 @c DEFAULT-VALUE is the default value of the variable. It is a
5801 symbol, integer, or M-text.
5803 @c VALUEs (if any) specifies the possible values of the variable.
5804 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5805 @c TO), where @c FROM and @c TO specifies a range of possible
5808 For instance, suppose an input method has the variables:
5810 @li name:intvar, description:"value is an integer",
5811 initial value:0, value-range:0..3,10,20
5813 @li name:symvar, description:"value is a symbol",
5814 initial value:nil, value-range:a, b, c, nil
5816 @li name:txtvar, description:"value is an M-text",
5817 initial value:empty text, no value-range (i.e. any text)
5819 Then, the returned plist is as follows.
5822 (intvar ("value is an integer" 0 (0 3) 10 20)
5823 symvar ("value is a symbol" nil a b c nil)
5824 txtvar ("value is an M-text" ""))
5828 If the input method uses any variables, a pointer to #MPlist is
5829 returned. As the plist is kept in the library, the caller must not
5830 modify nor free it. If the input method does not use any
5831 variable, @c NULL is returned. */
5833 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5835 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5836 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5837 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5841 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5842 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5846 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5848 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5850 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5853 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5854 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5855 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5857 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5859 @li name:intvar, ÀâÌÀ:"value is an integer",
5860 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5862 @li name:symvar, ÀâÌÀ:"value is a symbol",
5863 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5865 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5866 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5868 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5871 (intvar ("value is an integer" 0 (0 3) 10 20)
5872 symvar ("value is a symbol" nil a b c nil)
5873 txtvar ("value is an M-text" ""))
5877 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5878 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5879 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5882 minput_get_variables (MSymbol language, MSymbol name)
5884 MInputMethodInfo *im_info;
5889 im_info = get_im_info (language, name, Mnil, Mvariable);
5890 if (! im_info || ! im_info->configured_vars)
5893 M17N_OBJECT_UNREF (im_info->bc_vars);
5894 im_info->bc_vars = mplist ();
5895 MPLIST_DO (vars, im_info->configured_vars)
5897 MPlist *plist = MPLIST_PLIST (vars);
5898 MPlist *elt = mplist ();
5900 mplist_push (im_info->bc_vars, Mplist, elt);
5901 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5902 elt = MPLIST_NEXT (elt);
5903 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5904 M17N_OBJECT_UNREF (elt);
5906 return im_info->bc_vars;
5912 @brief Set the initial value of an input method variable.
5914 The minput_set_variable () function sets the initial value of
5915 input method variable $VARIABLE to $VALUE for the input method
5916 specified by $LANGUAGE and $NAME.
5918 By default, the initial value is 0.
5920 This setting gets effective in a newly opened input method.
5923 If the operation was successful, 0 is returned. Otherwise -1 is
5924 returned, and #merror_code is set to #MERROR_IM. */
5926 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5928 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5929 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5930 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5932 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5934 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5937 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5938 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5941 minput_set_variable (MSymbol language, MSymbol name,
5942 MSymbol variable, void *value)
5945 MInputMethodInfo *im_info;
5950 if (variable == Mnil)
5951 MERROR (MERROR_IM, -1);
5952 plist = minput_get_variable (language, name, variable);
5953 plist = MPLIST_PLIST (plist);
5954 plist = MPLIST_NEXT (plist);
5956 mplist_add (pl, MPLIST_KEY (plist), value);
5957 ret = minput_config_variable (language, name, variable, pl);
5958 M17N_OBJECT_UNREF (pl);
5961 im_info = get_im_info (language, name, Mnil, Mvariable);
5970 @brief Get information about input method commands.
5972 The minput_get_commands () function returns information about
5973 input method commands of the input method specified by $LANGUAGE
5974 and $NAME. An input method command is a pseudo key event to which
5975 one or more actual input key sequences are assigned.
5977 There are two kinds of commands, global and local. Global
5978 commands are used by multiple input methods for the same purpose,
5979 and have global key assignments. Local commands are used only by
5980 a specific input method, and have only local key assignments.
5982 Each input method may locally change key assignments for global
5983 commands. The global key assignment for a global command is
5984 effective only when the current input method does not have local
5985 key assignments for that command.
5987 If $NAME is #Mnil, information about global commands is returned.
5988 In this case $LANGUAGE is ignored.
5990 If $NAME is not #Mnil, information about those commands that have
5991 local key assignments in the input method specified by $LANGUAGE
5992 and $NAME is returned.
5995 If no input method commands are found, this function returns @c NULL.
5997 Otherwise, a pointer to a plist is returned. The key of each
5998 element in the plist is a symbol representing a command, and the
5999 value is a plist of the form COMMAND-INFO described below.
6001 The first element of COMMAND-INFO has the key #Mtext, and the
6002 value is an M-text describing the command.
6004 If there are no more elements, that means no key sequences are
6005 assigned to the command. Otherwise, each of the remaining
6006 elements has the key #Mplist, and the value is a plist whose keys are
6007 #Msymbol and values are symbols representing input keys, which are
6008 currently assigned to the command.
6010 As the returned plist is kept in the library, the caller must not
6011 modify nor free it. */
6013 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
6015 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
6016 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
6017 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
6018 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
6020 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
6021 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
6022 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
6023 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
6025 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
6026 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
6027 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
6030 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
6031 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
6033 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
6034 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
6038 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
6040 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
6041 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
6042 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
6044 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
6045 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
6046 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
6049 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
6050 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
6051 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
6052 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
6053 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
6055 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
6056 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
6059 minput_get_commands (MSymbol language, MSymbol name)
6061 MInputMethodInfo *im_info;
6066 im_info = get_im_info (language, name, Mnil, Mcommand);
6067 if (! im_info || ! im_info->configured_vars)
6069 M17N_OBJECT_UNREF (im_info->bc_cmds);
6070 im_info->bc_cmds = mplist ();
6071 MPLIST_DO (cmds, im_info->configured_cmds)
6073 MPlist *plist = MPLIST_PLIST (cmds);
6074 MPlist *elt = mplist ();
6076 mplist_push (im_info->bc_cmds, Mplist, elt);
6077 mplist_add (elt, MPLIST_SYMBOL (plist),
6078 mplist_copy (MPLIST_NEXT (plist)));
6079 M17N_OBJECT_UNREF (elt);
6081 return im_info->bc_cmds;
6087 @brief Assign a key sequence to an input method command (obsolete).
6089 This function is obsolete. Use minput_config_command () instead.
6091 The minput_assign_command_keys () function assigns input key
6092 sequence $KEYSEQ to input method command $COMMAND for the input
6093 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
6094 key sequence is assigned globally no matter what $LANGUAGE is.
6095 Otherwise the key sequence is assigned locally.
6097 Each element of $KEYSEQ must have the key $Msymbol and the value
6098 must be a symbol representing an input key.
6100 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
6101 globally or locally.
6103 This assignment gets effective in a newly opened input method.
6106 If the operation was successful, 0 is returned. Otherwise -1 is
6107 returned, and #merror_code is set to #MERROR_IM. */
6109 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
6111 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
6112 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
6113 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
6114 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
6115 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
6117 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
6118 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
6120 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6121 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6123 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6126 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6127 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6130 minput_assign_command_keys (MSymbol language, MSymbol name,
6131 MSymbol command, MPlist *keyseq)
6137 if (command == Mnil)
6138 MERROR (MERROR_IM, -1);
6143 if (! check_command_keyseq (keyseq))
6144 MERROR (MERROR_IM, -1);
6146 mplist_add (plist, Mplist, keyseq);
6151 ret = minput_config_command (language, name, command, keyseq);
6152 M17N_OBJECT_UNREF (keyseq);
6159 @brief Call a callback function
6161 The minput_callback () functions calls a callback function
6162 $COMMAND assigned for the input context $IC. The caller must set
6163 specific elements in $IC->plist if the callback function requires.
6166 If there exists a specified callback function, 0 is returned.
6167 Otherwise -1 is returned. By side effects, $IC->plist may be
6171 minput_callback (MInputContext *ic, MSymbol command)
6173 MInputCallbackFunc func;
6175 if (! ic->im->driver.callback_list)
6177 func = ((MInputCallbackFunc)
6178 mplist_get_func (ic->im->driver.callback_list, command));
6181 (func) (ic, command);
6188 /*** @addtogroup m17nDebug */
6194 @brief Dump an input method.
6196 The mdebug_dump_im () function prints the input method $IM in a
6197 human readable way to the stderr. $INDENT specifies how many
6198 columns to indent the lines but the first one.
6201 This function returns $IM. */
6203 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6205 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6206 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6209 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6212 mdebug_dump_im (MInputMethod *im, int indent)
6214 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6217 prefix = (char *) alloca (indent + 1);
6218 memset (prefix, 32, indent);
6219 prefix[indent] = '\0';
6221 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6222 msymbol_name (im->name));
6223 mdebug_dump_mtext (im_info->title, 0, 0);
6224 if (im->name != Mnil)
6228 MPLIST_DO (state, im_info->states)
6230 fprintf (stderr, "\n%s ", prefix);
6231 dump_im_state (MPLIST_VAL (state), indent + 2);
6234 fprintf (stderr, ")");