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 if (language == Mnil || name == Mnil)
1453 p = MPLIST_NEXT (p);
1454 if (MPLIST_TAIL_P (p))
1456 else if (MPLIST_SYMBOL_P (p))
1457 extra = MPLIST_SYMBOL (p);
1460 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1461 load_im_info (im_data, im_info);
1463 M17N_OBJECT_UNREF (plist);
1468 update_global_info (void)
1474 int ret = mdatabase__check (global_info->mdb);
1478 fini_im_info (global_info);
1482 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1484 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1486 if (! global_info->mdb
1487 || ! (plist = mdatabase_load (global_info->mdb)))
1490 load_im_info (plist, global_info);
1491 M17N_OBJECT_UNREF (plist);
1496 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1497 and EXTRA. KEY, if not Mnil, tells which kind of information about
1498 the input method is necessary, and the returned IM_INFO may contain
1499 only that information. */
1501 static MInputMethodInfo *
1502 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1505 MInputMethodInfo *im_info;
1508 if (name == Mnil && extra == Mnil)
1509 language = Mt, extra = Mglobal;
1510 im_info = lookup_im_info (im_info_list, language, name, extra);
1513 if (key == Mnil ? im_info->states != NULL
1514 : key == Mcommand ? im_info->cmds != NULL
1515 : key == Mvariable ? im_info->vars != NULL
1516 : key == Mtitle ? im_info->title != NULL
1517 : key == Mdescription ? im_info->description != NULL
1519 /* IM_INFO already contains required information. */
1521 /* We have not yet loaded required information. */
1525 mdb = mdatabase_find (Minput_method, language, name, extra);
1528 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1533 plist = mdatabase_load (im_info->mdb);
1537 mplist_push (load_im_info_keys, key, Mt);
1538 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1539 mplist_pop (load_im_info_keys);
1543 MERROR (MERROR_IM, im_info);
1544 update_global_info ();
1545 load_im_info (plist, im_info);
1546 M17N_OBJECT_UNREF (plist);
1549 if (! im_info->cmds)
1550 im_info->cmds = mplist ();
1551 if (! im_info->vars)
1552 im_info->vars = mplist ();
1554 if (! im_info->title
1555 && (key == Mnil || key == Mtitle))
1556 im_info->title = (name == Mnil ? mtext ()
1557 : mtext_from_data (MSYMBOL_NAME (name),
1558 MSYMBOL_NAMELEN (name),
1559 MTEXT_FORMAT_US_ASCII));
1563 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1564 If updated, but got unloadable, return -1. Otherwise, update
1565 contents of IM_INFO from the new database, and return 1. */
1568 reload_im_info (MInputMethodInfo *im_info)
1573 update_custom_info ();
1574 update_global_info ();
1575 check = mdatabase__check (im_info->mdb);
1578 plist = mdatabase_load (im_info->mdb);
1581 fini_im_info (im_info);
1582 load_im_info (plist, im_info);
1583 M17N_OBJECT_UNREF (plist);
1584 if (! im_info->cmds)
1585 im_info->cmds = mplist ();
1586 if (! im_info->vars)
1587 im_info->vars = mplist ();
1588 if (! im_info->title)
1590 MSymbol name = im_info->name;
1592 im_info->title = (name == Mnil ? mtext ()
1593 : mtext_from_data (MSYMBOL_NAME (name),
1594 MSYMBOL_NAMELEN (name),
1595 MTEXT_FORMAT_US_ASCII));
1600 static MInputMethodInfo *
1601 get_im_info_by_tags (MPlist *plist)
1606 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1607 i++, plist = MPLIST_NEXT (plist))
1608 tag[i] = MPLIST_SYMBOL (plist);
1613 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1618 check_description (MPlist *plist)
1622 if (MPLIST_MTEXT_P (plist))
1624 if (MPLIST_PLIST_P (plist))
1626 MPlist *pl = MPLIST_PLIST (plist);
1628 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1630 pl =MPLIST_NEXT (pl);
1631 if (MFAILP (MPLIST_MTEXT_P (pl)))
1633 mt = MPLIST_MTEXT (pl);
1634 M17N_OBJECT_REF (mt);
1637 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1639 if (translated == (char *) MTEXT_DATA (mt))
1640 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1641 if (translated != (char *) MTEXT_DATA (mt))
1643 M17N_OBJECT_UNREF (mt);
1644 mt = mtext__from_data (translated, strlen (translated),
1645 MTEXT_FORMAT_UTF_8, 0);
1649 mplist_set (plist, Mtext, mt);
1650 M17N_OBJECT_UNREF (mt);
1653 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1659 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1663 check_command_keyseq (MPlist *keyseq)
1665 if (MPLIST_PLIST_P (keyseq))
1667 MPlist *p = MPLIST_PLIST (keyseq);
1670 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1674 if (MPLIST_MTEXT_P (keyseq))
1676 MText *mt = MPLIST_MTEXT (keyseq);
1679 for (i = 0; i < mtext_nchars (mt); i++)
1680 if (mtext_ref_char (mt, i) >= 256)
1687 /* Load command defitions from PLIST into IM_INFO->cmds.
1689 PLIST is well-formed and has this form;
1690 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1691 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1692 M-text or a plist of symbols.
1694 The returned list has the same form, but for each element...
1696 (1) If DESCRIPTION and the rest are omitted, the element is not
1697 stored in the returned list.
1699 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1700 description in global_info->cmds (if any). */
1703 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1707 im_info->cmds = tail = mplist ();
1709 MPLIST_DO (plist, MPLIST_NEXT (plist))
1711 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1714 if (MFAILP (MPLIST_PLIST_P (plist)))
1716 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1717 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1719 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1720 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1722 if (MFAILP (im_info != global_info))
1723 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1727 if (! check_description (p))
1728 mplist_set (p, Msymbol, Mnil);
1729 p = MPLIST_NEXT (p);
1730 while (! MPLIST_TAIL_P (p))
1732 if (MFAILP (check_command_keyseq (p)))
1733 mplist__pop_unref (p);
1735 p = MPLIST_NEXT (p);
1738 tail = mplist_add (tail, Mplist, pl);
1743 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1744 MPlist *config_cmds)
1746 MPlist *global = NULL, *custom = NULL, *config = NULL;
1749 MPlist *description = NULL, *keyseq;
1751 name = MPLIST_SYMBOL (plist);
1752 plist = MPLIST_NEXT (plist);
1753 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1754 description = plist;
1755 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1756 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1757 if (MPLIST_TAIL_P (plist))
1760 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1761 global = MPLIST_NEXT (MPLIST_PLIST (global));
1764 keyseq = MPLIST_NEXT (global);
1765 status = Minherited;
1775 keyseq = MPLIST_NEXT (plist);
1779 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1781 config = MPLIST_NEXT (MPLIST_PLIST (config));
1782 if (! MPLIST_TAIL_P (config))
1784 keyseq = MPLIST_NEXT (config);
1785 status = Mconfigured;
1788 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1790 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1791 if (! MPLIST_TAIL_P (custom))
1793 keyseq = MPLIST_NEXT (custom);
1794 status = Mcustomized;
1799 mplist_add (plist, Msymbol, name);
1801 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1803 mplist_add (plist, Msymbol, Mnil);
1804 mplist_add (plist, Msymbol, status);
1805 mplist__conc (plist, keyseq);
1810 config_all_commands (MInputMethodInfo *im_info)
1812 MPlist *global_cmds, *custom_cmds, *config_cmds;
1813 MInputMethodInfo *temp;
1814 MPlist *tail, *plist;
1816 M17N_OBJECT_UNREF (im_info->configured_cmds);
1818 if (MPLIST_TAIL_P (im_info->cmds)
1822 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1823 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1824 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1826 im_info->configured_cmds = tail = mplist ();
1827 MPLIST_DO (plist, im_info->cmds)
1829 MPlist *pl = config_command (MPLIST_PLIST (plist),
1830 global_cmds, custom_cmds, config_cmds);
1833 tail = mplist_add (tail, Mplist, pl);
1834 M17N_OBJECT_UNREF (pl);
1839 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1840 valid, return 0 if not. */
1843 check_variable_value (MPlist *val, MPlist *global)
1845 MSymbol type = MPLIST_KEY (val);
1846 MPlist *valids = MPLIST_NEXT (val);
1848 if (type != Minteger && type != Mtext && type != Msymbol)
1852 if (MPLIST_KEY (global) != Mt
1853 && MPLIST_KEY (global) != MPLIST_KEY (val))
1855 if (MPLIST_TAIL_P (valids))
1856 valids = MPLIST_NEXT (global);
1858 if (MPLIST_TAIL_P (valids))
1861 if (type == Minteger)
1863 int n = MPLIST_INTEGER (val);
1865 MPLIST_DO (valids, valids)
1867 if (MPLIST_INTEGER_P (valids))
1869 if (n == MPLIST_INTEGER (valids))
1872 else if (MPLIST_PLIST_P (valids))
1874 MPlist *p = MPLIST_PLIST (valids);
1875 int min_bound, max_bound;
1877 if (! MPLIST_INTEGER_P (p))
1878 MERROR (MERROR_IM, 0);
1879 min_bound = MPLIST_INTEGER (p);
1880 p = MPLIST_NEXT (p);
1881 if (! MPLIST_INTEGER_P (p))
1882 MERROR (MERROR_IM, 0);
1883 max_bound = MPLIST_INTEGER (p);
1884 if (n >= min_bound && n <= max_bound)
1889 else if (type == Msymbol)
1891 MSymbol sym = MPLIST_SYMBOL (val);
1893 MPLIST_DO (valids, valids)
1895 if (! MPLIST_SYMBOL_P (valids))
1896 MERROR (MERROR_IM, 0);
1897 if (sym == MPLIST_SYMBOL (valids))
1903 MText *mt = MPLIST_MTEXT (val);
1905 MPLIST_DO (valids, valids)
1907 if (! MPLIST_MTEXT_P (valids))
1908 MERROR (MERROR_IM, 0);
1909 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1914 return (! MPLIST_TAIL_P (valids));
1917 /* Load variable defitions from PLIST into IM_INFO->vars.
1919 PLIST is well-formed and has this form;
1920 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1922 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1924 The returned list has the same form, but for each element...
1926 (1) If DESCRIPTION and the rest are omitted, the element is not
1927 stored in the returned list.
1929 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1930 description in global_info->vars (if any). */
1933 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1935 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1936 ? global_info->vars : NULL);
1939 im_info->vars = tail = mplist ();
1940 MPLIST_DO (plist, MPLIST_NEXT (plist))
1944 if (MFAILP (MPLIST_PLIST_P (plist)))
1946 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1947 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1949 if (im_info == global_info)
1951 /* Loading a global variable. */
1952 p = MPLIST_NEXT (pl);
1953 if (MPLIST_TAIL_P (p))
1954 mplist_add (p, Msymbol, Mnil);
1957 if (! check_description (p))
1958 mplist_set (p, Msymbol, Mnil);
1959 p = MPLIST_NEXT (p);
1960 if (MFAILP (! MPLIST_TAIL_P (p)
1961 && check_variable_value (p, NULL)))
1962 mplist_set (p, Mt, NULL);
1965 else if (im_info->mdb)
1967 /* Loading a local variable. */
1968 MSymbol name = MPLIST_SYMBOL (pl);
1969 MPlist *global = NULL;
1972 && (p = mplist__assq (global_vars, name)))
1974 /* P ::= ((NAME DESC ...) ...) */
1975 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1976 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1977 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1980 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1981 if (! MPLIST_TAIL_P (p))
1983 if (! check_description (p))
1984 mplist_set (p, Msymbol, Mnil);
1985 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1986 if (MFAILP (! MPLIST_TAIL_P (p)))
1987 mplist_set (p, Mt, NULL);
1990 MPlist *valid_values = MPLIST_NEXT (p);
1992 if (! MPLIST_TAIL_P (valid_values)
1993 ? MFAILP (check_variable_value (p, NULL))
1994 : global && MFAILP (check_variable_value (p, global)))
1995 mplist_set (p, Mt, NULL);
2001 /* Loading a variable customization. */
2002 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
2003 if (MFAILP (! MPLIST_TAIL_P (p)))
2005 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
2006 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
2007 || MPLIST_MTEXT_P (p)))
2010 tail = mplist_add (tail, Mplist, pl);
2015 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2016 MPlist *config_vars)
2018 MPlist *global = NULL, *custom = NULL, *config = NULL;
2019 MSymbol name = MPLIST_SYMBOL (plist);
2021 MPlist *description = NULL, *value, *valids;
2025 global = mplist__assq (global_vars, name);
2027 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2030 plist = MPLIST_NEXT (plist);
2031 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2032 description = plist;
2034 description = global;
2036 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2038 if (MPLIST_TAIL_P (plist))
2040 /* Inherit from global (if any). */
2044 if (MPLIST_KEY (value) == Mt)
2046 valids = MPLIST_NEXT (global);
2047 status = Minherited;
2059 value = plist = MPLIST_NEXT (plist);
2060 valids = MPLIST_NEXT (value);
2061 if (MPLIST_KEY (value) == Mt)
2063 if (! MPLIST_TAIL_P (valids))
2066 valids = MPLIST_NEXT (global);
2070 if (config_vars && (config = mplist__assq (config_vars, name)))
2072 config = MPLIST_NEXT (MPLIST_PLIST (config));
2073 if (! MPLIST_TAIL_P (config))
2075 value = MPLIST_NEXT (config);
2076 if (MFAILP (check_variable_value (value, global ? global : plist)))
2078 status = Mconfigured;
2081 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2083 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2084 if (! MPLIST_TAIL_P (custom))
2086 value = MPLIST_NEXT (custom);
2087 if (MFAILP (check_variable_value (value, global ? global : plist)))
2089 status = Mcustomized;
2094 mplist_add (plist, Msymbol, name);
2096 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2098 mplist_add (plist, Msymbol, Mnil);
2099 mplist_add (plist, Msymbol, status);
2101 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2103 mplist_add (plist, Mt, NULL);
2104 if (valids && ! MPLIST_TAIL_P (valids))
2105 mplist__conc (plist, valids);
2109 /* Return a configured variable definition list based on
2110 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2111 get it from global_info->vars. */
2114 config_all_variables (MInputMethodInfo *im_info)
2116 MPlist *global_vars, *custom_vars, *config_vars;
2117 MInputMethodInfo *temp;
2118 MPlist *tail, *plist;
2120 M17N_OBJECT_UNREF (im_info->configured_vars);
2122 if (MPLIST_TAIL_P (im_info->vars)
2126 global_vars = im_info != global_info ? global_info->vars : NULL;
2127 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2128 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2130 im_info->configured_vars = tail = mplist ();
2131 MPLIST_DO (plist, im_info->vars)
2133 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2134 global_vars, custom_vars, config_vars);
2137 tail = mplist_add (tail, Mplist, pl);
2138 M17N_OBJECT_UNREF (pl);
2143 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2144 CONFIG contains configuration information of the input method. */
2147 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2151 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2153 load_commands (im_info, MPLIST_PLIST (pl));
2154 config_all_commands (im_info);
2155 pl = mplist_pop (pl);
2156 M17N_OBJECT_UNREF (pl);
2159 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2161 load_variables (im_info, MPLIST_PLIST (pl));
2162 config_all_variables (im_info);
2163 pl = mplist_pop (pl);
2164 M17N_OBJECT_UNREF (pl);
2167 MPLIST_DO (plist, plist)
2168 if (MPLIST_PLIST_P (plist))
2170 MPlist *elt = MPLIST_PLIST (plist);
2173 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2175 key = MPLIST_SYMBOL (elt);
2180 elt = MPLIST_NEXT (elt);
2181 if (MFAILP (MPLIST_MTEXT_P (elt)))
2183 im_info->title = MPLIST_MTEXT (elt);
2184 M17N_OBJECT_REF (im_info->title);
2186 else if (key == Mmap)
2188 pl = mplist__from_alist (MPLIST_NEXT (elt));
2191 if (! im_info->maps)
2195 mplist__conc (im_info->maps, pl);
2196 M17N_OBJECT_UNREF (pl);
2199 else if (key == Mmacro)
2201 if (! im_info->macros)
2202 im_info->macros = mplist ();
2203 MPLIST_DO (elt, MPLIST_NEXT (elt))
2205 if (MFAILP (MPLIST_PLIST_P (elt)))
2207 load_macros (im_info, MPLIST_PLIST (elt));
2210 else if (key == Mmodule)
2212 if (! im_info->externals)
2213 im_info->externals = mplist ();
2214 MPLIST_DO (elt, MPLIST_NEXT (elt))
2216 if (MFAILP (MPLIST_PLIST_P (elt)))
2218 load_external_module (im_info, MPLIST_PLIST (elt));
2221 else if (key == Mstate)
2223 MPLIST_DO (elt, MPLIST_NEXT (elt))
2227 if (MFAILP (MPLIST_PLIST_P (elt)))
2229 pl = MPLIST_PLIST (elt);
2230 if (! im_info->states)
2231 im_info->states = mplist ();
2232 state = load_state (im_info, MPLIST_PLIST (elt));
2235 mplist_put (im_info->states, state->name, state);
2238 else if (key == Minclude)
2240 /* elt ::= include (tag1 tag2 ...) key item ... */
2242 MInputMethodInfo *temp;
2244 elt = MPLIST_NEXT (elt);
2245 if (MFAILP (MPLIST_PLIST_P (elt)))
2247 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2250 elt = MPLIST_NEXT (elt);
2251 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2253 key = MPLIST_SYMBOL (elt);
2254 elt = MPLIST_NEXT (elt);
2257 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2259 if (! im_info->maps)
2260 im_info->maps = mplist ();
2261 MPLIST_DO (pl, temp->maps)
2263 p = MPLIST_VAL (pl);
2264 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2265 M17N_OBJECT_REF (p);
2268 else if (key == Mmacro)
2270 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2272 if (! im_info->macros)
2273 im_info->macros = mplist ();
2274 MPLIST_DO (pl, temp->macros)
2276 p = MPLIST_VAL (pl);
2277 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2278 M17N_OBJECT_REF (p);
2281 else if (key == Mstate)
2283 if (! temp->states || MPLIST_TAIL_P (temp->states))
2285 if (! im_info->states)
2286 im_info->states = mplist ();
2287 MPLIST_DO (pl, temp->states)
2289 MIMState *state = MPLIST_VAL (pl);
2291 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2292 M17N_OBJECT_REF (state);
2296 else if (key == Mdescription)
2298 if (im_info->description)
2300 elt = MPLIST_NEXT (elt);
2301 if (! check_description (elt))
2303 im_info->description = MPLIST_MTEXT (elt);
2304 M17N_OBJECT_REF (im_info->description);
2307 im_info->tick = time (NULL);
2312 static int take_action_list (MInputContext *ic, MPlist *action_list);
2313 static void preedit_commit (MInputContext *ic);
2316 shift_state (MInputContext *ic, MSymbol state_name)
2318 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2319 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2320 MIMState *orig_state = ic_info->state, *state;
2322 /* Find a state to shift to. If not found, shift to the initial
2324 if (state_name == Mt)
2326 if (! ic_info->prev_state)
2328 state = ic_info->prev_state;
2330 else if (state_name == Mnil)
2332 state = (MIMState *) MPLIST_VAL (im_info->states);
2336 state = (MIMState *) mplist_get (im_info->states, state_name);
2338 state = (MIMState *) MPLIST_VAL (im_info->states);
2341 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2343 /* Enter the new state. */
2344 ic_info->state = state;
2345 ic_info->map = state->map;
2346 ic_info->state_key_head = ic_info->key_head;
2347 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2349 /* We have shifted to the initial state. */
2350 preedit_commit (ic);
2351 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2352 ic_info->state_pos = ic->cursor_pos;
2353 if (state != orig_state)
2355 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2357 /* Shifted to the initial state. */
2358 ic_info->prev_state = NULL;
2359 M17N_OBJECT_UNREF (ic_info->vars_saved);
2360 ic_info->vars_saved = mplist_copy (ic_info->vars);
2363 ic_info->prev_state = orig_state;
2366 ic->status = state->title;
2368 ic->status = im_info->title;
2369 ic->status_changed = 1;
2370 if (ic_info->map == ic_info->state->map
2371 && ic_info->map->map_actions)
2373 MDEBUG_PRINT (" init-actions:");
2374 take_action_list (ic, ic_info->map->map_actions);
2379 /* Find a candidate group that contains a candidate number INDEX from
2380 PLIST. Set START_INDEX to the first candidate number of the group,
2381 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2382 candidate group number if they are non-NULL. If INDEX is -1, find
2383 the last candidate group. */
2386 find_candidates_group (MPlist *plist, int index,
2387 int *start_index, int *end_index, int *group_index)
2389 int i = 0, gidx = 0, len;
2391 MPLIST_DO (plist, plist)
2393 if (MPLIST_MTEXT_P (plist))
2394 len = mtext_nchars (MPLIST_MTEXT (plist));
2396 len = mplist_length (MPLIST_PLIST (plist));
2397 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2403 *end_index = i + len;
2405 *group_index = gidx;
2414 /* Adjust markers for the change of preedit text.
2415 If FROM == TO, the change is insertion of INS chars.
2416 If FROM < TO and INS == 0, the change is deletion of the range.
2417 If FROM < TO and INS > 0, the change is replacement. */
2420 adjust_markers (MInputContext *ic, int from, int to, int ins)
2422 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2427 MPLIST_DO (markers, ic_info->markers)
2428 if (MPLIST_INTEGER (markers) > from)
2429 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2430 if (ic->cursor_pos >= from)
2431 ic->cursor_pos += ins;
2435 MPLIST_DO (markers, ic_info->markers)
2437 if (MPLIST_INTEGER (markers) >= to)
2438 MPLIST_VAL (markers)
2439 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2440 else if (MPLIST_INTEGER (markers) > from)
2441 MPLIST_VAL (markers) = (void *) from;
2443 if (ic->cursor_pos >= to)
2444 ic->cursor_pos += ins - (to - from);
2445 else if (ic->cursor_pos > from)
2446 ic->cursor_pos = from;
2452 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2454 int nchars = mt ? mtext_nchars (mt) : 1;
2457 mtext_ins (ic->preedit, pos, mt);
2459 mtext_ins_char (ic->preedit, pos, c, 1);
2460 adjust_markers (ic, pos, pos, nchars);
2461 ic->preedit_changed = 1;
2466 preedit_delete (MInputContext *ic, int from, int to)
2468 mtext_del (ic->preedit, from, to);
2469 adjust_markers (ic, from, to, 0);
2470 ic->preedit_changed = 1;
2474 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2478 mtext_del (ic->preedit, from, to);
2481 mtext_ins (ic->preedit, from, mt);
2482 ins = mtext_nchars (mt);
2486 mtext_ins_char (ic->preedit, from, c, 1);
2489 adjust_markers (ic, from, to, ins);
2490 ic->preedit_changed = 1;
2495 preedit_commit (MInputContext *ic)
2497 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2498 int preedit_len = mtext_nchars (ic->preedit);
2500 if (preedit_len > 0)
2504 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2505 Mcandidate_list, NULL, 0);
2506 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2507 Mcandidate_index, NULL, 0);
2508 mtext_cat (ic->produced, ic->preedit);
2509 if (mdebug__flag & mdebug_mask)
2513 MDEBUG_PRINT (" (commit");
2514 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2515 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2519 mtext_reset (ic->preedit);
2520 mtext_reset (ic_info->preedit_saved);
2521 MPLIST_DO (p, ic_info->markers)
2523 ic->cursor_pos = ic_info->state_pos = 0;
2524 ic->preedit_changed = 1;
2525 ic_info->commit_key_head = ic_info->key_head;
2527 if (ic->candidate_list)
2529 M17N_OBJECT_UNREF (ic->candidate_list);
2530 ic->candidate_list = NULL;
2531 ic->candidate_index = 0;
2532 ic->candidate_from = ic->candidate_to = 0;
2533 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2534 if (ic->candidate_show)
2536 ic->candidate_show = 0;
2537 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2543 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2545 int code = marker_code (sym, 0);
2547 if (mt && (code == '[' || code == ']'))
2551 if (code == '[' && current > 0)
2553 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2557 else if (code == ']' && current < mtext_nchars (mt))
2559 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2565 return (code == '<' ? 0
2566 : code == '>' ? limit
2567 : code == '-' ? current - 1
2568 : code == '+' ? current + 1
2569 : code == '=' ? current
2570 : code - '0' > limit ? limit
2574 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2578 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2580 int from = mtext_property_start (prop);
2581 int to = mtext_property_end (prop);
2583 MPlist *candidate_list = mtext_property_value (prop);
2584 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2586 int ingroup_index = idx - start;
2589 if (MPLIST_MTEXT_P (group))
2591 mt = MPLIST_MTEXT (group);
2592 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2600 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2601 i++, plist = MPLIST_NEXT (plist));
2602 mt = MPLIST_MTEXT (plist);
2603 preedit_replace (ic, from, to, mt, 0);
2604 to = from + mtext_nchars (mt);
2606 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2607 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2608 ic->cursor_pos = to;
2612 get_select_charset (MInputContextInfo * ic_info)
2614 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2617 if (! MPLIST_VAL (plist))
2619 sym = MPLIST_SYMBOL (plist);
2622 return MCHARSET (sym);
2626 adjust_candidates (MPlist *plist, MCharset *charset)
2630 /* plist ::= MTEXT ... | PLIST ... */
2631 plist = mplist_copy (plist);
2632 if (MPLIST_MTEXT_P (plist))
2635 while (! MPLIST_TAIL_P (pl))
2637 /* pl ::= MTEXT ... */
2638 MText *mt = MPLIST_MTEXT (pl);
2642 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2644 c = mtext_ref_char (mt, i);
2645 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2649 mt = mtext_dup (mt);
2650 mplist_set (pl, Mtext, mt);
2651 M17N_OBJECT_UNREF (mt);
2654 mtext_del (mt, i, i + 1);
2657 if (mtext_len (mt) > 0)
2658 pl = MPLIST_NEXT (pl);
2662 M17N_OBJECT_UNREF (mt);
2666 else /* MPLIST_PLIST_P (plist) */
2669 while (! MPLIST_TAIL_P (pl))
2671 /* pl ::= (MTEXT ...) ... */
2672 MPlist *p = MPLIST_PLIST (pl);
2674 /* p ::= MTEXT ... */
2678 while (! MPLIST_TAIL_P (p0))
2680 MText *mt = MPLIST_MTEXT (p0);
2683 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2685 c = mtext_ref_char (mt, i);
2686 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2691 p0 = MPLIST_NEXT (p0);
2698 p = mplist_copy (p);
2699 mplist_set (pl, Mplist, p);
2700 M17N_OBJECT_UNREF (p);
2704 p0 = MPLIST_NEXT (p0);
2707 M17N_OBJECT_UNREF (mt);
2710 if (! MPLIST_TAIL_P (p))
2711 pl = MPLIST_NEXT (pl);
2715 M17N_OBJECT_UNREF (p);
2719 if (MPLIST_TAIL_P (plist))
2721 M17N_OBJECT_UNREF (plist);
2728 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2730 MCharset *charset = get_select_charset (ic_info);
2735 plist = resolve_variable (ic_info, Mcandidates_group_size);
2736 column = MPLIST_INTEGER (plist);
2738 plist = MPLIST_PLIST (args);
2740 plist = adjust_candidates (plist, charset);
2742 if (plist && column > 0)
2744 if (MPLIST_MTEXT_P (plist))
2746 MText *mt = MPLIST_MTEXT (plist);
2747 MPlist *next = MPLIST_NEXT (plist);
2749 if (MPLIST_TAIL_P (next))
2750 M17N_OBJECT_REF (mt);
2753 mt = mtext_dup (mt);
2754 while (! MPLIST_TAIL_P (next))
2756 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2757 next = MPLIST_NEXT (next);
2760 M17N_OBJECT_UNREF (plist);
2762 len = mtext_nchars (mt);
2764 mplist_add (plist, Mtext, mt);
2767 for (i = 0; i < len; i += column)
2769 int to = (i + column < len ? i + column : len);
2770 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2772 mplist_add (plist, Mtext, sub);
2773 M17N_OBJECT_UNREF (sub);
2776 M17N_OBJECT_UNREF (mt);
2778 else if (! MPLIST_TAIL_P (plist))
2780 MPlist *tail = plist;
2781 MPlist *new = mplist ();
2782 MPlist *this = mplist ();
2785 MPLIST_DO (tail, tail)
2787 MPlist *p = MPLIST_PLIST (tail);
2791 MText *mt = MPLIST_MTEXT (p);
2793 if (count == column)
2795 mplist_add (new, Mplist, this);
2796 M17N_OBJECT_UNREF (this);
2800 mplist_add (this, Mtext, mt);
2804 mplist_add (new, Mplist, this);
2805 M17N_OBJECT_UNREF (this);
2806 mplist_set (plist, Mnil, NULL);
2807 MPLIST_DO (tail, new)
2809 MPlist *elt = MPLIST_PLIST (tail);
2811 mplist_add (plist, Mplist, elt);
2813 M17N_OBJECT_UNREF (new);
2822 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2824 MPlist *action = NULL;
2828 if (MPLIST_SYMBOL_P (action_list))
2830 MSymbol var = MPLIST_SYMBOL (action_list);
2833 MPLIST_DO (p, ic_info->vars)
2834 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2836 if (MPLIST_TAIL_P (p))
2838 action = MPLIST_NEXT (MPLIST_PLIST (p));
2839 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2842 if (MPLIST_PLIST_P (action_list))
2844 action = MPLIST_PLIST (action_list);
2845 if (MPLIST_SYMBOL_P (action))
2847 name = MPLIST_SYMBOL (action);
2848 args = MPLIST_NEXT (action);
2850 && MPLIST_PLIST_P (args))
2851 mplist_set (action, Msymbol, M_candidates);
2853 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2856 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2857 mplist_push (action, Msymbol, M_candidates);
2858 mplist_set (action_list, Mplist, action);
2859 M17N_OBJECT_UNREF (action);
2862 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2865 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2866 mplist_push (action, Msymbol, Minsert);
2867 mplist_set (action_list, Mplist, action);
2868 M17N_OBJECT_UNREF (action);
2873 /* Perform list of actions in ACTION_LIST for the current input
2874 context IC. If unhandle action was not performed, return 0.
2875 Otherwise, return -1. */
2878 take_action_list (MInputContext *ic, MPlist *action_list)
2880 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2881 MPlist *candidate_list = ic->candidate_list;
2882 int candidate_index = ic->candidate_index;
2883 int candidate_show = ic->candidate_show;
2884 MTextProperty *prop;
2886 MPLIST_DO (action_list, action_list)
2888 MPlist *action = regularize_action (action_list, ic_info);
2894 name = MPLIST_SYMBOL (action);
2895 args = MPLIST_NEXT (action);
2897 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2898 if (name == Minsert)
2900 if (MPLIST_SYMBOL_P (args))
2902 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2903 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2906 if (MPLIST_MTEXT_P (args))
2907 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2908 else /* MPLIST_INTEGER_P (args)) */
2909 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2911 else if (name == M_candidates)
2913 MPlist *plist = get_candidate_list (ic_info, args);
2916 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2918 if (MPLIST_MTEXT_P (plist))
2920 preedit_insert (ic, ic->cursor_pos, NULL,
2921 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2924 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2928 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2930 preedit_insert (ic, ic->cursor_pos, mt, 0);
2931 len = mtext_nchars (mt);
2933 mtext_put_prop (ic->preedit,
2934 ic->cursor_pos - len, ic->cursor_pos,
2935 Mcandidate_list, plist);
2936 mtext_put_prop (ic->preedit,
2937 ic->cursor_pos - len, ic->cursor_pos,
2938 Mcandidate_index, (void *) 0);
2940 else if (name == Mselect)
2943 int code, idx, gindex;
2944 int pos = ic->cursor_pos;
2946 int idx_decided = 0;
2949 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2952 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2953 group = find_candidates_group (mtext_property_value (prop), idx,
2954 &start, &end, &gindex);
2955 if (MPLIST_SYMBOL_P (args))
2957 code = marker_code (MPLIST_SYMBOL (args), 0);
2960 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2961 if (! MPLIST_INTEGER_P (args))
2963 idx = start + MPLIST_INTEGER (args);
2964 if (idx < start || idx >= end)
2972 if (code != '[' && code != ']')
2977 ? new_index (NULL, ic->candidate_index - start,
2978 end - start - 1, MPLIST_SYMBOL (args),
2980 : MPLIST_INTEGER (args)));
2983 find_candidates_group (mtext_property_value (prop), -1,
2988 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2993 int ingroup_index = idx - start;
2996 group = mtext_property_value (prop);
2997 len = mplist_length (group);
3010 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
3011 idx += (MPLIST_MTEXT_P (group)
3012 ? mtext_nchars (MPLIST_MTEXT (group))
3013 : mplist_length (MPLIST_PLIST (group)));
3014 len = (MPLIST_MTEXT_P (group)
3015 ? mtext_nchars (MPLIST_MTEXT (group))
3016 : mplist_length (MPLIST_PLIST (group)));
3017 if (ingroup_index >= len)
3018 ingroup_index = len - 1;
3019 idx += ingroup_index;
3021 update_candidate (ic, prop, idx);
3022 MDEBUG_PRINT1 ("(%d)", idx);
3024 else if (name == Mshow)
3025 ic->candidate_show = 1;
3026 else if (name == Mhide)
3027 ic->candidate_show = 0;
3028 else if (name == Mdelete)
3030 int len = mtext_nchars (ic->preedit);
3034 if (MPLIST_SYMBOL_P (args)
3035 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3037 to = ic->cursor_pos + pos;
3040 delete_surrounding_text (ic, to);
3045 delete_surrounding_text (ic, to - len);
3051 to = (MPLIST_SYMBOL_P (args)
3052 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3054 : MPLIST_INTEGER (args));
3060 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3061 if (to < ic->cursor_pos)
3062 preedit_delete (ic, to, ic->cursor_pos);
3063 else if (to > ic->cursor_pos)
3064 preedit_delete (ic, ic->cursor_pos, to);
3066 else if (name == Mmove)
3068 int len = mtext_nchars (ic->preedit);
3070 = (MPLIST_SYMBOL_P (args)
3071 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3073 : MPLIST_INTEGER (args));
3079 if (pos != ic->cursor_pos)
3081 ic->cursor_pos = pos;
3082 ic->preedit_changed = 1;
3084 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3086 else if (name == Mmark)
3088 int code = marker_code (MPLIST_SYMBOL (args), 0);
3092 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3093 (void *) ic->cursor_pos);
3094 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3097 else if (name == Mpushback)
3099 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3103 if (MPLIST_SYMBOL_P (args))
3105 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3106 if (MPLIST_INTEGER_P (args))
3107 num = MPLIST_INTEGER (args);
3112 num = MPLIST_INTEGER (args);
3115 ic_info->key_head -= num;
3117 ic_info->key_head = 0;
3119 ic_info->key_head = - num;
3120 if (ic_info->key_head > ic_info->used)
3121 ic_info->key_head = ic_info->used;
3123 else if (MPLIST_MTEXT_P (args))
3125 MText *mt = MPLIST_MTEXT (args);
3126 int i, len = mtext_nchars (mt);
3129 ic_info->key_head--;
3130 for (i = 0; i < len; i++)
3132 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3133 if (ic_info->key_head + i < ic_info->used)
3134 ic_info->keys[ic_info->key_head + i] = key;
3136 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3141 MPlist *plist = MPLIST_PLIST (args), *pl;
3145 ic_info->key_head--;
3147 MPLIST_DO (pl, plist)
3149 key = MPLIST_SYMBOL (pl);
3150 if (ic_info->key_head < ic_info->used)
3151 ic_info->keys[ic_info->key_head + i] = key;
3153 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3158 else if (name == Mpop)
3160 if (ic_info->key_head < ic_info->used)
3161 MLIST_DELETE1 (ic_info, keys, ic_info->key_head, 1);
3163 else if (name == Mcall)
3165 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3166 MIMExternalFunc func = NULL;
3167 MSymbol module, func_name;
3168 MPlist *func_args, *val;
3171 module = MPLIST_SYMBOL (args);
3172 args = MPLIST_NEXT (args);
3173 func_name = MPLIST_SYMBOL (args);
3175 if (im_info->externals)
3177 MIMExternalModule *external
3178 = (MIMExternalModule *) mplist_get (im_info->externals,
3181 func = (MIMExternalFunc) mplist_get (external->func_list,
3186 func_args = mplist ();
3187 mplist_add (func_args, Mt, ic);
3188 MPLIST_DO (args, MPLIST_NEXT (args))
3192 if (MPLIST_KEY (args) == Msymbol
3193 && MPLIST_KEY (args) != Mnil
3194 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3196 code = new_index (ic, ic->cursor_pos,
3197 mtext_nchars (ic->preedit),
3198 MPLIST_SYMBOL (args), ic->preedit);
3199 mplist_add (func_args, Minteger, (void *) code);
3202 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3204 val = (func) (func_args);
3205 M17N_OBJECT_UNREF (func_args);
3206 if (val && ! MPLIST_TAIL_P (val))
3207 ret = take_action_list (ic, val);
3208 M17N_OBJECT_UNREF (val);
3212 else if (name == Mshift)
3214 shift_state (ic, MPLIST_SYMBOL (args));
3216 else if (name == Mundo)
3218 int intarg = (MPLIST_TAIL_P (args)
3220 : integer_value (ic, args, NULL, 0));
3222 mtext_reset (ic->preedit);
3223 mtext_reset (ic_info->preedit_saved);
3224 mtext_reset (ic->produced);
3225 M17N_OBJECT_UNREF (ic_info->vars);
3226 ic_info->vars = mplist_copy (ic_info->vars_saved);
3227 ic->cursor_pos = ic_info->state_pos = 0;
3228 ic_info->state_key_head = ic_info->key_head
3229 = ic_info->commit_key_head = 0;
3231 shift_state (ic, Mnil);
3234 if (MPLIST_TAIL_P (args))
3239 ic_info->used += intarg;
3242 ic_info->used = intarg;
3245 else if (name == Mset || name == Madd || name == Msub
3246 || name == Mmul || name == Mdiv)
3248 MSymbol sym = MPLIST_SYMBOL (args);
3253 val1 = integer_value (ic, args, &value, 0);
3254 args = MPLIST_NEXT (args);
3255 val2 = resolve_expression (ic, args);
3257 val1 = val2, op = "=";
3258 else if (name == Madd)
3259 val1 += val2, op = "+=";
3260 else if (name == Msub)
3261 val1 -= val2, op = "-=";
3262 else if (name == Mmul)
3263 val1 *= val2, op = "*=";
3265 val1 /= val2, op = "/=";
3266 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3267 MSYMBOL_NAME (sym), op, val1, val1);
3269 mplist_set (value, Minteger, (void *) val1);
3271 else if (name == Mequal || name == Mless || name == Mgreater
3272 || name == Mless_equal || name == Mgreater_equal)
3275 MPlist *actions1, *actions2;
3278 val1 = resolve_expression (ic, args);
3279 args = MPLIST_NEXT (args);
3280 val2 = resolve_expression (ic, args);
3281 args = MPLIST_NEXT (args);
3282 actions1 = MPLIST_PLIST (args);
3283 args = MPLIST_NEXT (args);
3284 if (MPLIST_TAIL_P (args))
3287 actions2 = MPLIST_PLIST (args);
3288 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3289 if (name == Mequal ? val1 == val2
3290 : name == Mless ? val1 < val2
3291 : name == Mgreater ? val1 > val2
3292 : name == Mless_equal ? val1 <= val2
3295 MDEBUG_PRINT ("ok");
3296 ret = take_action_list (ic, actions1);
3300 MDEBUG_PRINT ("no");
3302 ret = take_action_list (ic, actions2);
3307 else if (name == Mcond)
3311 MPLIST_DO (args, args)
3316 if (! MPLIST_PLIST (args))
3318 cond = MPLIST_PLIST (args);
3319 if (resolve_expression (ic, cond) != 0)
3321 MDEBUG_PRINT1 ("(%dth)", idx);
3322 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3328 else if (name == Mcommit)
3330 preedit_commit (ic);
3332 else if (name == Munhandle)
3334 preedit_commit (ic);
3339 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3343 && (actions = mplist_get (im_info->macros, name)))
3345 if (take_action_list (ic, actions) < 0)
3351 if (ic->candidate_list)
3353 M17N_OBJECT_UNREF (ic->candidate_list);
3354 ic->candidate_list = NULL;
3356 if (ic->cursor_pos > 0
3357 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3360 ic->candidate_list = mtext_property_value (prop);
3361 M17N_OBJECT_REF (ic->candidate_list);
3363 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3365 ic->candidate_from = mtext_property_start (prop);
3366 ic->candidate_to = mtext_property_end (prop);
3369 if (candidate_list != ic->candidate_list)
3370 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3371 if (candidate_index != ic->candidate_index)
3372 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3373 if (candidate_show != ic->candidate_show)
3374 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3379 /* Handle the input key KEY in the current state and map specified in
3380 the input context IC. If KEY is handled correctly, return 0.
3381 Otherwise, return -1. */
3384 handle_key (MInputContext *ic)
3386 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3387 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3388 MIMMap *map = ic_info->map;
3389 MIMMap *submap = NULL;
3390 MSymbol key = ic_info->keys[ic_info->key_head];
3391 MSymbol alias = Mnil;
3394 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3395 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3399 submap = mplist_get (map->submaps, key);
3402 && (alias = msymbol_get (alias, M_key_alias))
3404 submap = mplist_get (map->submaps, alias);
3409 if (! alias || alias == key)
3410 MDEBUG_PRINT (" submap-found");
3412 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3413 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3414 ic->preedit_changed = 1;
3415 ic->cursor_pos = ic_info->state_pos;
3416 ic_info->key_head++;
3417 ic_info->map = map = submap;
3418 if (map->map_actions)
3420 MDEBUG_PRINT (" map-actions:");
3421 if (take_action_list (ic, map->map_actions) < 0)
3423 MDEBUG_PRINT ("\n");
3427 else if (map->submaps)
3429 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3431 MSymbol key = ic_info->keys[i];
3432 char *name = msymbol_name (key);
3434 if (! name[0] || ! name[1])
3435 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3439 /* If this is the terminal map or we have shifted to another
3440 state, perform branch actions (if any). */
3441 if (! map->submaps || map != ic_info->map)
3443 if (map->branch_actions)
3445 MDEBUG_PRINT (" branch-actions:");
3446 if (take_action_list (ic, map->branch_actions) < 0)
3448 MDEBUG_PRINT ("\n");
3452 /* If MAP is still not the root map, shift to the current
3454 if (ic_info->map != ic_info->state->map)
3455 shift_state (ic, ic_info->state->name);
3460 /* MAP can not handle KEY. */
3462 /* Perform branch actions if any. */
3463 if (map->branch_actions)
3465 MDEBUG_PRINT (" branch-actions:");
3466 if (take_action_list (ic, map->branch_actions) < 0)
3468 MDEBUG_PRINT ("\n");
3473 if (map == ic_info->map)
3475 /* The above branch actions didn't change the state. */
3477 /* If MAP is the root map of the initial state, and there
3478 still exist an unhandled key, it means that the current
3479 input method can not handle it. */
3480 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3481 && ic_info->key_head < ic_info->used)
3483 MDEBUG_PRINT (" unhandled\n");
3487 if (map != ic_info->state->map)
3489 /* MAP is not the root map. Shift to the root map of the
3491 shift_state (ic, ic_info->state->name);
3493 else if (! map->branch_actions)
3495 /* MAP is the root map without any default branch
3496 actions. Shift to the initial state. */
3497 shift_state (ic, Mnil);
3501 MDEBUG_PRINT ("\n");
3505 /* Initialize IC->ic_info. */
3508 init_ic_info (MInputContext *ic)
3510 MInputMethodInfo *im_info = ic->im->info;
3511 MInputContextInfo *ic_info = ic->info;
3514 MLIST_INIT1 (ic_info, keys, 8);;
3516 ic_info->markers = mplist ();
3518 ic_info->vars = mplist ();
3519 if (im_info->configured_vars)
3520 MPLIST_DO (plist, im_info->configured_vars)
3522 MPlist *pl = MPLIST_PLIST (plist);
3523 MSymbol name = MPLIST_SYMBOL (pl);
3525 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3526 if (MPLIST_KEY (pl) != Mt)
3528 MPlist *p = mplist ();
3530 mplist_push (ic_info->vars, Mplist, p);
3531 M17N_OBJECT_UNREF (p);
3532 mplist_add (p, Msymbol, name);
3533 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3536 ic_info->vars_saved = mplist_copy (ic_info->vars);
3538 if (im_info->externals)
3540 MPlist *func_args = mplist (), *plist;
3542 mplist_add (func_args, Mt, ic);
3543 MPLIST_DO (plist, im_info->externals)
3545 MIMExternalModule *external = MPLIST_VAL (plist);
3546 MIMExternalFunc func
3547 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3552 M17N_OBJECT_UNREF (func_args);
3555 ic_info->preedit_saved = mtext ();
3556 ic_info->tick = im_info->tick;
3559 /* Finalize IC->ic_info. */
3562 fini_ic_info (MInputContext *ic)
3564 MInputMethodInfo *im_info = ic->im->info;
3565 MInputContextInfo *ic_info = ic->info;
3567 if (im_info->externals)
3569 MPlist *func_args = mplist (), *plist;
3571 mplist_add (func_args, Mt, ic);
3572 MPLIST_DO (plist, im_info->externals)
3574 MIMExternalModule *external = MPLIST_VAL (plist);
3575 MIMExternalFunc func
3576 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3581 M17N_OBJECT_UNREF (func_args);
3584 MLIST_FREE1 (ic_info, keys);
3585 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3586 M17N_OBJECT_UNREF (ic_info->markers);
3587 M17N_OBJECT_UNREF (ic_info->vars);
3588 M17N_OBJECT_UNREF (ic_info->vars_saved);
3589 M17N_OBJECT_UNREF (ic_info->preceding_text);
3590 M17N_OBJECT_UNREF (ic_info->following_text);
3592 memset (ic_info, 0, sizeof (MInputContextInfo));
3596 re_init_ic (MInputContext *ic, int reload)
3598 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3599 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3600 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3602 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3603 preedit_changed = mtext_nchars (ic->preedit) > 0;
3604 cursor_pos_changed = ic->cursor_pos > 0;
3605 candidates_changed = 0;
3606 if (ic->candidate_list)
3608 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3609 M17N_OBJECT_UNREF (ic->candidate_list);
3610 ic->candidate_list = NULL;
3612 if (ic->candidate_show)
3614 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3615 ic->candidate_show = 0;
3617 if (ic->candidate_index > 0)
3619 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3620 ic->candidate_index = 0;
3621 ic->candidate_from = ic->candidate_to = 0;
3623 if (mtext_nchars (ic->produced) > 0)
3624 mtext_reset (ic->produced);
3625 if (mtext_nchars (ic->preedit) > 0)
3626 mtext_reset (ic->preedit);
3628 M17N_OBJECT_UNREF (ic->plist);
3629 ic->plist = mplist ();
3633 reload_im_info (im_info);
3635 shift_state (ic, Mnil);
3636 ic->status_changed = status_changed;
3637 ic->preedit_changed = preedit_changed;
3638 ic->cursor_pos_changed = cursor_pos_changed;
3639 ic->candidates_changed = candidates_changed;
3643 reset_ic (MInputContext *ic, MSymbol ignore)
3645 MDEBUG_PRINT ("\n [IM] reset\n");
3650 open_im (MInputMethod *im)
3652 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3655 MERROR (MERROR_IM, -1);
3662 close_im (MInputMethod *im)
3668 create_ic (MInputContext *ic)
3670 MInputContextInfo *ic_info;
3672 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3675 shift_state (ic, Mnil);
3680 destroy_ic (MInputContext *ic)
3687 check_reload (MInputContext *ic, MSymbol key)
3689 MInputMethodInfo *im_info = ic->im->info;
3690 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3694 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3698 MPLIST_DO (plist, plist)
3700 MSymbol this_key, alias;
3702 if (MPLIST_MTEXT_P (plist))
3704 MText *mt = MPLIST_MTEXT (plist);
3705 int c = mtext_ref_char (mt, 0);
3709 this_key = one_char_symbol[c];
3713 MPlist *pl = MPLIST_PLIST (plist);
3715 this_key = MPLIST_SYMBOL (pl);
3719 && (alias = msymbol_get (alias, M_key_alias))
3720 && alias != this_key);
3724 if (MPLIST_TAIL_P (plist))
3727 MDEBUG_PRINT ("\n [IM] reload");
3733 /** Handle the input key KEY in the current state and map of IC->info.
3734 If KEY is handled but no text is produced, return 0, otherwise
3740 filter (MInputContext *ic, MSymbol key, void *arg)
3742 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3743 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3746 if (check_reload (ic, key))
3749 if (! ic_info->state)
3751 ic_info->key_unhandled = 1;
3754 mtext_reset (ic->produced);
3755 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3756 M17N_OBJECT_UNREF (ic_info->preceding_text);
3757 M17N_OBJECT_UNREF (ic_info->following_text);
3758 ic_info->preceding_text = ic_info->following_text = NULL;
3759 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3760 ic_info->key_unhandled = 0;
3763 if (handle_key (ic) < 0)
3765 /* KEY was not handled. Delete it from the current key sequence. */
3766 if (ic_info->used > 0)
3768 memmove (ic_info->keys, ic_info->keys + 1,
3769 sizeof (int) * (ic_info->used - 1));
3771 if (ic_info->state_key_head > 0)
3772 ic_info->state_key_head--;
3773 if (ic_info->commit_key_head > 0)
3774 ic_info->commit_key_head--;
3776 /* This forces returning 1. */
3777 ic_info->key_unhandled = 1;
3783 reset_ic (ic, Mnil);
3784 ic_info->key_unhandled = 1;
3787 /* Break the loop if all keys were handled. */
3788 } while (ic_info->key_head < ic_info->used);
3790 /* If the current map is the root of the initial state, we should
3791 produce any preedit text in ic->produced. */
3792 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3793 preedit_commit (ic);
3795 if (mtext_nchars (ic->produced) > 0)
3797 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3799 if (mdebug__flag & mdebug_mask)
3801 MDEBUG_PRINT (" (produced");
3802 for (i = 0; i < mtext_nchars (ic->produced); i++)
3803 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3808 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3809 Mlanguage, ic->im->language);
3811 if (ic_info->commit_key_head > 0)
3813 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3814 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3815 ic_info->used -= ic_info->commit_key_head;
3816 ic_info->key_head -= ic_info->commit_key_head;
3817 ic_info->state_key_head -= ic_info->commit_key_head;
3818 ic_info->commit_key_head = 0;
3820 if (ic_info->key_unhandled)
3823 ic_info->key_head = ic_info->state_key_head
3824 = ic_info->commit_key_head = 0;
3827 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3831 /** Return 1 if the last event or key was not handled, otherwise
3834 There is no need of looking up because ic->produced should already
3835 contain the produced text (if any).
3840 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3842 mtext_cat (mt, ic->produced);
3843 mtext_reset (ic->produced);
3844 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3848 /* Input method command handler. */
3850 /* List of all (global and local) commands.
3851 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3852 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3853 Global commands are stored as (t (t COMMAND ...)) */
3856 /* Input method variable handler. */
3859 /* Support functions for mdebug_dump_im. */
3862 dump_im_map (MPlist *map_list, int indent)
3865 MSymbol key = MPLIST_KEY (map_list);
3866 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3868 prefix = (char *) alloca (indent + 1);
3869 memset (prefix, 32, indent);
3870 prefix[indent] = '\0';
3872 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3873 if (map->map_actions)
3874 mdebug_dump_plist (map->map_actions, indent + 2);
3877 MPLIST_DO (map_list, map->submaps)
3879 fprintf (stderr, "\n%s ", prefix);
3880 dump_im_map (map_list, indent + 2);
3883 if (map->branch_actions)
3885 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3886 mdebug_dump_plist (map->branch_actions, indent + 4);
3887 fprintf (stderr, ")");
3889 fprintf (stderr, ")");
3894 dump_im_state (MIMState *state, int indent)
3899 prefix = (char *) alloca (indent + 1);
3900 memset (prefix, 32, indent);
3901 prefix[indent] = '\0';
3903 fprintf (stderr, "(%s", msymbol_name (state->name));
3904 if (state->map->submaps)
3906 MPLIST_DO (map_list, state->map->submaps)
3908 fprintf (stderr, "\n%s ", prefix);
3909 dump_im_map (map_list, indent + 2);
3912 fprintf (stderr, ")");
3920 Minput_driver = msymbol ("input-driver");
3922 Minput_preedit_start = msymbol ("input-preedit-start");
3923 Minput_preedit_done = msymbol ("input-preedit-done");
3924 Minput_preedit_draw = msymbol ("input-preedit-draw");
3925 Minput_status_start = msymbol ("input-status-start");
3926 Minput_status_done = msymbol ("input-status-done");
3927 Minput_status_draw = msymbol ("input-status-draw");
3928 Minput_candidates_start = msymbol ("input-candidates-start");
3929 Minput_candidates_done = msymbol ("input-candidates-done");
3930 Minput_candidates_draw = msymbol ("input-candidates-draw");
3931 Minput_set_spot = msymbol ("input-set-spot");
3932 Minput_focus_move = msymbol ("input-focus-move");
3933 Minput_focus_in = msymbol ("input-focus-in");
3934 Minput_focus_out = msymbol ("input-focus-out");
3935 Minput_toggle = msymbol ("input-toggle");
3936 Minput_reset = msymbol ("input-reset");
3937 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3938 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3939 Mcustomized = msymbol ("customized");
3940 Mconfigured = msymbol ("configured");
3941 Minherited = msymbol ("inherited");
3943 minput_default_driver.open_im = open_im;
3944 minput_default_driver.close_im = close_im;
3945 minput_default_driver.create_ic = create_ic;
3946 minput_default_driver.destroy_ic = destroy_ic;
3947 minput_default_driver.filter = filter;
3948 minput_default_driver.lookup = lookup;
3949 minput_default_driver.callback_list = mplist ();
3950 mplist_put (minput_default_driver.callback_list, Minput_reset,
3952 minput_driver = &minput_default_driver;
3954 fully_initialized = 0;
3961 if (fully_initialized)
3963 free_im_list (im_info_list);
3965 free_im_list (im_custom_list);
3967 free_im_list (im_config_list);
3968 M17N_OBJECT_UNREF (load_im_info_keys);
3971 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3972 M17N_OBJECT_UNREF (minput_driver->callback_list);
3977 minput__char_to_key (int c)
3979 if (c < 0 || c >= 0x100)
3982 return one_char_symbol[c];
3986 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3991 /*** @addtogroup m17nInputMethod */
3996 @name Variables: Predefined symbols for callback commands.
3998 These are the predefined symbols that are used as the @c COMMAND
3999 argument of callback functions of an input method driver (see
4000 #MInputDriver::callback_list).
4002 Most of them do not require extra argument nor return any value;
4003 exceptions are these:
4005 Minput_get_surrounding_text: When a callback function assigned for
4006 this command is called, the first element of #MInputContext::plist
4007 has key #Minteger and the value specifies which portion of the
4008 surrounding text should be retrieved. If the value is positive,
4009 it specifies the number of characters following the current cursor
4010 position. If the value is negative, the absolute value specifies
4011 the number of characters preceding the current cursor position.
4012 If the value is zero, it means that the caller just wants to know
4013 if the surrounding text is currently supported or not.
4015 If the surrounding text is currently supported, the callback
4016 function must set the key of this element to #Mtext and the value
4017 to the retrieved M-text. The length of the M-text may be shorter
4018 than the requested number of characters, if the available text is
4019 not that long. The length can be zero in the worst case. Or, the
4020 length may be longer if an application thinks it is more efficient
4021 to return that length.
4023 If the surrounding text is not currently supported, the callback
4024 function should return without changing the first element of
4025 #MInputContext::plist.
4027 Minput_delete_surrounding_text: When a callback function assigned
4028 for this command is called, the first element of
4029 #MInputContext::plist has key #Minteger and the value specifies
4030 which portion of the surrounding text should be deleted in the
4031 same way as the case of Minput_get_surrounding_text. The callback
4032 function must delete the specified text. It should not alter
4033 #MInputContext::plist. */
4035 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4037 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4038 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4040 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4042 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4043 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4044 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4045 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4046 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4047 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4048 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4050 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4051 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4052 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4053 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4054 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4056 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4057 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4059 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4060 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4061 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4062 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4063 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4064 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4068 MSymbol Minput_preedit_start;
4069 MSymbol Minput_preedit_done;
4070 MSymbol Minput_preedit_draw;
4071 MSymbol Minput_status_start;
4072 MSymbol Minput_status_done;
4073 MSymbol Minput_status_draw;
4074 MSymbol Minput_candidates_start;
4075 MSymbol Minput_candidates_done;
4076 MSymbol Minput_candidates_draw;
4077 MSymbol Minput_set_spot;
4078 MSymbol Minput_toggle;
4079 MSymbol Minput_reset;
4080 MSymbol Minput_get_surrounding_text;
4081 MSymbol Minput_delete_surrounding_text;
4087 @name Variables: Predefined symbols for special input events.
4089 These are the predefined symbols that are used as the @c KEY
4090 argument of minput_filter (). */
4092 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4094 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4099 MSymbol Minput_focus_out;
4100 MSymbol Minput_focus_in;
4101 MSymbol Minput_focus_move;
4107 @name Variables: Predefined symbols used in input method information.
4109 These are the predefined symbols describing status of input method
4110 command and variable, and are used in a return value of
4111 minput_get_command () and minput_get_variable (). */
4113 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4115 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4116 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4120 MSymbol Mcustomized;
4121 MSymbol Mconfigured;
4127 @brief The default driver for internal input methods.
4129 The variable #minput_default_driver is the default driver for
4130 internal input methods.
4132 The member MInputDriver::open_im () searches the m17n database for
4133 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4134 $NAME\> and loads it.
4136 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4137 programmers responsibility to set it to a plist of proper callback
4138 functions. Otherwise, no feedback information (e.g. preedit text)
4139 can be shown to users.
4141 The macro M17N_INIT () sets the variable #minput_driver to the
4142 pointer to this driver so that all internal input methods use it.
4144 Therefore, unless @c minput_driver is set differently, the driver
4145 dependent arguments $ARG of the functions whose name begins with
4146 "minput_" are all ignored. */
4148 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4150 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4152 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4153 \< #Minput_method, $LANGUAGE, $NAME\>
4154 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4156 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4157 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4158 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4159 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4161 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4162 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4164 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4165 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4167 MInputDriver minput_default_driver;
4171 @brief The driver for internal input methods.
4173 The variable #minput_driver is a pointer to the input method
4174 driver that is used by internal input methods. The macro
4175 M17N_INIT () initializes it to a pointer to #minput_default_driver
4176 if <m17n<EM></EM>.h> is included. */
4178 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4180 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4181 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4182 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4183 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4185 MInputDriver *minput_driver;
4187 MSymbol Minput_driver;
4202 @brief Open an input method.
4204 The minput_open_im () function opens an input method whose
4205 language and name match $LANGUAGE and $NAME, and returns a pointer
4206 to the input method object newly allocated.
4208 This function at first decides a driver for the input method as
4211 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4212 #minput_driver is used.
4214 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4215 driver pointed to by the property value is used to open the input
4216 method. If $NAME has no such a property, @c NULL is returned.
4218 Then, the member MInputDriver::open_im () of the driver is
4221 $ARG is set in the member @c arg of the structure MInputMethod so
4222 that the driver can refer to it. */
4224 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4226 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4227 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4229 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4231 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4232 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4234 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4235 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4236 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4238 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4240 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4242 @latexonly \IPAlabel{minput_open} @endlatexonly
4247 minput_open_im (MSymbol language, MSymbol name, void *arg)
4250 MInputDriver *driver;
4254 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4255 msymbol_name (language), msymbol_name (name));
4257 driver = minput_driver;
4260 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4262 MERROR (MERROR_IM, NULL);
4265 MSTRUCT_CALLOC (im, MERROR_IM);
4266 im->language = language;
4269 im->driver = *driver;
4270 if ((*im->driver.open_im) (im) < 0)
4272 MDEBUG_PRINT (" failed\n");
4276 MDEBUG_PRINT (" ok\n");
4283 @brief Close an input method.
4285 The minput_close_im () function closes the input method $IM, which
4286 must have been created by minput_open_im (). */
4289 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4291 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4292 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4295 minput_close_im (MInputMethod *im)
4297 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4298 msymbol_name (im->name), msymbol_name (im->language));
4299 (*im->driver.close_im) (im);
4301 MDEBUG_PRINT (" done\n");
4307 @brief Create an input context.
4309 The minput_create_ic () function creates an input context object
4310 associated with input method $IM, and calls callback functions
4311 corresponding to #Minput_preedit_start, #Minput_status_start, and
4312 #Minput_status_draw in this order.
4315 If an input context is successfully created, minput_create_ic ()
4316 returns a pointer to it. Otherwise it returns @c NULL. */
4319 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4321 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4322 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4323 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4324 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4327 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4328 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4332 minput_create_ic (MInputMethod *im, void *arg)
4336 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4337 msymbol_name (im->name), msymbol_name (im->language));
4338 MSTRUCT_CALLOC (ic, MERROR_IM);
4341 ic->preedit = mtext ();
4342 ic->candidate_list = NULL;
4343 ic->produced = mtext ();
4344 ic->spot.x = ic->spot.y = 0;
4346 ic->plist = mplist ();
4347 if ((*im->driver.create_ic) (ic) < 0)
4349 MDEBUG_PRINT (" failed\n");
4350 M17N_OBJECT_UNREF (ic->preedit);
4351 M17N_OBJECT_UNREF (ic->produced);
4352 M17N_OBJECT_UNREF (ic->plist);
4357 if (im->driver.callback_list)
4359 minput_callback (ic, Minput_preedit_start);
4360 minput_callback (ic, Minput_status_start);
4361 minput_callback (ic, Minput_status_draw);
4364 MDEBUG_PRINT (" ok\n");
4371 @brief Destroy an input context.
4373 The minput_destroy_ic () function destroys the input context $IC,
4374 which must have been created by minput_create_ic (). It calls
4375 callback functions corresponding to #Minput_preedit_done,
4376 #Minput_status_done, and #Minput_candidates_done in this order. */
4379 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4381 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4382 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4383 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4384 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4385 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4389 minput_destroy_ic (MInputContext *ic)
4391 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4392 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4393 if (ic->im->driver.callback_list)
4395 minput_callback (ic, Minput_preedit_done);
4396 minput_callback (ic, Minput_status_done);
4397 minput_callback (ic, Minput_candidates_done);
4399 (*ic->im->driver.destroy_ic) (ic);
4400 M17N_OBJECT_UNREF (ic->preedit);
4401 M17N_OBJECT_UNREF (ic->produced);
4402 M17N_OBJECT_UNREF (ic->plist);
4403 MDEBUG_PRINT (" done\n");
4410 @brief Filter an input key.
4412 The minput_filter () function filters input key $KEY according to
4413 input context $IC, and calls callback functions corresponding to
4414 #Minput_preedit_draw, #Minput_status_draw, and
4415 #Minput_candidates_draw if the preedit text, the status, and the
4416 current candidate are changed respectively.
4418 To make the input method commit the current preedit text (if any)
4419 and shift to the initial state, call this function with #Mnil as
4422 To inform the input method about the focus-out event, call this
4423 function with #Minput_focus_out as $KEY.
4425 To inform the input method about the focus-in event, call this
4426 function with #Minput_focus_in as $KEY.
4428 To inform the input method about the focus-move event (i.e. input
4429 spot change within the same input context), call this function
4430 with #Minput_focus_move as $KEY.
4433 If $KEY is filtered out, this function returns 1. In that case,
4434 the caller should discard the key. Otherwise, it returns 0, and
4435 the caller should handle the key, for instance, by calling the
4436 function minput_lookup () with the same key. */
4439 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4441 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4442 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4443 #Minput_preedit_draw, #Minput_status_draw,
4444 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4447 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4448 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4449 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4450 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4452 @latexonly \IPAlabel{minput_filter} @endlatexonly
4456 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4463 if (ic->im->driver.callback_list
4464 && mtext_nchars (ic->preedit) > 0)
4465 minput_callback (ic, Minput_preedit_draw);
4467 ret = (*ic->im->driver.filter) (ic, key, arg);
4469 if (ic->im->driver.callback_list)
4471 if (ic->preedit_changed)
4472 minput_callback (ic, Minput_preedit_draw);
4473 if (ic->status_changed)
4474 minput_callback (ic, Minput_status_draw);
4475 if (ic->candidates_changed)
4476 minput_callback (ic, Minput_candidates_draw);
4485 @brief Look up a text produced in the input context.
4487 The minput_lookup () function looks up a text in the input context
4488 $IC. $KEY must be identical to the one that was used in the previous call of
4491 If a text was produced by the input method, it is concatenated
4494 This function calls #MInputDriver::lookup .
4497 If $KEY was correctly handled by the input method, this function
4498 returns 0. Otherwise, it returns -1, even though some text
4499 might be produced in $MT. */
4502 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4504 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4505 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4507 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4510 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4513 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4514 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4515 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4517 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4520 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4522 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4527 @brief Set the spot of the input context.
4529 The minput_set_spot () function sets the spot of input context $IC
4530 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4531 The semantics of these values depends on the input method driver.
4533 For instance, a driver designed to work in a CUI environment may
4534 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4535 $DESCENT . A driver designed to work in a window system may
4536 interpret $X and $Y as the pixel offsets relative to the origin of the
4537 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4538 descent pixels of the line at ($X . $Y ).
4540 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4542 $MT and $POS are the M-text and the character position at the spot.
4543 $MT may be @c NULL, in which case, the input method cannot get
4544 information about the text around the spot. */
4547 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4549 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4550 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4551 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4553 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4554 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4555 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4556 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4557 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4558 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4560 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4562 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4563 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4567 minput_set_spot (MInputContext *ic, int x, int y,
4568 int ascent, int descent, int fontsize,
4573 ic->spot.ascent = ascent;
4574 ic->spot.descent = descent;
4575 ic->spot.fontsize = fontsize;
4578 if (ic->im->driver.callback_list)
4579 minput_callback (ic, Minput_set_spot);
4584 @brief Toggle input method.
4586 The minput_toggle () function toggles the input method associated
4587 with input context $IC. */
4589 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4591 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4592 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4596 minput_toggle (MInputContext *ic)
4598 if (ic->im->driver.callback_list)
4599 minput_callback (ic, Minput_toggle);
4600 ic->active = ! ic->active;
4606 @brief Reset an input context.
4608 The minput_reset_ic () function resets input context $IC by
4609 calling a callback function corresponding to #Minput_reset. It
4610 resets the status of $IC to its initial one. As the
4611 current preedit text is deleted without commitment, if necessary,
4612 call minput_filter () with the arg @r key #Mnil to force the input
4613 method to commit the preedit in advance. */
4616 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4618 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4619 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4620 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4621 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4622 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4623 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4626 minput_reset_ic (MInputContext *ic)
4628 if (ic->im->driver.callback_list)
4629 minput_callback (ic, Minput_reset);
4635 @brief Get title and icon filename of an input method.
4637 The minput_get_title_icon () function returns a plist containing a
4638 title and icon filename (if any) of an input method specified by
4639 $LANGUAGE and $NAME.
4641 The first element of the plist has key #Mtext and the value is an
4642 M-text of the title for identifying the input method. The second
4643 element (if any) has key #Mtext and the value is an M-text of the
4644 icon image (absolute) filename for the same purpose.
4647 If there exists a specified input method and it defines an title,
4648 a plist is returned. Otherwise, NULL is returned. The caller
4649 must free the plist by m17n_object_unref (). */
4651 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4653 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4654 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4657 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4658 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4659 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4662 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4663 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4664 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4667 minput_get_title_icon (MSymbol language, MSymbol name)
4669 MInputMethodInfo *im_info;
4676 im_info = get_im_info (language, name, Mnil, Mtitle);
4677 if (! im_info || !im_info->title)
4679 mt = mtext_get_prop (im_info->title, 0, Mtext);
4681 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4684 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4687 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4688 (char *) MSYMBOL_NAME (name));
4689 file = mdatabase__find_file (buf);
4690 if (! file && language == Mt)
4692 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4693 file = mdatabase__find_file (buf);
4698 mplist_add (plist, Mtext, im_info->title);
4701 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4703 mplist_add (plist, Mtext, mt);
4704 M17N_OBJECT_UNREF (mt);
4712 @brief Get description text of an input method.
4714 The minput_get_description () function returns an M-text that
4715 describes the input method specified by $LANGUAGE and $NAME.
4718 If the specified input method has a description text, a pointer to
4719 #MText is returned. The caller has to free it by m17n_object_unref ().
4720 If the input method does not have a description text, @c NULL is
4723 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4725 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4726 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4728 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4729 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4730 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4731 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4734 minput_get_description (MSymbol language, MSymbol name)
4736 MInputMethodInfo *im_info;
4744 extra = language, language = Mt;
4746 im_info = get_im_info (language, name, extra, Mdescription);
4747 if (! im_info || ! im_info->description)
4749 M17N_OBJECT_REF (im_info->description);
4750 return im_info->description;
4756 @brief Get information about input method command(s).
4758 The minput_get_command () function returns information about
4759 the command $COMMAND of the input method specified by $LANGUAGE and
4760 $NAME. An input method command is a pseudo key event to which one
4761 or more actual input key sequences are assigned.
4763 There are two kinds of commands, global and local. A global
4764 command has a global definition, and the description and the key
4765 assignment may be inherited by a local command. Each input method
4766 defines a local command which has a local key assignment. It may
4767 also declare a local command that inherits the definition of a
4768 global command of the same name.
4770 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4771 information about a global command. Otherwise information about a
4772 local command is returned.
4774 If $COMMAND is #Mnil, information about all commands is returned.
4776 The return value is a @e well-formed plist (#m17nPlist) of this
4779 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4781 @c NAME is a symbol representing the command name.
4783 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4784 command has no description.
4786 @c STATUS is a symbol representing how the key assignment is decided.
4787 The value is #Mnil (the default key assignment), #Mcustomized (the
4788 key assignment is customized by per-user configuration file), or
4789 #Mconfigured (the key assignment is set by the call of
4790 minput_config_command ()). For a local command only, it may also
4791 be #Minherited (the key assignment is inherited from the
4792 corresponding global command).
4794 @c KEYSEQ is a plist of one or more symbols representing a key
4795 sequence assigned to the command. If there's no KEYSEQ, the
4796 command is currently disabled (i.e. no key sequence can trigger
4797 actions of the command).
4799 If $COMMAND is not #Mnil, the first element of the returned plist
4800 contains the information about $COMMAND.
4804 If the requested information was found, a pointer to a non-empty
4805 plist is returned. As the plist is kept in the library, the
4806 caller must not modify nor free it.
4808 Otherwise (the specified input method or the specified command
4809 does not exist), @c NULL is returned. */
4811 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4813 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4814 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4815 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4816 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4818 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4819 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4820 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4821 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4822 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4824 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4825 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4828 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4830 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4833 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4835 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4837 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4840 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4841 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4842 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4843 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4844 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4845 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4847 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4848 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4849 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4850 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4852 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4853 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4857 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4858 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4861 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4866 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4868 /* Return a description of the command COMMAND of the input method
4869 specified by LANGUAGE and NAME. */
4870 MPlist *cmd = minput_get_command (langauge, name, command);
4875 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4876 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4877 return (mplist_key (plist) == Mtext
4878 ? (MText *) mplist_value (plist)
4884 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4886 MInputMethodInfo *im_info;
4890 im_info = get_im_info (language, name, Mnil, Mcommand);
4892 || ! im_info->configured_cmds
4893 || MPLIST_TAIL_P (im_info->configured_cmds))
4895 if (command == Mnil)
4896 return im_info->configured_cmds;
4897 return mplist__assq (im_info->configured_cmds, command);
4903 @brief Configure the key sequence of an input method command.
4905 The minput_config_command () function assigns a list of key
4906 sequences $KEYSEQLIST to the command $COMMAND of the input method
4907 specified by $LANGUAGE and $NAME.
4909 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4910 sequences, and each key sequence must be a plist of symbols.
4912 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4914 If $KEYSEQLIST is NULL, the configuration of the command for the
4915 input method is canceled, and the default key sequences become
4916 effective. In such case, if $COMMAND is #Mnil, configurations for
4917 all commands of the input method are canceled.
4919 If $NAME is #Mnil, this function configures the key assignment of a
4920 global command, not that of a specific input method.
4922 The configuration takes effect for input methods opened or
4923 re-opened later in the current session. In order to make the
4924 configuration take effect for the future session, it must be saved
4925 in a per-user configuration file by the function
4926 minput_save_config ().
4930 If the operation was successful, this function returns 0,
4931 otherwise returns -1. The operation fails in these cases:
4933 <li>$KEYSEQLIST is not in a valid form.
4934 <li>$COMMAND is not available for the input method.
4935 <li>$LANGUAGE and $NAME do not specify an existing input method.
4939 minput_get_commands (), minput_save_config ().
4942 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4944 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4945 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4946 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4948 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4949 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4951 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4953 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4954 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4955 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4958 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4959 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4961 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4962 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4963 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4964 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4968 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4970 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4971 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4972 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4976 minput_get_commands (), minput_save_config ().
4980 /* Add "C-x u" to the "start" command of Unicode input method. */
4982 MSymbol start_command = msymbol ("start");
4983 MSymbol unicode = msymbol ("unicode");
4984 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4986 /* At first get the current key-sequence assignment. */
4987 cmd = mplist_get_command (Mt, unicode, start_command);
4990 /* The input method does not have the command "start". Here
4991 should come some error handling code. */
4993 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4994 the part (KEY-SEQUENCE ...). */
4995 plist = mplist_next (mplist_next (mplist_value (cmd)));
4996 /* Copy it because we should not modify it directly. */
4997 key_seq_list = mplist_copy (plist);
4998 m17n_object_unref (cmds);
5000 key_seq = mplist ();
5001 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
5002 mplist_add (key_seq, Msymbol, msymbol ("u"));
5003 mplist_add (key_seq_list, Mplist, key_seq);
5004 m17n_object_unref (key_seq);
5006 minput_config_command (Mt, unicode, start_command, key_seq_list);
5007 m17n_object_unref (key_seq_list);
5012 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
5015 MInputMethodInfo *im_info, *config;
5022 if (command == Mnil)
5023 MERROR (MERROR_IM, -1);
5024 MPLIST_DO (plist, keyseqlist)
5025 if (! MPLIST_PLIST_P (plist)
5026 || ! check_command_keyseq (plist))
5027 MERROR (MERROR_IM, -1);
5030 im_info = get_im_info (language, name, Mnil, Mcommand);
5032 MERROR (MERROR_IM, -1);
5035 || ! mplist__assq (im_info->cmds, command)))
5036 MERROR (MERROR_IM, -1);
5038 config = get_config_info (im_info);
5041 if (! im_config_list)
5042 im_config_list = mplist ();
5043 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5044 config->cmds = mplist ();
5045 config->vars = mplist ();
5048 if (command == Mnil)
5050 MInputMethodInfo *custom = get_custom_info (im_info);
5052 mplist_set (config->cmds, Mnil, NULL);
5053 if (custom && custom->cmds)
5055 MPLIST_DO (plist, custom->cmds)
5057 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5059 mplist_add (plist, Msymbol, command);
5060 mplist_push (config->cmds, Mplist, plist);
5061 M17N_OBJECT_UNREF (plist);
5067 plist = mplist__assq (config->cmds, command);
5070 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
5071 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
5072 if (! MPLIST_TAIL_P (plist))
5073 mplist_set (plist, Mnil, NULL); /* () */
5078 mplist_add (config->cmds, Mplist, plist);
5079 M17N_OBJECT_UNREF (plist);
5080 plist = mplist_add (plist, Msymbol, command);
5081 plist = MPLIST_NEXT (plist);
5087 plist = mplist_add (plist, Msymbol, Mnil);
5088 MPLIST_DO (keyseqlist, keyseqlist)
5090 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5091 plist = mplist_add (plist, Mplist, pl);
5092 M17N_OBJECT_UNREF (pl);
5096 config_all_commands (im_info);
5097 im_info->tick = time (NULL);
5104 @brief Get information about input method variable(s).
5106 The minput_get_variable () function returns information about
5107 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5108 An input method variable controls behavior of an input method.
5110 There are two kinds of variables, global and local. A global
5111 variable has a global definition, and the description and the value
5112 may be inherited by a local variable. Each input method defines a
5113 local variable which has local value. It may also declare a
5114 local variable that inherits definition of a global variable of
5117 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5118 variable is returned. Otherwise information about a local variable
5121 If $VARIABLE is #Mnil, information about all variables is
5124 The return value is a @e well-formed plist (#m17nPlist) of this
5127 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5129 @c NAME is a symbol representing the variable name.
5131 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5132 variable has no description.
5134 @c STATUS is a symbol representing how the value is decided. The
5135 value is #Mnil (the default value), #Mcustomized (the value is
5136 customized by per-user configuration file), or #Mconfigured (the
5137 value is set by the call of minput_config_variable ()). For a
5138 local variable only, it may also be #Minherited (the value is
5139 inherited from the corresponding global variable).
5141 @c VALUE is the initial value of the variable. If the key of this
5142 element is #Mt, the variable has no initial value. Otherwise, the
5143 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5146 @c VALID-VALUEs (if any) specify which values the variable can have.
5147 They have the same type (i.e. having the same key) as @c VALUE except
5148 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5149 may be a plist of two integers specifying the range of possible
5152 If there no @c VALID-VALUE, the variable can have any value as long
5153 as the type is the same as @c VALUE.
5155 If $VARIABLE is not #Mnil, the first element of the returned plist
5156 contains the information about $VARIABLE.
5160 If the requested information was found, a pointer to a non-empty
5161 plist is returned. As the plist is kept in the library, the
5162 caller must not modify nor free it.
5164 Otherwise (the specified input method or the specified variable
5165 does not exist), @c NULL is returned. */
5167 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5169 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5170 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5171 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5173 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5174 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5175 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5176 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5179 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5180 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5182 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5184 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5186 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5189 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5191 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5194 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5195 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5196 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5197 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5198 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5199 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5201 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5202 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5203 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5205 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5206 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5207 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5208 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5210 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5213 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5214 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5218 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5219 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5222 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5226 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5228 MInputMethodInfo *im_info;
5232 im_info = get_im_info (language, name, Mnil, Mvariable);
5233 if (! im_info || ! im_info->configured_vars)
5235 if (variable == Mnil)
5236 return im_info->configured_vars;
5237 return mplist__assq (im_info->configured_vars, variable);
5243 @brief Configure the value of an input method variable.
5245 The minput_config_variable () function assigns $VALUE to the
5246 variable $VARIABLE of the input method specified by $LANGUAGE and
5249 If $VALUE is not NULL, it must be a plist of one element whose key
5250 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5253 If $VALUE is NULL, a configuration for the variable for the input
5254 method is canceled, and the variable is initialized to the default
5255 value. In that case, if $VARIABLE is #Mnil, configurations for
5256 all variables of the input method are canceled.
5258 If $NAME is #Mnil, this function configure the value of global
5259 variable, not that of a specific input method.
5261 The configuration takes effect for input methods opened or
5262 re-opened later in the current session. To make the configuration
5263 take effect for the future session, it must be saved in a per-user
5264 configuration file by the function minput_save_config ().
5268 If the operation was successful, this function returns 0,
5269 otherwise returns -1. The operation fails in these cases:
5271 <li>$VALUE is not in a valid form, the type does not match the
5272 definition, or the value is our of range.
5273 <li>$VARIABLE is not available for the input method.
5274 <li>$LANGUAGE and $NAME do not specify an existing input method.
5278 minput_get_variable (), minput_save_config (). */
5280 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5282 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5283 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5285 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5286 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5288 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5289 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5290 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5292 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5293 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5295 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5296 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5297 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5298 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5302 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5304 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5305 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5306 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5310 minput_get_commands (), minput_save_config ().
5313 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5316 MInputMethodInfo *im_info, *config;
5321 im_info = get_im_info (language, name, Mnil, Mvariable);
5323 MERROR (MERROR_IM, -1);
5324 if (variable == Mnil)
5327 MERROR (MERROR_IM, -1);
5329 else if (! im_info->vars
5330 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5331 MERROR (MERROR_IM, -1);
5333 if (variable != Mnil && value)
5335 plist = MPLIST_PLIST (plist);
5336 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5337 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5338 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5339 if (MPLIST_KEY (plist) != Mt
5340 && ! check_variable_value (value, plist))
5341 MERROR (MERROR_IM, -1);
5344 config = get_config_info (im_info);
5347 if (! im_config_list)
5348 im_config_list = mplist ();
5349 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5350 config->cmds = mplist ();
5351 config->vars = mplist ();
5354 if (variable == Mnil)
5356 MInputMethodInfo *custom = get_custom_info (im_info);
5358 mplist_set (config->vars, Mnil, NULL);
5359 if (custom && custom->vars)
5361 MPLIST_DO (plist, custom->vars)
5363 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5365 mplist_add (plist, Msymbol, variable);
5366 mplist_push (config->vars, Mplist, plist);
5367 M17N_OBJECT_UNREF (plist);
5373 plist = mplist__assq (config->vars, variable);
5376 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5377 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5378 if (! MPLIST_TAIL_P (plist))
5379 mplist_set (plist, Mnil ,NULL); /* () */
5384 mplist_add (config->vars, Mplist, plist);
5385 M17N_OBJECT_UNREF (plist);
5386 plist = mplist_add (plist, Msymbol, variable);
5387 plist = MPLIST_NEXT (plist);
5391 plist = mplist_add (plist, Msymbol, Mnil);
5392 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5395 config_all_variables (im_info);
5396 im_info->tick = time (NULL);
5403 @brief Get the name of per-user configuration file.
5405 The minput_config_file () function returns the absolute path name
5406 of per-user configuration file into which minput_save_config ()
5407 save configurations. It is usually @c "config.mic" under the
5408 directory @c ".m17n.d" of user's home directory. It is not assured
5409 that the file of the returned name exists nor is
5410 readable/writable. If minput_save_config () fails and returns -1,
5411 an application program might check the file, make it
5412 writable (if possible), and try minput_save_config () again.
5416 This function returns a string. As the string is kept in the
5417 library, the caller must not modify nor free it.
5420 minput_save_config ()
5423 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5425 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5426 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5427 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5428 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5429 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5430 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5431 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5436 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5437 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5440 minput_save_config ()
5444 minput_config_file ()
5448 return mdatabase__file (im_custom_mdb);
5454 @brief Save configurations in per-user configuration file.
5456 The minput_save_config () function saves the configurations done
5457 so far in the current session into the per-user configuration
5462 If the operation was successful, 1 is returned. If the per-user
5463 configuration file is currently locked, 0 is returned. In that
5464 case, the caller may wait for a while and try again. If the
5465 configuration file is not writable, -1 is returned. In that case,
5466 the caller may check the name of the file by calling
5467 minput_config_file (), make it writable if possible, and try
5471 minput_config_file () */
5473 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5475 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5476 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5480 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5481 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5482 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5483 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5487 minput_config_file () */
5490 minput_save_config (void)
5492 MPlist *data, *tail, *plist, *p, *elt;
5496 ret = mdatabase__lock (im_custom_mdb);
5499 if (! im_config_list)
5501 update_custom_info ();
5502 if (! im_custom_list)
5503 im_custom_list = mplist ();
5504 data = tail = mplist ();
5506 MPLIST_DO (plist, im_config_list)
5508 MPlist *pl = MPLIST_PLIST (plist);
5509 MSymbol language, name, extra, command, variable;
5510 MInputMethodInfo *custom, *config;
5512 language = MPLIST_SYMBOL (pl);
5513 pl = MPLIST_NEXT (pl);
5514 name = MPLIST_SYMBOL (pl);
5515 pl = MPLIST_NEXT (pl);
5516 extra = MPLIST_SYMBOL (pl);
5517 pl = MPLIST_NEXT (pl);
5518 config = MPLIST_VAL (pl);
5519 custom = get_custom_info (config);
5521 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5523 MPLIST_DO (pl, config->cmds)
5525 elt = MPLIST_PLIST (pl);
5526 command = MPLIST_SYMBOL (elt);
5528 p = mplist__assq (custom->cmds, command);
5530 custom->cmds = mplist (), p = NULL;
5531 elt = MPLIST_NEXT (elt);
5532 if (MPLIST_TAIL_P (elt))
5535 mplist__pop_unref (p);
5539 elt = MPLIST_NEXT (elt);
5542 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5543 mplist_set (p, Mnil, NULL);
5544 mplist__conc (p, elt);
5548 p = MPLIST_PLIST (pl);
5549 mplist_add (custom->cmds, Mplist, p);
5554 MPLIST_DO (pl, config->vars)
5556 elt = MPLIST_PLIST (pl);
5557 variable = MPLIST_SYMBOL (elt);
5559 p = mplist__assq (custom->vars, variable);
5561 custom->vars = mplist (), p = NULL;
5562 elt = MPLIST_NEXT (elt);
5563 if (MPLIST_TAIL_P (elt))
5566 mplist__pop_unref (p);
5570 elt = MPLIST_NEXT (elt);
5573 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5574 mplist_set (p, Mnil, NULL);
5575 mplist__conc (p, elt);
5579 p = MPLIST_PLIST (pl);
5580 mplist_add (custom->vars, Mplist, p);
5585 M17N_OBJECT_UNREF (im_config_list);
5587 MPLIST_DO (plist, im_custom_list)
5589 MPlist *pl = MPLIST_PLIST (plist);
5590 MSymbol language, name, extra;
5591 MInputMethodInfo *custom, *im_info;
5593 language = MPLIST_SYMBOL (pl);
5594 pl = MPLIST_NEXT (pl);
5595 name = MPLIST_SYMBOL (pl);
5596 pl = MPLIST_NEXT (pl);
5597 extra = MPLIST_SYMBOL (pl);
5598 pl = MPLIST_NEXT (pl);
5599 custom = MPLIST_VAL (pl);
5600 im_info = lookup_im_info (im_info_list, language, name, extra);
5604 config_all_commands (im_info);
5606 config_all_variables (im_info);
5610 tail = mplist_add (tail, Mplist, elt);
5611 M17N_OBJECT_UNREF (elt);
5613 elt = mplist_add (elt, Mplist, pl);
5614 M17N_OBJECT_UNREF (pl);
5615 pl = mplist_add (pl, Msymbol, Minput_method);
5616 pl = mplist_add (pl, Msymbol, language);
5617 pl = mplist_add (pl, Msymbol, name);
5619 pl = mplist_add (pl, Msymbol, extra);
5620 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5623 elt = mplist_add (elt, Mplist, pl);
5624 M17N_OBJECT_UNREF (pl);
5625 pl = mplist_add (pl, Msymbol, Mcommand);
5626 MPLIST_DO (p, custom->cmds)
5627 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5629 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5632 elt = mplist_add (elt, Mplist, pl);
5633 M17N_OBJECT_UNREF (pl);
5634 pl = mplist_add (pl, Msymbol, Mvariable);
5635 MPLIST_DO (p, custom->vars)
5636 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5640 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5641 ret = mdatabase__save (im_custom_mdb, data);
5642 mdatabase__unlock (im_custom_mdb);
5643 M17N_OBJECT_UNREF (data);
5644 return (ret < 0 ? -1 : 1);
5651 @name Obsolete functions
5654 @name Obsolete ¤Ê´Ø¿ô
5660 @brief Get a list of variables of an input method (obsolete).
5662 This function is obsolete. Use minput_get_variable () instead.
5664 The minput_get_variables () function returns a plist (#MPlist) of
5665 variables used to control the behavior of the input method
5666 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5667 (#m17nPlist) of the following format:
5670 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5671 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5675 @c VARNAME is a symbol representing the variable name.
5677 @c DOC-MTEXT is an M-text describing the variable.
5679 @c DEFAULT-VALUE is the default value of the variable. It is a
5680 symbol, integer, or M-text.
5682 @c VALUEs (if any) specifies the possible values of the variable.
5683 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5684 @c TO), where @c FROM and @c TO specifies a range of possible
5687 For instance, suppose an input method has the variables:
5689 @li name:intvar, description:"value is an integer",
5690 initial value:0, value-range:0..3,10,20
5692 @li name:symvar, description:"value is a symbol",
5693 initial value:nil, value-range:a, b, c, nil
5695 @li name:txtvar, description:"value is an M-text",
5696 initial value:empty text, no value-range (i.e. any text)
5698 Then, the returned plist is as follows.
5701 (intvar ("value is an integer" 0 (0 3) 10 20)
5702 symvar ("value is a symbol" nil a b c nil)
5703 txtvar ("value is an M-text" ""))
5707 If the input method uses any variables, a pointer to #MPlist is
5708 returned. As the plist is kept in the library, the caller must not
5709 modify nor free it. If the input method does not use any
5710 variable, @c NULL is returned. */
5712 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5714 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5715 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5716 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5720 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5721 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5725 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5727 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5729 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5732 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5733 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5734 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5736 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5738 @li name:intvar, ÀâÌÀ:"value is an integer",
5739 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5741 @li name:symvar, ÀâÌÀ:"value is a symbol",
5742 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5744 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5745 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5747 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5750 (intvar ("value is an integer" 0 (0 3) 10 20)
5751 symvar ("value is a symbol" nil a b c nil)
5752 txtvar ("value is an M-text" ""))
5756 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5757 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5758 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5761 minput_get_variables (MSymbol language, MSymbol name)
5763 MInputMethodInfo *im_info;
5768 im_info = get_im_info (language, name, Mnil, Mvariable);
5769 if (! im_info || ! im_info->configured_vars)
5772 M17N_OBJECT_UNREF (im_info->bc_vars);
5773 im_info->bc_vars = mplist ();
5774 MPLIST_DO (vars, im_info->configured_vars)
5776 MPlist *plist = MPLIST_PLIST (vars);
5777 MPlist *elt = mplist ();
5779 mplist_push (im_info->bc_vars, Mplist, elt);
5780 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5781 elt = MPLIST_NEXT (elt);
5782 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5783 M17N_OBJECT_UNREF (elt);
5785 return im_info->bc_vars;
5791 @brief Set the initial value of an input method variable.
5793 The minput_set_variable () function sets the initial value of
5794 input method variable $VARIABLE to $VALUE for the input method
5795 specified by $LANGUAGE and $NAME.
5797 By default, the initial value is 0.
5799 This setting gets effective in a newly opened input method.
5802 If the operation was successful, 0 is returned. Otherwise -1 is
5803 returned, and #merror_code is set to #MERROR_IM. */
5805 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5807 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5808 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5809 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5811 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5813 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5816 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5817 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5820 minput_set_variable (MSymbol language, MSymbol name,
5821 MSymbol variable, void *value)
5824 MInputMethodInfo *im_info;
5829 if (variable == Mnil)
5830 MERROR (MERROR_IM, -1);
5831 plist = minput_get_variable (language, name, variable);
5832 plist = MPLIST_PLIST (plist);
5833 plist = MPLIST_NEXT (plist);
5835 mplist_add (pl, MPLIST_KEY (plist), value);
5836 ret = minput_config_variable (language, name, variable, pl);
5837 M17N_OBJECT_UNREF (pl);
5840 im_info = get_im_info (language, name, Mnil, Mvariable);
5849 @brief Get information about input method commands.
5851 The minput_get_commands () function returns information about
5852 input method commands of the input method specified by $LANGUAGE
5853 and $NAME. An input method command is a pseudo key event to which
5854 one or more actual input key sequences are assigned.
5856 There are two kinds of commands, global and local. Global
5857 commands are used by multiple input methods for the same purpose,
5858 and have global key assignments. Local commands are used only by
5859 a specific input method, and have only local key assignments.
5861 Each input method may locally change key assignments for global
5862 commands. The global key assignment for a global command is
5863 effective only when the current input method does not have local
5864 key assignments for that command.
5866 If $NAME is #Mnil, information about global commands is returned.
5867 In this case $LANGUAGE is ignored.
5869 If $NAME is not #Mnil, information about those commands that have
5870 local key assignments in the input method specified by $LANGUAGE
5871 and $NAME is returned.
5874 If no input method commands are found, this function returns @c NULL.
5876 Otherwise, a pointer to a plist is returned. The key of each
5877 element in the plist is a symbol representing a command, and the
5878 value is a plist of the form COMMAND-INFO described below.
5880 The first element of COMMAND-INFO has the key #Mtext, and the
5881 value is an M-text describing the command.
5883 If there are no more elements, that means no key sequences are
5884 assigned to the command. Otherwise, each of the remaining
5885 elements has the key #Mplist, and the value is a plist whose keys are
5886 #Msymbol and values are symbols representing input keys, which are
5887 currently assigned to the command.
5889 As the returned plist is kept in the library, the caller must not
5890 modify nor free it. */
5892 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5894 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5895 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5896 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5897 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5899 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5900 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5901 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5902 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5904 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5905 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5906 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5909 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5910 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5912 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5913 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5917 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5919 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5920 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5921 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5923 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5924 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5925 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5928 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5929 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5930 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5931 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5932 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5934 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5935 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5938 minput_get_commands (MSymbol language, MSymbol name)
5940 MInputMethodInfo *im_info;
5945 im_info = get_im_info (language, name, Mnil, Mcommand);
5946 if (! im_info || ! im_info->configured_vars)
5948 M17N_OBJECT_UNREF (im_info->bc_cmds);
5949 im_info->bc_cmds = mplist ();
5950 MPLIST_DO (cmds, im_info->configured_cmds)
5952 MPlist *plist = MPLIST_PLIST (cmds);
5953 MPlist *elt = mplist ();
5955 mplist_push (im_info->bc_cmds, Mplist, elt);
5956 mplist_add (elt, MPLIST_SYMBOL (plist),
5957 mplist_copy (MPLIST_NEXT (plist)));
5958 M17N_OBJECT_UNREF (elt);
5960 return im_info->bc_cmds;
5966 @brief Assign a key sequence to an input method command (obsolete).
5968 This function is obsolete. Use minput_config_command () instead.
5970 The minput_assign_command_keys () function assigns input key
5971 sequence $KEYSEQ to input method command $COMMAND for the input
5972 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5973 key sequence is assigned globally no matter what $LANGUAGE is.
5974 Otherwise the key sequence is assigned locally.
5976 Each element of $KEYSEQ must have the key $Msymbol and the value
5977 must be a symbol representing an input key.
5979 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5980 globally or locally.
5982 This assignment gets effective in a newly opened input method.
5985 If the operation was successful, 0 is returned. Otherwise -1 is
5986 returned, and #merror_code is set to #MERROR_IM. */
5988 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5990 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5991 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5992 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5993 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5994 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5996 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5997 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5999 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
6000 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
6002 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
6005 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
6006 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
6009 minput_assign_command_keys (MSymbol language, MSymbol name,
6010 MSymbol command, MPlist *keyseq)
6016 if (command == Mnil)
6017 MERROR (MERROR_IM, -1);
6022 if (! check_command_keyseq (keyseq))
6023 MERROR (MERROR_IM, -1);
6025 mplist_add (plist, Mplist, keyseq);
6030 ret = minput_config_command (language, name, command, keyseq);
6031 M17N_OBJECT_UNREF (keyseq);
6038 @brief Call a callback function
6040 The minput_callback () functions calls a callback function
6041 $COMMAND assigned for the input context $IC. The caller must set
6042 specific elements in $IC->plist if the callback function requires.
6045 If there exists a specified callback function, 0 is returned.
6046 Otherwise -1 is returned. By side effects, $IC->plist may be
6050 minput_callback (MInputContext *ic, MSymbol command)
6052 MInputCallbackFunc func;
6054 if (! ic->im->driver.callback_list)
6056 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
6060 (func) (ic, command);
6067 /*** @addtogroup m17nDebug */
6073 @brief Dump an input method.
6075 The mdebug_dump_im () function prints the input method $IM in a
6076 human readable way to the stderr. $INDENT specifies how many
6077 columns to indent the lines but the first one.
6080 This function returns $IM. */
6082 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6084 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6085 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6088 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6091 mdebug_dump_im (MInputMethod *im, int indent)
6093 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6096 prefix = (char *) alloca (indent + 1);
6097 memset (prefix, 32, indent);
6098 prefix[indent] = '\0';
6100 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6101 msymbol_name (im->name));
6102 mdebug_dump_mtext (im_info->title, 0, 0);
6103 if (im->name != Mnil)
6107 MPLIST_DO (state, im_info->states)
6109 fprintf (stderr, "\n%s ", prefix);
6110 dump_im_state (MPLIST_VAL (state), indent + 2);
6113 fprintf (stderr, ")");