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;
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 Mundo = msymbol ("undo");
406 Mcall = msymbol ("call");
407 Mshift = msymbol ("shift");
408 Mselect = msymbol ("select");
409 Mshow = msymbol ("show");
410 Mhide = msymbol ("hide");
411 Mcommit = msymbol ("commit");
412 Munhandle = msymbol ("unhandle");
413 Mset = msymbol ("set");
414 Madd = msymbol ("add");
415 Msub = msymbol ("sub");
416 Mmul = msymbol ("mul");
417 Mdiv = msymbol ("div");
418 Mequal = msymbol ("=");
419 Mless = msymbol ("<");
420 Mgreater = msymbol (">");
421 Mless_equal = msymbol ("<=");
422 Mgreater_equal = msymbol (">=");
423 Mcond = msymbol ("cond");
424 Mplus = msymbol ("+");
425 Mminus = msymbol ("-");
426 Mstar = msymbol ("*");
427 Mslash = msymbol ("/");
428 Mand = msymbol ("&");
430 Mnot = msymbol ("!");
432 Mat_reload = msymbol ("@reload");
434 Mcandidates_group_size = msymbol ("candidates-group-size");
435 Mcandidates_charset = msymbol ("candidates-charset");
437 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
438 Mcandidate_index = msymbol (" candidate-index");
440 Minit = msymbol ("init");
441 Mfini = msymbol ("fini");
443 Mdescription = msymbol ("description");
444 Mcommand = msymbol ("command");
445 Mvariable = msymbol ("variable");
446 Mglobal = msymbol ("global");
447 Mconfig = msymbol ("config");
448 M_gettext = msymbol ("_");
450 load_im_info_keys = mplist ();
451 mplist_add (load_im_info_keys, Mstate, Mnil);
452 mplist_push (load_im_info_keys, Mmap, Mnil);
454 im_info_list = mplist ();
455 im_config_list = im_custom_list = NULL;
456 im_custom_mdb = NULL;
457 update_custom_info ();
459 update_global_info ();
461 fully_initialized = 1;
464 #define MINPUT__INIT() \
466 if (! fully_initialized) \
467 fully_initialize (); \
472 marker_code (MSymbol sym, int surrounding)
478 name = MSYMBOL_NAME (sym);
479 return (name[0] != '@' ? -1
480 : (((name[1] >= '0' && name[1] <= '9')
481 || name[1] == '<' || name[1] == '>' || name[1] == '='
482 || name[1] == '[' || name[1] == ']'
484 && name[2] == '\0') ? name[1]
485 : (name[1] != '+' && name[1] != '-') ? -1
486 : (name[2] == '\0' || surrounding) ? name[1]
492 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
494 MPlist *plist = mplist__assq (ic_info->vars, var);
498 plist = MPLIST_PLIST (plist);
499 return MPLIST_NEXT (plist);
503 mplist_push (ic_info->vars, Mplist, plist);
504 M17N_OBJECT_UNREF (plist);
505 plist = mplist_add (plist, Msymbol, var);
506 plist = mplist_add (plist, Minteger, (void *) 0);
511 get_surrounding_text (MInputContext *ic, int len)
515 mplist_push (ic->plist, Minteger, (void *) len);
516 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
517 && MPLIST_MTEXT_P (ic->plist))
518 mt = MPLIST_MTEXT (ic->plist);
519 mplist_pop (ic->plist);
524 delete_surrounding_text (MInputContext *ic, int pos)
526 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
528 mplist_push (ic->plist, Minteger, (void *) pos);
529 minput_callback (ic, Minput_delete_surrounding_text);
530 mplist_pop (ic->plist);
533 M17N_OBJECT_UNREF (ic_info->preceding_text);
534 ic_info->preceding_text = NULL;
538 M17N_OBJECT_UNREF (ic_info->following_text);
539 ic_info->following_text = NULL;
544 get_preceding_char (MInputContext *ic, int pos)
546 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
550 if (pos && ic_info->preceding_text)
552 len = mtext_nchars (ic_info->preceding_text);
554 return mtext_ref_char (ic_info->preceding_text, len - pos);
555 if (ic->produced && mtext_len (ic->produced) >= pos - len)
556 return mtext_ref_char (ic->produced, len + mtext_len (ic->produced) - pos);
558 mt = get_surrounding_text (ic, - pos);
561 len = mtext_nchars (mt);
562 if (ic_info->preceding_text)
564 if (mtext_nchars (ic_info->preceding_text) < len)
566 M17N_OBJECT_UNREF (ic_info->preceding_text);
567 ic_info->preceding_text = mt;
571 ic_info->preceding_text = mt;
574 return mtext_ref_char (ic_info->preceding_text, len - pos);
578 get_following_char (MInputContext *ic, int pos)
580 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
584 if (ic_info->following_text)
586 len = mtext_nchars (ic_info->following_text);
588 return mtext_ref_char (ic_info->following_text, pos - 1);
590 mt = get_surrounding_text (ic, pos);
593 len = mtext_nchars (mt);
594 if (ic_info->following_text)
596 if (mtext_nchars (ic_info->following_text) < len)
598 M17N_OBJECT_UNREF (ic_info->following_text);
599 ic_info->following_text = mt;
603 ic_info->following_text = mt;
606 return mtext_ref_char (ic_info->following_text, pos - 1);
610 surrounding_pos (MSymbol sym)
616 name = MSYMBOL_NAME (sym);
618 && (name[1] == '-' || name[1] == '+')
619 && name[2] >= '1' && name[2] <= '9')
620 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
625 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
627 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
629 MText *preedit = ic->preedit;
630 int len = mtext_nchars (preedit);
634 if (MPLIST_INTEGER_P (arg))
635 return MPLIST_INTEGER (arg);
637 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
640 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
644 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
647 return ic_info->key_head;
648 if ((code == '-' || code == '+'))
650 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
654 pos = atoi (name + 1);
656 return get_preceding_char (ic, 0);
657 pos = ic->cursor_pos + pos;
659 return get_preceding_char (ic, - pos);
661 return get_following_char (ic, pos - len + 1);
664 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
666 else if (code >= '0' && code <= '9')
668 else if (code == '=')
669 pos = ic->cursor_pos;
670 else if (code == '[')
671 pos = ic->cursor_pos - 1;
672 else if (code == ']')
673 pos = ic->cursor_pos + 1;
674 else if (code == '<')
676 else if (code == '>')
678 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
682 parse_expression (MPlist *plist)
686 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
688 if (! MPLIST_PLIST_P (plist))
690 plist = MPLIST_PLIST (plist);
691 op = MPLIST_SYMBOL (plist);
692 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
693 && op != Mand && op != Mor && op != Mnot
694 && op != Mless && op != Mgreater && op != Mequal
695 && op != Mless_equal && op != Mgreater_equal)
696 MERROR (MERROR_IM, -1);
697 MPLIST_DO (plist, MPLIST_NEXT (plist))
698 if (parse_expression (plist) < 0)
704 resolve_expression (MInputContext *ic, MPlist *plist)
709 if (MPLIST_INTEGER_P (plist))
710 return MPLIST_INTEGER (plist);
711 if (MPLIST_SYMBOL_P (plist))
712 return integer_value (ic, plist, NULL, 1);
713 if (! MPLIST_PLIST_P (plist))
715 plist = MPLIST_PLIST (plist);
716 if (! MPLIST_SYMBOL_P (plist))
718 op = MPLIST_SYMBOL (plist);
719 plist = MPLIST_NEXT (plist);
720 val = resolve_expression (ic, plist);
722 MPLIST_DO (plist, MPLIST_NEXT (plist))
723 val += resolve_expression (ic, plist);
724 else if (op == Mminus)
725 MPLIST_DO (plist, MPLIST_NEXT (plist))
726 val -= resolve_expression (ic, plist);
727 else if (op == Mstar)
728 MPLIST_DO (plist, MPLIST_NEXT (plist))
729 val *= resolve_expression (ic, plist);
730 else if (op == Mslash)
731 MPLIST_DO (plist, MPLIST_NEXT (plist))
732 val /= resolve_expression (ic, plist);
734 MPLIST_DO (plist, MPLIST_NEXT (plist))
735 val &= resolve_expression (ic, plist);
737 MPLIST_DO (plist, MPLIST_NEXT (plist))
738 val |= resolve_expression (ic, plist);
741 else if (op == Mless)
742 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
743 else if (op == Mequal)
744 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
745 else if (op == Mgreater)
746 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
747 else if (op == Mless_equal)
748 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
749 else if (op == Mgreater_equal)
750 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
754 /* Parse PLIST as an action list. PLIST should have this form:
755 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
756 Return 0 if successfully parsed, otherwise return -1. */
759 parse_action_list (MPlist *plist, MPlist *macros)
761 MPLIST_DO (plist, plist)
763 if (MPLIST_MTEXT_P (plist))
765 /* This is a short form of (insert MTEXT). */
766 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
767 MERROR (MERROR_IM, -1); */
769 else if (MPLIST_PLIST_P (plist)
770 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
771 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
775 /* This is a short form of (insert (GROUPS *)). */
776 MPLIST_DO (pl, MPLIST_PLIST (plist))
778 if (MPLIST_PLIST_P (pl))
782 MPLIST_DO (elt, MPLIST_PLIST (pl))
783 if (! MPLIST_MTEXT_P (elt)
784 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
785 MERROR (MERROR_IM, -1);
789 if (! MPLIST_MTEXT_P (pl)
790 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
791 MERROR (MERROR_IM, -1);
795 else if (MPLIST_INTEGER_P (plist))
797 int c = MPLIST_INTEGER (plist);
799 if (c < 0 || c > MCHAR_MAX)
800 MERROR (MERROR_IM, -1);
802 else if (MPLIST_PLIST_P (plist)
803 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
805 MPlist *pl = MPLIST_PLIST (plist);
806 MSymbol action_name = MPLIST_SYMBOL (pl);
808 pl = MPLIST_NEXT (pl);
810 if (action_name == Minsert)
812 if (MPLIST_MTEXT_P (pl))
814 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
815 MERROR (MERROR_IM, -1);
817 else if (MPLIST_PLIST_P (pl))
821 if (MPLIST_PLIST_P (pl))
825 MPLIST_DO (elt, MPLIST_PLIST (pl))
826 if (! MPLIST_MTEXT_P (elt)
827 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
828 MERROR (MERROR_IM, -1);
832 if (! MPLIST_MTEXT_P (pl)
833 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
834 MERROR (MERROR_IM, -1);
838 else if (! MPLIST_SYMBOL_P (pl))
839 MERROR (MERROR_IM, -1);
841 else if (action_name == Mselect
842 || action_name == Mdelete
843 || action_name == Mmove)
845 if (parse_expression (pl) < 0)
848 else if (action_name == Mmark
849 || action_name == Mcall
850 || action_name == Mshift)
852 if (! MPLIST_SYMBOL_P (pl))
853 MERROR (MERROR_IM, -1);
855 else if (action_name == Mundo)
857 if (! MPLIST_TAIL_P (pl))
859 if (! MPLIST_SYMBOL_P (pl)
860 && ! MPLIST_INTEGER_P (pl))
861 MERROR (MERROR_IM, -1);
864 else if (action_name == Mpushback)
866 if (MPLIST_MTEXT_P (pl))
868 MText *mt = MPLIST_MTEXT (pl);
870 if (mtext_nchars (mt) != mtext_nbytes (mt))
871 MERROR (MERROR_IM, -1);
873 else if (MPLIST_PLIST_P (pl))
877 MPLIST_DO (p, MPLIST_PLIST (pl))
878 if (! MPLIST_SYMBOL_P (p))
879 MERROR (MERROR_IM, -1);
881 else if (! MPLIST_INTEGER_P (pl))
882 MERROR (MERROR_IM, -1);
884 else if (action_name == Mset || action_name == Madd
885 || action_name == Msub || action_name == Mmul
886 || action_name == Mdiv)
888 if (! MPLIST_SYMBOL_P (pl))
889 MERROR (MERROR_IM, -1);
890 if (parse_expression (MPLIST_NEXT (pl)) < 0)
893 else if (action_name == Mequal || action_name == Mless
894 || action_name == Mgreater || action_name == Mless_equal
895 || action_name == Mgreater_equal)
897 if (parse_expression (pl) < 0
898 || parse_expression (MPLIST_NEXT (pl)) < 0)
900 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
901 if (! MPLIST_PLIST_P (pl))
902 MERROR (MERROR_IM, -1);
903 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
904 MERROR (MERROR_IM, -1);
905 pl = MPLIST_NEXT (pl);
906 if (MPLIST_PLIST_P (pl)
907 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
908 MERROR (MERROR_IM, -1);
910 else if (action_name == Mshow || action_name == Mhide
911 || action_name == Mcommit || action_name == Munhandle)
913 else if (action_name == Mcond)
916 if (! MPLIST_PLIST_P (pl))
917 MERROR (MERROR_IM, -1);
919 else if (! macros || ! mplist_get (macros, action_name))
920 MERROR (MERROR_IM, -1);
922 else if (! MPLIST_SYMBOL_P (plist))
923 MERROR (MERROR_IM, -1);
930 resolve_command (MPlist *cmds, MSymbol command)
934 if (! cmds || ! (plist = mplist__assq (cmds, command)))
936 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
937 plist = MPLIST_NEXT (plist);
938 plist = MPLIST_NEXT (plist);
939 plist = MPLIST_NEXT (plist);
943 /* Load a translation into MAP from PLIST.
945 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
948 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
949 MPlist *branch_actions, MPlist *macros)
954 if (MPLIST_MTEXT_P (keylist))
956 MText *mt = MPLIST_MTEXT (keylist);
958 len = mtext_nchars (mt);
959 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
961 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
962 for (i = 0; i < len; i++)
963 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
969 if (MFAILP (MPLIST_PLIST_P (keylist)))
971 elt = MPLIST_PLIST (keylist);
972 len = MPLIST_LENGTH (elt);
973 if (MFAILP (len > 0))
975 keyseq = (MSymbol *) alloca (sizeof (int) * len);
976 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
978 if (MPLIST_INTEGER_P (elt))
980 int c = MPLIST_INTEGER (elt);
982 if (MFAILP (c >= 0 && c < 0x100))
984 keyseq[i] = one_char_symbol[c];
988 if (MFAILP (MPLIST_SYMBOL_P (elt)))
990 keyseq[i] = MPLIST_SYMBOL (elt);
995 for (i = 0; i < len; i++)
997 MIMMap *deeper = NULL;
1000 deeper = mplist_get (map->submaps, keyseq[i]);
1002 map->submaps = mplist ();
1005 /* Fixme: It is better to make all deeper maps at once. */
1006 MSTRUCT_CALLOC (deeper, MERROR_IM);
1007 mplist_put (map->submaps, keyseq[i], deeper);
1012 /* We reach a terminal map. */
1013 if (map->map_actions
1014 || map->branch_actions)
1015 /* This map is already defined. We avoid overriding it. */
1018 if (! MPLIST_TAIL_P (map_actions))
1020 if (parse_action_list (map_actions, macros) < 0)
1021 MERROR (MERROR_IM, -1);
1022 map->map_actions = map_actions;
1026 map->branch_actions = branch_actions;
1027 M17N_OBJECT_REF (branch_actions);
1033 /* Load a branch from PLIST into MAP. PLIST has this form:
1034 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1037 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1040 MPlist *branch_actions;
1042 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1044 map_name = MPLIST_SYMBOL (plist);
1045 plist = MPLIST_NEXT (plist);
1046 if (MPLIST_TAIL_P (plist))
1047 branch_actions = NULL;
1048 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1051 branch_actions = plist;
1052 if (map_name == Mnil)
1054 map->branch_actions = branch_actions;
1056 M17N_OBJECT_REF (branch_actions);
1058 else if (map_name == Mt)
1060 map->map_actions = branch_actions;
1062 M17N_OBJECT_REF (branch_actions);
1064 else if (im_info->maps
1065 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1067 MPLIST_DO (plist, plist)
1069 MPlist *keylist, *map_actions;
1071 if (! MPLIST_PLIST_P (plist))
1072 MERROR (MERROR_IM, -1);
1073 keylist = MPLIST_PLIST (plist);
1074 map_actions = MPLIST_NEXT (keylist);
1075 if (MPLIST_SYMBOL_P (keylist))
1077 MSymbol command = MPLIST_SYMBOL (keylist);
1080 if (MFAILP (command != Mat_reload))
1082 pl = resolve_command (im_info->configured_cmds, command);
1086 load_translation (map, pl, map_actions, branch_actions,
1090 load_translation (map, keylist, map_actions, branch_actions,
1098 /* Load a macro from PLIST into IM_INFO->macros.
1099 PLIST has this from:
1100 PLIST ::= ( MACRO-NAME ACTION * )
1101 IM_INFO->macros is a plist of macro names vs action list. */
1104 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1109 if (! MPLIST_SYMBOL_P (plist))
1110 MERROR (MERROR_IM, -1);
1111 name = MPLIST_SYMBOL (plist);
1112 plist = MPLIST_NEXT (plist);
1113 if (MPLIST_TAIL_P (plist)
1114 || parse_action_list (plist, im_info->macros) < 0)
1115 MERROR (MERROR_IM, -1);
1116 pl = mplist_get (im_info->macros, name);
1117 M17N_OBJECT_UNREF (pl);
1118 mplist_put (im_info->macros, name, plist);
1119 M17N_OBJECT_REF (plist);
1123 /* Load an external module from PLIST into IM_INFO->externals.
1124 PLIST has this form:
1125 PLIST ::= ( MODULE-NAME FUNCTION * )
1126 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1129 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1134 MIMExternalModule *external;
1138 if (MPLIST_MTEXT_P (plist))
1139 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1140 else if (MPLIST_SYMBOL_P (plist))
1141 module = MPLIST_SYMBOL (plist);
1142 module_file = alloca (strlen (MSYMBOL_NAME (module))
1143 + strlen (DLOPEN_SHLIB_EXT) + 1);
1144 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1146 handle = dlopen (module_file, RTLD_NOW);
1147 if (MFAILP (handle))
1149 fprintf (stderr, "%s\n", dlerror ());
1152 func_list = mplist ();
1153 MPLIST_DO (plist, MPLIST_NEXT (plist))
1155 if (! MPLIST_SYMBOL_P (plist))
1156 MERROR_GOTO (MERROR_IM, err_label);
1157 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1160 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1163 MSTRUCT_MALLOC (external, MERROR_IM);
1164 external->handle = handle;
1165 external->func_list = func_list;
1166 mplist_add (im_info->externals, module, external);
1171 M17N_OBJECT_UNREF (func_list);
1176 free_map (MIMMap *map, int top)
1181 M17N_OBJECT_UNREF (map->map_actions);
1184 MPLIST_DO (plist, map->submaps)
1185 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1186 M17N_OBJECT_UNREF (map->submaps);
1188 M17N_OBJECT_UNREF (map->branch_actions);
1193 free_state (void *object)
1195 MIMState *state = object;
1197 M17N_OBJECT_UNREF (state->title);
1199 free_map (state->map, 1);
1203 /** Load a state from PLIST into a newly allocated state object.
1204 PLIST has this form:
1205 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1206 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1207 Return the state object. */
1210 load_state (MInputMethodInfo *im_info, MPlist *plist)
1214 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1216 M17N_OBJECT (state, free_state, MERROR_IM);
1217 state->name = MPLIST_SYMBOL (plist);
1218 plist = MPLIST_NEXT (plist);
1219 if (MPLIST_MTEXT_P (plist))
1221 state->title = MPLIST_MTEXT (plist);
1222 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1223 Mlanguage, im_info->language);
1224 M17N_OBJECT_REF (state->title);
1225 plist = MPLIST_NEXT (plist);
1227 MSTRUCT_CALLOC (state->map, MERROR_IM);
1228 MPLIST_DO (plist, plist)
1230 if (MFAILP (MPLIST_PLIST_P (plist)))
1232 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1237 /* Return a newly created IM_INFO for an input method specified by
1238 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1240 static MInputMethodInfo *
1241 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1244 MInputMethodInfo *im_info;
1247 if (name == Mnil && extra == Mnil)
1248 language = Mt, extra = Mglobal;
1249 MSTRUCT_CALLOC (im_info, MERROR_IM);
1251 im_info->language = language;
1252 im_info->name = name;
1253 im_info->extra = extra;
1256 mplist_add (plist, Mplist, elt);
1257 M17N_OBJECT_UNREF (elt);
1258 elt = mplist_add (elt, Msymbol, language);
1259 elt = mplist_add (elt, Msymbol, name);
1260 elt = mplist_add (elt, Msymbol, extra);
1261 mplist_add (elt, Mt, im_info);
1267 fini_im_info (MInputMethodInfo *im_info)
1271 M17N_OBJECT_UNREF (im_info->cmds);
1272 M17N_OBJECT_UNREF (im_info->configured_cmds);
1273 M17N_OBJECT_UNREF (im_info->bc_cmds);
1274 M17N_OBJECT_UNREF (im_info->vars);
1275 M17N_OBJECT_UNREF (im_info->configured_vars);
1276 M17N_OBJECT_UNREF (im_info->bc_vars);
1277 M17N_OBJECT_UNREF (im_info->description);
1278 M17N_OBJECT_UNREF (im_info->title);
1279 if (im_info->states)
1281 MPLIST_DO (plist, im_info->states)
1283 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1285 M17N_OBJECT_UNREF (state);
1287 M17N_OBJECT_UNREF (im_info->states);
1290 if (im_info->macros)
1292 MPLIST_DO (plist, im_info->macros)
1293 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1294 M17N_OBJECT_UNREF (im_info->macros);
1297 if (im_info->externals)
1299 MPLIST_DO (plist, im_info->externals)
1301 MIMExternalModule *external = MPLIST_VAL (plist);
1303 dlclose (external->handle);
1304 M17N_OBJECT_UNREF (external->func_list);
1306 MPLIST_KEY (plist) = Mt;
1308 M17N_OBJECT_UNREF (im_info->externals);
1312 MPLIST_DO (plist, im_info->maps)
1314 MPlist *p = MPLIST_PLIST (plist);
1316 M17N_OBJECT_UNREF (p);
1318 M17N_OBJECT_UNREF (im_info->maps);
1325 free_im_info (MInputMethodInfo *im_info)
1327 fini_im_info (im_info);
1332 free_im_list (MPlist *plist)
1336 MPLIST_DO (pl, plist)
1338 MInputMethodInfo *im_info;
1340 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1341 im_info = MPLIST_VAL (elt);
1342 free_im_info (im_info);
1344 M17N_OBJECT_UNREF (plist);
1347 static MInputMethodInfo *
1348 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1350 if (name == Mnil && extra == Mnil)
1351 language = Mt, extra = Mglobal;
1352 while ((plist = mplist__assq (plist, language)))
1354 MPlist *elt = MPLIST_PLIST (plist);
1356 plist = MPLIST_NEXT (plist);
1357 elt = MPLIST_NEXT (elt);
1358 if (MPLIST_SYMBOL (elt) != name)
1360 elt = MPLIST_NEXT (elt);
1361 if (MPLIST_SYMBOL (elt) != extra)
1363 elt = MPLIST_NEXT (elt);
1364 return MPLIST_VAL (elt);
1369 static void load_im_info (MPlist *, MInputMethodInfo *);
1371 #define get_custom_info(im_info) \
1373 ? lookup_im_info (im_custom_list, (im_info)->language, \
1374 (im_info)->name, (im_info)->extra) \
1377 #define get_config_info(im_info) \
1379 ? lookup_im_info (im_config_list, (im_info)->language, \
1380 (im_info)->name, (im_info)->extra) \
1384 update_custom_info (void)
1390 if (mdatabase__check (im_custom_mdb) > 0)
1395 MDatabaseInfo *custom_dir_info;
1396 char custom_path[PATH_MAX + 1];
1398 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1399 if (! custom_dir_info->filename
1400 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1402 strcpy (custom_path, custom_dir_info->filename);
1403 strcat (custom_path, CUSTOM_FILE);
1404 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1410 free_im_list (im_custom_list);
1411 im_custom_list = NULL;
1413 plist = mdatabase_load (im_custom_mdb);
1416 im_custom_list = mplist ();
1418 MPLIST_DO (pl, plist)
1420 MSymbol language, name, extra;
1421 MInputMethodInfo *im_info;
1422 MPlist *im_data, *p;
1424 if (! MPLIST_PLIST_P (pl))
1426 p = MPLIST_PLIST (pl);
1427 im_data = MPLIST_NEXT (p);
1428 if (! MPLIST_PLIST_P (p))
1430 p = MPLIST_PLIST (p);
1431 if (! MPLIST_SYMBOL_P (p)
1432 || MPLIST_SYMBOL (p) != Minput_method)
1434 p = MPLIST_NEXT (p);
1435 if (! MPLIST_SYMBOL_P (p))
1437 language = MPLIST_SYMBOL (p);
1438 p = MPLIST_NEXT (p);
1439 if (! MPLIST_SYMBOL_P (p))
1441 name = MPLIST_SYMBOL (p);
1442 if (language == Mnil || name == Mnil)
1444 p = MPLIST_NEXT (p);
1445 if (MPLIST_TAIL_P (p))
1447 else if (MPLIST_SYMBOL_P (p))
1448 extra = MPLIST_SYMBOL (p);
1451 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1452 load_im_info (im_data, im_info);
1454 M17N_OBJECT_UNREF (plist);
1459 update_global_info (void)
1465 int ret = mdatabase__check (global_info->mdb);
1469 fini_im_info (global_info);
1473 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1475 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1477 if (! global_info->mdb
1478 || ! (plist = mdatabase_load (global_info->mdb)))
1481 load_im_info (plist, global_info);
1482 M17N_OBJECT_UNREF (plist);
1487 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1488 and EXTRA. KEY, if not Mnil, tells which kind of information about
1489 the input method is necessary, and the returned IM_INFO may contain
1490 only that information. */
1492 static MInputMethodInfo *
1493 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1496 MInputMethodInfo *im_info;
1499 if (name == Mnil && extra == Mnil)
1500 language = Mt, extra = Mglobal;
1501 im_info = lookup_im_info (im_info_list, language, name, extra);
1504 if (key == Mnil ? im_info->states != NULL
1505 : key == Mcommand ? im_info->cmds != NULL
1506 : key == Mvariable ? im_info->vars != NULL
1507 : key == Mtitle ? im_info->title != NULL
1508 : key == Mdescription ? im_info->description != NULL
1510 /* IM_INFO already contains required information. */
1512 /* We have not yet loaded required information. */
1516 mdb = mdatabase_find (Minput_method, language, name, extra);
1519 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1524 plist = mdatabase_load (im_info->mdb);
1528 mplist_push (load_im_info_keys, key, Mt);
1529 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1530 mplist_pop (load_im_info_keys);
1534 MERROR (MERROR_IM, im_info);
1535 update_global_info ();
1536 load_im_info (plist, im_info);
1537 M17N_OBJECT_UNREF (plist);
1540 if (! im_info->cmds)
1541 im_info->cmds = mplist ();
1542 if (! im_info->vars)
1543 im_info->vars = mplist ();
1545 if (! im_info->title
1546 && (key == Mnil || key == Mtitle))
1547 im_info->title = (name == Mnil ? mtext ()
1548 : mtext_from_data (MSYMBOL_NAME (name),
1549 MSYMBOL_NAMELEN (name),
1550 MTEXT_FORMAT_US_ASCII));
1554 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1555 If updated, but got unloadable, return -1. Otherwise, update
1556 contents of IM_INFO from the new database, and return 1. */
1559 reload_im_info (MInputMethodInfo *im_info)
1564 update_custom_info ();
1565 update_global_info ();
1566 check = mdatabase__check (im_info->mdb);
1569 plist = mdatabase_load (im_info->mdb);
1572 fini_im_info (im_info);
1573 load_im_info (plist, im_info);
1574 M17N_OBJECT_UNREF (plist);
1578 static MInputMethodInfo *
1579 get_im_info_by_tags (MPlist *plist)
1584 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1585 i++, plist = MPLIST_NEXT (plist))
1586 tag[i] = MPLIST_SYMBOL (plist);
1591 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1596 check_description (MPlist *plist)
1600 if (MPLIST_MTEXT_P (plist))
1602 if (MPLIST_PLIST_P (plist))
1604 MPlist *pl = MPLIST_PLIST (plist);
1606 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1608 pl =MPLIST_NEXT (pl);
1609 if (MFAILP (MPLIST_MTEXT_P (pl)))
1611 mt = MPLIST_MTEXT (pl);
1612 M17N_OBJECT_REF (mt);
1615 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1617 if (translated == (char *) MTEXT_DATA (mt))
1618 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1619 if (translated != (char *) MTEXT_DATA (mt))
1621 M17N_OBJECT_UNREF (mt);
1622 mt = mtext__from_data (translated, strlen (translated),
1623 MTEXT_FORMAT_UTF_8, 0);
1627 mplist_set (plist, Mtext, mt);
1628 M17N_OBJECT_UNREF (mt);
1631 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1637 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1641 check_command_keyseq (MPlist *keyseq)
1643 if (MPLIST_PLIST_P (keyseq))
1645 MPlist *p = MPLIST_PLIST (keyseq);
1648 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1652 if (MPLIST_MTEXT_P (keyseq))
1654 MText *mt = MPLIST_MTEXT (keyseq);
1657 for (i = 0; i < mtext_nchars (mt); i++)
1658 if (mtext_ref_char (mt, i) >= 256)
1665 /* Load command defitions from PLIST into IM_INFO->cmds.
1667 PLIST is well-formed and has this form;
1668 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1669 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1670 M-text or a plist of symbols.
1672 The returned list has the same form, but for each element...
1674 (1) If DESCRIPTION and the rest are omitted, the element is not
1675 stored in the returned list.
1677 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1678 description in global_info->cmds (if any). */
1681 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1685 im_info->cmds = tail = mplist ();
1687 MPLIST_DO (plist, MPLIST_NEXT (plist))
1689 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1692 if (MFAILP (MPLIST_PLIST_P (plist)))
1694 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1695 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1697 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1698 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1700 if (MFAILP (im_info != global_info))
1701 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1705 if (! check_description (p))
1706 mplist_set (p, Msymbol, Mnil);
1707 p = MPLIST_NEXT (p);
1708 while (! MPLIST_TAIL_P (p))
1710 if (MFAILP (check_command_keyseq (p)))
1711 mplist__pop_unref (p);
1713 p = MPLIST_NEXT (p);
1716 tail = mplist_add (tail, Mplist, pl);
1721 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1722 MPlist *config_cmds)
1724 MPlist *global = NULL, *custom = NULL, *config = NULL;
1727 MPlist *description = NULL, *keyseq;
1729 name = MPLIST_SYMBOL (plist);
1730 plist = MPLIST_NEXT (plist);
1731 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1732 description = plist;
1733 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1734 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1735 if (MPLIST_TAIL_P (plist))
1738 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1739 global = MPLIST_NEXT (MPLIST_PLIST (global));
1742 keyseq = MPLIST_NEXT (global);
1743 status = Minherited;
1753 keyseq = MPLIST_NEXT (plist);
1757 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1759 config = MPLIST_NEXT (MPLIST_PLIST (config));
1760 if (! MPLIST_TAIL_P (config))
1762 keyseq = MPLIST_NEXT (config);
1763 status = Mconfigured;
1766 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1768 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1769 if (! MPLIST_TAIL_P (custom))
1771 keyseq = MPLIST_NEXT (custom);
1772 status = Mcustomized;
1777 mplist_add (plist, Msymbol, name);
1779 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1781 mplist_add (plist, Msymbol, Mnil);
1782 mplist_add (plist, Msymbol, status);
1783 mplist__conc (plist, keyseq);
1788 config_all_commands (MInputMethodInfo *im_info)
1790 MPlist *global_cmds, *custom_cmds, *config_cmds;
1791 MInputMethodInfo *temp;
1792 MPlist *tail, *plist;
1794 M17N_OBJECT_UNREF (im_info->configured_cmds);
1796 if (MPLIST_TAIL_P (im_info->cmds)
1800 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1801 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1802 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1804 im_info->configured_cmds = tail = mplist ();
1805 MPLIST_DO (plist, im_info->cmds)
1807 MPlist *pl = config_command (MPLIST_PLIST (plist),
1808 global_cmds, custom_cmds, config_cmds);
1811 tail = mplist_add (tail, Mplist, pl);
1812 M17N_OBJECT_UNREF (pl);
1817 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1818 valid, return 0 if not. */
1821 check_variable_value (MPlist *val, MPlist *global)
1823 MSymbol type = MPLIST_KEY (val);
1824 MPlist *valids = MPLIST_NEXT (val);
1826 if (type != Minteger && type != Mtext && type != Msymbol)
1830 if (MPLIST_KEY (global) != Mt
1831 && MPLIST_KEY (global) != MPLIST_KEY (val))
1833 if (MPLIST_TAIL_P (valids))
1834 valids = MPLIST_NEXT (global);
1836 if (MPLIST_TAIL_P (valids))
1839 if (type == Minteger)
1841 int n = MPLIST_INTEGER (val);
1843 MPLIST_DO (valids, valids)
1845 if (MPLIST_INTEGER_P (valids))
1847 if (n == MPLIST_INTEGER (valids))
1850 else if (MPLIST_PLIST_P (valids))
1852 MPlist *p = MPLIST_PLIST (valids);
1853 int min_bound, max_bound;
1855 if (! MPLIST_INTEGER_P (p))
1856 MERROR (MERROR_IM, 0);
1857 min_bound = MPLIST_INTEGER (p);
1858 p = MPLIST_NEXT (p);
1859 if (! MPLIST_INTEGER_P (p))
1860 MERROR (MERROR_IM, 0);
1861 max_bound = MPLIST_INTEGER (p);
1862 if (n >= min_bound && n <= max_bound)
1867 else if (type == Msymbol)
1869 MSymbol sym = MPLIST_SYMBOL (val);
1871 MPLIST_DO (valids, valids)
1873 if (! MPLIST_SYMBOL_P (valids))
1874 MERROR (MERROR_IM, 0);
1875 if (sym == MPLIST_SYMBOL (valids))
1881 MText *mt = MPLIST_MTEXT (val);
1883 MPLIST_DO (valids, valids)
1885 if (! MPLIST_MTEXT_P (valids))
1886 MERROR (MERROR_IM, 0);
1887 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1892 return (MPLIST_TAIL_P (valids));
1895 /* Load variable defitions from PLIST into IM_INFO->vars.
1897 PLIST is well-formed and has this form;
1898 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1900 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1902 The returned list has the same form, but for each element...
1904 (1) If DESCRIPTION and the rest are omitted, the element is not
1905 stored in the returned list.
1907 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1908 description in global_info->vars (if any). */
1911 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1913 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1914 ? global_info->vars : NULL);
1917 im_info->vars = tail = mplist ();
1918 MPLIST_DO (plist, MPLIST_NEXT (plist))
1922 if (MFAILP (MPLIST_PLIST_P (plist)))
1924 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1925 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1927 if (im_info == global_info)
1929 /* Loading a global variable. */
1930 p = MPLIST_NEXT (pl);
1931 if (MPLIST_TAIL_P (p))
1932 mplist_add (p, Msymbol, Mnil);
1935 if (! check_description (p))
1936 mplist_set (p, Msymbol, Mnil);
1937 p = MPLIST_NEXT (p);
1938 if (MFAILP (! MPLIST_TAIL_P (p)
1939 && check_variable_value (p, NULL)))
1940 mplist_set (p, Mt, NULL);
1943 else if (im_info->mdb)
1945 /* Loading a local variable. */
1946 MSymbol name = MPLIST_SYMBOL (pl);
1947 MPlist *global = NULL;
1950 && (p = mplist__assq (global_vars, name)))
1952 /* P ::= ((NAME DESC ...) ...) */
1953 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1954 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1955 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1958 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1959 if (! MPLIST_TAIL_P (p))
1961 if (! check_description (p))
1962 mplist_set (p, Msymbol, Mnil);
1963 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1964 if (MFAILP (! MPLIST_TAIL_P (p)))
1965 mplist_set (p, Mt, NULL);
1968 MPlist *valid_values = MPLIST_NEXT (p);
1970 if (! MPLIST_TAIL_P (valid_values)
1971 ? MFAILP (check_variable_value (p, NULL))
1972 : global && MFAILP (check_variable_value (p, global)))
1973 mplist_set (p, Mt, NULL);
1979 /* Loading a variable customization. */
1980 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1981 if (MFAILP (! MPLIST_TAIL_P (p)))
1983 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1984 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1985 || MPLIST_MTEXT_P (p)))
1988 tail = mplist_add (tail, Mplist, pl);
1993 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
1994 MPlist *config_vars)
1996 MPlist *global = NULL, *custom = NULL, *config = NULL;
1997 MSymbol name = MPLIST_SYMBOL (plist);
1999 MPlist *description = NULL, *value, *valids;
2003 global = mplist__assq (global_vars, name);
2005 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2008 plist = MPLIST_NEXT (plist);
2009 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2010 description = plist;
2012 description = global;
2014 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2016 if (MPLIST_TAIL_P (plist))
2018 /* Inherit from global (if any). */
2022 if (MPLIST_KEY (value) == Mt)
2024 valids = MPLIST_NEXT (global);
2025 status = Minherited;
2037 value = plist = MPLIST_NEXT (plist);
2038 valids = MPLIST_NEXT (value);
2039 if (MPLIST_KEY (value) == Mt)
2041 if (! MPLIST_TAIL_P (valids))
2044 valids = MPLIST_NEXT (global);
2048 if (config_vars && (config = mplist__assq (config_vars, name)))
2050 config = MPLIST_NEXT (MPLIST_PLIST (config));
2051 if (! MPLIST_TAIL_P (config))
2053 value = MPLIST_NEXT (config);
2054 if (MFAILP (check_variable_value (value, global ? global : plist)))
2056 status = Mconfigured;
2059 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2061 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2062 if (! MPLIST_TAIL_P (custom))
2064 value = MPLIST_NEXT (custom);
2065 if (MFAILP (check_variable_value (value, global ? global : plist)))
2067 status = Mcustomized;
2072 mplist_add (plist, Msymbol, name);
2074 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2076 mplist_add (plist, Msymbol, Mnil);
2077 mplist_add (plist, Msymbol, status);
2079 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2081 mplist_add (plist, Mt, NULL);
2082 if (valids && ! MPLIST_TAIL_P (valids))
2083 mplist__conc (plist, valids);
2087 /* Return a configured variable definition list based on
2088 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2089 get it from global_info->vars. */
2092 config_all_variables (MInputMethodInfo *im_info)
2094 MPlist *global_vars, *custom_vars, *config_vars;
2095 MInputMethodInfo *temp;
2096 MPlist *tail, *plist;
2098 M17N_OBJECT_UNREF (im_info->configured_vars);
2100 if (MPLIST_TAIL_P (im_info->vars)
2104 global_vars = im_info != global_info ? global_info->vars : NULL;
2105 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2106 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2108 im_info->configured_vars = tail = mplist ();
2109 MPLIST_DO (plist, im_info->vars)
2111 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2112 global_vars, custom_vars, config_vars);
2115 tail = mplist_add (tail, Mplist, pl);
2116 M17N_OBJECT_UNREF (pl);
2121 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2122 CONFIG contains configuration information of the input method. */
2125 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2129 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2131 load_commands (im_info, MPLIST_PLIST (pl));
2132 config_all_commands (im_info);
2133 pl = mplist_pop (pl);
2134 M17N_OBJECT_UNREF (pl);
2137 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2139 load_variables (im_info, MPLIST_PLIST (pl));
2140 config_all_variables (im_info);
2141 pl = mplist_pop (pl);
2142 M17N_OBJECT_UNREF (pl);
2145 MPLIST_DO (plist, plist)
2146 if (MPLIST_PLIST_P (plist))
2148 MPlist *elt = MPLIST_PLIST (plist);
2151 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2153 key = MPLIST_SYMBOL (elt);
2158 elt = MPLIST_NEXT (elt);
2159 if (MFAILP (MPLIST_MTEXT_P (elt)))
2161 im_info->title = MPLIST_MTEXT (elt);
2162 M17N_OBJECT_REF (im_info->title);
2164 else if (key == Mmap)
2166 pl = mplist__from_alist (MPLIST_NEXT (elt));
2169 if (! im_info->maps)
2173 mplist__conc (im_info->maps, pl);
2174 M17N_OBJECT_UNREF (pl);
2177 else if (key == Mmacro)
2179 if (! im_info->macros)
2180 im_info->macros = mplist ();
2181 MPLIST_DO (elt, MPLIST_NEXT (elt))
2183 if (MFAILP (MPLIST_PLIST_P (elt)))
2185 load_macros (im_info, MPLIST_PLIST (elt));
2188 else if (key == Mmodule)
2190 if (! im_info->externals)
2191 im_info->externals = mplist ();
2192 MPLIST_DO (elt, MPLIST_NEXT (elt))
2194 if (MFAILP (MPLIST_PLIST_P (elt)))
2196 load_external_module (im_info, MPLIST_PLIST (elt));
2199 else if (key == Mstate)
2201 MPLIST_DO (elt, MPLIST_NEXT (elt))
2205 if (MFAILP (MPLIST_PLIST_P (elt)))
2207 pl = MPLIST_PLIST (elt);
2208 if (! im_info->states)
2209 im_info->states = mplist ();
2210 state = load_state (im_info, MPLIST_PLIST (elt));
2213 mplist_put (im_info->states, state->name, state);
2216 else if (key == Minclude)
2218 /* elt ::= include (tag1 tag2 ...) key item ... */
2220 MInputMethodInfo *temp;
2222 elt = MPLIST_NEXT (elt);
2223 if (MFAILP (MPLIST_PLIST_P (elt)))
2225 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2228 elt = MPLIST_NEXT (elt);
2229 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2231 key = MPLIST_SYMBOL (elt);
2232 elt = MPLIST_NEXT (elt);
2235 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2237 if (! im_info->maps)
2238 im_info->maps = mplist ();
2239 MPLIST_DO (pl, temp->maps)
2241 p = MPLIST_VAL (pl);
2242 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2243 M17N_OBJECT_REF (p);
2246 else if (key == Mmacro)
2248 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2250 if (! im_info->macros)
2251 im_info->macros = mplist ();
2252 MPLIST_DO (pl, temp->macros)
2254 p = MPLIST_VAL (pl);
2255 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2256 M17N_OBJECT_REF (p);
2259 else if (key == Mstate)
2261 if (! temp->states || MPLIST_TAIL_P (temp->states))
2263 if (! im_info->states)
2264 im_info->states = mplist ();
2265 MPLIST_DO (pl, temp->states)
2267 MIMState *state = MPLIST_VAL (pl);
2269 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2270 M17N_OBJECT_REF (state);
2274 else if (key == Mdescription)
2276 if (im_info->description)
2278 elt = MPLIST_NEXT (elt);
2279 if (! check_description (elt))
2281 im_info->description = MPLIST_MTEXT (elt);
2282 M17N_OBJECT_REF (im_info->description);
2285 im_info->tick = time (NULL);
2290 static int take_action_list (MInputContext *ic, MPlist *action_list);
2291 static void preedit_commit (MInputContext *ic);
2294 shift_state (MInputContext *ic, MSymbol state_name)
2296 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2297 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2298 MIMState *orig_state = ic_info->state, *state;
2300 /* Find a state to shift to. If not found, shift to the initial
2302 if (state_name == Mt)
2304 if (! ic_info->prev_state)
2306 state = ic_info->prev_state;
2308 else if (state_name == Mnil)
2310 state = (MIMState *) MPLIST_VAL (im_info->states);
2314 state = (MIMState *) mplist_get (im_info->states, state_name);
2316 state = (MIMState *) MPLIST_VAL (im_info->states);
2319 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2321 /* Enter the new state. */
2322 ic_info->state = state;
2323 ic_info->map = state->map;
2324 ic_info->state_key_head = ic_info->key_head;
2325 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2327 /* We have shifted to the initial state. */
2328 preedit_commit (ic);
2329 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2330 ic_info->state_pos = ic->cursor_pos;
2331 if (state != orig_state)
2333 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2335 /* Shifted to the initial state. */
2336 ic_info->prev_state = NULL;
2337 M17N_OBJECT_UNREF (ic_info->vars_saved);
2338 ic_info->vars_saved = mplist_copy (ic_info->vars);
2341 ic_info->prev_state = orig_state;
2344 ic->status = state->title;
2346 ic->status = im_info->title;
2347 ic->status_changed = 1;
2348 if (ic_info->map == ic_info->state->map
2349 && ic_info->map->map_actions)
2351 MDEBUG_PRINT (" init-actions:");
2352 take_action_list (ic, ic_info->map->map_actions);
2357 /* Find a candidate group that contains a candidate number INDEX from
2358 PLIST. Set START_INDEX to the first candidate number of the group,
2359 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2360 candidate group number if they are non-NULL. If INDEX is -1, find
2361 the last candidate group. */
2364 find_candidates_group (MPlist *plist, int index,
2365 int *start_index, int *end_index, int *group_index)
2367 int i = 0, gidx = 0, len;
2369 MPLIST_DO (plist, plist)
2371 if (MPLIST_MTEXT_P (plist))
2372 len = mtext_nchars (MPLIST_MTEXT (plist));
2374 len = mplist_length (MPLIST_PLIST (plist));
2375 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2381 *end_index = i + len;
2383 *group_index = gidx;
2392 /* Adjust markers for the change of preedit text.
2393 If FROM == TO, the change is insertion of INS chars.
2394 If FROM < TO and INS == 0, the change is deletion of the range.
2395 If FROM < TO and INS > 0, the change is replacement. */
2398 adjust_markers (MInputContext *ic, int from, int to, int ins)
2400 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2405 MPLIST_DO (markers, ic_info->markers)
2406 if (MPLIST_INTEGER (markers) > from)
2407 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2408 if (ic->cursor_pos >= from)
2409 ic->cursor_pos += ins;
2413 MPLIST_DO (markers, ic_info->markers)
2415 if (MPLIST_INTEGER (markers) >= to)
2416 MPLIST_VAL (markers)
2417 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2418 else if (MPLIST_INTEGER (markers) > from)
2419 MPLIST_VAL (markers) = (void *) from;
2421 if (ic->cursor_pos >= to)
2422 ic->cursor_pos += ins - (to - from);
2423 else if (ic->cursor_pos > from)
2424 ic->cursor_pos = from;
2430 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2432 int nchars = mt ? mtext_nchars (mt) : 1;
2435 mtext_ins (ic->preedit, pos, mt);
2437 mtext_ins_char (ic->preedit, pos, c, 1);
2438 adjust_markers (ic, pos, pos, nchars);
2439 ic->preedit_changed = 1;
2444 preedit_delete (MInputContext *ic, int from, int to)
2446 mtext_del (ic->preedit, from, to);
2447 adjust_markers (ic, from, to, 0);
2448 ic->preedit_changed = 1;
2452 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2456 mtext_del (ic->preedit, from, to);
2459 mtext_ins (ic->preedit, from, mt);
2460 ins = mtext_nchars (mt);
2464 mtext_ins_char (ic->preedit, from, c, 1);
2467 adjust_markers (ic, from, to, ins);
2468 ic->preedit_changed = 1;
2473 preedit_commit (MInputContext *ic)
2475 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2476 int preedit_len = mtext_nchars (ic->preedit);
2478 if (preedit_len > 0)
2482 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2483 Mcandidate_list, NULL, 0);
2484 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2485 Mcandidate_index, NULL, 0);
2486 mtext_cat (ic->produced, ic->preedit);
2487 mtext_reset (ic->preedit);
2488 mtext_reset (ic_info->preedit_saved);
2489 MPLIST_DO (p, ic_info->markers)
2491 ic->cursor_pos = ic_info->state_pos = 0;
2492 ic->preedit_changed = 1;
2493 ic_info->commit_key_head = ic_info->key_head;
2495 if (ic->candidate_list)
2497 M17N_OBJECT_UNREF (ic->candidate_list);
2498 ic->candidate_list = NULL;
2499 ic->candidate_index = 0;
2500 ic->candidate_from = ic->candidate_to = 0;
2501 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2502 if (ic->candidate_show)
2504 ic->candidate_show = 0;
2505 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2511 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2513 int code = marker_code (sym, 0);
2515 if (mt && (code == '[' || code == ']'))
2519 if (code == '[' && current > 0)
2521 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2525 else if (code == ']' && current < mtext_nchars (mt))
2527 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2533 return (code == '<' ? 0
2534 : code == '>' ? limit
2535 : code == '-' ? current - 1
2536 : code == '+' ? current + 1
2537 : code == '=' ? current
2538 : code - '0' > limit ? limit
2542 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2546 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2548 int from = mtext_property_start (prop);
2549 int to = mtext_property_end (prop);
2551 MPlist *candidate_list = mtext_property_value (prop);
2552 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2554 int ingroup_index = idx - start;
2557 if (MPLIST_MTEXT_P (group))
2559 mt = MPLIST_MTEXT (group);
2560 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2568 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2569 i++, plist = MPLIST_NEXT (plist));
2570 mt = MPLIST_MTEXT (plist);
2571 preedit_replace (ic, from, to, mt, 0);
2572 to = from + mtext_nchars (mt);
2574 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2575 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2576 ic->cursor_pos = to;
2580 get_select_charset (MInputContextInfo * ic_info)
2582 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2585 if (! MPLIST_VAL (plist))
2587 sym = MPLIST_SYMBOL (plist);
2590 return MCHARSET (sym);
2594 adjust_candidates (MPlist *plist, MCharset *charset)
2598 /* plist ::= MTEXT ... | PLIST ... */
2599 plist = mplist_copy (plist);
2600 if (MPLIST_MTEXT_P (plist))
2603 while (! MPLIST_TAIL_P (pl))
2605 /* pl ::= MTEXT ... */
2606 MText *mt = MPLIST_MTEXT (pl);
2610 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2612 c = mtext_ref_char (mt, i);
2613 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2617 mt = mtext_dup (mt);
2618 mplist_set (pl, Mtext, mt);
2619 M17N_OBJECT_UNREF (mt);
2622 mtext_del (mt, i, i + 1);
2625 if (mtext_len (mt) > 0)
2626 pl = MPLIST_NEXT (pl);
2630 M17N_OBJECT_UNREF (mt);
2634 else /* MPLIST_PLIST_P (plist) */
2637 while (! MPLIST_TAIL_P (pl))
2639 /* pl ::= (MTEXT ...) ... */
2640 MPlist *p = MPLIST_PLIST (pl);
2642 /* p ::= MTEXT ... */
2646 while (! MPLIST_TAIL_P (p0))
2648 MText *mt = MPLIST_MTEXT (p0);
2651 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2653 c = mtext_ref_char (mt, i);
2654 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2659 p0 = MPLIST_NEXT (p0);
2666 p = mplist_copy (p);
2667 mplist_set (pl, Mplist, p);
2668 M17N_OBJECT_UNREF (p);
2672 p0 = MPLIST_NEXT (p0);
2675 M17N_OBJECT_UNREF (mt);
2678 if (! MPLIST_TAIL_P (p))
2679 pl = MPLIST_NEXT (pl);
2683 M17N_OBJECT_UNREF (p);
2687 if (MPLIST_TAIL_P (plist))
2689 M17N_OBJECT_UNREF (plist);
2696 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2698 MCharset *charset = get_select_charset (ic_info);
2703 plist = resolve_variable (ic_info, Mcandidates_group_size);
2704 column = MPLIST_INTEGER (plist);
2706 plist = MPLIST_PLIST (args);
2708 plist = adjust_candidates (plist, charset);
2710 if (plist && column > 0)
2712 if (MPLIST_MTEXT_P (plist))
2714 MText *mt = MPLIST_MTEXT (plist);
2715 MPlist *next = MPLIST_NEXT (plist);
2717 if (MPLIST_TAIL_P (next))
2718 M17N_OBJECT_REF (mt);
2721 mt = mtext_dup (mt);
2722 while (! MPLIST_TAIL_P (next))
2724 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2725 next = MPLIST_NEXT (next);
2728 M17N_OBJECT_UNREF (plist);
2730 len = mtext_nchars (mt);
2732 mplist_add (plist, Mtext, mt);
2735 for (i = 0; i < len; i += column)
2737 int to = (i + column < len ? i + column : len);
2738 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2740 mplist_add (plist, Mtext, sub);
2741 M17N_OBJECT_UNREF (sub);
2744 M17N_OBJECT_UNREF (mt);
2746 else /* MPLIST_PLIST_P (plist) */
2748 MPlist *pl = MPLIST_PLIST (plist), *p;
2749 MPlist *next = MPLIST_NEXT (plist);
2752 if (MPLIST_TAIL_P (next))
2753 M17N_OBJECT_REF (pl);
2756 pl = mplist_copy (pl);
2757 while (! MPLIST_TAIL_P (next))
2759 p = mplist_copy (MPLIST_PLIST (next));
2760 pl = mplist__conc (pl, p);
2761 M17N_OBJECT_UNREF (p);
2762 next = MPLIST_NEXT (next);
2765 M17N_OBJECT_UNREF (plist);
2767 len = mplist_length (pl);
2769 mplist_add (plist, Mplist, pl);
2774 for (i = 0; i < len; i += column)
2777 mplist_add (plist, Mplist, p);
2778 M17N_OBJECT_UNREF (p);
2779 for (j = 0; j < column && i + j < len; j++)
2781 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
2782 p0 = MPLIST_NEXT (p0);
2786 M17N_OBJECT_UNREF (pl);
2795 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2797 MPlist *action = NULL;
2801 if (MPLIST_SYMBOL_P (action_list))
2803 MSymbol var = MPLIST_SYMBOL (action_list);
2806 MPLIST_DO (p, ic_info->vars)
2807 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2809 if (MPLIST_TAIL_P (p))
2811 action = MPLIST_NEXT (MPLIST_PLIST (p));
2812 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2815 if (MPLIST_PLIST_P (action_list))
2817 action = MPLIST_PLIST (action_list);
2818 if (MPLIST_SYMBOL_P (action))
2820 name = MPLIST_SYMBOL (action);
2821 args = MPLIST_NEXT (action);
2823 && MPLIST_PLIST_P (args))
2824 mplist_set (action, Msymbol, M_candidates);
2826 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2829 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2830 mplist_push (action, Msymbol, M_candidates);
2831 mplist_set (action_list, Mplist, action);
2832 M17N_OBJECT_UNREF (action);
2835 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2838 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2839 mplist_push (action, Msymbol, Minsert);
2840 mplist_set (action_list, Mplist, action);
2841 M17N_OBJECT_UNREF (action);
2846 /* Perform list of actions in ACTION_LIST for the current input
2847 context IC. If unhandle action was not performed, return 0.
2848 Otherwise, return -1. */
2851 take_action_list (MInputContext *ic, MPlist *action_list)
2853 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2854 MPlist *candidate_list = ic->candidate_list;
2855 int candidate_index = ic->candidate_index;
2856 int candidate_show = ic->candidate_show;
2857 MTextProperty *prop;
2859 MPLIST_DO (action_list, action_list)
2861 MPlist *action = regularize_action (action_list, ic_info);
2867 name = MPLIST_SYMBOL (action);
2868 args = MPLIST_NEXT (action);
2870 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2871 if (name == Minsert)
2873 if (MPLIST_SYMBOL_P (args))
2875 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2876 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2879 if (MPLIST_MTEXT_P (args))
2880 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2881 else /* MPLIST_INTEGER_P (args)) */
2882 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2884 else if (name == M_candidates)
2886 MPlist *plist = get_candidate_list (ic_info, args);
2891 if (MPLIST_MTEXT_P (plist))
2893 preedit_insert (ic, ic->cursor_pos, NULL,
2894 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2899 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2901 preedit_insert (ic, ic->cursor_pos, mt, 0);
2902 len = mtext_nchars (mt);
2904 mtext_put_prop (ic->preedit,
2905 ic->cursor_pos - len, ic->cursor_pos,
2906 Mcandidate_list, plist);
2907 mtext_put_prop (ic->preedit,
2908 ic->cursor_pos - len, ic->cursor_pos,
2909 Mcandidate_index, (void *) 0);
2911 else if (name == Mselect)
2914 int code, idx, gindex;
2915 int pos = ic->cursor_pos;
2917 int idx_decided = 0;
2920 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2923 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2924 group = find_candidates_group (mtext_property_value (prop), idx,
2925 &start, &end, &gindex);
2926 if (MPLIST_SYMBOL_P (args))
2928 code = marker_code (MPLIST_SYMBOL (args), 0);
2931 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2932 if (! MPLIST_INTEGER_P (args))
2934 idx = start + MPLIST_INTEGER (args);
2935 if (idx < start || idx >= end)
2943 if (code != '[' && code != ']')
2948 ? new_index (NULL, ic->candidate_index - start,
2949 end - start - 1, MPLIST_SYMBOL (args),
2951 : MPLIST_INTEGER (args)));
2954 find_candidates_group (mtext_property_value (prop), -1,
2959 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2964 int ingroup_index = idx - start;
2967 group = mtext_property_value (prop);
2968 len = mplist_length (group);
2981 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2982 idx += (MPLIST_MTEXT_P (group)
2983 ? mtext_nchars (MPLIST_MTEXT (group))
2984 : mplist_length (MPLIST_PLIST (group)));
2985 len = (MPLIST_MTEXT_P (group)
2986 ? mtext_nchars (MPLIST_MTEXT (group))
2987 : mplist_length (MPLIST_PLIST (group)));
2988 if (ingroup_index >= len)
2989 ingroup_index = len - 1;
2990 idx += ingroup_index;
2992 update_candidate (ic, prop, idx);
2993 MDEBUG_PRINT1 ("(%d)", idx);
2995 else if (name == Mshow)
2996 ic->candidate_show = 1;
2997 else if (name == Mhide)
2998 ic->candidate_show = 0;
2999 else if (name == Mdelete)
3001 int len = mtext_nchars (ic->preedit);
3005 if (MPLIST_SYMBOL_P (args)
3006 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3008 to = ic->cursor_pos + pos;
3011 delete_surrounding_text (ic, to);
3016 delete_surrounding_text (ic, to - len);
3022 to = (MPLIST_SYMBOL_P (args)
3023 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3025 : MPLIST_INTEGER (args));
3031 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3032 if (to < ic->cursor_pos)
3033 preedit_delete (ic, to, ic->cursor_pos);
3034 else if (to > ic->cursor_pos)
3035 preedit_delete (ic, ic->cursor_pos, to);
3037 else if (name == Mmove)
3039 int len = mtext_nchars (ic->preedit);
3041 = (MPLIST_SYMBOL_P (args)
3042 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3044 : MPLIST_INTEGER (args));
3050 if (pos != ic->cursor_pos)
3052 ic->cursor_pos = pos;
3053 ic->preedit_changed = 1;
3055 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3057 else if (name == Mmark)
3059 int code = marker_code (MPLIST_SYMBOL (args), 0);
3063 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3064 (void *) ic->cursor_pos);
3065 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3068 else if (name == Mpushback)
3070 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3074 if (MPLIST_SYMBOL_P (args))
3076 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3077 if (MPLIST_INTEGER_P (args))
3078 num = MPLIST_INTEGER (args);
3083 num = MPLIST_INTEGER (args);
3086 ic_info->key_head -= num;
3088 ic_info->key_head = 0;
3090 ic_info->key_head = - num;
3091 if (ic_info->key_head > ic_info->used)
3092 ic_info->key_head = ic_info->used;
3094 else if (MPLIST_MTEXT_P (args))
3096 MText *mt = MPLIST_MTEXT (args);
3097 int i, len = mtext_nchars (mt);
3100 ic_info->key_head--;
3101 for (i = 0; i < len; i++)
3103 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3104 if (ic_info->key_head + i < ic_info->used)
3105 ic_info->keys[ic_info->key_head + i] = key;
3107 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3112 MPlist *plist = MPLIST_PLIST (args), *pl;
3116 ic_info->key_head--;
3118 MPLIST_DO (pl, plist)
3120 key = MPLIST_SYMBOL (pl);
3121 if (ic_info->key_head < ic_info->used)
3122 ic_info->keys[ic_info->key_head + i] = key;
3124 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3129 else if (name == Mcall)
3131 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3132 MIMExternalFunc func = NULL;
3133 MSymbol module, func_name;
3134 MPlist *func_args, *val;
3137 module = MPLIST_SYMBOL (args);
3138 args = MPLIST_NEXT (args);
3139 func_name = MPLIST_SYMBOL (args);
3141 if (im_info->externals)
3143 MIMExternalModule *external
3144 = (MIMExternalModule *) mplist_get (im_info->externals,
3147 func = (MIMExternalFunc) mplist_get (external->func_list,
3152 func_args = mplist ();
3153 mplist_add (func_args, Mt, ic);
3154 MPLIST_DO (args, MPLIST_NEXT (args))
3158 if (MPLIST_KEY (args) == Msymbol
3159 && MPLIST_KEY (args) != Mnil
3160 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3162 code = new_index (ic, ic->cursor_pos,
3163 mtext_nchars (ic->preedit),
3164 MPLIST_SYMBOL (args), ic->preedit);
3165 mplist_add (func_args, Minteger, (void *) code);
3168 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3170 val = (func) (func_args);
3171 M17N_OBJECT_UNREF (func_args);
3172 if (val && ! MPLIST_TAIL_P (val))
3173 ret = take_action_list (ic, val);
3174 M17N_OBJECT_UNREF (val);
3178 else if (name == Mshift)
3180 shift_state (ic, MPLIST_SYMBOL (args));
3182 else if (name == Mundo)
3184 int intarg = (MPLIST_TAIL_P (args)
3186 : integer_value (ic, args, NULL, 0));
3188 mtext_reset (ic->preedit);
3189 mtext_reset (ic_info->preedit_saved);
3190 mtext_reset (ic->produced);
3191 M17N_OBJECT_UNREF (ic_info->vars);
3192 ic_info->vars = mplist_copy (ic_info->vars_saved);
3193 ic->cursor_pos = ic_info->state_pos = 0;
3194 ic_info->state_key_head = ic_info->key_head
3195 = ic_info->commit_key_head = 0;
3197 shift_state (ic, Mnil);
3200 if (MPLIST_TAIL_P (args))
3205 ic_info->used += intarg;
3208 ic_info->used = intarg;
3211 else if (name == Mset || name == Madd || name == Msub
3212 || name == Mmul || name == Mdiv)
3214 MSymbol sym = MPLIST_SYMBOL (args);
3219 val1 = integer_value (ic, args, &value, 0);
3220 args = MPLIST_NEXT (args);
3221 val2 = resolve_expression (ic, args);
3223 val1 = val2, op = "=";
3224 else if (name == Madd)
3225 val1 += val2, op = "+=";
3226 else if (name == Msub)
3227 val1 -= val2, op = "-=";
3228 else if (name == Mmul)
3229 val1 *= val2, op = "*=";
3231 val1 /= val2, op = "/=";
3232 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3233 MSYMBOL_NAME (sym), op, val1, val1);
3235 mplist_set (value, Minteger, (void *) val1);
3237 else if (name == Mequal || name == Mless || name == Mgreater
3238 || name == Mless_equal || name == Mgreater_equal)
3241 MPlist *actions1, *actions2;
3244 val1 = resolve_expression (ic, args);
3245 args = MPLIST_NEXT (args);
3246 val2 = resolve_expression (ic, args);
3247 args = MPLIST_NEXT (args);
3248 actions1 = MPLIST_PLIST (args);
3249 args = MPLIST_NEXT (args);
3250 if (MPLIST_TAIL_P (args))
3253 actions2 = MPLIST_PLIST (args);
3254 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3255 if (name == Mequal ? val1 == val2
3256 : name == Mless ? val1 < val2
3257 : name == Mgreater ? val1 > val2
3258 : name == Mless_equal ? val1 <= val2
3261 MDEBUG_PRINT ("ok");
3262 ret = take_action_list (ic, actions1);
3266 MDEBUG_PRINT ("no");
3268 ret = take_action_list (ic, actions2);
3273 else if (name == Mcond)
3277 MPLIST_DO (args, args)
3282 if (! MPLIST_PLIST (args))
3284 cond = MPLIST_PLIST (args);
3285 if (resolve_expression (ic, cond) != 0)
3287 MDEBUG_PRINT1 ("(%dth)", idx);
3288 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3294 else if (name == Mcommit)
3296 preedit_commit (ic);
3298 else if (name == Munhandle)
3300 preedit_commit (ic);
3305 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3309 && (actions = mplist_get (im_info->macros, name)))
3311 if (take_action_list (ic, actions) < 0)
3317 if (ic->candidate_list)
3319 M17N_OBJECT_UNREF (ic->candidate_list);
3320 ic->candidate_list = NULL;
3322 if (ic->cursor_pos > 0
3323 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3326 ic->candidate_list = mtext_property_value (prop);
3327 M17N_OBJECT_REF (ic->candidate_list);
3329 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3331 ic->candidate_from = mtext_property_start (prop);
3332 ic->candidate_to = mtext_property_end (prop);
3335 if (candidate_list != ic->candidate_list)
3336 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3337 if (candidate_index != ic->candidate_index)
3338 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3339 if (candidate_show != ic->candidate_show)
3340 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3345 /* Handle the input key KEY in the current state and map specified in
3346 the input context IC. If KEY is handled correctly, return 0.
3347 Otherwise, return -1. */
3350 handle_key (MInputContext *ic)
3352 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3353 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3354 MIMMap *map = ic_info->map;
3355 MIMMap *submap = NULL;
3356 MSymbol key = ic_info->keys[ic_info->key_head];
3357 MSymbol alias = Mnil;
3360 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3361 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3365 submap = mplist_get (map->submaps, key);
3368 && (alias = msymbol_get (alias, M_key_alias))
3370 submap = mplist_get (map->submaps, alias);
3375 if (! alias || alias == key)
3376 MDEBUG_PRINT (" submap-found");
3378 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3379 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3380 ic->preedit_changed = 1;
3381 ic->cursor_pos = ic_info->state_pos;
3382 ic_info->key_head++;
3383 ic_info->map = map = submap;
3384 if (map->map_actions)
3386 MDEBUG_PRINT (" map-actions:");
3387 if (take_action_list (ic, map->map_actions) < 0)
3389 MDEBUG_PRINT ("\n");
3393 else if (map->submaps)
3395 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3397 MSymbol key = ic_info->keys[i];
3398 char *name = msymbol_name (key);
3400 if (! name[0] || ! name[1])
3401 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3405 /* If this is the terminal map or we have shifted to another
3406 state, perform branch actions (if any). */
3407 if (! map->submaps || map != ic_info->map)
3409 if (map->branch_actions)
3411 MDEBUG_PRINT (" branch-actions:");
3412 if (take_action_list (ic, map->branch_actions) < 0)
3414 MDEBUG_PRINT ("\n");
3418 /* If MAP is still not the root map, shift to the current
3420 if (ic_info->map != ic_info->state->map)
3421 shift_state (ic, ic_info->state->name);
3426 /* MAP can not handle KEY. */
3428 /* Perform branch actions if any. */
3429 if (map->branch_actions)
3431 MDEBUG_PRINT (" branch-actions:");
3432 if (take_action_list (ic, map->branch_actions) < 0)
3434 MDEBUG_PRINT ("\n");
3439 if (map == ic_info->map)
3441 /* The above branch actions didn't change the state. */
3443 /* If MAP is the root map of the initial state, it means
3444 that the current input method can not handle KEY. */
3445 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3447 MDEBUG_PRINT (" unhandled\n");
3451 if (map != ic_info->state->map)
3453 /* MAP is not the root map. Shift to the root map of the
3455 shift_state (ic, ic_info->state->name);
3459 /* MAP is the root map. Shift to the initial state. */
3460 shift_state (ic, Mnil);
3464 MDEBUG_PRINT ("\n");
3468 /* Initialize IC->ic_info. */
3471 init_ic_info (MInputContext *ic)
3473 MInputMethodInfo *im_info = ic->im->info;
3474 MInputContextInfo *ic_info = ic->info;
3477 MLIST_INIT1 (ic_info, keys, 8);;
3479 ic_info->markers = mplist ();
3481 ic_info->vars = mplist ();
3482 if (im_info->configured_vars)
3483 MPLIST_DO (plist, im_info->configured_vars)
3485 MPlist *pl = MPLIST_PLIST (plist);
3486 MSymbol name = MPLIST_SYMBOL (pl);
3488 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3489 if (MPLIST_KEY (pl) != Mt)
3491 MPlist *p = mplist ();
3493 mplist_push (ic_info->vars, Mplist, p);
3494 M17N_OBJECT_UNREF (p);
3495 mplist_add (p, Msymbol, name);
3496 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3499 ic_info->vars_saved = mplist_copy (ic_info->vars);
3501 if (im_info->externals)
3503 MPlist *func_args = mplist (), *plist;
3505 mplist_add (func_args, Mt, ic);
3506 MPLIST_DO (plist, im_info->externals)
3508 MIMExternalModule *external = MPLIST_VAL (plist);
3509 MIMExternalFunc func
3510 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3515 M17N_OBJECT_UNREF (func_args);
3518 ic_info->preedit_saved = mtext ();
3519 ic_info->tick = im_info->tick;
3522 /* Finalize IC->ic_info. */
3525 fini_ic_info (MInputContext *ic)
3527 MInputMethodInfo *im_info = ic->im->info;
3528 MInputContextInfo *ic_info = ic->info;
3530 if (im_info->externals)
3532 MPlist *func_args = mplist (), *plist;
3534 mplist_add (func_args, Mt, ic);
3535 MPLIST_DO (plist, im_info->externals)
3537 MIMExternalModule *external = MPLIST_VAL (plist);
3538 MIMExternalFunc func
3539 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3544 M17N_OBJECT_UNREF (func_args);
3547 MLIST_FREE1 (ic_info, keys);
3548 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3549 M17N_OBJECT_UNREF (ic_info->markers);
3550 M17N_OBJECT_UNREF (ic_info->vars);
3551 M17N_OBJECT_UNREF (ic_info->vars_saved);
3552 M17N_OBJECT_UNREF (ic_info->preceding_text);
3553 M17N_OBJECT_UNREF (ic_info->following_text);
3555 memset (ic_info, 0, sizeof (MInputContextInfo));
3559 re_init_ic (MInputContext *ic, int reload)
3561 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3562 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3563 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3565 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3566 preedit_changed = mtext_nchars (ic->preedit) > 0;
3567 cursor_pos_changed = ic->cursor_pos > 0;
3568 candidates_changed = 0;
3569 if (ic->candidate_list)
3571 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3572 M17N_OBJECT_UNREF (ic->candidate_list);
3573 ic->candidate_list = NULL;
3575 if (ic->candidate_show)
3577 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3578 ic->candidate_show = 0;
3580 if (ic->candidate_index > 0)
3582 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3583 ic->candidate_index = 0;
3584 ic->candidate_from = ic->candidate_to = 0;
3586 if (mtext_nchars (ic->produced) > 0)
3587 mtext_reset (ic->produced);
3588 if (mtext_nchars (ic->preedit) > 0)
3589 mtext_reset (ic->preedit);
3591 M17N_OBJECT_UNREF (ic->plist);
3592 ic->plist = mplist ();
3596 reload_im_info (im_info);
3598 shift_state (ic, Mnil);
3599 ic->status_changed = status_changed;
3600 ic->preedit_changed = preedit_changed;
3601 ic->cursor_pos_changed = cursor_pos_changed;
3602 ic->candidates_changed = candidates_changed;
3606 reset_ic (MInputContext *ic, MSymbol ignore)
3608 MDEBUG_PRINT ("\n [IM] reset\n");
3613 open_im (MInputMethod *im)
3615 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3618 MERROR (MERROR_IM, -1);
3625 close_im (MInputMethod *im)
3631 create_ic (MInputContext *ic)
3633 MInputContextInfo *ic_info;
3635 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3638 shift_state (ic, Mnil);
3643 destroy_ic (MInputContext *ic)
3650 check_reload (MInputContext *ic, MSymbol key)
3652 MInputMethodInfo *im_info = ic->im->info;
3653 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3657 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3661 MPLIST_DO (plist, plist)
3663 MSymbol this_key, alias;
3665 if (MPLIST_MTEXT_P (plist))
3667 MText *mt = MPLIST_MTEXT (plist);
3668 int c = mtext_ref_char (mt, 0);
3672 this_key = one_char_symbol[c];
3676 MPlist *pl = MPLIST_PLIST (plist);
3678 this_key = MPLIST_SYMBOL (pl);
3682 && (alias = msymbol_get (alias, M_key_alias))
3683 && alias != this_key);
3687 if (MPLIST_TAIL_P (plist))
3690 MDEBUG_PRINT ("\n [IM] reload");
3696 /** Handle the input key KEY in the current state and map of IC->info.
3697 If KEY is handled but no text is produced, return 0, otherwise
3703 filter (MInputContext *ic, MSymbol key, void *arg)
3705 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3706 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3709 if (check_reload (ic, key))
3712 if (! ic_info->state)
3714 ic_info->key_unhandled = 1;
3717 mtext_reset (ic->produced);
3718 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3719 M17N_OBJECT_UNREF (ic_info->preceding_text);
3720 M17N_OBJECT_UNREF (ic_info->following_text);
3721 ic_info->preceding_text = ic_info->following_text = NULL;
3722 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3723 ic_info->key_unhandled = 0;
3726 if (handle_key (ic) < 0)
3728 /* KEY was not handled. Delete it from the current key sequence. */
3729 if (ic_info->used > 0)
3731 memmove (ic_info->keys, ic_info->keys + 1,
3732 sizeof (int) * (ic_info->used - 1));
3734 if (ic_info->state_key_head > 0)
3735 ic_info->state_key_head--;
3736 if (ic_info->commit_key_head > 0)
3737 ic_info->commit_key_head--;
3739 /* This forces returning 1. */
3740 ic_info->key_unhandled = 1;
3746 reset_ic (ic, Mnil);
3747 ic_info->key_unhandled = 1;
3750 /* Break the loop if all keys were handled. */
3751 } while (ic_info->key_head < ic_info->used);
3753 /* If the current map is the root of the initial state, we should
3754 produce any preedit text in ic->produced. */
3755 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3756 preedit_commit (ic);
3758 if (mtext_nchars (ic->produced) > 0)
3760 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3762 if (mdebug__flag & mdebug_mask)
3764 MDEBUG_PRINT (" (produced");
3765 for (i = 0; i < mtext_nchars (ic->produced); i++)
3766 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3771 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3772 Mlanguage, ic->im->language);
3774 if (ic_info->commit_key_head > 0)
3776 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3777 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3778 ic_info->used -= ic_info->commit_key_head;
3779 ic_info->key_head -= ic_info->commit_key_head;
3780 ic_info->state_key_head -= ic_info->commit_key_head;
3781 ic_info->commit_key_head = 0;
3783 if (ic_info->key_unhandled)
3786 ic_info->key_head = ic_info->state_key_head
3787 = ic_info->commit_key_head = 0;
3790 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3794 /** Return 1 if the last event or key was not handled, otherwise
3797 There is no need of looking up because ic->produced should already
3798 contain the produced text (if any).
3803 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3805 mtext_cat (mt, ic->produced);
3806 mtext_reset (ic->produced);
3807 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3811 /* Input method command handler. */
3813 /* List of all (global and local) commands.
3814 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3815 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3816 Global commands are stored as (t (t COMMAND ...)) */
3819 /* Input method variable handler. */
3822 /* Support functions for mdebug_dump_im. */
3825 dump_im_map (MPlist *map_list, int indent)
3828 MSymbol key = MPLIST_KEY (map_list);
3829 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3831 prefix = (char *) alloca (indent + 1);
3832 memset (prefix, 32, indent);
3833 prefix[indent] = '\0';
3835 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3836 if (map->map_actions)
3837 mdebug_dump_plist (map->map_actions, indent + 2);
3840 MPLIST_DO (map_list, map->submaps)
3842 fprintf (stderr, "\n%s ", prefix);
3843 dump_im_map (map_list, indent + 2);
3846 if (map->branch_actions)
3848 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3849 mdebug_dump_plist (map->branch_actions, indent + 4);
3850 fprintf (stderr, ")");
3852 fprintf (stderr, ")");
3857 dump_im_state (MIMState *state, int indent)
3862 prefix = (char *) alloca (indent + 1);
3863 memset (prefix, 32, indent);
3864 prefix[indent] = '\0';
3866 fprintf (stderr, "(%s", msymbol_name (state->name));
3867 if (state->map->submaps)
3869 MPLIST_DO (map_list, state->map->submaps)
3871 fprintf (stderr, "\n%s ", prefix);
3872 dump_im_map (map_list, indent + 2);
3875 fprintf (stderr, ")");
3883 Minput_driver = msymbol ("input-driver");
3885 Minput_preedit_start = msymbol ("input-preedit-start");
3886 Minput_preedit_done = msymbol ("input-preedit-done");
3887 Minput_preedit_draw = msymbol ("input-preedit-draw");
3888 Minput_status_start = msymbol ("input-status-start");
3889 Minput_status_done = msymbol ("input-status-done");
3890 Minput_status_draw = msymbol ("input-status-draw");
3891 Minput_candidates_start = msymbol ("input-candidates-start");
3892 Minput_candidates_done = msymbol ("input-candidates-done");
3893 Minput_candidates_draw = msymbol ("input-candidates-draw");
3894 Minput_set_spot = msymbol ("input-set-spot");
3895 Minput_focus_move = msymbol ("input-focus-move");
3896 Minput_focus_in = msymbol ("input-focus-in");
3897 Minput_focus_out = msymbol ("input-focus-out");
3898 Minput_toggle = msymbol ("input-toggle");
3899 Minput_reset = msymbol ("input-reset");
3900 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3901 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3902 Mcustomized = msymbol ("customized");
3903 Mconfigured = msymbol ("configured");
3904 Minherited = msymbol ("inherited");
3906 minput_default_driver.open_im = open_im;
3907 minput_default_driver.close_im = close_im;
3908 minput_default_driver.create_ic = create_ic;
3909 minput_default_driver.destroy_ic = destroy_ic;
3910 minput_default_driver.filter = filter;
3911 minput_default_driver.lookup = lookup;
3912 minput_default_driver.callback_list = mplist ();
3913 mplist_put (minput_default_driver.callback_list, Minput_reset,
3915 minput_driver = &minput_default_driver;
3917 fully_initialized = 0;
3924 if (fully_initialized)
3926 free_im_list (im_info_list);
3928 free_im_list (im_custom_list);
3930 free_im_list (im_config_list);
3931 M17N_OBJECT_UNREF (load_im_info_keys);
3934 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3935 M17N_OBJECT_UNREF (minput_driver->callback_list);
3940 minput__char_to_key (int c)
3942 if (c < 0 || c >= 0x100)
3945 return one_char_symbol[c];
3949 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3954 /*** @addtogroup m17nInputMethod */
3959 @name Variables: Predefined symbols for callback commands.
3961 These are the predefined symbols that are used as the @c COMMAND
3962 argument of callback functions of an input method driver (see
3963 #MInputDriver::callback_list).
3965 Most of them do not require extra argument nor return any value;
3966 exceptions are these:
3968 Minput_get_surrounding_text: When a callback function assigned for
3969 this command is called, the first element of #MInputContext::plist
3970 has key #Minteger and the value specifies which portion of the
3971 surrounding text should be retrieved. If the value is positive,
3972 it specifies the number of characters following the current cursor
3973 position. If the value is negative, the absolute value specifies
3974 the number of characters preceding the current cursor position.
3975 If the value is zero, it means that the caller just wants to know
3976 if the surrounding text is currently supported or not.
3978 If the surrounding text is currently supported, the callback
3979 function must set the key of this element to #Mtext and the value
3980 to the retrieved M-text. The length of the M-text may be shorter
3981 than the requested number of characters, if the available text is
3982 not that long. The length can be zero in the worst case. Or, the
3983 length may be longer if an application thinks it is more efficient
3984 to return that length.
3986 If the surrounding text is not currently supported, the callback
3987 function should return without changing the first element of
3988 #MInputContext::plist.
3990 Minput_delete_surrounding_text: When a callback function assigned
3991 for this command is called, the first element of
3992 #MInputContext::plist has key #Minteger and the value specifies
3993 which portion of the surrounding text should be deleted in the
3994 same way as the case of Minput_get_surrounding_text. The callback
3995 function must delete the specified text. It should not alter
3996 #MInputContext::plist. */
3998 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4000 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4001 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4003 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4005 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4006 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4007 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4008 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4009 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4010 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4011 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4013 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4014 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4015 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4016 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4017 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4019 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4020 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4022 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4023 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4024 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4025 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4026 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4027 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4031 MSymbol Minput_preedit_start;
4032 MSymbol Minput_preedit_done;
4033 MSymbol Minput_preedit_draw;
4034 MSymbol Minput_status_start;
4035 MSymbol Minput_status_done;
4036 MSymbol Minput_status_draw;
4037 MSymbol Minput_candidates_start;
4038 MSymbol Minput_candidates_done;
4039 MSymbol Minput_candidates_draw;
4040 MSymbol Minput_set_spot;
4041 MSymbol Minput_toggle;
4042 MSymbol Minput_reset;
4043 MSymbol Minput_get_surrounding_text;
4044 MSymbol Minput_delete_surrounding_text;
4050 @name Variables: Predefined symbols for special input events.
4052 These are the predefined symbols that are used as the @c KEY
4053 argument of minput_filter (). */
4055 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4057 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4062 MSymbol Minput_focus_out;
4063 MSymbol Minput_focus_in;
4064 MSymbol Minput_focus_move;
4070 @name Variables: Predefined symbols used in input method information.
4072 These are the predefined symbols describing status of input method
4073 command and variable, and are used in a return value of
4074 minput_get_command () and minput_get_variable (). */
4076 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4078 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4079 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4083 MSymbol Mcustomized;
4084 MSymbol Mconfigured;
4090 @brief The default driver for internal input methods.
4092 The variable #minput_default_driver is the default driver for
4093 internal input methods.
4095 The member MInputDriver::open_im () searches the m17n database for
4096 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4097 $NAME\> and loads it.
4099 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4100 programmers responsibility to set it to a plist of proper callback
4101 functions. Otherwise, no feedback information (e.g. preedit text)
4102 can be shown to users.
4104 The macro M17N_INIT () sets the variable #minput_driver to the
4105 pointer to this driver so that all internal input methods use it.
4107 Therefore, unless @c minput_driver is set differently, the driver
4108 dependent arguments $ARG of the functions whose name begins with
4109 "minput_" are all ignored. */
4111 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4113 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4115 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4116 \< #Minput_method, $LANGUAGE, $NAME\>
4117 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4119 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4120 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4121 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4122 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4124 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4125 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4127 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4128 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4130 MInputDriver minput_default_driver;
4134 @brief The driver for internal input methods.
4136 The variable #minput_driver is a pointer to the input method
4137 driver that is used by internal input methods. The macro
4138 M17N_INIT () initializes it to a pointer to #minput_default_driver
4139 if <m17n<EM></EM>.h> is included. */
4141 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4143 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4144 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4145 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4146 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4148 MInputDriver *minput_driver;
4150 MSymbol Minput_driver;
4165 @brief Open an input method.
4167 The minput_open_im () function opens an input method whose
4168 language and name match $LANGUAGE and $NAME, and returns a pointer
4169 to the input method object newly allocated.
4171 This function at first decides a driver for the input method as
4174 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4175 #minput_driver is used.
4177 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4178 driver pointed to by the property value is used to open the input
4179 method. If $NAME has no such a property, @c NULL is returned.
4181 Then, the member MInputDriver::open_im () of the driver is
4184 $ARG is set in the member @c arg of the structure MInputMethod so
4185 that the driver can refer to it. */
4187 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4189 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4190 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4192 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4194 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4195 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4197 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4198 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4199 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4201 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4203 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4205 @latexonly \IPAlabel{minput_open} @endlatexonly
4210 minput_open_im (MSymbol language, MSymbol name, void *arg)
4213 MInputDriver *driver;
4217 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4218 msymbol_name (language), msymbol_name (name));
4220 driver = minput_driver;
4223 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4225 MERROR (MERROR_IM, NULL);
4228 MSTRUCT_CALLOC (im, MERROR_IM);
4229 im->language = language;
4232 im->driver = *driver;
4233 if ((*im->driver.open_im) (im) < 0)
4235 MDEBUG_PRINT (" failed\n");
4239 MDEBUG_PRINT (" ok\n");
4246 @brief Close an input method.
4248 The minput_close_im () function closes the input method $IM, which
4249 must have been created by minput_open_im (). */
4252 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4254 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4255 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4258 minput_close_im (MInputMethod *im)
4260 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4261 msymbol_name (im->name), msymbol_name (im->language));
4262 (*im->driver.close_im) (im);
4264 MDEBUG_PRINT (" done\n");
4270 @brief Create an input context.
4272 The minput_create_ic () function creates an input context object
4273 associated with input method $IM, and calls callback functions
4274 corresponding to #Minput_preedit_start, #Minput_status_start, and
4275 #Minput_status_draw in this order.
4278 If an input context is successfully created, minput_create_ic ()
4279 returns a pointer to it. Otherwise it returns @c NULL. */
4282 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4284 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4285 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4286 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4287 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4290 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4291 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4295 minput_create_ic (MInputMethod *im, void *arg)
4299 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4300 msymbol_name (im->name), msymbol_name (im->language));
4301 MSTRUCT_CALLOC (ic, MERROR_IM);
4304 ic->preedit = mtext ();
4305 ic->candidate_list = NULL;
4306 ic->produced = mtext ();
4307 ic->spot.x = ic->spot.y = 0;
4309 ic->plist = mplist ();
4310 if ((*im->driver.create_ic) (ic) < 0)
4312 MDEBUG_PRINT (" failed\n");
4313 M17N_OBJECT_UNREF (ic->preedit);
4314 M17N_OBJECT_UNREF (ic->produced);
4315 M17N_OBJECT_UNREF (ic->plist);
4320 if (im->driver.callback_list)
4322 minput_callback (ic, Minput_preedit_start);
4323 minput_callback (ic, Minput_status_start);
4324 minput_callback (ic, Minput_status_draw);
4327 MDEBUG_PRINT (" ok\n");
4334 @brief Destroy an input context.
4336 The minput_destroy_ic () function destroys the input context $IC,
4337 which must have been created by minput_create_ic (). It calls
4338 callback functions corresponding to #Minput_preedit_done,
4339 #Minput_status_done, and #Minput_candidates_done in this order. */
4342 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4344 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4345 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4346 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4347 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4348 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4352 minput_destroy_ic (MInputContext *ic)
4354 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4355 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4356 if (ic->im->driver.callback_list)
4358 minput_callback (ic, Minput_preedit_done);
4359 minput_callback (ic, Minput_status_done);
4360 minput_callback (ic, Minput_candidates_done);
4362 (*ic->im->driver.destroy_ic) (ic);
4363 M17N_OBJECT_UNREF (ic->preedit);
4364 M17N_OBJECT_UNREF (ic->produced);
4365 M17N_OBJECT_UNREF (ic->plist);
4366 MDEBUG_PRINT (" done\n");
4373 @brief Filter an input key.
4375 The minput_filter () function filters input key $KEY according to
4376 input context $IC, and calls callback functions corresponding to
4377 #Minput_preedit_draw, #Minput_status_draw, and
4378 #Minput_candidates_draw if the preedit text, the status, and the
4379 current candidate are changed respectively.
4381 To make the input method commit the current preedit text (if any)
4382 and shift to the initial state, call this function with #Mnil as
4385 To inform the input method about the focus-out event, call this
4386 function with #Minput_focus_out as $KEY.
4388 To inform the input method about the focus-in event, call this
4389 function with #Minput_focus_in as $KEY.
4391 To inform the input method about the focus-move event (i.e. input
4392 spot change within the same input context), call this function
4393 with #Minput_focus_move as $KEY.
4396 If $KEY is filtered out, this function returns 1. In that case,
4397 the caller should discard the key. Otherwise, it returns 0, and
4398 the caller should handle the key, for instance, by calling the
4399 function minput_lookup () with the same key. */
4402 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4404 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4405 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4406 #Minput_preedit_draw, #Minput_status_draw,
4407 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4410 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4411 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4412 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4413 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4415 @latexonly \IPAlabel{minput_filter} @endlatexonly
4419 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4426 if (ic->im->driver.callback_list
4427 && mtext_nchars (ic->preedit) > 0)
4428 minput_callback (ic, Minput_preedit_draw);
4430 ret = (*ic->im->driver.filter) (ic, key, arg);
4432 if (ic->im->driver.callback_list)
4434 if (ic->preedit_changed)
4435 minput_callback (ic, Minput_preedit_draw);
4436 if (ic->status_changed)
4437 minput_callback (ic, Minput_status_draw);
4438 if (ic->candidates_changed)
4439 minput_callback (ic, Minput_candidates_draw);
4448 @brief Look up a text produced in the input context.
4450 The minput_lookup () function looks up a text in the input context
4451 $IC. $KEY must be identical to the one that was used in the previous call of
4454 If a text was produced by the input method, it is concatenated
4457 This function calls #MInputDriver::lookup .
4460 If $KEY was correctly handled by the input method, this function
4461 returns 0. Otherwise, it returns -1, even though some text
4462 might be produced in $MT. */
4465 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4467 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4468 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4470 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4473 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4476 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4477 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4478 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4480 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4483 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4485 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4490 @brief Set the spot of the input context.
4492 The minput_set_spot () function sets the spot of input context $IC
4493 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4494 The semantics of these values depends on the input method driver.
4496 For instance, a driver designed to work in a CUI environment may
4497 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4498 $DESCENT . A driver designed to work in a window system may
4499 interpret $X and $Y as the pixel offsets relative to the origin of the
4500 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4501 descent pixels of the line at ($X . $Y ).
4503 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4505 $MT and $POS are the M-text and the character position at the spot.
4506 $MT may be @c NULL, in which case, the input method cannot get
4507 information about the text around the spot. */
4510 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4512 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4513 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4514 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4516 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4517 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4518 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4519 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4520 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4521 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4523 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4525 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4526 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4530 minput_set_spot (MInputContext *ic, int x, int y,
4531 int ascent, int descent, int fontsize,
4536 ic->spot.ascent = ascent;
4537 ic->spot.descent = descent;
4538 ic->spot.fontsize = fontsize;
4541 if (ic->im->driver.callback_list)
4542 minput_callback (ic, Minput_set_spot);
4547 @brief Toggle input method.
4549 The minput_toggle () function toggles the input method associated
4550 with input context $IC. */
4552 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4554 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4555 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4559 minput_toggle (MInputContext *ic)
4561 if (ic->im->driver.callback_list)
4562 minput_callback (ic, Minput_toggle);
4563 ic->active = ! ic->active;
4569 @brief Reset an input context.
4571 The minput_reset_ic () function resets input context $IC by
4572 calling a callback function corresponding to #Minput_reset. It
4573 resets the status of $IC to its initial one. As the
4574 current preedit text is deleted without commitment, if necessary,
4575 call minput_filter () with the arg @r key #Mnil to force the input
4576 method to commit the preedit in advance. */
4579 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4581 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4582 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4583 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4584 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4585 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4586 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4589 minput_reset_ic (MInputContext *ic)
4591 if (ic->im->driver.callback_list)
4592 minput_callback (ic, Minput_reset);
4598 @brief Get title and icon filename of an input method.
4600 The minput_get_title_icon () function returns a plist containing a
4601 title and icon filename (if any) of an input method specified by
4602 $LANGUAGE and $NAME.
4604 The first element of the plist has key #Mtext and the value is an
4605 M-text of the title for identifying the input method. The second
4606 element (if any) has key #Mtext and the value is an M-text of the
4607 icon image (absolute) filename for the same purpose.
4610 If there exists a specified input method and it defines an title,
4611 a plist is returned. Otherwise, NULL is returned. The caller
4612 must free the plist by m17n_object_unref (). */
4614 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4616 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4617 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4620 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4621 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4622 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4625 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4626 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4627 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4630 minput_get_title_icon (MSymbol language, MSymbol name)
4632 MInputMethodInfo *im_info;
4639 im_info = get_im_info (language, name, Mnil, Mtitle);
4640 if (! im_info || !im_info->title)
4642 mt = mtext_get_prop (im_info->title, 0, Mtext);
4644 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4647 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4650 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4651 (char *) MSYMBOL_NAME (name));
4652 file = mdatabase__find_file (buf);
4653 if (! file && language == Mt)
4655 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4656 file = mdatabase__find_file (buf);
4661 mplist_add (plist, Mtext, im_info->title);
4664 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4666 mplist_add (plist, Mtext, mt);
4667 M17N_OBJECT_UNREF (mt);
4675 @brief Get description text of an input method.
4677 The minput_get_description () function returns an M-text that
4678 describes the input method specified by $LANGUAGE and $NAME.
4681 If the specified input method has a description text, a pointer to
4682 #MText is returned. The caller has to free it by m17n_object_unref ().
4683 If the input method does not have a description text, @c NULL is
4686 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4688 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4689 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4691 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4692 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4693 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4694 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4697 minput_get_description (MSymbol language, MSymbol name)
4699 MInputMethodInfo *im_info;
4707 extra = language, language = Mt;
4709 im_info = get_im_info (language, name, extra, Mdescription);
4710 if (! im_info || ! im_info->description)
4712 M17N_OBJECT_REF (im_info->description);
4713 return im_info->description;
4719 @brief Get information about input method command(s).
4721 The minput_get_command () function returns information about
4722 the command $COMMAND of the input method specified by $LANGUAGE and
4723 $NAME. An input method command is a pseudo key event to which one
4724 or more actual input key sequences are assigned.
4726 There are two kinds of commands, global and local. A global
4727 command has a global definition, and the description and the key
4728 assignment may be inherited by a local command. Each input method
4729 defines a local command which has a local key assignment. It may
4730 also declare a local command that inherits the definition of a
4731 global command of the same name.
4733 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4734 information about a global command. Otherwise information about a
4735 local command is returned.
4737 If $COMMAND is #Mnil, information about all commands is returned.
4739 The return value is a @e well-formed plist (#m17nPlist) of this
4742 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4744 @c NAME is a symbol representing the command name.
4746 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4747 command has no description.
4749 @c STATUS is a symbol representing how the key assignment is decided.
4750 The value is #Mnil (the default key assignment), #Mcustomized (the
4751 key assignment is customized by per-user configuration file), or
4752 #Mconfigured (the key assignment is set by the call of
4753 minput_config_command ()). For a local command only, it may also
4754 be #Minherited (the key assignment is inherited from the
4755 corresponding global command).
4757 @c KEYSEQ is a plist of one or more symbols representing a key
4758 sequence assigned to the command. If there's no KEYSEQ, the
4759 command is currently disabled (i.e. no key sequence can trigger
4760 actions of the command).
4762 If $COMMAND is not #Mnil, the first element of the returned plist
4763 contains the information about $COMMAND.
4767 If the requested information was found, a pointer to a non-empty
4768 plist is returned. As the plist is kept in the library, the
4769 caller must not modify nor free it.
4771 Otherwise (the specified input method or the specified command
4772 does not exist), @c NULL is returned. */
4774 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4776 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4777 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4778 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4779 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4781 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4782 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4783 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4784 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4785 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4787 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4788 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4791 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4793 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4796 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4798 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4800 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4803 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4804 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4805 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4806 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4807 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4808 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4810 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4811 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4812 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4813 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4815 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4816 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4820 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4821 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4824 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4829 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4831 /* Return a description of the command COMMAND of the input method
4832 specified by LANGUAGE and NAME. */
4833 MPlist *cmd = minput_get_command (langauge, name, command);
4838 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4839 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4840 return (mplist_key (plist) == Mtext
4841 ? (MText *) mplist_value (plist)
4847 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4849 MInputMethodInfo *im_info;
4853 im_info = get_im_info (language, name, Mnil, Mcommand);
4855 || ! im_info->configured_cmds
4856 || MPLIST_TAIL_P (im_info->configured_cmds))
4858 if (command == Mnil)
4859 return im_info->configured_cmds;
4860 return mplist__assq (im_info->configured_cmds, command);
4866 @brief Configure the key sequence of an input method command.
4868 The minput_config_command () function assigns a list of key
4869 sequences $KEYSEQLIST to the command $COMMAND of the input method
4870 specified by $LANGUAGE and $NAME.
4872 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4873 sequences, and each key sequence must be a plist of symbols.
4875 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4877 If $KEYSEQLIST is NULL, the configuration of the command for the
4878 input method is canceled, and the default key sequences become
4879 effective. In such case, if $COMMAND is #Mnil, configurations for
4880 all commands of the input method are canceled.
4882 If $NAME is #Mnil, this function configures the key assignment of a
4883 global command, not that of a specific input method.
4885 The configuration takes effect for input methods opened or
4886 re-opened later in the current session. In order to make the
4887 configuration take effect for the future session, it must be saved
4888 in a per-user configuration file by the function
4889 minput_save_config ().
4893 If the operation was successful, this function returns 0,
4894 otherwise returns -1. The operation fails in these cases:
4896 <li>$KEYSEQLIST is not in a valid form.
4897 <li>$COMMAND is not available for the input method.
4898 <li>$LANGUAGE and $NAME do not specify an existing input method.
4902 minput_get_commands (), minput_save_config ().
4905 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4907 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4908 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4909 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4911 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4912 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4914 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4916 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4917 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4918 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4921 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4922 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4924 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4925 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4926 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4927 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4931 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4933 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4934 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4935 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4939 minput_get_commands (), minput_save_config ().
4943 /* Add "C-x u" to the "start" command of Unicode input method. */
4945 MSymbol start_command = msymbol ("start");
4946 MSymbol unicode = msymbol ("unicode");
4947 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4949 /* At first get the current key-sequence assignment. */
4950 cmd = mplist_get_command (Mt, unicode, start_command);
4953 /* The input method does not have the command "start". Here
4954 should come some error handling code. */
4956 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4957 the part (KEY-SEQUENCE ...). */
4958 plist = mplist_next (mplist_next (mplist_value (cmd)));
4959 /* Copy it because we should not modify it directly. */
4960 key_seq_list = mplist_copy (plist);
4961 m17n_object_unref (cmds);
4963 key_seq = mplist ();
4964 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4965 mplist_add (key_seq, Msymbol, msymbol ("u"));
4966 mplist_add (key_seq_list, Mplist, key_seq);
4967 m17n_object_unref (key_seq);
4969 minput_config_command (Mt, unicode, start_command, key_seq_list);
4970 m17n_object_unref (key_seq_list);
4975 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4978 MInputMethodInfo *im_info, *config;
4985 if (command == Mnil)
4986 MERROR (MERROR_IM, -1);
4987 MPLIST_DO (plist, keyseqlist)
4988 if (! MPLIST_PLIST_P (plist)
4989 || ! check_command_keyseq (plist))
4990 MERROR (MERROR_IM, -1);
4993 im_info = get_im_info (language, name, Mnil, Mcommand);
4995 MERROR (MERROR_IM, -1);
4998 || ! mplist__assq (im_info->cmds, command)))
4999 MERROR (MERROR_IM, -1);
5001 config = get_config_info (im_info);
5004 if (! im_config_list)
5005 im_config_list = mplist ();
5006 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5007 config->cmds = mplist ();
5008 config->vars = mplist ();
5011 if (command == Mnil)
5013 MInputMethodInfo *custom = get_custom_info (im_info);
5015 mplist_set (config->cmds, Mnil, NULL);
5016 if (custom && custom->cmds)
5018 MPLIST_DO (plist, custom->cmds)
5020 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5022 mplist_add (plist, Msymbol, command);
5023 mplist_push (config->cmds, Mplist, plist);
5024 M17N_OBJECT_UNREF (plist);
5030 plist = mplist__assq (config->cmds, command);
5033 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
5034 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
5035 if (! MPLIST_TAIL_P (plist))
5036 mplist_set (plist, Mnil, NULL); /* () */
5041 mplist_add (config->cmds, Mplist, plist);
5042 M17N_OBJECT_UNREF (plist);
5043 plist = mplist_add (plist, Msymbol, command);
5044 plist = MPLIST_NEXT (plist);
5050 plist = mplist_add (plist, Msymbol, Mnil);
5051 MPLIST_DO (keyseqlist, keyseqlist)
5053 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5054 plist = mplist_add (plist, Mplist, pl);
5055 M17N_OBJECT_UNREF (pl);
5059 config_all_commands (im_info);
5060 im_info->tick = time (NULL);
5067 @brief Get information about input method variable(s).
5069 The minput_get_variable () function returns information about
5070 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5071 An input method variable controls behavior of an input method.
5073 There are two kinds of variables, global and local. A global
5074 variable has a global definition, and the description and the value
5075 may be inherited by a local variable. Each input method defines a
5076 local variable which has local value. It may also declare a
5077 local variable that inherits definition of a global variable of
5080 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5081 variable is returned. Otherwise information about a local variable
5084 If $VARIABLE is #Mnil, information about all variables is
5087 The return value is a @e well-formed plist (#m17nPlist) of this
5090 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5092 @c NAME is a symbol representing the variable name.
5094 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5095 variable has no description.
5097 @c STATUS is a symbol representing how the value is decided. The
5098 value is #Mnil (the default value), #Mcustomized (the value is
5099 customized by per-user configuration file), or #Mconfigured (the
5100 value is set by the call of minput_config_variable ()). For a
5101 local variable only, it may also be #Minherited (the value is
5102 inherited from the corresponding global variable).
5104 @c VALUE is the initial value of the variable. If the key of this
5105 element is #Mt, the variable has no initial value. Otherwise, the
5106 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5109 @c VALID-VALUEs (if any) specify which values the variable can have.
5110 They have the same type (i.e. having the same key) as @c VALUE except
5111 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5112 may be a plist of two integers specifying the range of possible
5115 If there no @c VALID-VALUE, the variable can have any value as long
5116 as the type is the same as @c VALUE.
5118 If $VARIABLE is not #Mnil, the first element of the returned plist
5119 contains the information about $VARIABLE.
5123 If the requested information was found, a pointer to a non-empty
5124 plist is returned. As the plist is kept in the library, the
5125 caller must not modify nor free it.
5127 Otherwise (the specified input method or the specified variable
5128 does not exist), @c NULL is returned. */
5130 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5132 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5133 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5134 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5136 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5137 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5138 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5139 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5142 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5143 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5145 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5147 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5149 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5152 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5154 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5157 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5158 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5159 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5160 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5161 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5162 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5164 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5165 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5166 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5168 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5169 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5170 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5171 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5173 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5176 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5177 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5181 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5182 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5185 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5189 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5191 MInputMethodInfo *im_info;
5195 im_info = get_im_info (language, name, Mnil, Mvariable);
5196 if (! im_info || ! im_info->configured_vars)
5198 if (variable == Mnil)
5199 return im_info->configured_vars;
5200 return mplist__assq (im_info->configured_vars, variable);
5206 @brief Configure the value of an input method variable.
5208 The minput_config_variable () function assigns $VALUE to the
5209 variable $VARIABLE of the input method specified by $LANGUAGE and
5212 If $VALUE is not NULL, it must be a plist of one element whose key
5213 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5216 If $VALUE is NULL, a configuration for the variable for the input
5217 method is canceled, and the variable is initialized to the default
5218 value. In that case, if $VARIABLE is #Mnil, configurations for
5219 all variables of the input method are canceled.
5221 If $NAME is #Mnil, this function configure the value of global
5222 variable, not that of a specific input method.
5224 The configuration takes effect for input methods opened or
5225 re-opened later in the current session. To make the configuration
5226 take effect for the future session, it must be saved in a per-user
5227 configuration file by the function minput_save_config ().
5231 If the operation was successful, this function returns 0,
5232 otherwise returns -1. The operation fails in these cases:
5234 <li>$VALUE is not in a valid form, the type does not match the
5235 definition, or the value is our of range.
5236 <li>$VARIABLE is not available for the input method.
5237 <li>$LANGUAGE and $NAME do not specify an existing input method.
5241 minput_get_variable (), minput_save_config (). */
5243 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5245 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5246 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5248 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5249 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5251 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5252 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5253 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5255 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5256 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5258 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5259 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5260 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5261 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5265 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5267 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5268 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5269 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5273 minput_get_commands (), minput_save_config ().
5276 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5279 MInputMethodInfo *im_info, *config;
5284 im_info = get_im_info (language, name, Mnil, Mvariable);
5286 MERROR (MERROR_IM, -1);
5287 if (variable == Mnil)
5290 MERROR (MERROR_IM, -1);
5292 else if (! im_info->vars
5293 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5294 MERROR (MERROR_IM, -1);
5296 if (variable != Mnil && value)
5298 plist = MPLIST_PLIST (plist);
5299 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5300 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5301 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5302 if (MPLIST_KEY (plist) != Mt
5303 && ! check_variable_value (value, plist))
5304 MERROR (MERROR_IM, -1);
5307 config = get_config_info (im_info);
5310 if (! im_config_list)
5311 im_config_list = mplist ();
5312 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5313 config->cmds = mplist ();
5314 config->vars = mplist ();
5317 if (variable == Mnil)
5319 MInputMethodInfo *custom = get_custom_info (im_info);
5321 mplist_set (config->vars, Mnil, NULL);
5322 if (custom && custom->cmds)
5324 MPLIST_DO (plist, custom->vars)
5326 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5328 mplist_add (plist, Msymbol, variable);
5329 mplist_push (config->vars, Mplist, plist);
5330 M17N_OBJECT_UNREF (plist);
5336 plist = mplist__assq (config->vars, variable);
5339 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5340 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5341 if (! MPLIST_TAIL_P (plist))
5342 mplist_set (plist, Mnil ,NULL); /* () */
5347 mplist_add (config->vars, Mplist, plist);
5348 M17N_OBJECT_UNREF (plist);
5349 plist = mplist_add (plist, Msymbol, variable);
5350 plist = MPLIST_NEXT (plist);
5354 plist = mplist_add (plist, Msymbol, Mnil);
5355 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5358 config_all_variables (im_info);
5359 im_info->tick = time (NULL);
5366 @brief Get the name of per-user configuration file.
5368 The minput_config_file () function returns the absolute path name
5369 of per-user configuration file into which minput_save_config ()
5370 save configurations. It is usually @c "config.mic" under the
5371 directory @c ".m17n.d" of user's home directory. It is not assured
5372 that the file of the returned name exists nor is
5373 readable/writable. If minput_save_config () fails and returns -1,
5374 an application program might check the file, make it
5375 writable (if possible), and try minput_save_config () again.
5379 This function returns a string. As the string is kept in the
5380 library, the caller must not modify nor free it.
5383 minput_save_config ()
5386 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5388 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5389 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5390 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5391 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5392 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5393 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5394 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5399 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5400 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5403 minput_save_config ()
5407 minput_config_file ()
5411 return mdatabase__file (im_custom_mdb);
5417 @brief Save configurations in per-user configuration file.
5419 The minput_save_config () function saves the configurations done
5420 so far in the current session into the per-user configuration
5425 If the operation was successful, 1 is returned. If the per-user
5426 configuration file is currently locked, 0 is returned. In that
5427 case, the caller may wait for a while and try again. If the
5428 configuration file is not writable, -1 is returned. In that case,
5429 the caller may check the name of the file by calling
5430 minput_config_file (), make it writable if possible, and try
5434 minput_config_file () */
5436 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5438 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5439 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5443 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5444 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5445 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5446 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5450 minput_config_file () */
5453 minput_save_config (void)
5455 MPlist *data, *tail, *plist, *p, *elt;
5459 ret = mdatabase__lock (im_custom_mdb);
5462 if (! im_config_list)
5464 update_custom_info ();
5465 if (! im_custom_list)
5466 im_custom_list = mplist ();
5467 data = tail = mplist ();
5469 MPLIST_DO (plist, im_config_list)
5471 MPlist *pl = MPLIST_PLIST (plist);
5472 MSymbol language, name, extra, command, variable;
5473 MInputMethodInfo *custom, *config;
5475 language = MPLIST_SYMBOL (pl);
5476 pl = MPLIST_NEXT (pl);
5477 name = MPLIST_SYMBOL (pl);
5478 pl = MPLIST_NEXT (pl);
5479 extra = MPLIST_SYMBOL (pl);
5480 pl = MPLIST_NEXT (pl);
5481 config = MPLIST_VAL (pl);
5482 custom = get_custom_info (config);
5484 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5486 MPLIST_DO (pl, config->cmds)
5488 elt = MPLIST_PLIST (pl);
5489 command = MPLIST_SYMBOL (elt);
5491 p = mplist__assq (custom->cmds, command);
5493 custom->cmds = mplist (), p = NULL;
5494 elt = MPLIST_NEXT (elt);
5495 if (MPLIST_TAIL_P (elt))
5498 mplist__pop_unref (p);
5502 elt = MPLIST_NEXT (elt);
5505 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5506 mplist_set (p, Mnil, NULL);
5507 mplist__conc (p, elt);
5511 p = MPLIST_PLIST (pl);
5512 mplist_add (custom->cmds, Mplist, p);
5517 MPLIST_DO (pl, config->vars)
5519 elt = MPLIST_PLIST (pl);
5520 variable = MPLIST_SYMBOL (elt);
5522 p = mplist__assq (custom->vars, variable);
5524 custom->vars = mplist (), p = NULL;
5525 elt = MPLIST_NEXT (elt);
5526 if (MPLIST_TAIL_P (elt))
5529 mplist__pop_unref (p);
5533 elt = MPLIST_NEXT (elt);
5536 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5537 mplist_set (p, Mnil, NULL);
5538 mplist__conc (p, elt);
5542 p = MPLIST_PLIST (pl);
5543 mplist_add (custom->vars, Mplist, p);
5548 M17N_OBJECT_UNREF (im_config_list);
5550 MPLIST_DO (plist, im_custom_list)
5552 MPlist *pl = MPLIST_PLIST (plist);
5553 MSymbol language, name, extra;
5554 MInputMethodInfo *custom, *im_info;
5556 language = MPLIST_SYMBOL (pl);
5557 pl = MPLIST_NEXT (pl);
5558 name = MPLIST_SYMBOL (pl);
5559 pl = MPLIST_NEXT (pl);
5560 extra = MPLIST_SYMBOL (pl);
5561 pl = MPLIST_NEXT (pl);
5562 custom = MPLIST_VAL (pl);
5563 im_info = lookup_im_info (im_info_list, language, name, extra);
5567 config_all_commands (im_info);
5569 config_all_variables (im_info);
5573 tail = mplist_add (tail, Mplist, elt);
5574 M17N_OBJECT_UNREF (elt);
5576 elt = mplist_add (elt, Mplist, pl);
5577 M17N_OBJECT_UNREF (pl);
5578 pl = mplist_add (pl, Msymbol, Minput_method);
5579 pl = mplist_add (pl, Msymbol, language);
5580 pl = mplist_add (pl, Msymbol, name);
5582 pl = mplist_add (pl, Msymbol, extra);
5583 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5586 elt = mplist_add (elt, Mplist, pl);
5587 M17N_OBJECT_UNREF (pl);
5588 pl = mplist_add (pl, Msymbol, Mcommand);
5589 MPLIST_DO (p, custom->cmds)
5590 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5592 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5595 elt = mplist_add (elt, Mplist, pl);
5596 M17N_OBJECT_UNREF (pl);
5597 pl = mplist_add (pl, Msymbol, Mvariable);
5598 MPLIST_DO (p, custom->vars)
5599 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5603 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5604 ret = mdatabase__save (im_custom_mdb, data);
5605 mdatabase__unlock (im_custom_mdb);
5606 M17N_OBJECT_UNREF (data);
5607 return (ret < 0 ? -1 : 1);
5614 @name Obsolete functions
5617 @name Obsolete ¤Ê´Ø¿ô
5623 @brief Get a list of variables of an input method (obsolete).
5625 This function is obsolete. Use minput_get_variable () instead.
5627 The minput_get_variables () function returns a plist (#MPlist) of
5628 variables used to control the behavior of the input method
5629 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5630 (#m17nPlist) of the following format:
5633 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5634 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5638 @c VARNAME is a symbol representing the variable name.
5640 @c DOC-MTEXT is an M-text describing the variable.
5642 @c DEFAULT-VALUE is the default value of the variable. It is a
5643 symbol, integer, or M-text.
5645 @c VALUEs (if any) specifies the possible values of the variable.
5646 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5647 @c TO), where @c FROM and @c TO specifies a range of possible
5650 For instance, suppose an input method has the variables:
5652 @li name:intvar, description:"value is an integer",
5653 initial value:0, value-range:0..3,10,20
5655 @li name:symvar, description:"value is a symbol",
5656 initial value:nil, value-range:a, b, c, nil
5658 @li name:txtvar, description:"value is an M-text",
5659 initial value:empty text, no value-range (i.e. any text)
5661 Then, the returned plist is as follows.
5664 (intvar ("value is an integer" 0 (0 3) 10 20)
5665 symvar ("value is a symbol" nil a b c nil)
5666 txtvar ("value is an M-text" ""))
5670 If the input method uses any variables, a pointer to #MPlist is
5671 returned. As the plist is kept in the library, the caller must not
5672 modify nor free it. If the input method does not use any
5673 variable, @c NULL is returned. */
5675 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5677 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5678 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5679 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5683 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5684 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5688 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5690 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5692 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5695 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5696 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5697 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5699 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5701 @li name:intvar, ÀâÌÀ:"value is an integer",
5702 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5704 @li name:symvar, ÀâÌÀ:"value is a symbol",
5705 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5707 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5708 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5710 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5713 (intvar ("value is an integer" 0 (0 3) 10 20)
5714 symvar ("value is a symbol" nil a b c nil)
5715 txtvar ("value is an M-text" ""))
5719 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5720 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5721 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5724 minput_get_variables (MSymbol language, MSymbol name)
5726 MInputMethodInfo *im_info;
5731 im_info = get_im_info (language, name, Mnil, Mvariable);
5732 if (! im_info || ! im_info->configured_vars)
5735 M17N_OBJECT_UNREF (im_info->bc_vars);
5736 im_info->bc_vars = mplist ();
5737 MPLIST_DO (vars, im_info->configured_vars)
5739 MPlist *plist = MPLIST_PLIST (vars);
5740 MPlist *elt = mplist ();
5742 mplist_push (im_info->bc_vars, Mplist, elt);
5743 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5744 elt = MPLIST_NEXT (elt);
5745 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5746 M17N_OBJECT_UNREF (elt);
5748 return im_info->bc_vars;
5754 @brief Set the initial value of an input method variable.
5756 The minput_set_variable () function sets the initial value of
5757 input method variable $VARIABLE to $VALUE for the input method
5758 specified by $LANGUAGE and $NAME.
5760 By default, the initial value is 0.
5762 This setting gets effective in a newly opened input method.
5765 If the operation was successful, 0 is returned. Otherwise -1 is
5766 returned, and #merror_code is set to #MERROR_IM. */
5768 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5770 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5771 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5772 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5774 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5776 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5779 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5780 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5783 minput_set_variable (MSymbol language, MSymbol name,
5784 MSymbol variable, void *value)
5787 MInputMethodInfo *im_info;
5792 if (variable == Mnil)
5793 MERROR (MERROR_IM, -1);
5794 plist = minput_get_variable (language, name, variable);
5795 plist = MPLIST_PLIST (plist);
5796 plist = MPLIST_NEXT (plist);
5798 mplist_add (pl, MPLIST_KEY (plist), value);
5799 ret = minput_config_variable (language, name, variable, pl);
5800 M17N_OBJECT_UNREF (pl);
5803 im_info = get_im_info (language, name, Mnil, Mvariable);
5812 @brief Get information about input method commands.
5814 The minput_get_commands () function returns information about
5815 input method commands of the input method specified by $LANGUAGE
5816 and $NAME. An input method command is a pseudo key event to which
5817 one or more actual input key sequences are assigned.
5819 There are two kinds of commands, global and local. Global
5820 commands are used by multiple input methods for the same purpose,
5821 and have global key assignments. Local commands are used only by
5822 a specific input method, and have only local key assignments.
5824 Each input method may locally change key assignments for global
5825 commands. The global key assignment for a global command is
5826 effective only when the current input method does not have local
5827 key assignments for that command.
5829 If $NAME is #Mnil, information about global commands is returned.
5830 In this case $LANGUAGE is ignored.
5832 If $NAME is not #Mnil, information about those commands that have
5833 local key assignments in the input method specified by $LANGUAGE
5834 and $NAME is returned.
5837 If no input method commands are found, this function returns @c NULL.
5839 Otherwise, a pointer to a plist is returned. The key of each
5840 element in the plist is a symbol representing a command, and the
5841 value is a plist of the form COMMAND-INFO described below.
5843 The first element of COMMAND-INFO has the key #Mtext, and the
5844 value is an M-text describing the command.
5846 If there are no more elements, that means no key sequences are
5847 assigned to the command. Otherwise, each of the remaining
5848 elements has the key #Mplist, and the value is a plist whose keys are
5849 #Msymbol and values are symbols representing input keys, which are
5850 currently assigned to the command.
5852 As the returned plist is kept in the library, the caller must not
5853 modify nor free it. */
5855 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5857 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5858 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5859 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5860 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5862 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5863 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5864 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5865 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5867 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5868 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5869 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5872 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5873 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5875 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5876 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5880 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5882 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5883 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5884 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5886 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5887 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5888 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5891 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5892 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5893 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5894 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5895 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5897 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5898 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5901 minput_get_commands (MSymbol language, MSymbol name)
5903 MInputMethodInfo *im_info;
5908 im_info = get_im_info (language, name, Mnil, Mcommand);
5909 if (! im_info || ! im_info->configured_vars)
5911 M17N_OBJECT_UNREF (im_info->bc_cmds);
5912 im_info->bc_cmds = mplist ();
5913 MPLIST_DO (cmds, im_info->configured_cmds)
5915 MPlist *plist = MPLIST_PLIST (cmds);
5916 MPlist *elt = mplist ();
5918 mplist_push (im_info->bc_cmds, Mplist, elt);
5919 mplist_add (elt, MPLIST_SYMBOL (plist),
5920 mplist_copy (MPLIST_NEXT (plist)));
5921 M17N_OBJECT_UNREF (elt);
5923 return im_info->bc_cmds;
5929 @brief Assign a key sequence to an input method command (obsolete).
5931 This function is obsolete. Use minput_config_command () instead.
5933 The minput_assign_command_keys () function assigns input key
5934 sequence $KEYSEQ to input method command $COMMAND for the input
5935 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5936 key sequence is assigned globally no matter what $LANGUAGE is.
5937 Otherwise the key sequence is assigned locally.
5939 Each element of $KEYSEQ must have the key $Msymbol and the value
5940 must be a symbol representing an input key.
5942 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5943 globally or locally.
5945 This assignment gets effective in a newly opened input method.
5948 If the operation was successful, 0 is returned. Otherwise -1 is
5949 returned, and #merror_code is set to #MERROR_IM. */
5951 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5953 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5954 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5955 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5956 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5957 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5959 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5960 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5962 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5963 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5965 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5968 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5969 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5972 minput_assign_command_keys (MSymbol language, MSymbol name,
5973 MSymbol command, MPlist *keyseq)
5979 if (command == Mnil)
5980 MERROR (MERROR_IM, -1);
5985 if (! check_command_keyseq (keyseq))
5986 MERROR (MERROR_IM, -1);
5988 mplist_add (plist, Mplist, keyseq);
5993 ret = minput_config_command (language, name, command, keyseq);
5994 M17N_OBJECT_UNREF (keyseq);
6001 @brief Call a callback function
6003 The minput_callback () functions calls a callback function
6004 $COMMAND assigned for the input context $IC. The caller must set
6005 specific elements in $IC->plist if the callback function requires.
6008 If there exists a specified callback function, 0 is returned.
6009 Otherwise -1 is returned. By side effects, $IC->plist may be
6013 minput_callback (MInputContext *ic, MSymbol command)
6015 MInputCallbackFunc func;
6017 if (! ic->im->driver.callback_list)
6019 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
6023 (func) (ic, command);
6030 /*** @addtogroup m17nDebug */
6036 @brief Dump an input method.
6038 The mdebug_dump_im () function prints the input method $IM in a
6039 human readable way to the stderr. $INDENT specifies how many
6040 columns to indent the lines but the first one.
6043 This function returns $IM. */
6045 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6047 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6048 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6051 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6054 mdebug_dump_im (MInputMethod *im, int indent)
6056 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6059 prefix = (char *) alloca (indent + 1);
6060 memset (prefix, 32, indent);
6061 prefix[indent] = '\0';
6063 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6064 msymbol_name (im->name));
6065 mdebug_dump_mtext (im_info->title, 0, 0);
6066 if (im->name != Mnil)
6070 MPLIST_DO (state, im_info->states)
6072 fprintf (stderr, "\n%s ", prefix);
6073 dump_im_state (MPLIST_VAL (state), indent + 2);
6076 fprintf (stderr, ")");