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., 59 Temple Place, Suite 330, Boston, MA
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 (ic_info->preceding_text)
552 len = mtext_nchars (ic_info->preceding_text);
554 return mtext_ref_char (ic_info->preceding_text, len - pos);
556 mt = get_surrounding_text (ic, - pos);
559 len = mtext_nchars (mt);
560 if (ic_info->preceding_text)
562 if (mtext_nchars (ic_info->preceding_text) < len)
564 M17N_OBJECT_UNREF (ic_info->preceding_text);
565 ic_info->preceding_text = mt;
569 ic_info->preceding_text = mt;
572 return mtext_ref_char (ic_info->preceding_text, len - pos);
576 get_following_char (MInputContext *ic, int pos)
578 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
582 if (ic_info->following_text)
584 len = mtext_nchars (ic_info->following_text);
586 return mtext_ref_char (ic_info->following_text, pos - 1);
588 mt = get_surrounding_text (ic, pos);
591 len = mtext_nchars (mt);
592 if (ic_info->following_text)
594 if (mtext_nchars (ic_info->following_text) < len)
596 M17N_OBJECT_UNREF (ic_info->following_text);
597 ic_info->following_text = mt;
601 ic_info->following_text = mt;
604 return mtext_ref_char (ic_info->following_text, pos - 1);
608 surrounding_pos (MSymbol sym)
614 name = MSYMBOL_NAME (sym);
616 && (name[1] == '-' || name[1] == '+')
617 && name[2] >= '1' && name[2] <= '9')
618 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
623 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
625 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
627 MText *preedit = ic->preedit;
628 int len = mtext_nchars (preedit);
632 if (MPLIST_INTEGER_P (arg))
633 return MPLIST_INTEGER (arg);
635 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
638 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
642 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
645 return ic_info->key_head;
646 if ((code == '-' || code == '+'))
648 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
652 pos = atoi (name + 1);
654 return get_preceding_char (ic, 0);
655 pos = ic->cursor_pos + pos;
657 return get_preceding_char (ic, - pos);
659 return get_following_char (ic, pos - len + 1);
662 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
664 else if (code >= '0' && code <= '9')
666 else if (code == '=')
667 pos = ic->cursor_pos;
668 else if (code == '[')
669 pos = ic->cursor_pos - 1;
670 else if (code == ']')
671 pos = ic->cursor_pos + 1;
672 else if (code == '<')
674 else if (code == '>')
676 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
680 parse_expression (MPlist *plist)
684 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
686 if (! MPLIST_PLIST_P (plist))
688 plist = MPLIST_PLIST (plist);
689 op = MPLIST_SYMBOL (plist);
690 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
691 && op != Mand && op != Mor && op != Mnot
692 && op != Mless && op != Mgreater && op != Mequal
693 && op != Mless_equal && op != Mgreater_equal)
694 MERROR (MERROR_IM, -1);
695 MPLIST_DO (plist, MPLIST_NEXT (plist))
696 if (parse_expression (plist) < 0)
702 resolve_expression (MInputContext *ic, MPlist *plist)
707 if (MPLIST_INTEGER_P (plist))
708 return MPLIST_INTEGER (plist);
709 if (MPLIST_SYMBOL_P (plist))
710 return integer_value (ic, plist, NULL, 1);
711 if (! MPLIST_PLIST_P (plist))
713 plist = MPLIST_PLIST (plist);
714 if (! MPLIST_SYMBOL_P (plist))
716 op = MPLIST_SYMBOL (plist);
717 plist = MPLIST_NEXT (plist);
718 val = resolve_expression (ic, plist);
720 MPLIST_DO (plist, MPLIST_NEXT (plist))
721 val += resolve_expression (ic, plist);
722 else if (op == Mminus)
723 MPLIST_DO (plist, MPLIST_NEXT (plist))
724 val -= resolve_expression (ic, plist);
725 else if (op == Mstar)
726 MPLIST_DO (plist, MPLIST_NEXT (plist))
727 val *= resolve_expression (ic, plist);
728 else if (op == Mslash)
729 MPLIST_DO (plist, MPLIST_NEXT (plist))
730 val /= resolve_expression (ic, plist);
732 MPLIST_DO (plist, MPLIST_NEXT (plist))
733 val &= resolve_expression (ic, plist);
735 MPLIST_DO (plist, MPLIST_NEXT (plist))
736 val |= resolve_expression (ic, plist);
739 else if (op == Mless)
740 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
741 else if (op == Mequal)
742 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
743 else if (op == Mgreater)
744 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
745 else if (op == Mless_equal)
746 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
747 else if (op == Mgreater_equal)
748 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
752 /* Parse PLIST as an action list. PLIST should have this form:
753 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
754 Return 0 if successfully parsed, otherwise return -1. */
757 parse_action_list (MPlist *plist, MPlist *macros)
759 MPLIST_DO (plist, plist)
761 if (MPLIST_MTEXT_P (plist))
763 /* This is a short form of (insert MTEXT). */
764 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
765 MERROR (MERROR_IM, -1); */
767 else if (MPLIST_PLIST_P (plist)
768 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
769 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
773 /* This is a short form of (insert (GROUPS *)). */
774 MPLIST_DO (pl, MPLIST_PLIST (plist))
776 if (MPLIST_PLIST_P (pl))
780 MPLIST_DO (elt, MPLIST_PLIST (pl))
781 if (! MPLIST_MTEXT_P (elt)
782 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
783 MERROR (MERROR_IM, -1);
787 if (! MPLIST_MTEXT_P (pl)
788 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
789 MERROR (MERROR_IM, -1);
793 else if (MPLIST_INTEGER_P (plist))
795 int c = MPLIST_INTEGER (plist);
797 if (c < 0 || c > MCHAR_MAX)
798 MERROR (MERROR_IM, -1);
800 else if (MPLIST_PLIST_P (plist)
801 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
803 MPlist *pl = MPLIST_PLIST (plist);
804 MSymbol action_name = MPLIST_SYMBOL (pl);
806 pl = MPLIST_NEXT (pl);
808 if (action_name == Minsert)
810 if (MPLIST_MTEXT_P (pl))
812 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
813 MERROR (MERROR_IM, -1);
815 else if (MPLIST_PLIST_P (pl))
819 if (MPLIST_PLIST_P (pl))
823 MPLIST_DO (elt, MPLIST_PLIST (pl))
824 if (! MPLIST_MTEXT_P (elt)
825 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
826 MERROR (MERROR_IM, -1);
830 if (! MPLIST_MTEXT_P (pl)
831 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
832 MERROR (MERROR_IM, -1);
836 else if (! MPLIST_SYMBOL_P (pl))
837 MERROR (MERROR_IM, -1);
839 else if (action_name == Mselect
840 || action_name == Mdelete
841 || action_name == Mmove)
843 if (parse_expression (pl) < 0)
846 else if (action_name == Mmark
847 || action_name == Mcall
848 || action_name == Mshift)
850 if (! MPLIST_SYMBOL_P (pl))
851 MERROR (MERROR_IM, -1);
853 else if (action_name == Mundo)
855 if (! MPLIST_TAIL_P (pl))
857 if (! MPLIST_SYMBOL_P (pl)
858 && (! MPLIST_INTEGER_P (pl)
859 || MPLIST_INTEGER (pl) == 0))
860 MERROR (MERROR_IM, -1);
863 else if (action_name == Mpushback)
865 if (MPLIST_MTEXT_P (pl))
867 MText *mt = MPLIST_MTEXT (pl);
869 if (mtext_nchars (mt) != mtext_nbytes (mt))
870 MERROR (MERROR_IM, -1);
872 else if (MPLIST_PLIST_P (pl))
876 MPLIST_DO (p, MPLIST_PLIST (pl))
877 if (! MPLIST_SYMBOL_P (p))
878 MERROR (MERROR_IM, -1);
880 else if (! MPLIST_INTEGER_P (pl))
881 MERROR (MERROR_IM, -1);
883 else if (action_name == Mset || action_name == Madd
884 || action_name == Msub || action_name == Mmul
885 || action_name == Mdiv)
887 if (! MPLIST_SYMBOL_P (pl))
888 MERROR (MERROR_IM, -1);
889 if (parse_expression (MPLIST_NEXT (pl)) < 0)
892 else if (action_name == Mequal || action_name == Mless
893 || action_name == Mgreater || action_name == Mless_equal
894 || action_name == Mgreater_equal)
896 if (parse_expression (pl) < 0
897 || parse_expression (MPLIST_NEXT (pl)) < 0)
899 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
900 if (! MPLIST_PLIST_P (pl))
901 MERROR (MERROR_IM, -1);
902 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
903 MERROR (MERROR_IM, -1);
904 pl = MPLIST_NEXT (pl);
905 if (MPLIST_PLIST_P (pl)
906 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
907 MERROR (MERROR_IM, -1);
909 else if (action_name == Mshow || action_name == Mhide
910 || action_name == Mcommit || action_name == Munhandle)
912 else if (action_name == Mcond)
915 if (! MPLIST_PLIST_P (pl))
916 MERROR (MERROR_IM, -1);
918 else if (! macros || ! mplist_get (macros, action_name))
919 MERROR (MERROR_IM, -1);
921 else if (! MPLIST_SYMBOL_P (plist))
922 MERROR (MERROR_IM, -1);
929 resolve_command (MPlist *cmds, MSymbol command)
933 if (! cmds || ! (plist = mplist__assq (cmds, command)))
935 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
936 plist = MPLIST_NEXT (plist);
937 plist = MPLIST_NEXT (plist);
938 plist = MPLIST_NEXT (plist);
942 /* Load a translation into MAP from PLIST.
944 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
947 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
948 MPlist *branch_actions, MPlist *macros)
953 if (MPLIST_MTEXT_P (keylist))
955 MText *mt = MPLIST_MTEXT (keylist);
957 len = mtext_nchars (mt);
958 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
960 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
961 for (i = 0; i < len; i++)
962 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
968 if (MFAILP (MPLIST_PLIST_P (keylist)))
970 elt = MPLIST_PLIST (keylist);
971 len = MPLIST_LENGTH (elt);
972 if (MFAILP (len > 0))
974 keyseq = (MSymbol *) alloca (sizeof (int) * len);
975 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
977 if (MPLIST_INTEGER_P (elt))
979 int c = MPLIST_INTEGER (elt);
981 if (MFAILP (c >= 0 && c < 0x100))
983 keyseq[i] = one_char_symbol[c];
987 if (MFAILP (MPLIST_SYMBOL_P (elt)))
989 keyseq[i] = MPLIST_SYMBOL (elt);
994 for (i = 0; i < len; i++)
996 MIMMap *deeper = NULL;
999 deeper = mplist_get (map->submaps, keyseq[i]);
1001 map->submaps = mplist ();
1004 /* Fixme: It is better to make all deeper maps at once. */
1005 MSTRUCT_CALLOC (deeper, MERROR_IM);
1006 mplist_put (map->submaps, keyseq[i], deeper);
1011 /* We reach a terminal map. */
1012 if (map->map_actions
1013 || map->branch_actions)
1014 /* This map is already defined. We avoid overriding it. */
1017 if (! MPLIST_TAIL_P (map_actions))
1019 if (parse_action_list (map_actions, macros) < 0)
1020 MERROR (MERROR_IM, -1);
1021 map->map_actions = map_actions;
1025 map->branch_actions = branch_actions;
1026 M17N_OBJECT_REF (branch_actions);
1032 /* Load a branch from PLIST into MAP. PLIST has this form:
1033 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1036 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1039 MPlist *branch_actions;
1041 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1043 map_name = MPLIST_SYMBOL (plist);
1044 plist = MPLIST_NEXT (plist);
1045 if (MPLIST_TAIL_P (plist))
1046 branch_actions = NULL;
1047 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1050 branch_actions = plist;
1051 if (map_name == Mnil)
1053 map->branch_actions = branch_actions;
1055 M17N_OBJECT_REF (branch_actions);
1057 else if (map_name == Mt)
1059 map->map_actions = branch_actions;
1061 M17N_OBJECT_REF (branch_actions);
1063 else if (im_info->maps
1064 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1066 MPLIST_DO (plist, plist)
1068 MPlist *keylist, *map_actions;
1070 if (! MPLIST_PLIST_P (plist))
1071 MERROR (MERROR_IM, -1);
1072 keylist = MPLIST_PLIST (plist);
1073 map_actions = MPLIST_NEXT (keylist);
1074 if (MPLIST_SYMBOL_P (keylist))
1076 MSymbol command = MPLIST_SYMBOL (keylist);
1079 if (MFAILP (command != Mat_reload))
1081 pl = resolve_command (im_info->configured_cmds, command);
1085 load_translation (map, pl, map_actions, branch_actions,
1089 load_translation (map, keylist, map_actions, branch_actions,
1097 /* Load a macro from PLIST into IM_INFO->macros.
1098 PLIST has this from:
1099 PLIST ::= ( MACRO-NAME ACTION * )
1100 IM_INFO->macros is a plist of macro names vs action list. */
1103 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1108 if (! MPLIST_SYMBOL_P (plist))
1109 MERROR (MERROR_IM, -1);
1110 name = MPLIST_SYMBOL (plist);
1111 plist = MPLIST_NEXT (plist);
1112 if (MPLIST_TAIL_P (plist)
1113 || parse_action_list (plist, im_info->macros) < 0)
1114 MERROR (MERROR_IM, -1);
1115 pl = mplist_get (im_info->macros, name);
1116 M17N_OBJECT_UNREF (pl);
1117 mplist_put (im_info->macros, name, plist);
1118 M17N_OBJECT_REF (plist);
1122 /* Load an external module from PLIST into IM_INFO->externals.
1123 PLIST has this form:
1124 PLIST ::= ( MODULE-NAME FUNCTION * )
1125 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1128 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1133 MIMExternalModule *external;
1137 if (MPLIST_MTEXT_P (plist))
1138 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1139 else if (MPLIST_SYMBOL_P (plist))
1140 module = MPLIST_SYMBOL (plist);
1141 module_file = alloca (strlen (MSYMBOL_NAME (module))
1142 + strlen (DLOPEN_SHLIB_EXT) + 1);
1143 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1145 handle = dlopen (module_file, RTLD_NOW);
1146 if (MFAILP (handle))
1148 fprintf (stderr, "%s\n", dlerror ());
1151 func_list = mplist ();
1152 MPLIST_DO (plist, MPLIST_NEXT (plist))
1154 if (! MPLIST_SYMBOL_P (plist))
1155 MERROR_GOTO (MERROR_IM, err_label);
1156 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1159 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1162 MSTRUCT_MALLOC (external, MERROR_IM);
1163 external->handle = handle;
1164 external->func_list = func_list;
1165 mplist_add (im_info->externals, module, external);
1170 M17N_OBJECT_UNREF (func_list);
1175 free_map (MIMMap *map, int top)
1180 M17N_OBJECT_UNREF (map->map_actions);
1183 MPLIST_DO (plist, map->submaps)
1184 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1185 M17N_OBJECT_UNREF (map->submaps);
1187 M17N_OBJECT_UNREF (map->branch_actions);
1192 free_state (void *object)
1194 MIMState *state = object;
1196 M17N_OBJECT_UNREF (state->title);
1198 free_map (state->map, 1);
1202 /** Load a state from PLIST into a newly allocated state object.
1203 PLIST has this form:
1204 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1205 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1206 Return the state object. */
1209 load_state (MInputMethodInfo *im_info, MPlist *plist)
1213 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1215 M17N_OBJECT (state, free_state, MERROR_IM);
1216 state->name = MPLIST_SYMBOL (plist);
1217 plist = MPLIST_NEXT (plist);
1218 if (MPLIST_MTEXT_P (plist))
1220 state->title = MPLIST_MTEXT (plist);
1221 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1222 Mlanguage, im_info->language);
1223 M17N_OBJECT_REF (state->title);
1224 plist = MPLIST_NEXT (plist);
1226 MSTRUCT_CALLOC (state->map, MERROR_IM);
1227 MPLIST_DO (plist, plist)
1229 if (MFAILP (MPLIST_PLIST_P (plist)))
1231 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1236 /* Return a newly created IM_INFO for an input method specified by
1237 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1239 static MInputMethodInfo *
1240 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1243 MInputMethodInfo *im_info;
1246 if (name == Mnil && extra == Mnil)
1247 language = Mt, extra = Mglobal;
1248 MSTRUCT_CALLOC (im_info, MERROR_IM);
1250 im_info->language = language;
1251 im_info->name = name;
1252 im_info->extra = extra;
1255 mplist_add (plist, Mplist, elt);
1256 M17N_OBJECT_UNREF (elt);
1257 elt = mplist_add (elt, Msymbol, language);
1258 elt = mplist_add (elt, Msymbol, name);
1259 elt = mplist_add (elt, Msymbol, extra);
1260 mplist_add (elt, Mt, im_info);
1266 fini_im_info (MInputMethodInfo *im_info)
1270 M17N_OBJECT_UNREF (im_info->cmds);
1271 M17N_OBJECT_UNREF (im_info->configured_cmds);
1272 M17N_OBJECT_UNREF (im_info->bc_cmds);
1273 M17N_OBJECT_UNREF (im_info->vars);
1274 M17N_OBJECT_UNREF (im_info->configured_vars);
1275 M17N_OBJECT_UNREF (im_info->bc_vars);
1276 M17N_OBJECT_UNREF (im_info->description);
1277 M17N_OBJECT_UNREF (im_info->title);
1278 if (im_info->states)
1280 MPLIST_DO (plist, im_info->states)
1282 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1284 M17N_OBJECT_UNREF (state);
1286 M17N_OBJECT_UNREF (im_info->states);
1289 if (im_info->macros)
1291 MPLIST_DO (plist, im_info->macros)
1292 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1293 M17N_OBJECT_UNREF (im_info->macros);
1296 if (im_info->externals)
1298 MPLIST_DO (plist, im_info->externals)
1300 MIMExternalModule *external = MPLIST_VAL (plist);
1302 dlclose (external->handle);
1303 M17N_OBJECT_UNREF (external->func_list);
1305 MPLIST_KEY (plist) = Mt;
1307 M17N_OBJECT_UNREF (im_info->externals);
1311 MPLIST_DO (plist, im_info->maps)
1313 MPlist *p = MPLIST_PLIST (plist);
1315 M17N_OBJECT_UNREF (p);
1317 M17N_OBJECT_UNREF (im_info->maps);
1324 free_im_info (MInputMethodInfo *im_info)
1326 fini_im_info (im_info);
1331 free_im_list (MPlist *plist)
1335 MPLIST_DO (pl, plist)
1337 MInputMethodInfo *im_info;
1339 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1340 im_info = MPLIST_VAL (elt);
1341 free_im_info (im_info);
1343 M17N_OBJECT_UNREF (plist);
1346 static MInputMethodInfo *
1347 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1349 if (name == Mnil && extra == Mnil)
1350 language = Mt, extra = Mglobal;
1351 while ((plist = mplist__assq (plist, language)))
1353 MPlist *elt = MPLIST_PLIST (plist);
1355 plist = MPLIST_NEXT (plist);
1356 elt = MPLIST_NEXT (elt);
1357 if (MPLIST_SYMBOL (elt) != name)
1359 elt = MPLIST_NEXT (elt);
1360 if (MPLIST_SYMBOL (elt) != extra)
1362 elt = MPLIST_NEXT (elt);
1363 return MPLIST_VAL (elt);
1368 static void load_im_info (MPlist *, MInputMethodInfo *);
1370 #define get_custom_info(im_info) \
1372 ? lookup_im_info (im_custom_list, (im_info)->language, \
1373 (im_info)->name, (im_info)->extra) \
1376 #define get_config_info(im_info) \
1378 ? lookup_im_info (im_config_list, (im_info)->language, \
1379 (im_info)->name, (im_info)->extra) \
1383 update_custom_info (void)
1389 if (mdatabase__check (im_custom_mdb) > 0)
1394 MDatabaseInfo *custom_dir_info;
1395 char custom_path[PATH_MAX + 1];
1397 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1398 if (! custom_dir_info->filename
1399 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1401 strcpy (custom_path, custom_dir_info->filename);
1402 strcat (custom_path, CUSTOM_FILE);
1403 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1409 free_im_list (im_custom_list);
1410 im_custom_list = NULL;
1412 plist = mdatabase_load (im_custom_mdb);
1415 im_custom_list = mplist ();
1417 MPLIST_DO (pl, plist)
1419 MSymbol language, name, extra;
1420 MInputMethodInfo *im_info;
1421 MPlist *im_data, *p;
1423 if (! MPLIST_PLIST_P (pl))
1425 p = MPLIST_PLIST (pl);
1426 im_data = MPLIST_NEXT (p);
1427 if (! MPLIST_PLIST_P (p))
1429 p = MPLIST_PLIST (p);
1430 if (! MPLIST_SYMBOL_P (p)
1431 || MPLIST_SYMBOL (p) != Minput_method)
1433 p = MPLIST_NEXT (p);
1434 if (! MPLIST_SYMBOL_P (p))
1436 language = MPLIST_SYMBOL (p);
1437 p = MPLIST_NEXT (p);
1438 if (! MPLIST_SYMBOL_P (p))
1440 name = MPLIST_SYMBOL (p);
1441 if (language == Mnil || name == Mnil)
1443 p = MPLIST_NEXT (p);
1444 if (MPLIST_TAIL_P (p))
1446 else if (MPLIST_SYMBOL_P (p))
1447 extra = MPLIST_SYMBOL (p);
1450 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1451 load_im_info (im_data, im_info);
1453 M17N_OBJECT_UNREF (plist);
1458 update_global_info (void)
1464 int ret = mdatabase__check (global_info->mdb);
1468 fini_im_info (global_info);
1472 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1474 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1476 if (! global_info->mdb
1477 || ! (plist = mdatabase_load (global_info->mdb)))
1480 load_im_info (plist, global_info);
1481 M17N_OBJECT_UNREF (plist);
1486 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1487 and EXTRA. KEY, if not Mnil, tells which kind of information about
1488 the input method is necessary, and the returned IM_INFO may contain
1489 only that information. */
1491 static MInputMethodInfo *
1492 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1495 MInputMethodInfo *im_info;
1498 if (name == Mnil && extra == Mnil)
1499 language = Mt, extra = Mglobal;
1500 im_info = lookup_im_info (im_info_list, language, name, extra);
1503 if (key == Mnil ? im_info->states != NULL
1504 : key == Mcommand ? im_info->cmds != NULL
1505 : key == Mvariable ? im_info->vars != NULL
1506 : key == Mtitle ? im_info->title != NULL
1507 : key == Mdescription ? im_info->description != NULL
1509 /* IM_INFO already contains required information. */
1511 /* We have not yet loaded required information. */
1515 mdb = mdatabase_find (Minput_method, language, name, extra);
1518 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1523 plist = mdatabase_load (im_info->mdb);
1527 mplist_push (load_im_info_keys, key, Mt);
1528 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1529 mplist_pop (load_im_info_keys);
1533 MERROR (MERROR_IM, im_info);
1534 update_global_info ();
1535 load_im_info (plist, im_info);
1536 M17N_OBJECT_UNREF (plist);
1539 if (! im_info->cmds)
1540 im_info->cmds = mplist ();
1541 if (! im_info->vars)
1542 im_info->vars = mplist ();
1544 if (! im_info->title
1545 && (key == Mnil || key == Mtitle))
1546 im_info->title = (name == Mnil ? mtext ()
1547 : mtext_from_data (MSYMBOL_NAME (name),
1548 MSYMBOL_NAMELEN (name),
1549 MTEXT_FORMAT_US_ASCII));
1553 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1554 If updated, but got unloadable, return -1. Otherwise, update
1555 contents of IM_INFO from the new database, and return 1. */
1558 reload_im_info (MInputMethodInfo *im_info)
1563 update_custom_info ();
1564 update_global_info ();
1565 check = mdatabase__check (im_info->mdb);
1568 plist = mdatabase_load (im_info->mdb);
1571 fini_im_info (im_info);
1572 load_im_info (plist, im_info);
1573 M17N_OBJECT_UNREF (plist);
1577 static MInputMethodInfo *
1578 get_im_info_by_tags (MPlist *plist)
1583 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1584 i++, plist = MPLIST_NEXT (plist))
1585 tag[i] = MPLIST_SYMBOL (plist);
1590 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1595 check_description (MPlist *plist)
1599 if (MPLIST_MTEXT_P (plist))
1601 if (MPLIST_PLIST_P (plist))
1603 MPlist *pl = MPLIST_PLIST (plist);
1605 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1607 pl =MPLIST_NEXT (pl);
1608 if (MFAILP (MPLIST_MTEXT_P (pl)))
1610 mt = MPLIST_MTEXT (pl);
1611 M17N_OBJECT_REF (mt);
1614 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1616 if (translated == (char *) MTEXT_DATA (mt))
1617 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1618 if (translated != (char *) MTEXT_DATA (mt))
1620 M17N_OBJECT_UNREF (mt);
1621 mt = mtext__from_data (translated, strlen (translated),
1622 MTEXT_FORMAT_UTF_8, 0);
1626 mplist_set (plist, Mtext, mt);
1627 M17N_OBJECT_UNREF (mt);
1630 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1636 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1640 check_command_keyseq (MPlist *keyseq)
1642 if (MPLIST_PLIST_P (keyseq))
1644 MPlist *p = MPLIST_PLIST (keyseq);
1647 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1651 if (MPLIST_MTEXT_P (keyseq))
1653 MText *mt = MPLIST_MTEXT (keyseq);
1656 for (i = 0; i < mtext_nchars (mt); i++)
1657 if (mtext_ref_char (mt, i) >= 256)
1664 /* Load command defitions from PLIST into IM_INFO->cmds.
1666 PLIST is well-formed and has this form;
1667 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1668 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1669 M-text or a plist of symbols.
1671 The returned list has the same form, but for each element...
1673 (1) If DESCRIPTION and the rest are omitted, the element is not
1674 stored in the returned list.
1676 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1677 description in global_info->cmds (if any). */
1680 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1684 im_info->cmds = tail = mplist ();
1686 MPLIST_DO (plist, MPLIST_NEXT (plist))
1688 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1691 if (MFAILP (MPLIST_PLIST_P (plist)))
1693 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1694 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1696 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1697 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1699 if (MFAILP (im_info != global_info))
1700 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1704 if (! check_description (p))
1705 mplist_set (p, Msymbol, Mnil);
1706 p = MPLIST_NEXT (p);
1707 while (! MPLIST_TAIL_P (p))
1709 if (MFAILP (check_command_keyseq (p)))
1710 mplist__pop_unref (p);
1712 p = MPLIST_NEXT (p);
1715 tail = mplist_add (tail, Mplist, pl);
1720 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1721 MPlist *config_cmds)
1723 MPlist *global = NULL, *custom = NULL, *config = NULL;
1726 MPlist *description = NULL, *keyseq;
1728 name = MPLIST_SYMBOL (plist);
1729 plist = MPLIST_NEXT (plist);
1730 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1731 description = plist;
1732 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1733 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1734 if (MPLIST_TAIL_P (plist))
1737 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1738 global = MPLIST_NEXT (MPLIST_PLIST (global));
1741 keyseq = MPLIST_NEXT (global);
1742 status = Minherited;
1752 keyseq = MPLIST_NEXT (plist);
1756 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1758 config = MPLIST_NEXT (MPLIST_PLIST (config));
1759 if (! MPLIST_TAIL_P (config))
1761 keyseq = MPLIST_NEXT (config);
1762 status = Mconfigured;
1765 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1767 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1768 if (! MPLIST_TAIL_P (custom))
1770 keyseq = MPLIST_NEXT (custom);
1771 status = Mcustomized;
1776 mplist_add (plist, Msymbol, name);
1778 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1780 mplist_add (plist, Msymbol, Mnil);
1781 mplist_add (plist, Msymbol, status);
1782 mplist__conc (plist, keyseq);
1787 config_all_commands (MInputMethodInfo *im_info)
1789 MPlist *global_cmds, *custom_cmds, *config_cmds;
1790 MInputMethodInfo *temp;
1791 MPlist *tail, *plist;
1793 M17N_OBJECT_UNREF (im_info->configured_cmds);
1795 if (MPLIST_TAIL_P (im_info->cmds)
1799 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1800 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1801 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1803 im_info->configured_cmds = tail = mplist ();
1804 MPLIST_DO (plist, im_info->cmds)
1806 MPlist *pl = config_command (MPLIST_PLIST (plist),
1807 global_cmds, custom_cmds, config_cmds);
1810 tail = mplist_add (tail, Mplist, pl);
1811 M17N_OBJECT_UNREF (pl);
1816 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1817 valid, return 0 if not. */
1820 check_variable_value (MPlist *val, MPlist *global)
1822 MSymbol type = MPLIST_KEY (val);
1823 MPlist *valids = MPLIST_NEXT (val);
1825 if (type != Minteger && type != Mtext && type != Msymbol)
1829 if (MPLIST_KEY (global) != Mt
1830 && MPLIST_KEY (global) != MPLIST_KEY (val))
1832 if (MPLIST_TAIL_P (valids))
1833 valids = MPLIST_NEXT (global);
1835 if (MPLIST_TAIL_P (valids))
1838 if (type == Minteger)
1840 int n = MPLIST_INTEGER (val);
1842 MPLIST_DO (valids, valids)
1844 if (MPLIST_INTEGER_P (valids))
1846 if (n == MPLIST_INTEGER (valids))
1849 else if (MPLIST_PLIST_P (valids))
1851 MPlist *p = MPLIST_PLIST (valids);
1852 int min_bound, max_bound;
1854 if (! MPLIST_INTEGER_P (p))
1855 MERROR (MERROR_IM, 0);
1856 min_bound = MPLIST_INTEGER (p);
1857 p = MPLIST_NEXT (p);
1858 if (! MPLIST_INTEGER_P (p))
1859 MERROR (MERROR_IM, 0);
1860 max_bound = MPLIST_INTEGER (p);
1861 if (n >= min_bound && n <= max_bound)
1866 else if (type == Msymbol)
1868 MSymbol sym = MPLIST_SYMBOL (val);
1870 MPLIST_DO (valids, valids)
1872 if (! MPLIST_SYMBOL_P (valids))
1873 MERROR (MERROR_IM, 0);
1874 if (sym == MPLIST_SYMBOL (valids))
1880 MText *mt = MPLIST_MTEXT (val);
1882 MPLIST_DO (valids, valids)
1884 if (! MPLIST_MTEXT_P (valids))
1885 MERROR (MERROR_IM, 0);
1886 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1891 return (MPLIST_TAIL_P (valids));
1894 /* Load variable defitions from PLIST into IM_INFO->vars.
1896 PLIST is well-formed and has this form;
1897 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1899 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1901 The returned list has the same form, but for each element...
1903 (1) If DESCRIPTION and the rest are omitted, the element is not
1904 stored in the returned list.
1906 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1907 description in global_info->vars (if any). */
1910 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1912 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1913 ? global_info->vars : NULL);
1916 im_info->vars = tail = mplist ();
1917 MPLIST_DO (plist, MPLIST_NEXT (plist))
1921 if (MFAILP (MPLIST_PLIST_P (plist)))
1923 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1924 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1926 if (im_info == global_info)
1928 /* Loading a global variable. */
1929 p = MPLIST_NEXT (pl);
1930 if (MPLIST_TAIL_P (p))
1931 mplist_add (p, Msymbol, Mnil);
1934 if (! check_description (p))
1935 mplist_set (p, Msymbol, Mnil);
1936 p = MPLIST_NEXT (p);
1937 if (MFAILP (! MPLIST_TAIL_P (p)
1938 && check_variable_value (p, NULL)))
1939 mplist_set (p, Mt, NULL);
1942 else if (im_info->mdb)
1944 /* Loading a local variable. */
1945 MSymbol name = MPLIST_SYMBOL (pl);
1946 MPlist *global = NULL;
1949 && (p = mplist__assq (global_vars, name)))
1951 /* P ::= ((NAME DESC ...) ...) */
1952 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1953 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1954 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1957 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1958 if (! MPLIST_TAIL_P (p))
1960 if (! check_description (p))
1961 mplist_set (p, Msymbol, Mnil);
1962 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1963 if (MFAILP (! MPLIST_TAIL_P (p)))
1964 mplist_set (p, Mt, NULL);
1967 MPlist *valid_values = MPLIST_NEXT (p);
1969 if (! MPLIST_TAIL_P (valid_values)
1970 ? MFAILP (check_variable_value (p, NULL))
1971 : global && MFAILP (check_variable_value (p, global)))
1972 mplist_set (p, Mt, NULL);
1978 /* Loading a variable customization. */
1979 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1980 if (MFAILP (! MPLIST_TAIL_P (p)))
1982 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1983 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1984 || MPLIST_MTEXT_P (p)))
1987 tail = mplist_add (tail, Mplist, pl);
1992 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
1993 MPlist *config_vars)
1995 MPlist *global = NULL, *custom = NULL, *config = NULL;
1996 MSymbol name = MPLIST_SYMBOL (plist);
1998 MPlist *description = NULL, *value, *valids;
2002 global = mplist__assq (global_vars, name);
2004 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2007 plist = MPLIST_NEXT (plist);
2008 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2009 description = plist;
2011 description = global;
2013 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2015 if (MPLIST_TAIL_P (plist))
2017 /* Inherit from global (if any). */
2021 if (MPLIST_KEY (value) == Mt)
2023 valids = MPLIST_NEXT (global);
2024 status = Minherited;
2036 value = plist = MPLIST_NEXT (plist);
2037 valids = MPLIST_NEXT (value);
2038 if (MPLIST_KEY (value) == Mt)
2040 if (! MPLIST_TAIL_P (valids))
2043 valids = MPLIST_NEXT (global);
2047 if (config_vars && (config = mplist__assq (config_vars, name)))
2049 config = MPLIST_NEXT (MPLIST_PLIST (config));
2050 if (! MPLIST_TAIL_P (config))
2052 value = MPLIST_NEXT (config);
2053 if (MFAILP (check_variable_value (value, global ? global : plist)))
2055 status = Mconfigured;
2058 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2060 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2061 if (! MPLIST_TAIL_P (custom))
2063 value = MPLIST_NEXT (custom);
2064 if (MFAILP (check_variable_value (value, global ? global : plist)))
2066 status = Mcustomized;
2071 mplist_add (plist, Msymbol, name);
2073 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2075 mplist_add (plist, Msymbol, Mnil);
2076 mplist_add (plist, Msymbol, status);
2078 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2080 mplist_add (plist, Mt, NULL);
2081 if (valids && ! MPLIST_TAIL_P (valids))
2082 mplist__conc (plist, valids);
2086 /* Return a configured variable definition list based on
2087 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2088 get it from global_info->vars. */
2091 config_all_variables (MInputMethodInfo *im_info)
2093 MPlist *global_vars, *custom_vars, *config_vars;
2094 MInputMethodInfo *temp;
2095 MPlist *tail, *plist;
2097 M17N_OBJECT_UNREF (im_info->configured_vars);
2099 if (MPLIST_TAIL_P (im_info->vars)
2103 global_vars = im_info != global_info ? global_info->vars : NULL;
2104 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2105 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2107 im_info->configured_vars = tail = mplist ();
2108 MPLIST_DO (plist, im_info->vars)
2110 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2111 global_vars, custom_vars, config_vars);
2114 tail = mplist_add (tail, Mplist, pl);
2115 M17N_OBJECT_UNREF (pl);
2120 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2121 CONFIG contains configuration information of the input method. */
2124 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2128 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2130 load_commands (im_info, MPLIST_PLIST (pl));
2131 config_all_commands (im_info);
2132 pl = mplist_pop (pl);
2133 M17N_OBJECT_UNREF (pl);
2136 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2138 load_variables (im_info, MPLIST_PLIST (pl));
2139 config_all_variables (im_info);
2140 pl = mplist_pop (pl);
2141 M17N_OBJECT_UNREF (pl);
2144 MPLIST_DO (plist, plist)
2145 if (MPLIST_PLIST_P (plist))
2147 MPlist *elt = MPLIST_PLIST (plist);
2150 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2152 key = MPLIST_SYMBOL (elt);
2157 elt = MPLIST_NEXT (elt);
2158 if (MFAILP (MPLIST_MTEXT_P (elt)))
2160 im_info->title = MPLIST_MTEXT (elt);
2161 M17N_OBJECT_REF (im_info->title);
2163 else if (key == Mmap)
2165 pl = mplist__from_alist (MPLIST_NEXT (elt));
2168 if (! im_info->maps)
2172 mplist__conc (im_info->maps, pl);
2173 M17N_OBJECT_UNREF (pl);
2176 else if (key == Mmacro)
2178 if (! im_info->macros)
2179 im_info->macros = mplist ();
2180 MPLIST_DO (elt, MPLIST_NEXT (elt))
2182 if (MFAILP (MPLIST_PLIST_P (elt)))
2184 load_macros (im_info, MPLIST_PLIST (elt));
2187 else if (key == Mmodule)
2189 if (! im_info->externals)
2190 im_info->externals = mplist ();
2191 MPLIST_DO (elt, MPLIST_NEXT (elt))
2193 if (MFAILP (MPLIST_PLIST_P (elt)))
2195 load_external_module (im_info, MPLIST_PLIST (elt));
2198 else if (key == Mstate)
2200 MPLIST_DO (elt, MPLIST_NEXT (elt))
2204 if (MFAILP (MPLIST_PLIST_P (elt)))
2206 pl = MPLIST_PLIST (elt);
2207 if (! im_info->states)
2208 im_info->states = mplist ();
2209 state = load_state (im_info, MPLIST_PLIST (elt));
2212 mplist_put (im_info->states, state->name, state);
2215 else if (key == Minclude)
2217 /* elt ::= include (tag1 tag2 ...) key item ... */
2219 MInputMethodInfo *temp;
2221 elt = MPLIST_NEXT (elt);
2222 if (MFAILP (MPLIST_PLIST_P (elt)))
2224 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2227 elt = MPLIST_NEXT (elt);
2228 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2230 key = MPLIST_SYMBOL (elt);
2231 elt = MPLIST_NEXT (elt);
2234 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2236 if (! im_info->maps)
2237 im_info->maps = mplist ();
2238 MPLIST_DO (pl, temp->maps)
2240 p = MPLIST_VAL (pl);
2241 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2242 M17N_OBJECT_REF (p);
2245 else if (key == Mmacro)
2247 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2249 if (! im_info->macros)
2250 im_info->macros = mplist ();
2251 MPLIST_DO (pl, temp->macros)
2253 p = MPLIST_VAL (pl);
2254 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2255 M17N_OBJECT_REF (p);
2258 else if (key == Mstate)
2260 if (! temp->states || MPLIST_TAIL_P (temp->states))
2262 if (! im_info->states)
2263 im_info->states = mplist ();
2264 MPLIST_DO (pl, temp->states)
2266 MIMState *state = MPLIST_VAL (pl);
2268 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2269 M17N_OBJECT_REF (state);
2273 else if (key == Mdescription)
2275 if (im_info->description)
2277 elt = MPLIST_NEXT (elt);
2278 if (! check_description (elt))
2280 im_info->description = MPLIST_MTEXT (elt);
2281 M17N_OBJECT_REF (im_info->description);
2284 im_info->tick = time (NULL);
2289 static int take_action_list (MInputContext *ic, MPlist *action_list);
2290 static void preedit_commit (MInputContext *ic);
2293 shift_state (MInputContext *ic, MSymbol state_name)
2295 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2296 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2297 MIMState *orig_state = ic_info->state, *state;
2299 /* Find a state to shift to. If not found, shift to the initial
2301 if (state_name == Mt)
2303 if (! ic_info->prev_state)
2305 state = ic_info->prev_state;
2307 else if (state_name == Mnil)
2309 state = (MIMState *) MPLIST_VAL (im_info->states);
2313 state = (MIMState *) mplist_get (im_info->states, state_name);
2315 state = (MIMState *) MPLIST_VAL (im_info->states);
2318 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2320 /* Enter the new state. */
2321 ic_info->state = state;
2322 ic_info->map = state->map;
2323 ic_info->state_key_head = ic_info->key_head;
2324 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2326 /* We have shifted to the initial state. */
2327 preedit_commit (ic);
2328 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2329 ic_info->state_pos = ic->cursor_pos;
2330 if (state != orig_state)
2332 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2334 /* Shifted to the initial state. */
2335 ic_info->prev_state = NULL;
2336 M17N_OBJECT_UNREF (ic_info->vars_saved);
2337 ic_info->vars_saved = mplist_copy (ic_info->vars);
2340 ic_info->prev_state = orig_state;
2343 ic->status = state->title;
2345 ic->status = im_info->title;
2346 ic->status_changed = 1;
2347 if (ic_info->map == ic_info->state->map
2348 && ic_info->map->map_actions)
2350 MDEBUG_PRINT (" init-actions:");
2351 take_action_list (ic, ic_info->map->map_actions);
2356 /* Find a candidate group that contains a candidate number INDEX from
2357 PLIST. Set START_INDEX to the first candidate number of the group,
2358 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2359 candidate group number if they are non-NULL. If INDEX is -1, find
2360 the last candidate group. */
2363 find_candidates_group (MPlist *plist, int index,
2364 int *start_index, int *end_index, int *group_index)
2366 int i = 0, gidx = 0, len;
2368 MPLIST_DO (plist, plist)
2370 if (MPLIST_MTEXT_P (plist))
2371 len = mtext_nchars (MPLIST_MTEXT (plist));
2373 len = mplist_length (MPLIST_PLIST (plist));
2374 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2380 *end_index = i + len;
2382 *group_index = gidx;
2392 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2394 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2396 int nchars = mt ? mtext_nchars (mt) : 1;
2399 mtext_ins (ic->preedit, pos, mt);
2401 mtext_ins_char (ic->preedit, pos, c, 1);
2402 MPLIST_DO (markers, ic_info->markers)
2403 if (MPLIST_INTEGER (markers) > pos)
2404 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
2405 if (ic->cursor_pos >= pos)
2406 ic->cursor_pos += nchars;
2407 ic->preedit_changed = 1;
2412 preedit_delete (MInputContext *ic, int from, int to)
2414 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2417 mtext_del (ic->preedit, from, to);
2418 MPLIST_DO (markers, ic_info->markers)
2420 if (MPLIST_INTEGER (markers) > to)
2421 MPLIST_VAL (markers)
2422 = (void *) (MPLIST_INTEGER (markers) - (to - from));
2423 else if (MPLIST_INTEGER (markers) > from);
2424 MPLIST_VAL (markers) = (void *) from;
2426 if (ic->cursor_pos >= to)
2427 ic->cursor_pos -= to - from;
2428 else if (ic->cursor_pos > from)
2429 ic->cursor_pos = from;
2430 ic->preedit_changed = 1;
2434 preedit_commit (MInputContext *ic)
2436 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2437 int preedit_len = mtext_nchars (ic->preedit);
2439 if (preedit_len > 0)
2443 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2444 Mcandidate_list, NULL, 0);
2445 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2446 Mcandidate_index, NULL, 0);
2447 mtext_cat (ic->produced, ic->preedit);
2448 mtext_reset (ic->preedit);
2449 mtext_reset (ic_info->preedit_saved);
2450 MPLIST_DO (p, ic_info->markers)
2452 ic->cursor_pos = ic_info->state_pos = 0;
2453 ic->preedit_changed = 1;
2455 if (ic->candidate_list)
2457 M17N_OBJECT_UNREF (ic->candidate_list);
2458 ic->candidate_list = NULL;
2459 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2460 if (ic->candidate_show)
2462 ic->candidate_show = 0;
2463 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2469 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2471 int code = marker_code (sym, 0);
2473 if (mt && (code == '[' || code == ']'))
2477 if (code == '[' && current > 0)
2479 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2483 else if (code == ']' && current < mtext_nchars (mt))
2485 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2491 return (code == '<' ? 0
2492 : code == '>' ? limit
2493 : code == '-' ? current - 1
2494 : code == '+' ? current + 1
2495 : code == '=' ? current
2496 : code - '0' > limit ? limit
2500 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2504 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2506 int from = mtext_property_start (prop);
2507 int to = mtext_property_end (prop);
2509 MPlist *candidate_list = mtext_property_value (prop);
2510 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2512 int ingroup_index = idx - start;
2515 preedit_delete (ic, from, to);
2516 if (MPLIST_MTEXT_P (group))
2518 mt = MPLIST_MTEXT (group);
2519 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
2527 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2528 i++, plist = MPLIST_NEXT (plist));
2529 mt = MPLIST_MTEXT (plist);
2530 preedit_insert (ic, from, mt, 0);
2531 to = from + mtext_nchars (mt);
2533 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2534 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2535 ic->cursor_pos = to;
2539 get_select_charset (MInputContextInfo * ic_info)
2541 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2544 if (! MPLIST_VAL (plist))
2546 sym = MPLIST_SYMBOL (plist);
2549 return MCHARSET (sym);
2553 adjust_candidates (MPlist *plist, MCharset *charset)
2557 /* plist ::= MTEXT ... | PLIST ... */
2558 plist = mplist_copy (plist);
2559 if (MPLIST_MTEXT_P (plist))
2562 while (! MPLIST_TAIL_P (pl))
2564 /* pl ::= MTEXT ... */
2565 MText *mt = MPLIST_MTEXT (pl);
2569 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2571 c = mtext_ref_char (mt, i);
2572 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2576 mt = mtext_dup (mt);
2577 mplist_set (pl, Mtext, mt);
2578 M17N_OBJECT_UNREF (mt);
2581 mtext_del (mt, i, i + 1);
2584 if (mtext_len (mt) > 0)
2585 pl = MPLIST_NEXT (pl);
2589 M17N_OBJECT_UNREF (mt);
2593 else /* MPLIST_PLIST_P (plist) */
2596 while (! MPLIST_TAIL_P (pl))
2598 /* pl ::= (MTEXT ...) ... */
2599 MPlist *p = MPLIST_PLIST (pl);
2601 /* p ::= MTEXT ... */
2605 while (! MPLIST_TAIL_P (p0))
2607 MText *mt = MPLIST_MTEXT (p0);
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)
2618 p0 = MPLIST_NEXT (p0);
2625 p = mplist_copy (p);
2626 mplist_set (pl, Mplist, p);
2627 M17N_OBJECT_UNREF (p);
2631 p0 = MPLIST_NEXT (p0);
2634 M17N_OBJECT_UNREF (mt);
2637 if (! MPLIST_TAIL_P (p))
2638 pl = MPLIST_NEXT (pl);
2642 M17N_OBJECT_UNREF (p);
2646 if (MPLIST_TAIL_P (plist))
2648 M17N_OBJECT_UNREF (plist);
2655 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2657 MCharset *charset = get_select_charset (ic_info);
2662 plist = resolve_variable (ic_info, Mcandidates_group_size);
2663 column = MPLIST_INTEGER (plist);
2665 plist = MPLIST_PLIST (args);
2667 plist = adjust_candidates (plist, charset);
2669 if (plist && column > 0)
2671 if (MPLIST_MTEXT_P (plist))
2673 MText *mt = MPLIST_MTEXT (plist);
2674 MPlist *next = MPLIST_NEXT (plist);
2676 if (MPLIST_TAIL_P (next))
2677 M17N_OBJECT_REF (mt);
2680 mt = mtext_dup (mt);
2681 while (! MPLIST_TAIL_P (next))
2683 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2684 next = MPLIST_NEXT (next);
2687 M17N_OBJECT_UNREF (plist);
2689 len = mtext_nchars (mt);
2691 mplist_add (plist, Mtext, mt);
2694 for (i = 0; i < len; i += column)
2696 int to = (i + column < len ? i + column : len);
2697 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2699 mplist_add (plist, Mtext, sub);
2700 M17N_OBJECT_UNREF (sub);
2703 M17N_OBJECT_UNREF (mt);
2705 else /* MPLIST_PLIST_P (plist) */
2707 MPlist *pl = MPLIST_PLIST (plist), *p;
2708 MPlist *next = MPLIST_NEXT (plist);
2711 if (MPLIST_TAIL_P (next))
2712 M17N_OBJECT_REF (pl);
2715 pl = mplist_copy (pl);
2716 while (! MPLIST_TAIL_P (next))
2718 p = mplist_copy (MPLIST_PLIST (next));
2719 pl = mplist__conc (pl, p);
2720 M17N_OBJECT_UNREF (p);
2721 next = MPLIST_NEXT (next);
2724 M17N_OBJECT_UNREF (plist);
2726 len = mplist_length (pl);
2728 mplist_add (plist, Mplist, pl);
2733 for (i = 0; i < len; i += column)
2736 mplist_add (plist, Mplist, p);
2737 M17N_OBJECT_UNREF (p);
2738 for (j = 0; j < column && i + j < len; j++)
2740 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
2741 p0 = MPLIST_NEXT (p0);
2745 M17N_OBJECT_UNREF (pl);
2754 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2756 MPlist *action = NULL;
2760 if (MPLIST_SYMBOL_P (action_list))
2762 MSymbol var = MPLIST_SYMBOL (action_list);
2765 MPLIST_DO (p, ic_info->vars)
2766 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2768 if (MPLIST_TAIL_P (p))
2770 action = MPLIST_NEXT (MPLIST_PLIST (p));
2771 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2774 if (MPLIST_PLIST_P (action_list))
2776 action = MPLIST_PLIST (action_list);
2777 if (MPLIST_SYMBOL_P (action))
2779 name = MPLIST_SYMBOL (action);
2780 args = MPLIST_NEXT (action);
2782 && MPLIST_PLIST_P (args))
2783 mplist_set (action, Msymbol, M_candidates);
2785 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2788 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2789 mplist_push (action, Msymbol, M_candidates);
2790 mplist_set (action_list, Mplist, action);
2791 M17N_OBJECT_UNREF (action);
2794 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2797 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2798 mplist_push (action, Msymbol, Minsert);
2799 mplist_set (action_list, Mplist, action);
2800 M17N_OBJECT_UNREF (action);
2805 /* Perform list of actions in ACTION_LIST for the current input
2806 context IC. If all actions are performed without error, return 0.
2807 Otherwise, return -1. */
2810 take_action_list (MInputContext *ic, MPlist *action_list)
2812 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2813 MPlist *candidate_list = ic->candidate_list;
2814 int candidate_index = ic->candidate_index;
2815 int candidate_show = ic->candidate_show;
2816 MTextProperty *prop;
2818 MPLIST_DO (action_list, action_list)
2820 MPlist *action = regularize_action (action_list, ic_info);
2826 name = MPLIST_SYMBOL (action);
2827 args = MPLIST_NEXT (action);
2829 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2830 if (name == Minsert)
2832 if (MPLIST_SYMBOL_P (args))
2834 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2835 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2838 if (MPLIST_MTEXT_P (args))
2839 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2840 else /* MPLIST_INTEGER_P (args)) */
2841 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2843 else if (name == M_candidates)
2845 MPlist *plist = get_candidate_list (ic_info, args);
2850 if (MPLIST_MTEXT_P (plist))
2852 preedit_insert (ic, ic->cursor_pos, NULL,
2853 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2858 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2860 preedit_insert (ic, ic->cursor_pos, mt, 0);
2861 len = mtext_nchars (mt);
2863 mtext_put_prop (ic->preedit,
2864 ic->cursor_pos - len, ic->cursor_pos,
2865 Mcandidate_list, plist);
2866 mtext_put_prop (ic->preedit,
2867 ic->cursor_pos - len, ic->cursor_pos,
2868 Mcandidate_index, (void *) 0);
2870 else if (name == Mselect)
2873 int code, idx, gindex;
2874 int pos = ic->cursor_pos;
2878 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2881 if (MPLIST_SYMBOL_P (args))
2883 code = marker_code (MPLIST_SYMBOL (args), 0);
2889 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2890 group = find_candidates_group (mtext_property_value (prop), idx,
2891 &start, &end, &gindex);
2893 if (code != '[' && code != ']')
2897 ? new_index (NULL, ic->candidate_index - start,
2898 end - start - 1, MPLIST_SYMBOL (args),
2900 : MPLIST_INTEGER (args)));
2903 find_candidates_group (mtext_property_value (prop), -1,
2908 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2913 int ingroup_index = idx - start;
2916 group = mtext_property_value (prop);
2917 len = mplist_length (group);
2930 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2931 idx += (MPLIST_MTEXT_P (group)
2932 ? mtext_nchars (MPLIST_MTEXT (group))
2933 : mplist_length (MPLIST_PLIST (group)));
2934 len = (MPLIST_MTEXT_P (group)
2935 ? mtext_nchars (MPLIST_MTEXT (group))
2936 : mplist_length (MPLIST_PLIST (group)));
2937 if (ingroup_index >= len)
2938 ingroup_index = len - 1;
2939 idx += ingroup_index;
2941 update_candidate (ic, prop, idx);
2943 else if (name == Mshow)
2944 ic->candidate_show = 1;
2945 else if (name == Mhide)
2946 ic->candidate_show = 0;
2947 else if (name == Mdelete)
2949 int len = mtext_nchars (ic->preedit);
2953 if (MPLIST_SYMBOL_P (args)
2954 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
2956 delete_surrounding_text (ic, pos);
2957 to = ic->cursor_pos + pos;
2960 delete_surrounding_text (ic, to);
2965 delete_surrounding_text (ic, to - len);
2971 to = (MPLIST_SYMBOL_P (args)
2972 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2974 : MPLIST_INTEGER (args));
2980 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
2981 if (to < ic->cursor_pos)
2982 preedit_delete (ic, to, ic->cursor_pos);
2983 else if (to > ic->cursor_pos)
2984 preedit_delete (ic, ic->cursor_pos, to);
2986 else if (name == Mmove)
2988 int len = mtext_nchars (ic->preedit);
2990 = (MPLIST_SYMBOL_P (args)
2991 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2993 : MPLIST_INTEGER (args));
2999 if (pos != ic->cursor_pos)
3001 ic->cursor_pos = pos;
3002 ic->preedit_changed = 1;
3005 else if (name == Mmark)
3007 int code = marker_code (MPLIST_SYMBOL (args), 0);
3010 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3011 (void *) ic->cursor_pos);
3013 else if (name == Mpushback)
3015 if (MPLIST_INTEGER_P (args))
3017 int num = MPLIST_INTEGER (args);
3020 ic_info->key_head -= num;
3022 ic_info->key_head = num;
3023 if (ic_info->key_head > ic_info->used)
3024 ic_info->key_head = ic_info->used;
3026 else if (MPLIST_MTEXT_P (args))
3028 MText *mt = MPLIST_MTEXT (args);
3029 int i, len = mtext_nchars (mt);
3032 ic_info->key_head--;
3033 for (i = 0; i < len; i++)
3035 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3036 if (ic_info->key_head + i < ic_info->used)
3037 ic_info->keys[ic_info->key_head + i] = key;
3039 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3044 MPlist *plist = MPLIST_PLIST (args), *pl;
3048 ic_info->key_head--;
3050 MPLIST_DO (pl, plist)
3052 key = MPLIST_SYMBOL (pl);
3053 if (ic_info->key_head < ic_info->used)
3054 ic_info->keys[ic_info->key_head + i] = key;
3056 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3061 else if (name == Mcall)
3063 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3064 MIMExternalFunc func = NULL;
3065 MSymbol module, func_name;
3066 MPlist *func_args, *val;
3069 module = MPLIST_SYMBOL (args);
3070 args = MPLIST_NEXT (args);
3071 func_name = MPLIST_SYMBOL (args);
3073 if (im_info->externals)
3075 MIMExternalModule *external
3076 = (MIMExternalModule *) mplist_get (im_info->externals,
3079 func = (MIMExternalFunc) mplist_get (external->func_list,
3084 func_args = mplist ();
3085 mplist_add (func_args, Mt, ic);
3086 MPLIST_DO (args, MPLIST_NEXT (args))
3090 if (MPLIST_KEY (args) == Msymbol
3091 && MPLIST_KEY (args) != Mnil
3092 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3094 code = new_index (ic, ic->cursor_pos,
3095 mtext_nchars (ic->preedit),
3096 MPLIST_SYMBOL (args), ic->preedit);
3097 mplist_add (func_args, Minteger, (void *) code);
3100 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3102 val = (func) (func_args);
3103 M17N_OBJECT_UNREF (func_args);
3104 if (val && ! MPLIST_TAIL_P (val))
3105 ret = take_action_list (ic, val);
3106 M17N_OBJECT_UNREF (val);
3110 else if (name == Mshift)
3112 shift_state (ic, MPLIST_SYMBOL (args));
3114 else if (name == Mundo)
3116 int intarg = (MPLIST_TAIL_P (args)
3118 : integer_value (ic, args, NULL, 0));
3120 mtext_reset (ic->preedit);
3121 mtext_reset (ic_info->preedit_saved);
3122 mtext_reset (ic->produced);
3123 M17N_OBJECT_UNREF (ic_info->vars);
3124 ic_info->vars = mplist_copy (ic_info->vars_saved);
3125 ic->cursor_pos = ic_info->state_pos = 0;
3126 ic_info->state_key_head = ic_info->key_head = 0;
3128 shift_state (ic, Mnil);
3131 if (MPLIST_TAIL_P (args))
3136 ic_info->used += intarg;
3139 ic_info->used = intarg;
3142 else if (name == Mset || name == Madd || name == Msub
3143 || name == Mmul || name == Mdiv)
3145 MSymbol sym = MPLIST_SYMBOL (args);
3150 val1 = integer_value (ic, args, &value, 0);
3151 args = MPLIST_NEXT (args);
3152 val2 = resolve_expression (ic, args);
3154 val1 = val2, op = "=";
3155 else if (name == Madd)
3156 val1 += val2, op = "+=";
3157 else if (name == Msub)
3158 val1 -= val2, op = "-=";
3159 else if (name == Mmul)
3160 val1 *= val2, op = "*=";
3162 val1 /= val2, op = "/=";
3163 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3164 MSYMBOL_NAME (sym), op, val1, val1);
3166 mplist_set (value, Minteger, (void *) val1);
3168 else if (name == Mequal || name == Mless || name == Mgreater
3169 || name == Mless_equal || name == Mgreater_equal)
3172 MPlist *actions1, *actions2;
3175 val1 = resolve_expression (ic, args);
3176 args = MPLIST_NEXT (args);
3177 val2 = resolve_expression (ic, args);
3178 args = MPLIST_NEXT (args);
3179 actions1 = MPLIST_PLIST (args);
3180 args = MPLIST_NEXT (args);
3181 if (MPLIST_TAIL_P (args))
3184 actions2 = MPLIST_PLIST (args);
3185 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3186 if (name == Mequal ? val1 == val2
3187 : name == Mless ? val1 < val2
3188 : name == Mgreater ? val1 > val2
3189 : name == Mless_equal ? val1 <= val2
3192 MDEBUG_PRINT ("ok");
3193 ret = take_action_list (ic, actions1);
3197 MDEBUG_PRINT ("no");
3199 ret = take_action_list (ic, actions2);
3204 else if (name == Mcond)
3208 MPLIST_DO (args, args)
3213 if (! MPLIST_PLIST (args))
3215 cond = MPLIST_PLIST (args);
3216 if (resolve_expression (ic, cond) != 0)
3218 MDEBUG_PRINT1 ("(%dth)", idx);
3219 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3225 else if (name == Mcommit)
3227 preedit_commit (ic);
3229 else if (name == Munhandle)
3231 preedit_commit (ic);
3236 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3240 && (actions = mplist_get (im_info->macros, name)))
3242 if (take_action_list (ic, actions) < 0)
3248 if (ic->candidate_list)
3250 M17N_OBJECT_UNREF (ic->candidate_list);
3251 ic->candidate_list = NULL;
3253 if (ic->cursor_pos > 0
3254 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3257 ic->candidate_list = mtext_property_value (prop);
3258 M17N_OBJECT_REF (ic->candidate_list);
3260 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3262 ic->candidate_from = mtext_property_start (prop);
3263 ic->candidate_to = mtext_property_end (prop);
3266 if (candidate_list != ic->candidate_list)
3267 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3268 if (candidate_index != ic->candidate_index)
3269 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3270 if (candidate_show != ic->candidate_show)
3271 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3276 /* Handle the input key KEY in the current state and map specified in
3277 the input context IC. If KEY is handled correctly, return 0.
3278 Otherwise, return -1. */
3281 handle_key (MInputContext *ic)
3283 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3284 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3285 MIMMap *map = ic_info->map;
3286 MIMMap *submap = NULL;
3287 MSymbol key = ic_info->keys[ic_info->key_head];
3288 MSymbol alias = Mnil;
3291 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3292 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3296 submap = mplist_get (map->submaps, key);
3299 && (alias = msymbol_get (alias, M_key_alias))
3301 submap = mplist_get (map->submaps, alias);
3306 if (! alias || alias == key)
3307 MDEBUG_PRINT (" submap-found");
3309 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3310 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3311 ic->preedit_changed = 1;
3312 ic->cursor_pos = ic_info->state_pos;
3313 ic_info->key_head++;
3314 ic_info->map = map = submap;
3315 if (map->map_actions)
3317 MDEBUG_PRINT (" map-actions:");
3318 if (take_action_list (ic, map->map_actions) < 0)
3320 MDEBUG_PRINT ("\n");
3324 else if (map->submaps)
3326 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3328 MSymbol key = ic_info->keys[i];
3329 char *name = msymbol_name (key);
3331 if (! name[0] || ! name[1])
3332 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3336 /* If this is the terminal map or we have shifted to another
3337 state, perform branch actions (if any). */
3338 if (! map->submaps || map != ic_info->map)
3340 if (map->branch_actions)
3342 MDEBUG_PRINT (" branch-actions:");
3343 if (take_action_list (ic, map->branch_actions) < 0)
3345 MDEBUG_PRINT ("\n");
3349 /* If MAP is still not the root map, shift to the current
3351 if (ic_info->map != ic_info->state->map)
3352 shift_state (ic, ic_info->state->name);
3357 /* MAP can not handle KEY. */
3359 /* If MAP is the root map of the initial state, it means that
3360 the current input method can not handle KEY. */
3361 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3363 MDEBUG_PRINT (" unhandled\n");
3367 if (map != ic_info->state->map)
3369 /* If MAP is not the root map... */
3370 /* If MAP has branch actions, perform them. */
3371 if (map->branch_actions)
3373 MDEBUG_PRINT (" branch-actions:");
3374 if (take_action_list (ic, map->branch_actions) < 0)
3376 MDEBUG_PRINT ("\n");
3380 /* If MAP is still not the root map, shift to the current
3382 if (ic_info->map != ic_info->state->map)
3383 shift_state (ic, ic_info->state->name);
3387 /* MAP is the root map, perform branch actions (if any) or
3388 shift to the initial state. */
3389 if (map->branch_actions)
3391 MDEBUG_PRINT (" branch-actions:");
3392 if (take_action_list (ic, map->branch_actions) < 0)
3394 MDEBUG_PRINT ("\n");
3399 shift_state (ic, Mnil);
3402 MDEBUG_PRINT ("\n");
3406 /* Initialize IC->ic_info. */
3409 init_ic_info (MInputContext *ic)
3411 MInputMethodInfo *im_info = ic->im->info;
3412 MInputContextInfo *ic_info = ic->info;
3415 MLIST_INIT1 (ic_info, keys, 8);;
3417 ic_info->markers = mplist ();
3419 ic_info->vars = mplist ();
3420 if (im_info->configured_vars)
3421 MPLIST_DO (plist, im_info->configured_vars)
3423 MPlist *pl = MPLIST_PLIST (plist);
3424 MSymbol name = MPLIST_SYMBOL (pl);
3426 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3427 if (MPLIST_KEY (pl) != Mt)
3429 MPlist *p = mplist ();
3431 mplist_push (ic_info->vars, Mplist, p);
3432 M17N_OBJECT_UNREF (p);
3433 mplist_add (p, Msymbol, name);
3434 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3437 ic_info->vars_saved = mplist_copy (ic_info->vars);
3439 if (im_info->externals)
3441 MPlist *func_args = mplist (), *plist;
3443 mplist_add (func_args, Mt, ic);
3444 MPLIST_DO (plist, im_info->externals)
3446 MIMExternalModule *external = MPLIST_VAL (plist);
3447 MIMExternalFunc func
3448 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3453 M17N_OBJECT_UNREF (func_args);
3456 ic_info->preedit_saved = mtext ();
3457 ic_info->tick = im_info->tick;
3460 /* Finalize IC->ic_info. */
3463 fini_ic_info (MInputContext *ic)
3465 MInputMethodInfo *im_info = ic->im->info;
3466 MInputContextInfo *ic_info = ic->info;
3468 if (im_info->externals)
3470 MPlist *func_args = mplist (), *plist;
3472 mplist_add (func_args, Mt, ic);
3473 MPLIST_DO (plist, im_info->externals)
3475 MIMExternalModule *external = MPLIST_VAL (plist);
3476 MIMExternalFunc func
3477 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3482 M17N_OBJECT_UNREF (func_args);
3485 MLIST_FREE1 (ic_info, keys);
3486 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3487 M17N_OBJECT_UNREF (ic_info->markers);
3488 M17N_OBJECT_UNREF (ic_info->vars);
3489 M17N_OBJECT_UNREF (ic_info->vars_saved);
3490 M17N_OBJECT_UNREF (ic_info->preceding_text);
3491 M17N_OBJECT_UNREF (ic_info->following_text);
3493 memset (ic_info, 0, sizeof (MInputContextInfo));
3497 re_init_ic (MInputContext *ic, int reload)
3499 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3500 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3501 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3503 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3504 preedit_changed = mtext_nchars (ic->preedit) > 0;
3505 cursor_pos_changed = ic->cursor_pos > 0;
3506 candidates_changed = 0;
3507 if (ic->candidate_list)
3509 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3510 M17N_OBJECT_UNREF (ic->candidate_list);
3511 ic->candidate_list = NULL;
3513 if (ic->candidate_show)
3515 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3516 ic->candidate_show = 0;
3518 if (ic->candidate_index > 0)
3520 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3521 ic->candidate_index = 0;
3522 ic->candidate_from = ic->candidate_to = 0;
3524 if (mtext_nchars (ic->produced) > 0)
3525 mtext_reset (ic->produced);
3526 if (mtext_nchars (ic->preedit) > 0)
3527 mtext_reset (ic->preedit);
3529 M17N_OBJECT_UNREF (ic->plist);
3530 ic->plist = mplist ();
3534 reload_im_info (im_info);
3536 shift_state (ic, Mnil);
3537 ic->status_changed = status_changed;
3538 ic->preedit_changed = preedit_changed;
3539 ic->cursor_pos_changed = cursor_pos_changed;
3540 ic->candidates_changed = candidates_changed;
3544 reset_ic (MInputContext *ic, MSymbol ignore)
3546 MDEBUG_PRINT ("\n [IM] reset\n");
3551 open_im (MInputMethod *im)
3553 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3556 MERROR (MERROR_IM, -1);
3563 close_im (MInputMethod *im)
3569 create_ic (MInputContext *ic)
3571 MInputContextInfo *ic_info;
3573 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3576 shift_state (ic, Mnil);
3581 destroy_ic (MInputContext *ic)
3588 check_reload (MInputContext *ic, MSymbol key)
3590 MInputMethodInfo *im_info = ic->im->info;
3591 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3595 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3599 MPLIST_DO (plist, plist)
3601 MSymbol this_key, alias;
3603 if (MPLIST_MTEXT_P (plist))
3605 MText *mt = MPLIST_MTEXT (plist);
3606 int c = mtext_ref_char (mt, 0);
3610 this_key = one_char_symbol[c];
3614 MPlist *pl = MPLIST_PLIST (plist);
3616 this_key = MPLIST_SYMBOL (pl);
3620 && (alias = msymbol_get (alias, M_key_alias))
3621 && alias != this_key);
3625 if (MPLIST_TAIL_P (plist))
3628 MDEBUG_PRINT ("\n [IM] reload");
3634 /** Handle the input key KEY in the current state and map of IC->info.
3635 If KEY is handled but no text is produced, return 0, otherwise
3641 filter (MInputContext *ic, MSymbol key, void *arg)
3643 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3644 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3647 if (check_reload (ic, key))
3650 if (! ic_info->state)
3652 ic_info->key_unhandled = 1;
3655 mtext_reset (ic->produced);
3656 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3657 M17N_OBJECT_UNREF (ic_info->preceding_text);
3658 M17N_OBJECT_UNREF (ic_info->following_text);
3659 ic_info->preceding_text = ic_info->following_text = NULL;
3660 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3661 ic_info->key_unhandled = 0;
3664 if (handle_key (ic) < 0)
3666 /* KEY was not handled. Delete it from the current key sequence. */
3667 if (ic_info->used > 0)
3669 memmove (ic_info->keys, ic_info->keys + 1,
3670 sizeof (int) * (ic_info->used - 1));
3672 if (ic_info->state_key_head > 0)
3673 ic_info->state_key_head--;
3675 /* This forces returning 1. */
3676 ic_info->key_unhandled = 1;
3682 reset_ic (ic, Mnil);
3683 ic_info->key_unhandled = 1;
3686 /* Break the loop if all keys were handled. */
3687 } while (ic_info->key_head < ic_info->used);
3689 /* If the current map is the root of the initial state, we should
3690 produce any preedit text in ic->produced. */
3691 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3692 preedit_commit (ic);
3694 if (mtext_nchars (ic->produced) > 0)
3696 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3698 if (mdebug__flag & mdebug_mask)
3700 MDEBUG_PRINT (" (produced");
3701 for (i = 0; i < mtext_nchars (ic->produced); i++)
3702 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3707 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3708 Mlanguage, ic->im->language);
3709 if (ic_info->state_key_head > 0)
3711 memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head,
3712 sizeof (int) * (ic_info->used - ic_info->state_key_head));
3713 ic_info->used -= ic_info->state_key_head;
3714 ic_info->key_head -= ic_info->state_key_head;
3715 ic_info->state_key_head = 0;
3719 if (ic_info->key_unhandled)
3722 ic_info->key_head = ic_info->state_key_head = 0;
3725 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3729 /** Return 1 if the last event or key was not handled, otherwise
3732 There is no need of looking up because ic->produced should already
3733 contain the produced text (if any).
3738 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3740 mtext_cat (mt, ic->produced);
3741 mtext_reset (ic->produced);
3742 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3746 /* Input method command handler. */
3748 /* List of all (global and local) commands.
3749 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3750 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3751 Global commands are stored as (t (t COMMAND ...)) */
3754 /* Input method variable handler. */
3757 /* Support functions for mdebug_dump_im. */
3760 dump_im_map (MPlist *map_list, int indent)
3763 MSymbol key = MPLIST_KEY (map_list);
3764 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3766 prefix = (char *) alloca (indent + 1);
3767 memset (prefix, 32, indent);
3768 prefix[indent] = '\0';
3770 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3771 if (map->map_actions)
3772 mdebug_dump_plist (map->map_actions, indent + 2);
3775 MPLIST_DO (map_list, map->submaps)
3777 fprintf (stderr, "\n%s ", prefix);
3778 dump_im_map (map_list, indent + 2);
3781 if (map->branch_actions)
3783 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3784 mdebug_dump_plist (map->branch_actions, indent + 4);
3785 fprintf (stderr, ")");
3787 fprintf (stderr, ")");
3792 dump_im_state (MIMState *state, int indent)
3797 prefix = (char *) alloca (indent + 1);
3798 memset (prefix, 32, indent);
3799 prefix[indent] = '\0';
3801 fprintf (stderr, "(%s", msymbol_name (state->name));
3802 if (state->map->submaps)
3804 MPLIST_DO (map_list, state->map->submaps)
3806 fprintf (stderr, "\n%s ", prefix);
3807 dump_im_map (map_list, indent + 2);
3810 fprintf (stderr, ")");
3818 Minput_driver = msymbol ("input-driver");
3820 Minput_preedit_start = msymbol ("input-preedit-start");
3821 Minput_preedit_done = msymbol ("input-preedit-done");
3822 Minput_preedit_draw = msymbol ("input-preedit-draw");
3823 Minput_status_start = msymbol ("input-status-start");
3824 Minput_status_done = msymbol ("input-status-done");
3825 Minput_status_draw = msymbol ("input-status-draw");
3826 Minput_candidates_start = msymbol ("input-candidates-start");
3827 Minput_candidates_done = msymbol ("input-candidates-done");
3828 Minput_candidates_draw = msymbol ("input-candidates-draw");
3829 Minput_set_spot = msymbol ("input-set-spot");
3830 Minput_focus_move = msymbol ("input-focus-move");
3831 Minput_focus_in = msymbol ("input-focus-in");
3832 Minput_focus_out = msymbol ("input-focus-out");
3833 Minput_toggle = msymbol ("input-toggle");
3834 Minput_reset = msymbol ("input-reset");
3835 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3836 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3837 Mcustomized = msymbol ("customized");
3838 Mconfigured = msymbol ("configured");
3839 Minherited = msymbol ("inherited");
3841 minput_default_driver.open_im = open_im;
3842 minput_default_driver.close_im = close_im;
3843 minput_default_driver.create_ic = create_ic;
3844 minput_default_driver.destroy_ic = destroy_ic;
3845 minput_default_driver.filter = filter;
3846 minput_default_driver.lookup = lookup;
3847 minput_default_driver.callback_list = mplist ();
3848 mplist_put (minput_default_driver.callback_list, Minput_reset,
3850 minput_driver = &minput_default_driver;
3852 fully_initialized = 0;
3859 if (fully_initialized)
3861 free_im_list (im_info_list);
3863 free_im_list (im_custom_list);
3865 free_im_list (im_config_list);
3866 M17N_OBJECT_UNREF (load_im_info_keys);
3869 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3870 M17N_OBJECT_UNREF (minput_driver->callback_list);
3875 minput__callback (MInputContext *ic, MSymbol command)
3877 MInputCallbackFunc func;
3879 if (! ic->im->driver.callback_list)
3881 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3885 (func) (ic, command);
3890 minput__char_to_key (int c)
3892 if (c < 0 || c >= 0x100)
3895 return one_char_symbol[c];
3899 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3904 /*** @addtogroup m17nInputMethod */
3909 @name Variables: Predefined symbols for callback commands.
3911 These are the predefined symbols that are used as the @c COMMAND
3912 argument of callback functions of an input method driver (see
3913 #MInputDriver::callback_list).
3915 Most of them do not require extra argument nor return any value;
3916 exceptions are these:
3918 Minput_get_surrounding_text: When a callback function assigned for
3919 this command is called, the first element of #MInputContext::plist
3920 has key #Minteger and the value specifies which portion of the
3921 surrounding text should be retrieved. If the value is positive,
3922 it specifies the number of characters following the current cursor
3923 position. If the value is negative, the absolute value specifies
3924 the number of characters preceding the current cursor position.
3926 If the surrounding text is currently supported, the callback
3927 function must set the key of this element to #Mtext and the value
3928 to the retrieved M-text. The length of the M-text may be shorter
3929 than the requested number of characters, if the available text is
3930 not that long. The length can be zero in the worst case. Or, the
3931 length may be longer if an application thinks it is more efficient
3932 to return that length.
3934 If the surrounding text is not currently supported, the callback
3935 function should return without changing the first element of
3936 #MInputContext::plist.
3938 Minput_delete_surrounding_text: When a callback function assigned
3939 for this command is called, the first element of
3940 #MInputContext::plist has key #Minteger and the value specifies
3941 which portion of the surrounding text should be deleted in the
3942 same way as the case of Minput_get_surrounding_text. The callback
3943 function must delete the specified text. It should not alter
3944 #MInputContext::plist. */
3946 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3948 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3949 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3951 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
3953 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
3954 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
3955 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
3956 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
3957 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
3960 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
3961 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
3962 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
3963 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
3964 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
3966 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
3967 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѲ½¤µ¤»¤ë¤³¤È¤Ê¤¯ÊÖ¤µ¤Ê¤¯¤Æ
3970 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
3971 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
3972 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
3973 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
3974 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
3975 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
3979 MSymbol Minput_preedit_start;
3980 MSymbol Minput_preedit_done;
3981 MSymbol Minput_preedit_draw;
3982 MSymbol Minput_status_start;
3983 MSymbol Minput_status_done;
3984 MSymbol Minput_status_draw;
3985 MSymbol Minput_candidates_start;
3986 MSymbol Minput_candidates_done;
3987 MSymbol Minput_candidates_draw;
3988 MSymbol Minput_set_spot;
3989 MSymbol Minput_toggle;
3990 MSymbol Minput_reset;
3991 MSymbol Minput_get_surrounding_text;
3992 MSymbol Minput_delete_surrounding_text;
3998 @name Variables: Predefined symbols for special input events.
4000 These are the predefined symbols that are used as the @c KEY
4001 argument of minput_filter (). */
4003 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4005 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4010 MSymbol Minput_focus_out;
4011 MSymbol Minput_focus_in;
4012 MSymbol Minput_focus_move;
4018 @name Variables: Predefined symbols used in input method information.
4020 These are the predefined symbols describing status of input method
4021 command and variable, and are used in a return value of
4022 minput_get_command () and minput_get_variable (). */
4024 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4026 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4027 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4031 MSymbol Mcustomized;
4032 MSymbol Mconfigured;
4038 @brief The default driver for internal input methods.
4040 The variable #minput_default_driver is the default driver for
4041 internal input methods.
4043 The member MInputDriver::open_im () searches the m17n database for
4044 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4045 $NAME\> and loads it.
4047 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4048 programmers responsibility to set it to a plist of proper callback
4049 functions. Otherwise, no feedback information (e.g. preedit text)
4050 can be shown to users.
4052 The macro M17N_INIT () sets the variable #minput_driver to the
4053 pointer to this driver so that all internal input methods use it.
4055 Therefore, unless @c minput_driver is set differently, the driver
4056 dependent arguments $ARG of the functions whose name begins with
4057 "minput_" are all ignored. */
4059 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4061 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4063 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4064 \< #Minput_method, $LANGUAGE, $NAME\>
4065 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4067 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4068 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4069 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4070 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4072 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4073 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4075 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4076 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4078 MInputDriver minput_default_driver;
4082 @brief The driver for internal input methods.
4084 The variable #minput_driver is a pointer to the input method
4085 driver that is used by internal input methods. The macro
4086 M17N_INIT () initializes it to a pointer to #minput_default_driver
4087 if <m17n<EM></EM>.h> is included. */
4089 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4091 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4092 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4093 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4094 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4096 MInputDriver *minput_driver;
4098 MSymbol Minput_driver;
4113 @brief Open an input method.
4115 The minput_open_im () function opens an input method whose
4116 language and name match $LANGUAGE and $NAME, and returns a pointer
4117 to the input method object newly allocated.
4119 This function at first decides a driver for the input method as
4122 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4123 #minput_driver is used.
4125 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4126 driver pointed to by the property value is used to open the input
4127 method. If $NAME has no such a property, @c NULL is returned.
4129 Then, the member MInputDriver::open_im () of the driver is
4132 $ARG is set in the member @c arg of the structure MInputMethod so
4133 that the driver can refer to it. */
4135 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4137 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4138 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4140 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4142 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4143 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4145 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4146 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4147 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4149 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4151 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4153 @latexonly \IPAlabel{minput_open} @endlatexonly
4158 minput_open_im (MSymbol language, MSymbol name, void *arg)
4161 MInputDriver *driver;
4165 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4166 msymbol_name (language), msymbol_name (name));
4168 driver = minput_driver;
4171 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4173 MERROR (MERROR_IM, NULL);
4176 MSTRUCT_CALLOC (im, MERROR_IM);
4177 im->language = language;
4180 im->driver = *driver;
4181 if ((*im->driver.open_im) (im) < 0)
4183 MDEBUG_PRINT (" failed\n");
4187 MDEBUG_PRINT (" ok\n");
4194 @brief Close an input method.
4196 The minput_close_im () function closes the input method $IM, which
4197 must have been created by minput_open_im (). */
4200 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4202 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4203 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4206 minput_close_im (MInputMethod *im)
4208 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4209 msymbol_name (im->name), msymbol_name (im->language));
4210 (*im->driver.close_im) (im);
4212 MDEBUG_PRINT (" done\n");
4218 @brief Create an input context.
4220 The minput_create_ic () function creates an input context object
4221 associated with input method $IM, and calls callback functions
4222 corresponding to #Minput_preedit_start, #Minput_status_start, and
4223 #Minput_status_draw in this order.
4226 If an input context is successfully created, minput_create_ic ()
4227 returns a pointer to it. Otherwise it returns @c NULL. */
4230 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4232 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4233 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4234 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4235 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4238 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4239 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4243 minput_create_ic (MInputMethod *im, void *arg)
4247 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4248 msymbol_name (im->name), msymbol_name (im->language));
4249 MSTRUCT_CALLOC (ic, MERROR_IM);
4252 ic->preedit = mtext ();
4253 ic->candidate_list = NULL;
4254 ic->produced = mtext ();
4255 ic->spot.x = ic->spot.y = 0;
4257 ic->plist = mplist ();
4258 if ((*im->driver.create_ic) (ic) < 0)
4260 MDEBUG_PRINT (" failed\n");
4261 M17N_OBJECT_UNREF (ic->preedit);
4262 M17N_OBJECT_UNREF (ic->produced);
4263 M17N_OBJECT_UNREF (ic->plist);
4268 if (im->driver.callback_list)
4270 minput__callback (ic, Minput_preedit_start);
4271 minput__callback (ic, Minput_status_start);
4272 minput__callback (ic, Minput_status_draw);
4275 MDEBUG_PRINT (" ok\n");
4282 @brief Destroy an input context.
4284 The minput_destroy_ic () function destroys the input context $IC,
4285 which must have been created by minput_create_ic (). It calls
4286 callback functions corresponding to #Minput_preedit_done,
4287 #Minput_status_done, and #Minput_candidates_done in this order. */
4290 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4292 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4293 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4294 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4295 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4296 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4300 minput_destroy_ic (MInputContext *ic)
4302 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4303 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4304 if (ic->im->driver.callback_list)
4306 minput__callback (ic, Minput_preedit_done);
4307 minput__callback (ic, Minput_status_done);
4308 minput__callback (ic, Minput_candidates_done);
4310 (*ic->im->driver.destroy_ic) (ic);
4311 M17N_OBJECT_UNREF (ic->preedit);
4312 M17N_OBJECT_UNREF (ic->produced);
4313 M17N_OBJECT_UNREF (ic->plist);
4314 MDEBUG_PRINT (" done\n");
4321 @brief Filter an input key.
4323 The minput_filter () function filters input key $KEY according to
4324 input context $IC, and calls callback functions corresponding to
4325 #Minput_preedit_draw, #Minput_status_draw, and
4326 #Minput_candidates_draw if the preedit text, the status, and the
4327 current candidate are changed respectively.
4329 To make the input method commit the current preedit text (if any)
4330 and shift to the initial state, call this function with #Mnil as
4333 To inform the input method about the focus-out event, call this
4334 function with #Minput_focus_out as $KEY.
4336 To inform the input method about the focus-in event, call this
4337 function with #Minput_focus_in as $KEY.
4339 To inform the input method about the focus-move event (i.e. input
4340 spot change within the same input context), call this function
4341 with #Minput_focus_move as $KEY.
4344 If $KEY is filtered out, this function returns 1. In that case,
4345 the caller should discard the key. Otherwise, it returns 0, and
4346 the caller should handle the key, for instance, by calling the
4347 function minput_lookup () with the same key. */
4350 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4352 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4353 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4354 #Minput_preedit_draw, #Minput_status_draw,
4355 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4358 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4359 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4360 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4361 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4363 @latexonly \IPAlabel{minput_filter} @endlatexonly
4367 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4374 ret = (*ic->im->driver.filter) (ic, key, arg);
4376 if (ic->im->driver.callback_list)
4378 if (ic->preedit_changed)
4379 minput__callback (ic, Minput_preedit_draw);
4380 if (ic->status_changed)
4381 minput__callback (ic, Minput_status_draw);
4382 if (ic->candidates_changed)
4383 minput__callback (ic, Minput_candidates_draw);
4392 @brief Look up a text produced in the input context.
4394 The minput_lookup () function looks up a text in the input context
4395 $IC. $KEY must be identical to the one that was used in the previous call of
4398 If a text was produced by the input method, it is concatenated
4401 This function calls #MInputDriver::lookup .
4404 If $KEY was correctly handled by the input method, this function
4405 returns 0. Otherwise, it returns -1, even though some text
4406 might be produced in $MT. */
4409 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4411 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4412 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4414 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4417 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4420 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4421 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4422 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4424 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4427 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4429 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4434 @brief Set the spot of the input context.
4436 The minput_set_spot () function sets the spot of input context $IC
4437 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4438 The semantics of these values depends on the input method driver.
4440 For instance, a driver designed to work in a CUI environment may
4441 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4442 $DESCENT . A driver designed to work in a window system may
4443 interpret $X and $Y as the pixel offsets relative to the origin of the
4444 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4445 descent pixels of the line at ($X . $Y ).
4447 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4449 $MT and $POS are the M-text and the character position at the spot.
4450 $MT may be @c NULL, in which case, the input method cannot get
4451 information about the text around the spot. */
4454 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4456 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4457 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4458 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4460 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4461 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4462 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4463 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4464 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4465 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4467 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4469 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4470 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4474 minput_set_spot (MInputContext *ic, int x, int y,
4475 int ascent, int descent, int fontsize,
4480 ic->spot.ascent = ascent;
4481 ic->spot.descent = descent;
4482 ic->spot.fontsize = fontsize;
4485 if (ic->im->driver.callback_list)
4486 minput__callback (ic, Minput_set_spot);
4491 @brief Toggle input method.
4493 The minput_toggle () function toggles the input method associated
4494 with input context $IC. */
4496 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4498 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4499 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4503 minput_toggle (MInputContext *ic)
4505 if (ic->im->driver.callback_list)
4506 minput__callback (ic, Minput_toggle);
4507 ic->active = ! ic->active;
4513 @brief Reset an input context.
4515 The minput_reset_ic () function resets input context $IC by
4516 calling a callback function corresponding to #Minput_reset. It
4517 resets the status of $IC to its initial one. As the
4518 current preedit text is deleted without commitment, if necessary,
4519 call minput_filter () with the arg @r key #Mnil to force the input
4520 method to commit the preedit in advance. */
4523 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4525 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4526 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4527 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4528 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4529 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4530 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4533 minput_reset_ic (MInputContext *ic)
4535 if (ic->im->driver.callback_list)
4536 minput__callback (ic, Minput_reset);
4542 @brief Get title and icon filename of an input method.
4544 The minput_get_title_icon () function returns a plist containing a
4545 title and icon filename (if any) of an input method specified by
4546 $LANGUAGE and $NAME.
4548 The first element of the plist has key #Mtext and the value is an
4549 M-text of the title for identifying the input method. The second
4550 element (if any) has key #Mtext and the value is an M-text of the
4551 icon image (absolute) filename for the same purpose.
4554 If there exists a specified input method and it defines an title,
4555 a plist is returned. Otherwise, NULL is returned. The caller
4556 must free the plist by m17n_object_unref (). */
4558 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4560 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4561 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4564 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4565 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4566 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¤ÎÀäÂÐ¥Õ¥¡¥¤¥ë¥Í¡¼¥à¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4569 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4570 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4571 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4574 minput_get_title_icon (MSymbol language, MSymbol name)
4576 MInputMethodInfo *im_info;
4583 im_info = get_im_info (language, name, Mnil, Mtitle);
4584 if (! im_info || !im_info->title)
4586 mt = mtext_get_prop (im_info->title, 0, Mtext);
4588 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4591 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4594 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4595 (char *) MSYMBOL_NAME (name));
4596 file = mdatabase__find_file (buf);
4597 if (! file && language == Mt)
4599 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4600 file = mdatabase__find_file (buf);
4605 mplist_add (plist, Mtext, im_info->title);
4608 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4610 mplist_add (plist, Mtext, mt);
4611 M17N_OBJECT_UNREF (mt);
4619 @brief Get description text of an input method.
4621 The minput_get_description () function returns an M-text that
4622 describes the input method specified by $LANGUAGE and $NAME.
4625 If the specified input method has a description text, a pointer to
4626 #MText is returned. The caller has to free it by m17n_object_unref ().
4627 If the input method does not have a description text, @c NULL is
4630 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4632 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4633 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4635 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4636 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4637 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4638 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4641 minput_get_description (MSymbol language, MSymbol name)
4643 MInputMethodInfo *im_info;
4651 extra = language, language = Mt;
4653 im_info = get_im_info (language, name, extra, Mdescription);
4654 if (! im_info || ! im_info->description)
4656 M17N_OBJECT_REF (im_info->description);
4657 return im_info->description;
4663 @brief Get information about input method command(s).
4665 The minput_get_command () function returns information about
4666 the command $COMMAND of the input method specified by $LANGUAGE and
4667 $NAME. An input method command is a pseudo key event to which one
4668 or more actual input key sequences are assigned.
4670 There are two kinds of commands, global and local. A global
4671 command has a global definition, and the description and the key
4672 assignment may be inherited by a local command. Each input method
4673 defines a local command which has a local key assignment. It may
4674 also declare a local command that inherits the definition of a
4675 global command of the same name.
4677 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4678 information about a global command. Otherwise information about a
4679 local command is returned.
4681 If $COMMAND is #Mnil, information about all commands is returned.
4683 The return value is a @e well-formed plist (#m17nPlist) of this
4686 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4688 @c NAME is a symbol representing the command name.
4690 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4691 command has no description.
4693 @c STATUS is a symbol representing how the key assignment is decided.
4694 The value is #Mnil (the default key assignment), #Mcustomized (the
4695 key assignment is customized by per-user configuration file), or
4696 #Mconfigured (the key assignment is set by the call of
4697 minput_config_command ()). For a local command only, it may also
4698 be #Minherited (the key assignment is inherited from the
4699 corresponding global command).
4701 @c KEYSEQ is a plist of one or more symbols representing a key
4702 sequence assigned to the command. If there's no KEYSEQ, the
4703 command is currently disabled (i.e. no key sequence can trigger
4704 actions of the command).
4706 If $COMMAND is not #Mnil, the first element of the returned plist
4707 contains the information about $COMMAND.
4711 If the requested information was found, a pointer to a non-empty
4712 plist is returned. As the plist is kept in the library, the
4713 caller must not modify nor free it.
4715 Otherwise (the specified input method or the specified command
4716 does not exist), @c NULL is returned. */
4718 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4720 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4721 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4722 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4723 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4725 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4726 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4727 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4728 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4729 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4731 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4732 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4735 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4737 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4740 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4742 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4744 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4747 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4748 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4749 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4750 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4751 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4752 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4754 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4755 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4756 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4757 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4759 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4760 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4764 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4765 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4768 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4773 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4775 /* Return a description of the command COMMAND of the input method
4776 specified by LANGUAGE and NAME. */
4777 MPlist *cmd = minput_get_command (langauge, name, command);
4782 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4783 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4784 return (mplist_key (plist) == Mtext
4785 ? (MText *) mplist_value (plist)
4791 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4793 MInputMethodInfo *im_info;
4797 im_info = get_im_info (language, name, Mnil, Mcommand);
4799 || ! im_info->configured_cmds
4800 || MPLIST_TAIL_P (im_info->configured_cmds))
4802 if (command == Mnil)
4803 return im_info->configured_cmds;
4804 return mplist__assq (im_info->configured_cmds, command);
4810 @brief Configure the key sequence of an input method command.
4812 The minput_config_command () function assigns a list of key
4813 sequences $KEYSEQLIST to the command $COMMAND of the input method
4814 specified by $LANGUAGE and $NAME.
4816 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4817 sequences, and each key sequence must be a plist of symbols.
4819 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4821 If $KEYSEQLIST is NULL, the configuration of the command for the
4822 input method is canceled, and the default key sequences become
4823 effective. In such case, if $COMMAND is #Mnil, configurations for
4824 all commands of the input method are canceled.
4826 If $NAME is #Mnil, this function configures the key assignment of a
4827 global command, not that of a specific input method.
4829 The configuration takes effect for input methods opened or
4830 re-opened later in the current session. In order to make the
4831 configuration take effect for the future session, it must be saved
4832 in a per-user configuration file by the function
4833 minput_save_config ().
4837 If the operation was successful, this function returns 0,
4838 otherwise returns -1. The operation fails in these cases:
4840 <li>$KEYSEQLIST is not in a valid form.
4841 <li>$COMMAND is not available for the input method.
4842 <li>$LANGUAGE and $NAME do not specify an existing input method.
4846 minput_get_commands (), minput_save_config ().
4849 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4851 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4852 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4853 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4855 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4856 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4858 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4860 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4861 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4862 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4865 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4866 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4868 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4869 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4870 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4871 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4875 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4877 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4878 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4879 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4883 minput_get_commands (), minput_save_config ().
4887 /* Add "C-x u" to the "start" command of Unicode input method. */
4889 MSymbol start_command = msymbol ("start");
4890 MSymbol unicode = msymbol ("unicode");
4891 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4893 /* At first get the current key-sequence assignment. */
4894 cmd = mplist_get_command (Mt, unicode, start_command);
4897 /* The input method does not have the command "start". Here
4898 should come some error handling code. */
4900 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4901 the part (KEY-SEQUENCE ...). */
4902 plist = mplist_next (mplist_next (mplist_value (cmd)));
4903 /* Copy it because we should not modify it directly. */
4904 key_seq_list = mplist_copy (plist);
4905 m17n_object_unref (cmds);
4907 key_seq = mplist ();
4908 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4909 mplist_add (key_seq, Msymbol, msymbol ("u"));
4910 mplist_add (key_seq_list, Mplist, key_seq);
4911 m17n_object_unref (key_seq);
4913 minput_config_command (Mt, unicode, start_command, key_seq_list);
4914 m17n_object_unref (key_seq_list);
4919 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4922 MInputMethodInfo *im_info, *config;
4929 if (command == Mnil)
4930 MERROR (MERROR_IM, -1);
4931 MPLIST_DO (plist, keyseqlist)
4932 if (! MPLIST_PLIST_P (plist)
4933 || ! check_command_keyseq (plist))
4934 MERROR (MERROR_IM, -1);
4937 im_info = get_im_info (language, name, Mnil, Mcommand);
4939 MERROR (MERROR_IM, -1);
4942 || ! mplist__assq (im_info->cmds, command)))
4943 MERROR (MERROR_IM, -1);
4945 config = get_config_info (im_info);
4948 if (! im_config_list)
4949 im_config_list = mplist ();
4950 config = new_im_info (NULL, language, name, Mnil, im_config_list);
4951 config->cmds = mplist ();
4952 config->vars = mplist ();
4955 if (command == Mnil)
4957 MInputMethodInfo *custom = get_custom_info (im_info);
4959 mplist_set (config->cmds, Mnil, NULL);
4960 if (custom && custom->cmds)
4962 MPLIST_DO (plist, custom->cmds)
4964 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
4966 mplist_add (plist, Msymbol, command);
4967 mplist_push (config->cmds, Mplist, plist);
4968 M17N_OBJECT_UNREF (plist);
4974 plist = mplist__assq (config->cmds, command);
4977 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
4978 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
4979 if (! MPLIST_TAIL_P (plist))
4980 mplist_set (plist, Mnil, NULL); /* () */
4985 mplist_add (config->cmds, Mplist, plist);
4986 M17N_OBJECT_UNREF (plist);
4987 plist = mplist_add (plist, Msymbol, command);
4988 plist = MPLIST_NEXT (plist);
4994 plist = mplist_add (plist, Msymbol, Mnil);
4995 MPLIST_DO (keyseqlist, keyseqlist)
4997 pl = mplist_copy (MPLIST_VAL (keyseqlist));
4998 plist = mplist_add (plist, Mplist, pl);
4999 M17N_OBJECT_UNREF (pl);
5003 config_all_commands (im_info);
5004 im_info->tick = time (NULL);
5011 @brief Get information about input method variable(s).
5013 The minput_get_variable () function returns information about
5014 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5015 An input method variable controls behavior of an input method.
5017 There are two kinds of variables, global and local. A global
5018 variable has a global definition, and the description and the value
5019 may be inherited by a local variable. Each input method defines a
5020 local variable which has local value. It may also declare a
5021 local variable that inherits definition of a global variable of
5024 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5025 variable is returned. Otherwise information about a local variable
5028 If $VARIABLE is #Mnil, information about all variables is
5031 The return value is a @e well-formed plist (#m17nPlist) of this
5034 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5036 @c NAME is a symbol representing the variable name.
5038 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5039 variable has no description.
5041 @c STATUS is a symbol representing how the value is decided. The
5042 value is #Mnil (the default value), #Mcustomized (the value is
5043 customized by per-user configuration file), or #Mconfigured (the
5044 value is set by the call of minput_config_variable ()). For a
5045 local variable only, it may also be #Minherited (the value is
5046 inherited from the corresponding global variable).
5048 @c VALUE is the initial value of the variable. If the key of this
5049 element is #Mt, the variable has no initial value. Otherwise, the
5050 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5053 @c VALID-VALUEs (if any) specify which values the variable can have.
5054 They have the same type (i.e. having the same key) as @c VALUE except
5055 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5056 may be a plist of two integers specifying the range of possible
5059 If there no @c VALID-VALUE, the variable can have any value as long
5060 as the type is the same as @c VALUE.
5062 If $VARIABLE is not #Mnil, the first element of the returned plist
5063 contains the information about $VARIABLE.
5067 If the requested information was found, a pointer to a non-empty
5068 plist is returned. As the plist is kept in the library, the
5069 caller must not modify nor free it.
5071 Otherwise (the specified input method or the specified variable
5072 does not exist), @c NULL is returned. */
5074 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5076 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5077 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5078 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5080 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5081 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5082 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5083 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5086 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5087 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5089 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5091 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5093 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5096 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5098 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5101 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5102 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5103 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5104 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5105 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5106 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5108 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5109 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5110 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5112 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5113 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5114 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5115 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5117 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5120 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5121 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5125 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5126 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5129 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5133 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5135 MInputMethodInfo *im_info;
5139 im_info = get_im_info (language, name, Mnil, Mvariable);
5140 if (! im_info || ! im_info->configured_vars)
5142 if (variable == Mnil)
5143 return im_info->configured_vars;
5144 return mplist__assq (im_info->configured_vars, variable);
5150 @brief Configure the value of an input method variable.
5152 The minput_config_variable () function assigns $VALUE to the
5153 variable $VARIABLE of the input method specified by $LANGUAGE and
5156 If $VALUE is not NULL, it must be a plist of one element whose key
5157 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5160 If $VALUE is NULL, a configuration for the variable for the input
5161 method is canceled, and the variable is initialized to the default
5162 value. In that case, if $VARIABLE is #Mnil, configurations for
5163 all variables of the input method are canceled.
5165 If $NAME is #Mnil, this function configure the value of global
5166 variable, not that of a specific input method.
5168 The configuration takes effect for input methods opened or
5169 re-opened later in the current session. To make the configuration
5170 take effect for the future session, it must be saved in a per-user
5171 configuration file by the function minput_save_config ().
5175 If the operation was successful, this function returns 0,
5176 otherwise returns -1. The operation fails in these cases:
5178 <li>$VALUE is not in a valid form, the type does not match the
5179 definition, or the value is our of range.
5180 <li>$VARIABLE is not available for the input method.
5181 <li>$LANGUAGE and $NAME do not specify an existing input method.
5185 minput_get_variable (), minput_save_config (). */
5187 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5189 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5190 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5192 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5193 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5195 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5196 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5197 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5199 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5200 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5202 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5203 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5204 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5205 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5209 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5211 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5212 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5213 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5217 minput_get_commands (), minput_save_config ().
5220 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5223 MInputMethodInfo *im_info, *config;
5228 im_info = get_im_info (language, name, Mnil, Mvariable);
5230 MERROR (MERROR_IM, -1);
5231 if (variable == Mnil)
5234 MERROR (MERROR_IM, -1);
5236 else if (! im_info->vars
5237 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5238 MERROR (MERROR_IM, -1);
5240 if (variable != Mnil && value)
5242 plist = MPLIST_PLIST (plist);
5243 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5244 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5245 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5246 if (MPLIST_KEY (plist) != Mt
5247 && ! check_variable_value (value, plist))
5248 MERROR (MERROR_IM, -1);
5251 config = get_config_info (im_info);
5254 if (! im_config_list)
5255 im_config_list = mplist ();
5256 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5257 config->cmds = mplist ();
5258 config->vars = mplist ();
5261 if (variable == Mnil)
5263 MInputMethodInfo *custom = get_custom_info (im_info);
5265 mplist_set (config->vars, Mnil, NULL);
5266 if (custom && custom->cmds)
5268 MPLIST_DO (plist, custom->vars)
5270 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5272 mplist_add (plist, Msymbol, variable);
5273 mplist_push (config->vars, Mplist, plist);
5274 M17N_OBJECT_UNREF (plist);
5280 plist = mplist__assq (config->vars, variable);
5283 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5284 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5285 if (! MPLIST_TAIL_P (plist))
5286 mplist_set (plist, Mnil ,NULL); /* () */
5291 mplist_add (config->vars, Mplist, plist);
5292 M17N_OBJECT_UNREF (plist);
5293 plist = mplist_add (plist, Msymbol, variable);
5294 plist = MPLIST_NEXT (plist);
5298 plist = mplist_add (plist, Msymbol, Mnil);
5299 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5302 config_all_variables (im_info);
5303 im_info->tick = time (NULL);
5310 @brief Get the name of per-user configuration file.
5312 The minput_config_file () function returns the absolute path name
5313 of per-user configuration file into which minput_save_config ()
5314 save configurations. It is usually @c "config.mic" under the
5315 directory @c ".m17n.d" of user's home directory. It is not assured
5316 that the file of the returned name exists nor is
5317 readable/writable. If minput_save_config () fails and returns -1,
5318 an application program might check the file, make it
5319 writable (if possible), and try minput_save_config () again.
5323 This function returns a string. As the string is kept in the
5324 library, the caller must not modify nor free it.
5327 minput_save_config ()
5330 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5332 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5333 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5334 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5335 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5336 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5337 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5338 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5343 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5344 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5347 minput_save_config ()
5351 minput_config_file ()
5355 return mdatabase__file (im_custom_mdb);
5361 @brief Save configurations in per-user configuration file.
5363 The minput_save_config () function saves the configurations done
5364 so far in the current session into the per-user configuration
5369 If the operation was successful, 1 is returned. If the per-user
5370 configuration file is currently locked, 0 is returned. In that
5371 case, the caller may wait for a while and try again. If the
5372 configuration file is not writable, -1 is returned. In that case,
5373 the caller may check the name of the file by calling
5374 minput_config_file (), make it writable if possible, and try
5378 minput_config_file () */
5380 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5382 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5383 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5387 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5388 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5389 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5390 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5394 minput_config_file () */
5397 minput_save_config (void)
5399 MPlist *data, *tail, *plist, *p, *elt;
5403 ret = mdatabase__lock (im_custom_mdb);
5406 if (! im_config_list)
5408 update_custom_info ();
5409 if (! im_custom_list)
5410 im_custom_list = mplist ();
5411 data = tail = mplist ();
5413 MPLIST_DO (plist, im_config_list)
5415 MPlist *pl = MPLIST_PLIST (plist);
5416 MSymbol language, name, extra, command, variable;
5417 MInputMethodInfo *custom, *config;
5419 language = MPLIST_SYMBOL (pl);
5420 pl = MPLIST_NEXT (pl);
5421 name = MPLIST_SYMBOL (pl);
5422 pl = MPLIST_NEXT (pl);
5423 extra = MPLIST_SYMBOL (pl);
5424 pl = MPLIST_NEXT (pl);
5425 config = MPLIST_VAL (pl);
5426 custom = get_custom_info (config);
5428 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5430 MPLIST_DO (pl, config->cmds)
5432 elt = MPLIST_PLIST (pl);
5433 command = MPLIST_SYMBOL (elt);
5435 p = mplist__assq (custom->cmds, command);
5437 custom->cmds = mplist (), p = NULL;
5438 elt = MPLIST_NEXT (elt);
5439 if (MPLIST_TAIL_P (elt))
5442 mplist__pop_unref (p);
5446 elt = MPLIST_NEXT (elt);
5449 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5450 mplist_set (p, Mnil, NULL);
5451 mplist__conc (p, elt);
5455 p = MPLIST_PLIST (pl);
5456 mplist_add (custom->cmds, Mplist, p);
5461 MPLIST_DO (pl, config->vars)
5463 elt = MPLIST_PLIST (pl);
5464 variable = MPLIST_SYMBOL (elt);
5466 p = mplist__assq (custom->vars, variable);
5468 custom->vars = mplist (), p = NULL;
5469 elt = MPLIST_NEXT (elt);
5470 if (MPLIST_TAIL_P (elt))
5473 mplist__pop_unref (p);
5477 elt = MPLIST_NEXT (elt);
5480 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5481 mplist_set (p, Mnil, NULL);
5482 mplist__conc (p, elt);
5486 p = MPLIST_PLIST (pl);
5487 mplist_add (custom->vars, Mplist, p);
5492 M17N_OBJECT_UNREF (im_config_list);
5494 MPLIST_DO (plist, im_custom_list)
5496 MPlist *pl = MPLIST_PLIST (plist);
5497 MSymbol language, name, extra;
5498 MInputMethodInfo *custom, *im_info;
5500 language = MPLIST_SYMBOL (pl);
5501 pl = MPLIST_NEXT (pl);
5502 name = MPLIST_SYMBOL (pl);
5503 pl = MPLIST_NEXT (pl);
5504 extra = MPLIST_SYMBOL (pl);
5505 pl = MPLIST_NEXT (pl);
5506 custom = MPLIST_VAL (pl);
5507 im_info = lookup_im_info (im_info_list, language, name, extra);
5511 config_all_commands (im_info);
5513 config_all_variables (im_info);
5517 tail = mplist_add (tail, Mplist, elt);
5518 M17N_OBJECT_UNREF (elt);
5520 elt = mplist_add (elt, Mplist, pl);
5521 M17N_OBJECT_UNREF (pl);
5522 pl = mplist_add (pl, Msymbol, Minput_method);
5523 pl = mplist_add (pl, Msymbol, language);
5524 pl = mplist_add (pl, Msymbol, name);
5526 pl = mplist_add (pl, Msymbol, extra);
5527 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5530 elt = mplist_add (elt, Mplist, pl);
5531 M17N_OBJECT_UNREF (pl);
5532 pl = mplist_add (pl, Msymbol, Mcommand);
5533 MPLIST_DO (p, custom->cmds)
5534 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5536 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5539 elt = mplist_add (elt, Mplist, pl);
5540 M17N_OBJECT_UNREF (pl);
5541 pl = mplist_add (pl, Msymbol, Mvariable);
5542 MPLIST_DO (p, custom->vars)
5543 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5547 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5548 ret = mdatabase__save (im_custom_mdb, data);
5549 mdatabase__unlock (im_custom_mdb);
5550 M17N_OBJECT_UNREF (data);
5551 return (ret < 0 ? -1 : 1);
5558 @name Obsolete functions
5561 @name Obsolete ¤Ê´Ø¿ô
5567 @brief Get a list of variables of an input method (obsolete).
5569 This function is obsolete. Use minput_get_variable () instead.
5571 The minput_get_variables () function returns a plist (#MPlist) of
5572 variables used to control the behavior of the input method
5573 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5574 (#m17nPlist) of the following format:
5577 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5578 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5582 @c VARNAME is a symbol representing the variable name.
5584 @c DOC-MTEXT is an M-text describing the variable.
5586 @c DEFAULT-VALUE is the default value of the variable. It is a
5587 symbol, integer, or M-text.
5589 @c VALUEs (if any) specifies the possible values of the variable.
5590 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5591 @c TO), where @c FROM and @c TO specifies a range of possible
5594 For instance, suppose an input method has the variables:
5596 @li name:intvar, description:"value is an integer",
5597 initial value:0, value-range:0..3,10,20
5599 @li name:symvar, description:"value is a symbol",
5600 initial value:nil, value-range:a, b, c, nil
5602 @li name:txtvar, description:"value is an M-text",
5603 initial value:empty text, no value-range (i.e. any text)
5605 Then, the returned plist is as follows.
5608 (intvar ("value is an integer" 0 (0 3) 10 20)
5609 symvar ("value is a symbol" nil a b c nil)
5610 txtvar ("value is an M-text" ""))
5614 If the input method uses any variables, a pointer to #MPlist is
5615 returned. As the plist is kept in the library, the caller must not
5616 modify nor free it. If the input method does not use any
5617 variable, @c NULL is returned. */
5619 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5621 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5622 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5623 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5627 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5628 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5632 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5634 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5636 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5639 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5640 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5641 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5643 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5645 @li name:intvar, ÀâÌÀ:"value is an integer",
5646 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5648 @li name:symvar, ÀâÌÀ:"value is a symbol",
5649 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5651 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5652 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5654 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5657 (intvar ("value is an integer" 0 (0 3) 10 20)
5658 symvar ("value is a symbol" nil a b c nil)
5659 txtvar ("value is an M-text" ""))
5663 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5664 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5665 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5668 minput_get_variables (MSymbol language, MSymbol name)
5670 MInputMethodInfo *im_info;
5675 im_info = get_im_info (language, name, Mnil, Mvariable);
5676 if (! im_info || ! im_info->configured_vars)
5679 M17N_OBJECT_UNREF (im_info->bc_vars);
5680 im_info->bc_vars = mplist ();
5681 MPLIST_DO (vars, im_info->configured_vars)
5683 MPlist *plist = MPLIST_PLIST (vars);
5684 MPlist *elt = mplist ();
5686 mplist_push (im_info->bc_vars, Mplist, elt);
5687 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5688 elt = MPLIST_NEXT (elt);
5689 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5690 M17N_OBJECT_UNREF (elt);
5692 return im_info->bc_vars;
5698 @brief Set the initial value of an input method variable.
5700 The minput_set_variable () function sets the initial value of
5701 input method variable $VARIABLE to $VALUE for the input method
5702 specified by $LANGUAGE and $NAME.
5704 By default, the initial value is 0.
5706 This setting gets effective in a newly opened input method.
5709 If the operation was successful, 0 is returned. Otherwise -1 is
5710 returned, and #merror_code is set to #MERROR_IM. */
5712 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5714 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5715 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5716 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5718 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5720 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5723 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5724 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5727 minput_set_variable (MSymbol language, MSymbol name,
5728 MSymbol variable, void *value)
5731 MInputMethodInfo *im_info;
5736 if (variable == Mnil)
5737 MERROR (MERROR_IM, -1);
5738 plist = minput_get_variable (language, name, variable);
5739 plist = MPLIST_PLIST (plist);
5740 plist = MPLIST_NEXT (plist);
5742 mplist_add (pl, MPLIST_KEY (plist), value);
5743 ret = minput_config_variable (language, name, variable, pl);
5744 M17N_OBJECT_UNREF (pl);
5747 im_info = get_im_info (language, name, Mnil, Mvariable);
5756 @brief Get information about input method commands.
5758 The minput_get_commands () function returns information about
5759 input method commands of the input method specified by $LANGUAGE
5760 and $NAME. An input method command is a pseudo key event to which
5761 one or more actual input key sequences are assigned.
5763 There are two kinds of commands, global and local. Global
5764 commands are used by multiple input methods for the same purpose,
5765 and have global key assignments. Local commands are used only by
5766 a specific input method, and have only local key assignments.
5768 Each input method may locally change key assignments for global
5769 commands. The global key assignment for a global command is
5770 effective only when the current input method does not have local
5771 key assignments for that command.
5773 If $NAME is #Mnil, information about global commands is returned.
5774 In this case $LANGUAGE is ignored.
5776 If $NAME is not #Mnil, information about those commands that have
5777 local key assignments in the input method specified by $LANGUAGE
5778 and $NAME is returned.
5781 If no input method commands are found, this function returns @c NULL.
5783 Otherwise, a pointer to a plist is returned. The key of each
5784 element in the plist is a symbol representing a command, and the
5785 value is a plist of the form COMMAND-INFO described below.
5787 The first element of COMMAND-INFO has the key #Mtext, and the
5788 value is an M-text describing the command.
5790 If there are no more elements, that means no key sequences are
5791 assigned to the command. Otherwise, each of the remaining
5792 elements has the key #Mplist, and the value is a plist whose keys are
5793 #Msymbol and values are symbols representing input keys, which are
5794 currently assigned to the command.
5796 As the returned plist is kept in the library, the caller must not
5797 modify nor free it. */
5799 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5801 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5802 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5803 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5804 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5806 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5807 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5808 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5809 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5811 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5812 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5813 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5816 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5817 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5819 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5820 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5824 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5826 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5827 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5828 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5830 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5831 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5832 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5835 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5836 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5837 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5838 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5839 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5841 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5842 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5845 minput_get_commands (MSymbol language, MSymbol name)
5847 MInputMethodInfo *im_info;
5852 im_info = get_im_info (language, name, Mnil, Mcommand);
5853 if (! im_info || ! im_info->configured_vars)
5855 M17N_OBJECT_UNREF (im_info->bc_cmds);
5856 im_info->bc_cmds = mplist ();
5857 MPLIST_DO (cmds, im_info->configured_cmds)
5859 MPlist *plist = MPLIST_PLIST (cmds);
5860 MPlist *elt = mplist ();
5862 mplist_push (im_info->bc_cmds, Mplist, elt);
5863 mplist_add (elt, MPLIST_SYMBOL (plist),
5864 mplist_copy (MPLIST_NEXT (plist)));
5865 M17N_OBJECT_UNREF (elt);
5867 return im_info->bc_cmds;
5873 @brief Assign a key sequence to an input method command (obsolete).
5875 This function is obsolete. Use minput_config_command () instead.
5877 The minput_assign_command_keys () function assigns input key
5878 sequence $KEYSEQ to input method command $COMMAND for the input
5879 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5880 key sequence is assigned globally no matter what $LANGUAGE is.
5881 Otherwise the key sequence is assigned locally.
5883 Each element of $KEYSEQ must have the key $Msymbol and the value
5884 must be a symbol representing an input key.
5886 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5887 globally or locally.
5889 This assignment gets effective in a newly opened input method.
5892 If the operation was successful, 0 is returned. Otherwise -1 is
5893 returned, and #merror_code is set to #MERROR_IM. */
5895 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5897 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5898 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5899 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5900 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5901 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5903 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5904 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5906 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5907 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5909 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5912 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5913 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5916 minput_assign_command_keys (MSymbol language, MSymbol name,
5917 MSymbol command, MPlist *keyseq)
5923 if (command == Mnil)
5924 MERROR (MERROR_IM, -1);
5929 if (! check_command_keyseq (keyseq))
5930 MERROR (MERROR_IM, -1);
5932 mplist_add (plist, Mplist, keyseq);
5937 ret = minput_config_command (language, name, command, keyseq);
5938 M17N_OBJECT_UNREF (keyseq);
5945 /*** @addtogroup m17nDebug */
5951 @brief Dump an input method.
5953 The mdebug_dump_im () function prints the input method $IM in a
5954 human readable way to the stderr. $INDENT specifies how many
5955 columns to indent the lines but the first one.
5958 This function returns $IM. */
5960 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
5962 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
5963 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
5966 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
5969 mdebug_dump_im (MInputMethod *im, int indent)
5971 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
5974 prefix = (char *) alloca (indent + 1);
5975 memset (prefix, 32, indent);
5976 prefix[indent] = '\0';
5978 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
5979 msymbol_name (im->name));
5980 mdebug_dump_mtext (im_info->title, 0, 0);
5981 if (im->name != Mnil)
5985 MPLIST_DO (state, im_info->states)
5987 fprintf (stderr, "\n%s ", prefix);
5988 dump_im_state (MPLIST_VAL (state), indent + 2);
5991 fprintf (stderr, ")");