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 /** Structure to hold a map. */
206 /** List of actions to take when we reach the map. In a root map,
207 the actions are executed only when there is no more key. */
210 /** List of deeper maps. If NULL, this is a terminal map. */
213 /** List of actions to take when we leave the map successfully. In
214 a root map, the actions are executed only when none of submaps
215 handle the current key. */
216 MPlist *branch_actions;
219 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
224 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
231 /** Name of the state. */
234 /** Title of the state, or NULL. */
237 /** Key translation map of the state. Built by merging all maps of
242 #define CUSTOM_FILE "config.mic"
244 static MPlist *load_im_info_keys;
246 /* List of input method information. The format is:
247 (LANGUAGE NAME t:IM_INFO ... ... ...) */
248 static MPlist *im_info_list;
250 /* Database for user's customization file. */
251 static MDatabase *im_custom_mdb;
253 /* List of input method information loaded from im_custom_mdb. The
254 format is the same as im_info_list. */
255 static MPlist *im_custom_list;
257 /* List of input method information configured by
258 minput_config_command and minput_config_variable. The format is
259 the same as im_info_list. */
260 static MPlist *im_config_list;
262 /* Global input method information. It points into the element of
263 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
265 static MInputMethodInfo *global_info;
267 static int update_global_info (void);
268 static int update_custom_info (void);
269 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
276 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
277 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
278 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
280 char buf[6], buf2[32];
282 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
285 M_key_alias = msymbol (" key-alias");
290 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
292 one_char_symbol[i] = msymbol (buf);
293 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
296 alias[j++] = one_char_symbol[i];
299 /* Ex: `Escape' == `C-[' */
300 alias[j++] = msymbol (key_names[i]);
302 if (buf[2] >= 'A' && buf[2] <= 'Z')
304 /* Ex: `C-a' == `C-A' */
306 alias[j++] = msymbol (buf);
309 /* Establish cyclic alias chain. */
312 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
316 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
318 one_char_symbol[i] = msymbol (buf + 2);
319 if (i >= 'A' && i <= 'Z')
321 /* Ex: `A' == `S-A' == `S-a'. */
322 alias[0] = alias[3] = one_char_symbol[i];
323 alias[1] = msymbol (buf);
325 alias[2] = msymbol (buf);
327 for (j = 0; j < 3; j++)
328 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
333 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
334 alias[1] = msymbol ("C-?");
335 for (j = 0; j < 2; j++)
336 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
341 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
344 /* `C-M-a' == `C-A-a' */
346 alias[j++] = one_char_symbol[i] = msymbol (buf);
348 alias[j++] = msymbol (buf);
349 if (key_names[i - 128])
351 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
353 strcpy (buf2 + 2, key_names[i - 128]);
354 alias[j++] = msymbol (buf2);
356 alias[j++] = msymbol (buf2);
358 if (buf[4] >= 'A' && buf[4] <= 'Z')
360 /* Ex: `C-M-a' == `C-M-A'. */
363 alias[j++] = msymbol (buf);
365 alias[j++] = msymbol (buf);
368 /* Establish cyclic alias chain. */
371 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
373 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
376 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
378 alias[1] = msymbol (buf + 2);
379 for (j = 0; j < 2; j++)
380 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
383 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
384 alias[1] = msymbol ("A-Delete");
385 alias[2] = msymbol ("C-M-?");
386 alias[3] = msymbol ("C-A-?");
387 for (j = 0; j < 4; j++)
388 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
390 Minput_method = msymbol ("input-method");
391 Mtitle = msymbol ("title");
392 Mmacro = msymbol ("macro");
393 Mmodule = msymbol ("module");
394 Mmap = msymbol ("map");
395 Mstate = msymbol ("state");
396 Minclude = msymbol ("include");
397 Minsert = msymbol ("insert");
398 M_candidates = msymbol (" candidates");
399 Mdelete = msymbol ("delete");
400 Mmove = msymbol ("move");
401 Mmark = msymbol ("mark");
402 Mpushback = msymbol ("pushback");
403 Mundo = msymbol ("undo");
404 Mcall = msymbol ("call");
405 Mshift = msymbol ("shift");
406 Mselect = msymbol ("select");
407 Mshow = msymbol ("show");
408 Mhide = msymbol ("hide");
409 Mcommit = msymbol ("commit");
410 Munhandle = msymbol ("unhandle");
411 Mset = msymbol ("set");
412 Madd = msymbol ("add");
413 Msub = msymbol ("sub");
414 Mmul = msymbol ("mul");
415 Mdiv = msymbol ("div");
416 Mequal = msymbol ("=");
417 Mless = msymbol ("<");
418 Mgreater = msymbol (">");
419 Mless_equal = msymbol ("<=");
420 Mgreater_equal = msymbol (">=");
421 Mcond = msymbol ("cond");
422 Mplus = msymbol ("+");
423 Mminus = msymbol ("-");
424 Mstar = msymbol ("*");
425 Mslash = msymbol ("/");
426 Mand = msymbol ("&");
428 Mnot = msymbol ("!");
430 Mat_reload = msymbol ("@reload");
432 Mcandidates_group_size = msymbol ("candidates-group-size");
433 Mcandidates_charset = msymbol ("candidates-charset");
435 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
436 Mcandidate_index = msymbol (" candidate-index");
438 Minit = msymbol ("init");
439 Mfini = msymbol ("fini");
441 Mdescription = msymbol ("description");
442 Mcommand = msymbol ("command");
443 Mvariable = msymbol ("variable");
444 Mglobal = msymbol ("global");
445 Mconfig = msymbol ("config");
447 load_im_info_keys = mplist ();
448 mplist_add (load_im_info_keys, Mstate, Mnil);
449 mplist_push (load_im_info_keys, Mmap, Mnil);
451 im_info_list = mplist ();
452 im_config_list = im_custom_list = NULL;
453 im_custom_mdb = NULL;
454 update_custom_info ();
456 update_global_info ();
458 fully_initialized = 1;
461 #define MINPUT__INIT() \
463 if (! fully_initialized) \
464 fully_initialize (); \
469 marker_code (MSymbol sym)
475 name = MSYMBOL_NAME (sym);
476 return ((name[0] == '@'
477 && ((name[1] >= '0' && name[1] <= '9')
478 || name[1] == '<' || name[1] == '>'
479 || name[1] == '=' || name[1] == '+' || name[1] == '-'
480 || name[1] == '[' || name[1] == ']'
488 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
490 MPlist *plist = mplist__assq (ic_info->vars, var);
494 plist = MPLIST_PLIST (plist);
495 return MPLIST_NEXT (plist);
499 mplist_push (ic_info->vars, Mplist, plist);
500 M17N_OBJECT_UNREF (plist);
501 plist = mplist_add (plist, Msymbol, var);
502 plist = mplist_add (plist, Minteger, (void *) 0);
507 get_surrounding_text (MInputContext *ic, int len)
511 mplist_push (ic->plist, Minteger, (void *) len);
512 if (minput__callback (ic, Minput_get_surrounding_text) >= 0
513 && MPLIST_MTEXT_P (ic->plist))
514 mt = MPLIST_MTEXT (ic->plist);
515 mplist_pop (ic->plist);
520 delete_surrounding_text (MInputContext *ic, int pos)
522 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
524 mplist_push (ic->plist minput__callback (ic, Minput_delete_surrounding_text);
525 mplist_pop (ic->plist);
527 M17N_OBJECT_UNREF (ic_info->preceding_text);
529 M17N_OBJECT_UNREF (ic_info->following_text);
533 get_preceding_char (MInputContext *ic, int pos)
535 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
539 if (ic_info->preceding_text)
541 len = mtext_nchars (ic_info->preceding_text);
543 return mtext_ref_char (ic_info->preceding_text, len - pos);
545 mt = get_surrounding_text (ic, - pos);
548 len = mtext_nchars (mt);
549 if (ic_info->preceding_text)
551 if (mtext_nchars (ic_info->preceding_text) < len)
553 M17N_OBJECT_UNREF (ic_info->preceding_text);
554 ic_info->preceding_text = mt;
558 ic_info->preceding_text = mt;
561 return mtext_ref_char (ic_info->preceding_text, len - pos);
565 get_following_char (MInputContext *ic, int pos)
567 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
571 if (ic_info->following_text)
573 len = mtext_nchars (ic_info->following_text);
575 return mtext_ref_char (ic_info->following_text, pos - 1);
577 mt = get_surrounding_text (ic, pos);
580 len = mtext_nchars (mt);
581 if (ic_info->following_text)
583 if (mtext_nchars (ic_info->following_text) < len)
585 M17N_OBJECT_UNREF (ic_info->following_text);
586 ic_info->following_text = mt;
590 ic_info->following_text = mt;
593 return mtext_ref_char (ic_info->following_text, pos - 1);
597 surrounding_pos (MSymbol sym)
603 name = MSYMBOL_NAME (sym);
604 if ((name[1] == '-' || name[1] == '+')
605 && name[2] >= '1' && name[2] <= '9')
606 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
611 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
613 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
615 MText *preedit = ic->preedit;
616 int len = mtext_nchars (preedit);
620 if (MPLIST_INTEGER_P (arg))
621 return MPLIST_INTEGER (arg);
623 && (surrounding = surrounding_pos (MPLIST_SYMBOL (arg))) != 0)
624 return (surrounding < 0
625 ? get_preceding_char (ic, - surrounding)
626 : get_following_char (ic, surrounding));
627 code = marker_code (MPLIST_SYMBOL (arg));
630 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
634 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
637 return ic_info->key_head;
638 if (code >= '0' && code <= '9')
640 else if (code == '=')
641 code = ic->cursor_pos;
642 else if (code == '-' || code == '[')
643 code = ic->cursor_pos - 1;
644 else if (code == '+' || code == ']')
645 code = ic->cursor_pos + 1;
646 else if (code == '<')
648 else if (code == '>')
650 return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
654 parse_expression (MPlist *plist)
658 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
660 if (! MPLIST_PLIST_P (plist))
662 plist = MPLIST_PLIST (plist);
663 op = MPLIST_SYMBOL (plist);
664 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
665 && op != Mand && op != Mor && op != Mnot
666 && op != Mless && op != Mgreater && op != Mequal
667 && op != Mless_equal && op != Mgreater_equal)
668 MERROR (MERROR_IM, -1);
669 MPLIST_DO (plist, MPLIST_NEXT (plist))
670 if (parse_expression (plist) < 0)
676 resolve_expression (MInputContext *ic, MPlist *plist)
681 if (MPLIST_INTEGER_P (plist))
682 return MPLIST_INTEGER (plist);
683 if (MPLIST_SYMBOL_P (plist))
684 return integer_value (ic, plist, NULL, 1);
685 if (! MPLIST_PLIST_P (plist))
687 plist = MPLIST_PLIST (plist);
688 if (! MPLIST_SYMBOL_P (plist))
690 op = MPLIST_SYMBOL (plist);
691 plist = MPLIST_NEXT (plist);
692 val = resolve_expression (ic, plist);
694 MPLIST_DO (plist, MPLIST_NEXT (plist))
695 val += resolve_expression (ic, plist);
696 else if (op == Mminus)
697 MPLIST_DO (plist, MPLIST_NEXT (plist))
698 val -= resolve_expression (ic, plist);
699 else if (op == Mstar)
700 MPLIST_DO (plist, MPLIST_NEXT (plist))
701 val *= resolve_expression (ic, plist);
702 else if (op == Mslash)
703 MPLIST_DO (plist, MPLIST_NEXT (plist))
704 val /= resolve_expression (ic, plist);
706 MPLIST_DO (plist, MPLIST_NEXT (plist))
707 val &= resolve_expression (ic, plist);
709 MPLIST_DO (plist, MPLIST_NEXT (plist))
710 val |= resolve_expression (ic, plist);
713 else if (op == Mless)
714 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
715 else if (op == Mequal)
716 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
717 else if (op == Mgreater)
718 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
719 else if (op == Mless_equal)
720 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
721 else if (op == Mgreater_equal)
722 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
726 /* Parse PLIST as an action list. PLIST should have this form:
727 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
728 Return 0 if successfully parsed, otherwise return -1. */
731 parse_action_list (MPlist *plist, MPlist *macros)
733 MPLIST_DO (plist, plist)
735 if (MPLIST_MTEXT_P (plist))
737 /* This is a short form of (insert MTEXT). */
738 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
739 MERROR (MERROR_IM, -1); */
741 else if (MPLIST_PLIST_P (plist)
742 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
743 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
747 /* This is a short form of (insert (GROUPS *)). */
748 MPLIST_DO (pl, MPLIST_PLIST (plist))
750 if (MPLIST_PLIST_P (pl))
754 MPLIST_DO (elt, MPLIST_PLIST (pl))
755 if (! MPLIST_MTEXT_P (elt)
756 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
757 MERROR (MERROR_IM, -1);
761 if (! MPLIST_MTEXT_P (pl)
762 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
763 MERROR (MERROR_IM, -1);
767 else if (MPLIST_INTEGER_P (plist))
769 int c = MPLIST_INTEGER (plist);
771 if (c < 0 || c > MCHAR_MAX)
772 MERROR (MERROR_IM, -1);
774 else if (MPLIST_PLIST_P (plist)
775 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
777 MPlist *pl = MPLIST_PLIST (plist);
778 MSymbol action_name = MPLIST_SYMBOL (pl);
780 pl = MPLIST_NEXT (pl);
782 if (action_name == Minsert)
784 if (MPLIST_MTEXT_P (pl))
786 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
787 MERROR (MERROR_IM, -1);
789 else if (MPLIST_PLIST_P (pl))
793 if (MPLIST_PLIST_P (pl))
797 MPLIST_DO (elt, MPLIST_PLIST (pl))
798 if (! MPLIST_MTEXT_P (elt)
799 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
800 MERROR (MERROR_IM, -1);
804 if (! MPLIST_MTEXT_P (pl)
805 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
806 MERROR (MERROR_IM, -1);
810 else if (! MPLIST_SYMBOL_P (pl))
811 MERROR (MERROR_IM, -1);
813 else if (action_name == Mselect
814 || action_name == Mdelete
815 || action_name == Mmove)
817 if (parse_expression (pl) < 0)
820 else if (action_name == Mmark
821 || action_name == Mcall
822 || action_name == Mshift)
824 if (! MPLIST_SYMBOL_P (pl))
825 MERROR (MERROR_IM, -1);
827 else if (action_name == Mundo)
829 if (! MPLIST_TAIL_P (pl))
831 if (! MPLIST_SYMBOL_P (pl)
832 && (! MPLIST_INTEGER_P (pl)
833 || MPLIST_INTEGER (pl) == 0))
834 MERROR (MERROR_IM, -1);
837 else if (action_name == Mpushback)
839 if (MPLIST_MTEXT_P (pl))
841 MText *mt = MPLIST_MTEXT (pl);
843 if (mtext_nchars (mt) != mtext_nbytes (mt))
844 MERROR (MERROR_IM, -1);
846 else if (MPLIST_PLIST_P (pl))
850 MPLIST_DO (p, MPLIST_PLIST (pl))
851 if (! MPLIST_SYMBOL_P (p))
852 MERROR (MERROR_IM, -1);
854 else if (! MPLIST_INTEGER_P (pl))
855 MERROR (MERROR_IM, -1);
857 else if (action_name == Mset || action_name == Madd
858 || action_name == Msub || action_name == Mmul
859 || action_name == Mdiv)
861 if (! MPLIST_SYMBOL_P (pl))
862 MERROR (MERROR_IM, -1);
863 if (parse_expression (MPLIST_NEXT (pl)) < 0)
866 else if (action_name == Mequal || action_name == Mless
867 || action_name == Mgreater || action_name == Mless_equal
868 || action_name == Mgreater_equal)
870 if (parse_expression (pl) < 0
871 || parse_expression (MPLIST_NEXT (pl)) < 0)
873 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
874 if (! MPLIST_PLIST_P (pl))
875 MERROR (MERROR_IM, -1);
876 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
877 MERROR (MERROR_IM, -1);
878 pl = MPLIST_NEXT (pl);
879 if (MPLIST_PLIST_P (pl)
880 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
881 MERROR (MERROR_IM, -1);
883 else if (action_name == Mshow || action_name == Mhide
884 || action_name == Mcommit || action_name == Munhandle)
886 else if (action_name == Mcond)
889 if (! MPLIST_PLIST_P (pl))
890 MERROR (MERROR_IM, -1);
892 else if (! macros || ! mplist_get (macros, action_name))
893 MERROR (MERROR_IM, -1);
895 else if (! MPLIST_SYMBOL_P (plist))
896 MERROR (MERROR_IM, -1);
903 resolve_command (MPlist *cmds, MSymbol command)
907 if (! cmds || ! (plist = mplist__assq (cmds, command)))
909 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
910 plist = MPLIST_NEXT (plist);
911 plist = MPLIST_NEXT (plist);
912 plist = MPLIST_NEXT (plist);
916 /* Load a translation into MAP from PLIST.
918 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
921 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
922 MPlist *branch_actions, MPlist *macros)
927 if (MPLIST_MTEXT_P (keylist))
929 MText *mt = MPLIST_MTEXT (keylist);
931 len = mtext_nchars (mt);
932 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
934 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
935 for (i = 0; i < len; i++)
936 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
942 if (MFAILP (MPLIST_PLIST_P (keylist)))
944 elt = MPLIST_PLIST (keylist);
945 len = MPLIST_LENGTH (elt);
946 if (MFAILP (len > 0))
948 keyseq = (MSymbol *) alloca (sizeof (int) * len);
949 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
951 if (MPLIST_INTEGER_P (elt))
953 int c = MPLIST_INTEGER (elt);
955 if (MFAILP (c >= 0 && c < 0x100))
957 keyseq[i] = one_char_symbol[c];
961 if (MFAILP (MPLIST_SYMBOL_P (elt)))
963 keyseq[i] = MPLIST_SYMBOL (elt);
968 for (i = 0; i < len; i++)
970 MIMMap *deeper = NULL;
973 deeper = mplist_get (map->submaps, keyseq[i]);
975 map->submaps = mplist ();
978 /* Fixme: It is better to make all deeper maps at once. */
979 MSTRUCT_CALLOC (deeper, MERROR_IM);
980 mplist_put (map->submaps, keyseq[i], deeper);
985 /* We reach a terminal map. */
987 || map->branch_actions)
988 /* This map is already defined. We avoid overriding it. */
991 if (! MPLIST_TAIL_P (map_actions))
993 if (parse_action_list (map_actions, macros) < 0)
994 MERROR (MERROR_IM, -1);
995 map->map_actions = map_actions;
999 map->branch_actions = branch_actions;
1000 M17N_OBJECT_REF (branch_actions);
1006 /* Load a branch from PLIST into MAP. PLIST has this form:
1007 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1010 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1013 MPlist *branch_actions;
1015 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1017 map_name = MPLIST_SYMBOL (plist);
1018 plist = MPLIST_NEXT (plist);
1019 if (MPLIST_TAIL_P (plist))
1020 branch_actions = NULL;
1021 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1024 branch_actions = plist;
1025 if (map_name == Mnil)
1027 map->branch_actions = branch_actions;
1029 M17N_OBJECT_REF (branch_actions);
1031 else if (map_name == Mt)
1033 map->map_actions = branch_actions;
1035 M17N_OBJECT_REF (branch_actions);
1037 else if (im_info->maps
1038 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1040 MPLIST_DO (plist, plist)
1042 MPlist *keylist, *map_actions;
1044 if (! MPLIST_PLIST_P (plist))
1045 MERROR (MERROR_IM, -1);
1046 keylist = MPLIST_PLIST (plist);
1047 map_actions = MPLIST_NEXT (keylist);
1048 if (MPLIST_SYMBOL_P (keylist))
1050 MSymbol command = MPLIST_SYMBOL (keylist);
1053 if (MFAILP (command != Mat_reload))
1055 pl = resolve_command (im_info->configured_cmds, command);
1059 load_translation (map, pl, map_actions, branch_actions,
1063 load_translation (map, keylist, map_actions, branch_actions,
1071 /* Load a macro from PLIST into IM_INFO->macros.
1072 PLIST has this from:
1073 PLIST ::= ( MACRO-NAME ACTION * )
1074 IM_INFO->macros is a plist of macro names vs action list. */
1077 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1082 if (! MPLIST_SYMBOL_P (plist))
1083 MERROR (MERROR_IM, -1);
1084 name = MPLIST_SYMBOL (plist);
1085 plist = MPLIST_NEXT (plist);
1086 if (MPLIST_TAIL_P (plist)
1087 || parse_action_list (plist, im_info->macros) < 0)
1088 MERROR (MERROR_IM, -1);
1089 pl = mplist_get (im_info->macros, name);
1090 M17N_OBJECT_UNREF (pl);
1091 mplist_put (im_info->macros, name, plist);
1092 M17N_OBJECT_REF (plist);
1096 /* Load an external module from PLIST into IM_INFO->externals.
1097 PLIST has this form:
1098 PLIST ::= ( MODULE-NAME FUNCTION * )
1099 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1102 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1107 MIMExternalModule *external;
1111 if (MPLIST_MTEXT_P (plist))
1112 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1113 else if (MPLIST_SYMBOL_P (plist))
1114 module = MPLIST_SYMBOL (plist);
1115 module_file = alloca (strlen (MSYMBOL_NAME (module))
1116 + strlen (DLOPEN_SHLIB_EXT) + 1);
1117 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1119 handle = dlopen (module_file, RTLD_NOW);
1120 if (MFAILP (handle))
1122 fprintf (stderr, "%s\n", dlerror ());
1125 func_list = mplist ();
1126 MPLIST_DO (plist, MPLIST_NEXT (plist))
1128 if (! MPLIST_SYMBOL_P (plist))
1129 MERROR_GOTO (MERROR_IM, err_label);
1130 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1133 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1136 MSTRUCT_MALLOC (external, MERROR_IM);
1137 external->handle = handle;
1138 external->func_list = func_list;
1139 mplist_add (im_info->externals, module, external);
1144 M17N_OBJECT_UNREF (func_list);
1149 free_map (MIMMap *map, int top)
1154 M17N_OBJECT_UNREF (map->map_actions);
1157 MPLIST_DO (plist, map->submaps)
1158 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1159 M17N_OBJECT_UNREF (map->submaps);
1161 M17N_OBJECT_UNREF (map->branch_actions);
1166 free_state (void *object)
1168 MIMState *state = object;
1170 M17N_OBJECT_UNREF (state->title);
1172 free_map (state->map, 1);
1176 /** Load a state from PLIST into a newly allocated state object.
1177 PLIST has this form:
1178 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1179 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1180 Return the state object. */
1183 load_state (MInputMethodInfo *im_info, MPlist *plist)
1187 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1189 M17N_OBJECT (state, free_state, MERROR_IM);
1190 state->name = MPLIST_SYMBOL (plist);
1191 plist = MPLIST_NEXT (plist);
1192 if (MPLIST_MTEXT_P (plist))
1194 state->title = MPLIST_MTEXT (plist);
1195 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1196 Mlanguage, im_info->language);
1197 M17N_OBJECT_REF (state->title);
1198 plist = MPLIST_NEXT (plist);
1200 MSTRUCT_CALLOC (state->map, MERROR_IM);
1201 MPLIST_DO (plist, plist)
1203 if (MFAILP (MPLIST_PLIST_P (plist)))
1205 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1210 /* Return a newly created IM_INFO for an input method specified by
1211 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1213 static MInputMethodInfo *
1214 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1217 MInputMethodInfo *im_info;
1220 if (name == Mnil && extra == Mnil)
1221 language = Mt, extra = Mglobal;
1222 MSTRUCT_CALLOC (im_info, MERROR_IM);
1224 im_info->language = language;
1225 im_info->name = name;
1226 im_info->extra = extra;
1229 mplist_add (plist, Mplist, elt);
1230 M17N_OBJECT_UNREF (elt);
1231 elt = mplist_add (elt, Msymbol, language);
1232 elt = mplist_add (elt, Msymbol, name);
1233 elt = mplist_add (elt, Msymbol, extra);
1234 mplist_add (elt, Mt, im_info);
1240 fini_im_info (MInputMethodInfo *im_info)
1244 M17N_OBJECT_UNREF (im_info->cmds);
1245 M17N_OBJECT_UNREF (im_info->configured_cmds);
1246 M17N_OBJECT_UNREF (im_info->bc_cmds);
1247 M17N_OBJECT_UNREF (im_info->vars);
1248 M17N_OBJECT_UNREF (im_info->configured_vars);
1249 M17N_OBJECT_UNREF (im_info->bc_vars);
1250 M17N_OBJECT_UNREF (im_info->description);
1251 M17N_OBJECT_UNREF (im_info->title);
1252 if (im_info->states)
1254 MPLIST_DO (plist, im_info->states)
1256 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1258 M17N_OBJECT_UNREF (state);
1260 M17N_OBJECT_UNREF (im_info->states);
1263 if (im_info->macros)
1265 MPLIST_DO (plist, im_info->macros)
1266 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1267 M17N_OBJECT_UNREF (im_info->macros);
1270 if (im_info->externals)
1272 MPLIST_DO (plist, im_info->externals)
1274 MIMExternalModule *external = MPLIST_VAL (plist);
1276 dlclose (external->handle);
1277 M17N_OBJECT_UNREF (external->func_list);
1279 MPLIST_KEY (plist) = Mt;
1281 M17N_OBJECT_UNREF (im_info->externals);
1285 MPLIST_DO (plist, im_info->maps)
1287 MPlist *p = MPLIST_PLIST (plist);
1289 M17N_OBJECT_UNREF (p);
1291 M17N_OBJECT_UNREF (im_info->maps);
1298 free_im_info (MInputMethodInfo *im_info)
1300 fini_im_info (im_info);
1305 free_im_list (MPlist *plist)
1309 MPLIST_DO (pl, plist)
1311 MInputMethodInfo *im_info;
1313 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1314 im_info = MPLIST_VAL (elt);
1315 free_im_info (im_info);
1317 M17N_OBJECT_UNREF (plist);
1320 static MInputMethodInfo *
1321 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1323 if (name == Mnil && extra == Mnil)
1324 language = Mt, extra = Mglobal;
1325 while ((plist = mplist__assq (plist, language)))
1327 MPlist *elt = MPLIST_PLIST (plist);
1329 plist = MPLIST_NEXT (plist);
1330 elt = MPLIST_NEXT (elt);
1331 if (MPLIST_SYMBOL (elt) != name)
1333 elt = MPLIST_NEXT (elt);
1334 if (MPLIST_SYMBOL (elt) != extra)
1336 elt = MPLIST_NEXT (elt);
1337 return MPLIST_VAL (elt);
1342 static void load_im_info (MPlist *, MInputMethodInfo *);
1344 #define get_custom_info(im_info) \
1346 ? lookup_im_info (im_custom_list, (im_info)->language, \
1347 (im_info)->name, (im_info)->extra) \
1350 #define get_config_info(im_info) \
1352 ? lookup_im_info (im_config_list, (im_info)->language, \
1353 (im_info)->name, (im_info)->extra) \
1357 update_custom_info (void)
1363 if (mdatabase__check (im_custom_mdb) > 0)
1368 MDatabaseInfo *custom_dir_info;
1369 char custom_path[PATH_MAX + 1];
1371 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1372 if (! custom_dir_info->filename
1373 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1375 strcpy (custom_path, custom_dir_info->filename);
1376 strcat (custom_path, CUSTOM_FILE);
1377 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1383 free_im_list (im_custom_list);
1384 im_custom_list = NULL;
1386 plist = mdatabase_load (im_custom_mdb);
1389 im_custom_list = mplist ();
1391 MPLIST_DO (pl, plist)
1393 MSymbol language, name, extra;
1394 MInputMethodInfo *im_info;
1395 MPlist *im_data, *p;
1397 if (! MPLIST_PLIST_P (pl))
1399 p = MPLIST_PLIST (pl);
1400 im_data = MPLIST_NEXT (p);
1401 if (! MPLIST_PLIST_P (p))
1403 p = MPLIST_PLIST (p);
1404 if (! MPLIST_SYMBOL_P (p)
1405 || MPLIST_SYMBOL (p) != Minput_method)
1407 p = MPLIST_NEXT (p);
1408 if (! MPLIST_SYMBOL_P (p))
1410 language = MPLIST_SYMBOL (p);
1411 p = MPLIST_NEXT (p);
1412 if (! MPLIST_SYMBOL_P (p))
1414 name = MPLIST_SYMBOL (p);
1415 if (language == Mnil || name == Mnil)
1417 p = MPLIST_NEXT (p);
1418 if (MPLIST_TAIL_P (p))
1420 else if (MPLIST_SYMBOL_P (p))
1421 extra = MPLIST_SYMBOL (p);
1424 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1425 load_im_info (im_data, im_info);
1427 M17N_OBJECT_UNREF (plist);
1432 update_global_info (void)
1438 int ret = mdatabase__check (global_info->mdb);
1442 fini_im_info (global_info);
1446 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1448 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1450 if (! global_info->mdb
1451 || ! (plist = mdatabase_load (global_info->mdb)))
1454 load_im_info (plist, global_info);
1455 M17N_OBJECT_UNREF (plist);
1460 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1461 and EXTRA. KEY, if not Mnil, tells which kind of information about
1462 the input method is necessary, and the returned IM_INFO may contain
1463 only that information. */
1465 static MInputMethodInfo *
1466 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1469 MInputMethodInfo *im_info;
1472 if (name == Mnil && extra == Mnil)
1473 language = Mt, extra = Mglobal;
1474 im_info = lookup_im_info (im_info_list, language, name, extra);
1477 if (key == Mnil ? im_info->states != NULL
1478 : key == Mcommand ? im_info->cmds != NULL
1479 : key == Mvariable ? im_info->vars != NULL
1480 : key == Mtitle ? im_info->title != NULL
1481 : key == Mdescription ? im_info->description != NULL
1483 /* IM_INFO already contains required information. */
1485 /* We have not yet loaded required information. */
1489 mdb = mdatabase_find (Minput_method, language, name, extra);
1492 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1497 plist = mdatabase_load (im_info->mdb);
1501 mplist_push (load_im_info_keys, key, Mt);
1502 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1503 mplist_pop (load_im_info_keys);
1507 MERROR (MERROR_IM, im_info);
1508 update_global_info ();
1509 load_im_info (plist, im_info);
1510 M17N_OBJECT_UNREF (plist);
1513 if (! im_info->cmds)
1514 im_info->cmds = mplist ();
1515 if (! im_info->vars)
1516 im_info->vars = mplist ();
1518 if (! im_info->title
1519 && (key == Mnil || key == Mtitle))
1520 im_info->title = (name == Mnil ? mtext ()
1521 : mtext_from_data (MSYMBOL_NAME (name),
1522 MSYMBOL_NAMELEN (name),
1523 MTEXT_FORMAT_US_ASCII));
1527 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1528 If updated, but got unloadable, return -1. Otherwise, update
1529 contents of IM_INFO from the new database, and return 1. */
1532 reload_im_info (MInputMethodInfo *im_info)
1537 check = mdatabase__check (im_info->mdb);
1542 plist = mdatabase_load (im_info->mdb);
1545 fini_im_info (im_info);
1546 load_im_info (plist, im_info);
1547 M17N_OBJECT_UNREF (plist);
1551 static MInputMethodInfo *
1552 get_im_info_by_tags (MPlist *plist)
1557 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1558 i++, plist = MPLIST_NEXT (plist))
1559 tag[i] = MPLIST_SYMBOL (plist);
1564 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1567 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1571 check_command_keyseq (MPlist *keyseq)
1573 if (MPLIST_PLIST_P (keyseq))
1575 MPlist *p = MPLIST_PLIST (keyseq);
1578 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1582 if (MPLIST_MTEXT_P (keyseq))
1584 MText *mt = MPLIST_MTEXT (keyseq);
1587 for (i = 0; i < mtext_nchars (mt); i++)
1588 if (mtext_ref_char (mt, i) >= 256)
1595 /* Load command defitions from PLIST into IM_INFO->cmds.
1597 PLIST is well-formed and has this form;
1598 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1599 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1600 M-text or a plist of symbols.
1602 The returned list has the same form, but for each element...
1604 (1) If DESCRIPTION and the rest are omitted, the element is not
1605 stored in the returned list.
1607 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1608 description in global_info->cmds (if any). */
1611 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1615 im_info->cmds = tail = mplist ();
1617 MPLIST_DO (plist, MPLIST_NEXT (plist))
1619 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1622 if (MFAILP (MPLIST_PLIST_P (plist)))
1624 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1625 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1627 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1628 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1630 if (MFAILP (im_info != global_info))
1631 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1635 if (! MPLIST_MTEXT_P (p)
1636 && (! MPLIST_SYMBOL_P (p) || MPLIST_SYMBOL (p) != Mnil))
1637 mplist_set (p, Msymbol, Mnil);
1638 p = MPLIST_NEXT (p);
1639 while (! MPLIST_TAIL_P (p))
1641 if (MFAILP (check_command_keyseq (p)))
1642 mplist__pop_unref (p);
1644 p = MPLIST_NEXT (p);
1647 tail = mplist_add (tail, Mplist, pl);
1652 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1653 MPlist *config_cmds)
1655 MPlist *global = NULL, *custom = NULL, *config = NULL;
1657 MText *description = NULL;
1661 name = MPLIST_SYMBOL (plist);
1662 plist = MPLIST_NEXT (plist);
1663 if (MPLIST_MTEXT_P (plist))
1664 description = MPLIST_MTEXT (plist);
1665 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1667 global = MPLIST_NEXT (MPLIST_PLIST (global));
1668 description = MPLIST_MTEXT_P (global) ? MPLIST_MTEXT (global) : NULL;
1670 if (MPLIST_TAIL_P (plist))
1673 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1674 global = MPLIST_NEXT (MPLIST_PLIST (global));
1677 keyseq = MPLIST_NEXT (global);
1678 status = Minherited;
1688 keyseq = MPLIST_NEXT (plist);
1692 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1694 config = MPLIST_NEXT (MPLIST_PLIST (config));
1695 if (! MPLIST_TAIL_P (config))
1697 keyseq = MPLIST_NEXT (config);
1698 status = Mconfigured;
1701 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1703 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1704 if (! MPLIST_TAIL_P (custom))
1706 keyseq = MPLIST_NEXT (custom);
1707 status = Mcustomized;
1712 mplist_add (plist, Msymbol, name);
1714 mplist_add (plist, Mtext, description);
1716 mplist_add (plist, Msymbol, Mnil);
1717 mplist_add (plist, Msymbol, status);
1718 mplist__conc (plist, keyseq);
1723 config_all_commands (MInputMethodInfo *im_info)
1725 MPlist *global_cmds, *custom_cmds, *config_cmds;
1726 MInputMethodInfo *temp;
1727 MPlist *tail, *plist;
1729 M17N_OBJECT_UNREF (im_info->configured_cmds);
1731 if (MPLIST_TAIL_P (im_info->cmds)
1735 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1736 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1737 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1739 im_info->configured_cmds = tail = mplist ();
1740 MPLIST_DO (plist, im_info->cmds)
1742 MPlist *pl = config_command (MPLIST_PLIST (plist),
1743 global_cmds, custom_cmds, config_cmds);
1745 tail = mplist_add (tail, Mplist, pl);
1749 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1750 valid, return 0 if not. */
1753 check_variable_value (MPlist *val, MPlist *global)
1755 MSymbol type = MPLIST_KEY (val);
1756 MPlist *valids = MPLIST_NEXT (val);
1758 if (type != Minteger && type != Mtext && type != Msymbol)
1762 if (MPLIST_KEY (global) != Mt
1763 && MPLIST_KEY (global) != MPLIST_KEY (val))
1765 if (MPLIST_TAIL_P (valids))
1766 valids = MPLIST_NEXT (global);
1768 if (MPLIST_TAIL_P (valids))
1771 if (type == Minteger)
1773 int n = MPLIST_INTEGER (val);
1775 MPLIST_DO (valids, valids)
1777 if (MPLIST_INTEGER_P (valids))
1779 if (n == MPLIST_INTEGER (valids))
1782 else if (MPLIST_PLIST_P (valids))
1784 MPlist *p = MPLIST_PLIST (valids);
1785 int min_bound, max_bound;
1787 if (! MPLIST_INTEGER_P (p))
1788 MERROR (MERROR_IM, 0);
1789 min_bound = MPLIST_INTEGER (p);
1790 p = MPLIST_NEXT (p);
1791 if (! MPLIST_INTEGER_P (p))
1792 MERROR (MERROR_IM, 0);
1793 max_bound = MPLIST_INTEGER (p);
1794 if (n >= min_bound && n <= max_bound)
1799 else if (type == Msymbol)
1801 MSymbol sym = MPLIST_SYMBOL (val);
1803 MPLIST_DO (valids, valids)
1805 if (! MPLIST_SYMBOL_P (valids))
1806 MERROR (MERROR_IM, 0);
1807 if (sym == MPLIST_SYMBOL (valids))
1813 MText *mt = MPLIST_MTEXT (val);
1815 MPLIST_DO (valids, valids)
1817 if (! MPLIST_MTEXT_P (valids))
1818 MERROR (MERROR_IM, 0);
1819 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1824 return (MPLIST_TAIL_P (valids));
1827 /* Load variable defitions from PLIST into IM_INFO->vars.
1829 PLIST is well-formed and has this form;
1830 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1832 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1834 The returned list has the same form, but for each element...
1836 (1) If DESCRIPTION and the rest are omitted, the element is not
1837 stored in the returned list.
1839 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1840 description in global_info->vars (if any). */
1843 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1845 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1846 ? global_info->vars : NULL);
1849 im_info->vars = tail = mplist ();
1850 MPLIST_DO (plist, MPLIST_NEXT (plist))
1854 if (MFAILP (MPLIST_PLIST_P (plist)))
1856 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1857 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1859 if (im_info == global_info)
1861 /* Loading a global variable. */
1862 p = MPLIST_NEXT (pl);
1863 if (MPLIST_TAIL_P (p))
1864 mplist_add (p, Msymbol, Mnil);
1867 if (MFAILP (MPLIST_MTEXT_P (p)))
1868 mplist_set (p, Msymbol, Mnil);
1869 p = MPLIST_NEXT (p);
1870 if (MFAILP (! MPLIST_TAIL_P (p)
1871 && check_variable_value (p, NULL)))
1872 mplist_set (p, Mt, NULL);
1875 else if (im_info->mdb)
1877 /* Loading a local variable. */
1878 MSymbol name = MPLIST_SYMBOL (pl);
1879 MPlist *global = NULL;
1882 && (p = mplist__assq (global_vars, name)))
1884 /* P ::= ((NAME DESC ...) ...) */
1885 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1886 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1887 global = MPLIST_NEXT (p); /* P ::= (VALUE ...) */
1890 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1891 if (! MPLIST_TAIL_P (p))
1893 if (MFAILP (MPLIST_MTEXT_P (p)
1894 || (MPLIST_SYMBOL_P (p)
1895 && MPLIST_SYMBOL (p) == Mnil)))
1896 mplist_set (p, Msymbol, Mnil);
1897 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1898 if (MFAILP (! MPLIST_TAIL_P (p)))
1899 mplist_set (p, Mt, NULL);
1902 MPlist *valid_values = MPLIST_NEXT (p);
1904 if (! MPLIST_TAIL_P (valid_values)
1905 ? MFAILP (check_variable_value (p, NULL))
1906 : global && MFAILP (check_variable_value (p, global)))
1907 mplist_set (p, Mt, NULL);
1913 /* Loading a variable customization. */
1914 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1915 if (MFAILP (! MPLIST_TAIL_P (p)))
1917 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1918 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1919 || MPLIST_MTEXT_P (p)))
1922 tail = mplist_add (tail, Mplist, pl);
1927 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
1928 MPlist *config_vars)
1930 MPlist *global = NULL, *custom = NULL, *config = NULL;
1931 MSymbol name = MPLIST_SYMBOL (plist);
1932 MText *description = NULL;
1934 MPlist *value, *valids;
1938 global = mplist__assq (global_vars, name);
1940 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
1943 plist = MPLIST_NEXT (plist);
1944 if (MPLIST_MTEXT_P (plist))
1945 description = MPLIST_MTEXT (plist);
1946 else if (global && MPLIST_MTEXT (global))
1947 description = MPLIST_MTEXT (global);
1949 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
1951 if (MPLIST_TAIL_P (plist))
1953 /* Inherit from global (if any). */
1957 if (MPLIST_KEY (value) == Mt)
1959 valids = MPLIST_NEXT (global);
1960 status = Minherited;
1972 value = plist = MPLIST_NEXT (plist);
1973 valids = MPLIST_NEXT (value);
1974 if (MPLIST_KEY (value) == Mt)
1976 if (! MPLIST_TAIL_P (valids))
1979 valids = MPLIST_NEXT (global);
1983 if (config_vars && (config = mplist__assq (config_vars, name)))
1985 config = MPLIST_NEXT (MPLIST_PLIST (config));
1986 if (! MPLIST_TAIL_P (config))
1988 value = MPLIST_NEXT (config);
1989 if (MFAILP (check_variable_value (value, global ? global : plist)))
1991 status = Mconfigured;
1994 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
1996 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1997 if (! MPLIST_TAIL_P (custom))
1999 value = MPLIST_NEXT (custom);
2000 if (MFAILP (check_variable_value (value, global ? global : plist)))
2002 status = Mcustomized;
2007 mplist_add (plist, Msymbol, name);
2009 mplist_add (plist, Mtext, description);
2011 mplist_add (plist, Msymbol, Mnil);
2012 mplist_add (plist, Msymbol, status);
2014 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2016 mplist_add (plist, Mt, NULL);
2017 if (valids && ! MPLIST_TAIL_P (valids))
2018 mplist__conc (plist, valids);
2022 /* Return a configured variable definition list based on
2023 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2024 get it from global_info->vars. */
2027 config_all_variables (MInputMethodInfo *im_info)
2029 MPlist *global_vars, *custom_vars, *config_vars;
2030 MInputMethodInfo *temp;
2031 MPlist *tail, *plist;
2033 M17N_OBJECT_UNREF (im_info->configured_vars);
2035 if (MPLIST_TAIL_P (im_info->vars)
2039 global_vars = im_info != global_info ? global_info->vars : NULL;
2040 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2041 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2043 im_info->configured_vars = tail = mplist ();
2044 MPLIST_DO (plist, im_info->vars)
2046 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2047 global_vars, custom_vars, config_vars);
2049 tail = mplist_add (tail, Mplist, pl);
2053 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2054 CONFIG contains configuration information of the input method. */
2057 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2061 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2063 load_commands (im_info, MPLIST_PLIST (pl));
2064 config_all_commands (im_info);
2065 pl = mplist_pop (pl);
2066 M17N_OBJECT_UNREF (pl);
2069 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2071 load_variables (im_info, MPLIST_PLIST (pl));
2072 config_all_variables (im_info);
2073 pl = mplist_pop (pl);
2074 M17N_OBJECT_UNREF (pl);
2077 MPLIST_DO (plist, plist)
2078 if (MPLIST_PLIST_P (plist))
2080 MPlist *elt = MPLIST_PLIST (plist);
2083 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2085 key = MPLIST_SYMBOL (elt);
2090 elt = MPLIST_NEXT (elt);
2091 if (MFAILP (MPLIST_MTEXT_P (elt)))
2093 im_info->title = MPLIST_MTEXT (elt);
2094 M17N_OBJECT_REF (im_info->title);
2096 else if (key == Mmap)
2098 pl = mplist__from_alist (MPLIST_NEXT (elt));
2101 if (! im_info->maps)
2105 mplist__conc (im_info->maps, pl);
2106 M17N_OBJECT_UNREF (pl);
2109 else if (key == Mmacro)
2111 if (! im_info->macros)
2112 im_info->macros = mplist ();
2113 MPLIST_DO (elt, MPLIST_NEXT (elt))
2115 if (MFAILP (MPLIST_PLIST_P (elt)))
2117 load_macros (im_info, MPLIST_PLIST (elt));
2120 else if (key == Mmodule)
2122 if (! im_info->externals)
2123 im_info->externals = mplist ();
2124 MPLIST_DO (elt, MPLIST_NEXT (elt))
2126 if (MFAILP (MPLIST_PLIST_P (elt)))
2128 load_external_module (im_info, MPLIST_PLIST (elt));
2131 else if (key == Mstate)
2133 MPLIST_DO (elt, MPLIST_NEXT (elt))
2137 if (MFAILP (MPLIST_PLIST_P (elt)))
2139 pl = MPLIST_PLIST (elt);
2140 if (! im_info->states)
2141 im_info->states = mplist ();
2142 state = load_state (im_info, MPLIST_PLIST (elt));
2145 mplist_put (im_info->states, state->name, state);
2148 else if (key == Minclude)
2150 /* elt ::= include (tag1 tag2 ...) key item ... */
2152 MInputMethodInfo *temp;
2154 elt = MPLIST_NEXT (elt);
2155 if (MFAILP (MPLIST_PLIST_P (elt)))
2157 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2160 elt = MPLIST_NEXT (elt);
2161 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2163 key = MPLIST_SYMBOL (elt);
2164 elt = MPLIST_NEXT (elt);
2167 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2169 if (! im_info->maps)
2170 im_info->maps = mplist ();
2171 MPLIST_DO (pl, temp->maps)
2173 p = MPLIST_VAL (pl);
2174 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2175 M17N_OBJECT_REF (p);
2178 else if (key == Mmacro)
2180 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2182 if (! im_info->macros)
2183 im_info->macros = mplist ();
2184 MPLIST_DO (pl, temp->macros)
2186 p = MPLIST_VAL (pl);
2187 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2188 M17N_OBJECT_REF (p);
2191 else if (key == Mstate)
2193 if (! temp->states || MPLIST_TAIL_P (temp->states))
2195 if (! im_info->states)
2196 im_info->states = mplist ();
2197 MPLIST_DO (pl, temp->states)
2199 MIMState *state = MPLIST_VAL (pl);
2201 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2202 M17N_OBJECT_REF (state);
2206 else if (key == Mdescription)
2208 if (im_info->description)
2210 elt = MPLIST_NEXT (elt);
2211 if (MFAILP (MPLIST_MTEXT_P (elt)))
2213 im_info->description = MPLIST_MTEXT (elt);
2214 M17N_OBJECT_REF (im_info->description);
2218 im_info->tick = time (NULL);
2223 static int take_action_list (MInputContext *ic, MPlist *action_list);
2224 static void preedit_commit (MInputContext *ic);
2227 shift_state (MInputContext *ic, MSymbol state_name)
2229 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2230 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2231 MIMState *orig_state = ic_info->state, *state;
2233 /* Find a state to shift to. If not found, shift to the initial
2235 if (state_name == Mt)
2237 if (! ic_info->prev_state)
2239 state = ic_info->prev_state;
2241 else if (state_name == Mnil)
2243 state = (MIMState *) MPLIST_VAL (im_info->states);
2247 state = (MIMState *) mplist_get (im_info->states, state_name);
2249 state = (MIMState *) MPLIST_VAL (im_info->states);
2252 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2254 /* Enter the new state. */
2255 ic_info->state = state;
2256 ic_info->map = state->map;
2257 ic_info->state_key_head = ic_info->key_head;
2258 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2260 /* We have shifted to the initial state. */
2261 preedit_commit (ic);
2262 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2263 ic_info->state_pos = ic->cursor_pos;
2264 if (state != orig_state)
2266 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2267 ic_info->prev_state = NULL;
2269 ic_info->prev_state = orig_state;
2272 ic->status = state->title;
2274 ic->status = im_info->title;
2275 ic->status_changed = 1;
2276 if (ic_info->map == ic_info->state->map
2277 && ic_info->map->map_actions)
2279 MDEBUG_PRINT (" init-actions:");
2280 take_action_list (ic, ic_info->map->map_actions);
2285 /* Find a candidate group that contains a candidate number INDEX from
2286 PLIST. Set START_INDEX to the first candidate number of the group,
2287 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2288 candidate group number if they are non-NULL. If INDEX is -1, find
2289 the last candidate group. */
2292 find_candidates_group (MPlist *plist, int index,
2293 int *start_index, int *end_index, int *group_index)
2295 int i = 0, gidx = 0, len;
2297 MPLIST_DO (plist, plist)
2299 if (MPLIST_MTEXT_P (plist))
2300 len = mtext_nchars (MPLIST_MTEXT (plist));
2302 len = mplist_length (MPLIST_PLIST (plist));
2303 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2309 *end_index = i + len;
2311 *group_index = gidx;
2321 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2323 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2325 int nchars = mt ? mtext_nchars (mt) : 1;
2328 mtext_ins (ic->preedit, pos, mt);
2330 mtext_ins_char (ic->preedit, pos, c, 1);
2331 MPLIST_DO (markers, ic_info->markers)
2332 if (MPLIST_INTEGER (markers) > pos)
2333 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
2334 if (ic->cursor_pos >= pos)
2335 ic->cursor_pos += nchars;
2336 ic->preedit_changed = 1;
2341 preedit_delete (MInputContext *ic, int from, int to)
2343 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2346 mtext_del (ic->preedit, from, to);
2347 MPLIST_DO (markers, ic_info->markers)
2349 if (MPLIST_INTEGER (markers) > to)
2350 MPLIST_VAL (markers)
2351 = (void *) (MPLIST_INTEGER (markers) - (to - from));
2352 else if (MPLIST_INTEGER (markers) > from);
2353 MPLIST_VAL (markers) = (void *) from;
2355 if (ic->cursor_pos >= to)
2356 ic->cursor_pos -= to - from;
2357 else if (ic->cursor_pos > from)
2358 ic->cursor_pos = from;
2359 ic->preedit_changed = 1;
2363 preedit_commit (MInputContext *ic)
2365 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2366 int preedit_len = mtext_nchars (ic->preedit);
2368 if (preedit_len > 0)
2372 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2373 Mcandidate_list, NULL, 0);
2374 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2375 Mcandidate_index, NULL, 0);
2376 mtext_cat (ic->produced, ic->preedit);
2377 if ((mdebug__flag & mdebug_mask)
2378 && mtext_nchars (ic->preedit) > 0)
2382 MDEBUG_PRINT (" (produced");
2383 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2384 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2387 mtext_reset (ic->preedit);
2388 mtext_reset (ic_info->preedit_saved);
2389 MPLIST_DO (p, ic_info->markers)
2391 ic->cursor_pos = ic_info->state_pos = 0;
2392 ic->preedit_changed = 1;
2394 if (ic->candidate_list)
2396 M17N_OBJECT_UNREF (ic->candidate_list);
2397 ic->candidate_list = NULL;
2398 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2399 if (ic->candidate_show)
2401 ic->candidate_show = 0;
2402 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2405 memmove (ic_info->keys, ic_info->keys + ic_info->key_head,
2406 sizeof (int) * (ic_info->used - ic_info->key_head));
2407 ic_info->used -= ic_info->key_head;
2408 ic_info->state_key_head = ic_info->key_head = 0;
2412 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2414 int code = marker_code (sym);
2416 if (mt && (code == '[' || code == ']'))
2420 if (code == '[' && current > 0)
2422 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2426 else if (code == ']' && current < mtext_nchars (mt))
2428 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2434 return (code == '<' ? 0
2435 : code == '>' ? limit
2436 : code == '-' ? current - 1
2437 : code == '+' ? current + 1
2438 : code == '=' ? current
2439 : code - '0' > limit ? limit
2443 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2447 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2449 int from = mtext_property_start (prop);
2450 int to = mtext_property_end (prop);
2452 MPlist *candidate_list = mtext_property_value (prop);
2453 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2455 int ingroup_index = idx - start;
2458 preedit_delete (ic, from, to);
2459 if (MPLIST_MTEXT_P (group))
2461 mt = MPLIST_MTEXT (group);
2462 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
2470 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2471 i++, plist = MPLIST_NEXT (plist));
2472 mt = MPLIST_MTEXT (plist);
2473 preedit_insert (ic, from, mt, 0);
2474 to = from + mtext_nchars (mt);
2476 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2477 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2478 ic->cursor_pos = to;
2482 get_select_charset (MInputContextInfo * ic_info)
2484 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2487 if (! MPLIST_VAL (plist))
2489 sym = MPLIST_SYMBOL (plist);
2492 return MCHARSET (sym);
2496 adjust_candidates (MPlist *plist, MCharset *charset)
2500 /* plist ::= MTEXT ... | PLIST ... */
2501 plist = mplist_copy (plist);
2502 if (MPLIST_MTEXT_P (plist))
2505 while (! MPLIST_TAIL_P (pl))
2507 /* pl ::= MTEXT ... */
2508 MText *mt = MPLIST_MTEXT (pl);
2512 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2514 c = mtext_ref_char (mt, i);
2515 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2519 mt = mtext_dup (mt);
2520 mplist_set (pl, Mtext, mt);
2521 M17N_OBJECT_UNREF (mt);
2524 mtext_del (mt, i, i + 1);
2527 if (mtext_len (mt) > 0)
2528 pl = MPLIST_NEXT (pl);
2532 M17N_OBJECT_UNREF (mt);
2536 else /* MPLIST_PLIST_P (plist) */
2539 while (! MPLIST_TAIL_P (pl))
2541 /* pl ::= (MTEXT ...) ... */
2542 MPlist *p = MPLIST_PLIST (pl);
2544 /* p ::= MTEXT ... */
2548 while (! MPLIST_TAIL_P (p0))
2550 MText *mt = MPLIST_MTEXT (p0);
2553 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2555 c = mtext_ref_char (mt, i);
2556 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2561 p0 = MPLIST_NEXT (p0);
2568 p = mplist_copy (p);
2569 mplist_set (pl, Mplist, p);
2570 M17N_OBJECT_UNREF (p);
2574 p0 = MPLIST_NEXT (p0);
2577 M17N_OBJECT_UNREF (mt);
2580 if (! MPLIST_TAIL_P (p))
2581 pl = MPLIST_NEXT (pl);
2585 M17N_OBJECT_UNREF (p);
2589 if (MPLIST_TAIL_P (plist))
2591 M17N_OBJECT_UNREF (plist);
2598 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2600 MCharset *charset = get_select_charset (ic_info);
2605 plist = resolve_variable (ic_info, Mcandidates_group_size);
2606 column = MPLIST_INTEGER (plist);
2608 plist = MPLIST_PLIST (args);
2611 if (! (plist = adjust_candidates (plist, charset)))
2615 M17N_OBJECT_REF (plist);
2619 if (MPLIST_MTEXT_P (plist))
2621 MText *mt = MPLIST_MTEXT (plist);
2622 MPlist *next = MPLIST_NEXT (plist);
2624 if (MPLIST_TAIL_P (next))
2625 M17N_OBJECT_REF (mt);
2628 mt = mtext_dup (mt);
2629 while (! MPLIST_TAIL_P (next))
2631 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2632 next = MPLIST_NEXT (next);
2635 M17N_OBJECT_UNREF (plist);
2637 len = mtext_nchars (mt);
2639 mplist_add (plist, Mtext, mt);
2642 for (i = 0; i < len; i += column)
2644 int to = (i + column < len ? i + column : len);
2645 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2647 mplist_add (plist, Mtext, sub);
2648 M17N_OBJECT_UNREF (sub);
2651 M17N_OBJECT_UNREF (mt);
2653 else /* MPLIST_PLIST_P (plist) */
2655 MPlist *pl = MPLIST_PLIST (plist), *p;
2656 MPlist *next = MPLIST_NEXT (plist);
2659 if (MPLIST_TAIL_P (next))
2660 M17N_OBJECT_REF (pl);
2663 pl = mplist_copy (pl);
2664 while (! MPLIST_TAIL_P (next))
2666 p = mplist_copy (MPLIST_PLIST (next));
2667 pl = mplist__conc (pl, p);
2668 M17N_OBJECT_UNREF (p);
2669 next = MPLIST_NEXT (next);
2672 M17N_OBJECT_UNREF (plist);
2674 len = mplist_length (pl);
2676 mplist_add (plist, Mplist, pl);
2681 for (i = 0; i < len; i += column)
2684 mplist_add (plist, Mplist, p);
2685 M17N_OBJECT_UNREF (p);
2686 for (j = 0; j < column && i + j < len; j++)
2688 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
2689 p0 = MPLIST_NEXT (p0);
2693 M17N_OBJECT_UNREF (pl);
2702 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2704 MPlist *action = NULL;
2708 if (MPLIST_SYMBOL_P (action_list))
2710 MSymbol var = MPLIST_SYMBOL (action_list);
2713 MPLIST_DO (p, ic_info->vars)
2714 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2716 if (MPLIST_TAIL_P (p))
2718 action = MPLIST_NEXT (MPLIST_PLIST (p));
2719 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2722 if (MPLIST_PLIST_P (action_list))
2724 action = MPLIST_PLIST (action_list);
2725 if (MPLIST_SYMBOL_P (action))
2727 name = MPLIST_SYMBOL (action);
2728 args = MPLIST_NEXT (action);
2730 && MPLIST_PLIST_P (args))
2731 mplist_set (action, Msymbol, M_candidates);
2733 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2736 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2737 mplist_push (action, Msymbol, M_candidates);
2738 mplist_set (action_list, Mplist, action);
2739 M17N_OBJECT_UNREF (action);
2742 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2745 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2746 mplist_push (action, Msymbol, Minsert);
2747 mplist_set (action_list, Mplist, action);
2748 M17N_OBJECT_UNREF (action);
2753 /* Perform list of actions in ACTION_LIST for the current input
2754 context IC. If all actions are performed without error, return 0.
2755 Otherwise, return -1. */
2758 take_action_list (MInputContext *ic, MPlist *action_list)
2760 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2761 MPlist *candidate_list = ic->candidate_list;
2762 int candidate_index = ic->candidate_index;
2763 int candidate_show = ic->candidate_show;
2764 MTextProperty *prop;
2766 MPLIST_DO (action_list, action_list)
2768 MPlist *action = regularize_action (action_list, ic_info);
2774 name = MPLIST_SYMBOL (action);
2775 args = MPLIST_NEXT (action);
2777 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2778 if (name == Minsert)
2780 if (MPLIST_SYMBOL_P (args))
2782 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2783 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2786 if (MPLIST_MTEXT_P (args))
2787 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2788 else /* MPLIST_INTEGER_P (args)) */
2789 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2791 else if (name == M_candidates)
2793 MPlist *plist = get_candidate_list (ic_info, args);
2798 if (MPLIST_MTEXT_P (plist))
2800 preedit_insert (ic, ic->cursor_pos, NULL,
2801 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2806 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2808 preedit_insert (ic, ic->cursor_pos, mt, 0);
2809 len = mtext_nchars (mt);
2811 mtext_put_prop (ic->preedit,
2812 ic->cursor_pos - len, ic->cursor_pos,
2813 Mcandidate_list, plist);
2814 mtext_put_prop (ic->preedit,
2815 ic->cursor_pos - len, ic->cursor_pos,
2816 Mcandidate_index, (void *) 0);
2817 M17N_OBJECT_UNREF (plist);
2819 else if (name == Mselect)
2822 int code, idx, gindex;
2823 int pos = ic->cursor_pos;
2827 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2830 if (MPLIST_SYMBOL_P (args))
2832 code = marker_code (MPLIST_SYMBOL (args));
2838 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2839 group = find_candidates_group (mtext_property_value (prop), idx,
2840 &start, &end, &gindex);
2842 if (code != '[' && code != ']')
2846 ? new_index (NULL, ic->candidate_index - start,
2847 end - start - 1, MPLIST_SYMBOL (args),
2849 : MPLIST_INTEGER (args)));
2852 find_candidates_group (mtext_property_value (prop), -1,
2857 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2862 int ingroup_index = idx - start;
2865 group = mtext_property_value (prop);
2866 len = mplist_length (group);
2879 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2880 idx += (MPLIST_MTEXT_P (group)
2881 ? mtext_nchars (MPLIST_MTEXT (group))
2882 : mplist_length (MPLIST_PLIST (group)));
2883 len = (MPLIST_MTEXT_P (group)
2884 ? mtext_nchars (MPLIST_MTEXT (group))
2885 : mplist_length (MPLIST_PLIST (group)));
2886 if (ingroup_index >= len)
2887 ingroup_index = len - 1;
2888 idx += ingroup_index;
2890 update_candidate (ic, prop, idx);
2892 else if (name == Mshow)
2893 ic->candidate_show = 1;
2894 else if (name == Mhide)
2895 ic->candidate_show = 0;
2896 else if (name == Mdelete)
2898 int len = mtext_nchars (ic->preedit);
2902 if (MPLIST_SYMBOL_P (args)
2903 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
2905 delete_surrounding_text (ic, pos);
2909 to = (MPLIST_SYMBOL_P (args)
2910 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2912 : MPLIST_INTEGER (args));
2917 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
2918 if (to < ic->cursor_pos)
2919 preedit_delete (ic, to, ic->cursor_pos);
2920 else if (to > ic->cursor_pos)
2921 preedit_delete (ic, ic->cursor_pos, to);
2924 else if (name == Mmove)
2926 int len = mtext_nchars (ic->preedit);
2928 = (MPLIST_SYMBOL_P (args)
2929 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2931 : MPLIST_INTEGER (args));
2937 if (pos != ic->cursor_pos)
2939 ic->cursor_pos = pos;
2940 ic->preedit_changed = 1;
2943 else if (name == Mmark)
2945 int code = marker_code (MPLIST_SYMBOL (args));
2948 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
2949 (void *) ic->cursor_pos);
2951 else if (name == Mpushback)
2953 if (MPLIST_INTEGER_P (args))
2955 int num = MPLIST_INTEGER (args);
2958 ic_info->key_head -= num;
2960 ic_info->key_head = num;
2961 if (ic_info->key_head > ic_info->used)
2962 ic_info->key_head = ic_info->used;
2964 else if (MPLIST_MTEXT_P (args))
2966 MText *mt = MPLIST_MTEXT (args);
2967 int i, len = mtext_nchars (mt);
2970 ic_info->key_head--;
2971 for (i = 0; i < len; i++)
2973 key = one_char_symbol[MTEXT_DATA (mt)[i]];
2974 if (ic_info->key_head + i < ic_info->used)
2975 ic_info->keys[ic_info->key_head + i] = key;
2977 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2982 MPlist *plist = MPLIST_PLIST (args), *pl;
2986 ic_info->key_head--;
2988 MPLIST_DO (pl, plist)
2990 key = MPLIST_SYMBOL (pl);
2991 if (ic_info->key_head < ic_info->used)
2992 ic_info->keys[ic_info->key_head + i] = key;
2994 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
2999 else if (name == Mcall)
3001 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3002 MIMExternalFunc func = NULL;
3003 MSymbol module, func_name;
3004 MPlist *func_args, *val;
3007 module = MPLIST_SYMBOL (args);
3008 args = MPLIST_NEXT (args);
3009 func_name = MPLIST_SYMBOL (args);
3011 if (im_info->externals)
3013 MIMExternalModule *external
3014 = (MIMExternalModule *) mplist_get (im_info->externals,
3017 func = (MIMExternalFunc) mplist_get (external->func_list,
3022 func_args = mplist ();
3023 mplist_add (func_args, Mt, ic);
3024 MPLIST_DO (args, MPLIST_NEXT (args))
3028 if (MPLIST_KEY (args) == Msymbol
3029 && MPLIST_KEY (args) != Mnil
3030 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
3032 code = new_index (ic, ic->cursor_pos,
3033 mtext_nchars (ic->preedit),
3034 MPLIST_SYMBOL (args), ic->preedit);
3035 mplist_add (func_args, Minteger, (void *) code);
3038 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3040 val = (func) (func_args);
3041 M17N_OBJECT_UNREF (func_args);
3042 if (val && ! MPLIST_TAIL_P (val))
3043 ret = take_action_list (ic, val);
3044 M17N_OBJECT_UNREF (val);
3048 else if (name == Mshift)
3050 shift_state (ic, MPLIST_SYMBOL (args));
3052 else if (name == Mundo)
3054 int intarg = (MPLIST_TAIL_P (args)
3056 : integer_value (ic, args, NULL, 0));
3058 mtext_reset (ic->preedit);
3059 mtext_reset (ic_info->preedit_saved);
3060 ic->cursor_pos = ic_info->state_pos = 0;
3061 ic_info->state_key_head = ic_info->key_head = 0;
3064 ic_info->used += intarg;
3066 ic_info->used = intarg;
3067 shift_state (ic, Mnil);
3070 else if (name == Mset || name == Madd || name == Msub
3071 || name == Mmul || name == Mdiv)
3073 MSymbol sym = MPLIST_SYMBOL (args);
3078 val1 = integer_value (ic, args, &value, 0);
3079 args = MPLIST_NEXT (args);
3080 val2 = resolve_expression (ic, args);
3082 val1 = val2, op = "=";
3083 else if (name == Madd)
3084 val1 += val2, op = "+=";
3085 else if (name == Msub)
3086 val1 -= val2, op = "-=";
3087 else if (name == Mmul)
3088 val1 *= val2, op = "*=";
3090 val1 /= val2, op = "/=";
3091 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3092 MSYMBOL_NAME (sym), op, val1, val1);
3094 mplist_set (value, Minteger, (void *) val1);
3096 else if (name == Mequal || name == Mless || name == Mgreater
3097 || name == Mless_equal || name == Mgreater_equal)
3100 MPlist *actions1, *actions2;
3103 val1 = resolve_expression (ic, args);
3104 args = MPLIST_NEXT (args);
3105 val2 = resolve_expression (ic, args);
3106 args = MPLIST_NEXT (args);
3107 actions1 = MPLIST_PLIST (args);
3108 args = MPLIST_NEXT (args);
3109 if (MPLIST_TAIL_P (args))
3112 actions2 = MPLIST_PLIST (args);
3113 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3114 if (name == Mequal ? val1 == val2
3115 : name == Mless ? val1 < val2
3116 : name == Mgreater ? val1 > val2
3117 : name == Mless_equal ? val1 <= val2
3120 MDEBUG_PRINT ("ok");
3121 ret = take_action_list (ic, actions1);
3125 MDEBUG_PRINT ("no");
3127 ret = take_action_list (ic, actions2);
3132 else if (name == Mcond)
3136 MPLIST_DO (args, args)
3141 if (! MPLIST_PLIST (args))
3143 cond = MPLIST_PLIST (args);
3144 if (resolve_expression (ic, cond) != 0)
3146 MDEBUG_PRINT1 ("(%dth)", idx);
3147 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3153 else if (name == Mcommit)
3155 preedit_commit (ic);
3157 else if (name == Munhandle)
3159 preedit_commit (ic);
3164 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3168 && (actions = mplist_get (im_info->macros, name)))
3170 if (take_action_list (ic, actions) < 0)
3176 M17N_OBJECT_UNREF (ic->candidate_list);
3177 if (ic->cursor_pos > 0
3178 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3181 ic->candidate_list = mtext_property_value (prop);
3182 M17N_OBJECT_REF (ic->candidate_list);
3184 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3186 ic->candidate_from = mtext_property_start (prop);
3187 ic->candidate_to = mtext_property_end (prop);
3190 if (candidate_list != ic->candidate_list)
3191 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3192 if (candidate_index != ic->candidate_index)
3193 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3194 if (candidate_show != ic->candidate_show)
3195 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3200 /* Handle the input key KEY in the current state and map specified in
3201 the input context IC. If KEY is handled correctly, return 0.
3202 Otherwise, return -1. */
3205 handle_key (MInputContext *ic)
3207 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3208 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3209 MIMMap *map = ic_info->map;
3210 MIMMap *submap = NULL;
3211 MSymbol key = ic_info->keys[ic_info->key_head];
3212 MSymbol alias = Mnil;
3215 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3216 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3220 submap = mplist_get (map->submaps, key);
3223 && (alias = msymbol_get (alias, M_key_alias))
3225 submap = mplist_get (map->submaps, alias);
3230 if (! alias || alias == key)
3231 MDEBUG_PRINT (" submap-found");
3233 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3234 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3235 ic->preedit_changed = 1;
3236 ic->cursor_pos = ic_info->state_pos;
3237 ic_info->key_head++;
3238 ic_info->map = map = submap;
3239 if (map->map_actions)
3241 MDEBUG_PRINT (" map-actions:");
3242 if (take_action_list (ic, map->map_actions) < 0)
3244 MDEBUG_PRINT ("\n");
3248 else if (map->submaps)
3250 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3252 MSymbol key = ic_info->keys[i];
3253 char *name = msymbol_name (key);
3255 if (! name[0] || ! name[1])
3256 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3260 /* If this is the terminal map or we have shifted to another
3261 state, perform branch actions (if any). */
3262 if (! map->submaps || map != ic_info->map)
3264 if (map->branch_actions)
3266 MDEBUG_PRINT (" branch-actions:");
3267 if (take_action_list (ic, map->branch_actions) < 0)
3269 MDEBUG_PRINT ("\n");
3273 /* If MAP is still not the root map, shift to the current
3275 if (ic_info->map != ic_info->state->map)
3276 shift_state (ic, ic_info->state->name);
3281 /* MAP can not handle KEY. */
3283 /* If MAP is the root map of the initial state, it means that
3284 the current input method can not handle KEY. */
3285 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3287 MDEBUG_PRINT (" unhandled\n");
3291 if (map != ic_info->state->map)
3293 /* If MAP is not the root map... */
3294 /* If MAP has branch actions, perform them. */
3295 if (map->branch_actions)
3297 MDEBUG_PRINT (" branch-actions:");
3298 if (take_action_list (ic, map->branch_actions) < 0)
3300 MDEBUG_PRINT ("\n");
3304 /* If MAP is still not the root map, shift to the current
3306 if (ic_info->map != ic_info->state->map)
3307 shift_state (ic, ic_info->state->name);
3311 /* MAP is the root map, perform branch actions (if any) or
3312 shift to the initial state. */
3313 if (map->branch_actions)
3315 MDEBUG_PRINT (" branch-actions:");
3316 if (take_action_list (ic, map->branch_actions) < 0)
3318 MDEBUG_PRINT ("\n");
3323 shift_state (ic, Mnil);
3326 MDEBUG_PRINT ("\n");
3330 /* Initialize IC->ic_info. */
3333 init_ic_info (MInputContext *ic)
3335 MInputMethodInfo *im_info = ic->im->info;
3336 MInputContextInfo *ic_info = ic->info;
3339 MLIST_INIT1 (ic_info, keys, 8);;
3341 ic_info->markers = mplist ();
3343 ic_info->vars = mplist ();
3344 if (im_info->configured_vars)
3345 MPLIST_DO (plist, im_info->configured_vars)
3347 MPlist *pl = MPLIST_PLIST (plist);
3348 MSymbol name = MPLIST_SYMBOL (pl);
3350 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
3351 if (MPLIST_KEY (pl) != Mt)
3353 MPlist *p = mplist ();
3355 mplist_push (ic_info->vars, Mplist, p);
3356 M17N_OBJECT_UNREF (p);
3357 mplist_add (p, Msymbol, name);
3358 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3362 if (im_info->externals)
3364 MPlist *func_args = mplist (), *plist;
3366 mplist_add (func_args, Mt, ic);
3367 MPLIST_DO (plist, im_info->externals)
3369 MIMExternalModule *external = MPLIST_VAL (plist);
3370 MIMExternalFunc func
3371 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3376 M17N_OBJECT_UNREF (func_args);
3379 ic_info->preedit_saved = mtext ();
3380 ic_info->tick = im_info->tick;
3383 /* Finalize IC->ic_info. */
3386 fini_ic_info (MInputContext *ic)
3388 MInputMethodInfo *im_info = ic->im->info;
3389 MInputContextInfo *ic_info = ic->info;
3391 if (im_info->externals)
3393 MPlist *func_args = mplist (), *plist;
3395 mplist_add (func_args, Mt, ic);
3396 MPLIST_DO (plist, im_info->externals)
3398 MIMExternalModule *external = MPLIST_VAL (plist);
3399 MIMExternalFunc func
3400 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3405 M17N_OBJECT_UNREF (func_args);
3408 MLIST_FREE1 (ic_info, keys);
3409 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3410 M17N_OBJECT_UNREF (ic_info->markers);
3411 M17N_OBJECT_UNREF (ic_info->vars);
3412 M17N_OBJECT_UNREF (ic_info->preceding_text);
3413 M17N_OBJECT_UNREF (ic_info->following_text);
3415 memset (ic_info, 0, sizeof (MInputContextInfo));
3419 re_init_ic (MInputContext *ic, int reload)
3421 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3422 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3423 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3425 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3426 preedit_changed = mtext_nchars (ic->preedit) > 0;
3427 cursor_pos_changed = ic->cursor_pos > 0;
3428 candidates_changed = 0;
3429 if (ic->candidate_list)
3431 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3432 M17N_OBJECT_UNREF (ic->candidate_list);
3434 if (ic->candidate_show)
3436 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3437 ic->candidate_show = 0;
3439 if (ic->candidate_index > 0)
3441 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3442 ic->candidate_index = 0;
3443 ic->candidate_from = ic->candidate_to = 0;
3445 if (mtext_nchars (ic->produced) > 0)
3446 mtext_reset (ic->produced);
3447 if (mtext_nchars (ic->preedit) > 0)
3448 mtext_reset (ic->preedit);
3450 M17N_OBJECT_UNREF (ic->plist);
3451 ic->plist = mplist ();
3455 reload_im_info (im_info);
3457 shift_state (ic, Mnil);
3458 ic->status_changed = status_changed;
3459 ic->preedit_changed = preedit_changed;
3460 ic->cursor_pos_changed = cursor_pos_changed;
3461 ic->candidates_changed = candidates_changed;
3465 reset_ic (MInputContext *ic, MSymbol ignore)
3467 MDEBUG_PRINT ("\n [IM] reset\n");
3472 open_im (MInputMethod *im)
3474 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3477 MERROR (MERROR_IM, -1);
3484 close_im (MInputMethod *im)
3490 create_ic (MInputContext *ic)
3492 MInputContextInfo *ic_info;
3494 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3497 shift_state (ic, Mnil);
3502 destroy_ic (MInputContext *ic)
3509 check_reload (MInputContext *ic, MSymbol key)
3511 MInputMethodInfo *im_info = ic->im->info;
3512 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3516 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3520 MPLIST_DO (plist, plist)
3522 MSymbol this_key, alias;
3524 if (MPLIST_MTEXT_P (plist))
3526 MText *mt = MPLIST_MTEXT (plist);
3527 int c = mtext_ref_char (mt, 0);
3531 this_key = one_char_symbol[c];
3535 MPlist *pl = MPLIST_PLIST (plist);
3537 this_key = MPLIST_SYMBOL (pl);
3541 && (alias = msymbol_get (alias, M_key_alias))
3542 && alias != this_key);
3546 if (MPLIST_TAIL_P (plist))
3549 MDEBUG_PRINT ("\n [IM] reload");
3555 /** Handle the input key KEY in the current state and map of IC->info.
3556 If KEY is handled but no text is produced, return 0, otherwise
3562 filter (MInputContext *ic, MSymbol key, void *arg)
3564 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3565 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3568 if (check_reload (ic, key))
3571 if (! ic_info->state)
3573 ic_info->key_unhandled = 1;
3576 mtext_reset (ic->produced);
3577 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3578 M17N_OBJECT_UNREF (ic_info->preceding_text);
3579 M17N_OBJECT_UNREF (ic_info->following_text);
3580 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3581 ic_info->key_unhandled = 0;
3584 if (handle_key (ic) < 0)
3586 /* KEY was not handled. Delete it from the current key sequence. */
3587 if (ic_info->used > 0)
3589 memmove (ic_info->keys, ic_info->keys + 1,
3590 sizeof (int) * (ic_info->used - 1));
3593 /* This forces returning 1. */
3594 ic_info->key_unhandled = 1;
3600 reset_ic (ic, Mnil);
3601 ic_info->key_unhandled = 1;
3604 /* Break the loop if all keys were handled. */
3605 } while (ic_info->key_head < ic_info->used);
3607 /* If the current map is the root of the initial state, we should
3608 produce any preedit text in ic->produced. */
3609 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3610 && mtext_nchars (ic->preedit) > 0)
3611 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
3613 if (mtext_nchars (ic->produced) > 0)
3615 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3618 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3619 Mlanguage, ic->im->language);
3622 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3626 /** Return 1 if the last event or key was not handled, otherwise
3629 There is no need of looking up because ic->produced should already
3630 contain the produced text (if any).
3635 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3637 mtext_cat (mt, ic->produced);
3638 mtext_reset (ic->produced);
3639 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3643 /* Input method command handler. */
3645 /* List of all (global and local) commands.
3646 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3647 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3648 Global commands are stored as (t (t COMMAND ...)) */
3651 /* Input method variable handler. */
3654 /* Support functions for mdebug_dump_im. */
3657 dump_im_map (MPlist *map_list, int indent)
3660 MSymbol key = MPLIST_KEY (map_list);
3661 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3663 prefix = (char *) alloca (indent + 1);
3664 memset (prefix, 32, indent);
3665 prefix[indent] = '\0';
3667 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3668 if (map->map_actions)
3669 mdebug_dump_plist (map->map_actions, indent + 2);
3672 MPLIST_DO (map_list, map->submaps)
3674 fprintf (stderr, "\n%s ", prefix);
3675 dump_im_map (map_list, indent + 2);
3678 if (map->branch_actions)
3680 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3681 mdebug_dump_plist (map->branch_actions, indent + 4);
3682 fprintf (stderr, ")");
3684 fprintf (stderr, ")");
3689 dump_im_state (MIMState *state, int indent)
3694 prefix = (char *) alloca (indent + 1);
3695 memset (prefix, 32, indent);
3696 prefix[indent] = '\0';
3698 fprintf (stderr, "(%s", msymbol_name (state->name));
3699 if (state->map->submaps)
3701 MPLIST_DO (map_list, state->map->submaps)
3703 fprintf (stderr, "\n%s ", prefix);
3704 dump_im_map (map_list, indent + 2);
3707 fprintf (stderr, ")");
3715 Minput_driver = msymbol ("input-driver");
3717 Minput_preedit_start = msymbol ("input-preedit-start");
3718 Minput_preedit_done = msymbol ("input-preedit-done");
3719 Minput_preedit_draw = msymbol ("input-preedit-draw");
3720 Minput_status_start = msymbol ("input-status-start");
3721 Minput_status_done = msymbol ("input-status-done");
3722 Minput_status_draw = msymbol ("input-status-draw");
3723 Minput_candidates_start = msymbol ("input-candidates-start");
3724 Minput_candidates_done = msymbol ("input-candidates-done");
3725 Minput_candidates_draw = msymbol ("input-candidates-draw");
3726 Minput_set_spot = msymbol ("input-set-spot");
3727 Minput_focus_move = msymbol ("input-focus-move");
3728 Minput_focus_in = msymbol ("input-focus-in");
3729 Minput_focus_out = msymbol ("input-focus-out");
3730 Minput_toggle = msymbol ("input-toggle");
3731 Minput_reset = msymbol ("input-reset");
3732 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3733 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3734 Mcustomized = msymbol ("customized");
3735 Mconfigured = msymbol ("configured");
3736 Minherited = msymbol ("inherited");
3738 minput_default_driver.open_im = open_im;
3739 minput_default_driver.close_im = close_im;
3740 minput_default_driver.create_ic = create_ic;
3741 minput_default_driver.destroy_ic = destroy_ic;
3742 minput_default_driver.filter = filter;
3743 minput_default_driver.lookup = lookup;
3744 minput_default_driver.callback_list = mplist ();
3745 mplist_put (minput_default_driver.callback_list, Minput_reset,
3747 minput_driver = &minput_default_driver;
3749 fully_initialized = 0;
3756 if (fully_initialized)
3758 free_im_list (im_info_list);
3760 free_im_list (im_custom_list);
3762 free_im_list (im_config_list);
3763 M17N_OBJECT_UNREF (load_im_info_keys);
3766 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3767 M17N_OBJECT_UNREF (minput_driver->callback_list);
3772 minput__callback (MInputContext *ic, MSymbol command)
3774 MInputCallbackFunc func;
3776 if (! ic->im->driver.callback_list)
3778 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3782 (func) (ic, command);
3787 minput__char_to_key (int c)
3789 if (c < 0 || c >= 0x100)
3792 return one_char_symbol[c];
3796 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3801 /*** @addtogroup m17nInputMethod */
3806 @name Variables: Predefined symbols for callback commands.
3808 These are the predefined symbols that are used as the @c COMMAND
3809 argument of callback functions of an input method driver (see
3810 #MInputDriver::callback_list).
3812 Most of them do not require extra argument nor return any value;
3813 exceptions are these:
3815 Minput_get_surrounding_text: When a callback function assigned for
3816 this command is called, the first element of #MInputContext::plist
3817 has key #Minteger and the value specifies which portion of the
3818 surrounding text should be retrieved. If the value is positive,
3819 it specifies the number of characters following the current cursor
3820 position. If the value is negative, the absolute value specifies
3821 the number of characters preceding the current cursor position.
3823 If the surrounding text is currently supported, the callback
3824 function must set the key of this element to #Mtext and the value
3825 to the retrieved M-text. The length of the M-text may be shorter
3826 than the requested number of characters, if the available text is
3827 not that long. The length can be zero in the worst case. Or, the
3828 length may be longer if an application thinks it's more efficient
3829 to return that length).
3831 If the surrounding text is not currently supported, the callback
3832 function should return without changing the first element of
3833 #MInputContext::plist.
3835 Minput_delete_surrounding_text: When a callback function assigned
3836 for this command is called, the first element of
3837 #MInputContext::plist has key #Minteger and the value specifies
3838 which portion of the surrounding text should be deleted in the
3839 same way as the case of Minput_get_surrounding_text. The callback
3840 function must delete the specified text. It should not alter
3841 #MInputContext::plist. */
3844 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3846 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3847 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3852 MSymbol Minput_preedit_start;
3853 MSymbol Minput_preedit_done;
3854 MSymbol Minput_preedit_draw;
3855 MSymbol Minput_status_start;
3856 MSymbol Minput_status_done;
3857 MSymbol Minput_status_draw;
3858 MSymbol Minput_candidates_start;
3859 MSymbol Minput_candidates_done;
3860 MSymbol Minput_candidates_draw;
3861 MSymbol Minput_set_spot;
3862 MSymbol Minput_toggle;
3863 MSymbol Minput_reset;
3864 MSymbol Minput_get_surrounding_text;
3865 MSymbol Minput_delete_surrounding_text;
3871 @name Variables: Predefined symbols for special input events.
3873 These are the predefined symbols that are used as the @c KEY
3874 argument of minput_filter (). */
3879 MSymbol Minput_focus_out;
3880 MSymbol Minput_focus_in;
3881 MSymbol Minput_focus_move;
3887 @name Variables: Predefined symbols used in input method information.
3889 These are the predefined symbols describing status of input method
3890 command and variable, and are used in a return value of
3891 minput_get_command () and minput_get_variable (). */
3895 MSymbol Mcustomized;
3896 MSymbol Mconfigured;
3902 @brief The default driver for internal input methods.
3904 The variable #minput_default_driver is the default driver for
3905 internal input methods.
3907 The member MInputDriver::open_im () searches the m17n database for
3908 an input method that matches the tag \< #Minput_method, $LANGUAGE,
3909 $NAME\> and loads it.
3911 The member MInputDriver::callback_list () is @c NULL. Thus, it is
3912 programmers responsibility to set it to a plist of proper callback
3913 functions. Otherwise, no feedback information (e.g. preedit text)
3914 can be shown to users.
3916 The macro M17N_INIT () sets the variable #minput_driver to the
3917 pointer to this driver so that all internal input methods use it.
3919 Therefore, unless @c minput_driver is set differently, the driver
3920 dependent arguments $ARG of the functions whose name begins with
3921 "minput_" are all ignored. */
3924 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
3926 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
3928 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
3929 \< #Minput_method, $LANGUAGE, $NAME\>
3930 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
3932 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
3933 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
3934 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
3935 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
3937 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
3938 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
3940 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
3941 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
3943 MInputDriver minput_default_driver;
3947 @brief The driver for internal input methods.
3949 The variable #minput_driver is a pointer to the input method
3950 driver that is used by internal input methods. The macro
3951 M17N_INIT () initializes it to a pointer to #minput_default_driver
3952 if <m17n<EM></EM>.h> is included. */
3954 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
3956 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
3957 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
3958 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
3959 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
3961 MInputDriver *minput_driver;
3963 MSymbol Minput_driver;
3968 @brief Open an input method.
3970 The minput_open_im () function opens an input method whose
3971 language and name match $LANGUAGE and $NAME, and returns a pointer
3972 to the input method object newly allocated.
3974 This function at first decides a driver for the input method as
3977 If $LANGUAGE is not #Mnil, the driver pointed by the variable
3978 #minput_driver is used.
3980 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
3981 driver pointed to by the property value is used to open the input
3982 method. If $NAME has no such a property, @c NULL is returned.
3984 Then, the member MInputDriver::open_im () of the driver is
3987 $ARG is set in the member @c arg of the structure MInputMethod so
3988 that the driver can refer to it. */
3991 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
3993 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
3994 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
3996 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
3998 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
3999 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4001 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4002 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4003 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4005 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4007 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4009 @latexonly \IPAlabel{minput_open} @endlatexonly
4014 minput_open_im (MSymbol language, MSymbol name, void *arg)
4017 MInputDriver *driver;
4021 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4022 msymbol_name (language), msymbol_name (name));
4024 driver = minput_driver;
4027 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4029 MERROR (MERROR_IM, NULL);
4032 MSTRUCT_CALLOC (im, MERROR_IM);
4033 im->language = language;
4036 im->driver = *driver;
4037 if ((*im->driver.open_im) (im) < 0)
4039 MDEBUG_PRINT (" failed\n");
4043 MDEBUG_PRINT (" ok\n");
4050 @brief Close an input method.
4052 The minput_close_im () function closes the input method $IM, which
4053 must have been created by minput_open_im (). */
4056 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4058 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4059 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4062 minput_close_im (MInputMethod *im)
4064 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4065 msymbol_name (im->name), msymbol_name (im->language));
4066 (*im->driver.close_im) (im);
4068 MDEBUG_PRINT (" done\n");
4074 @brief Create an input context.
4076 The minput_create_ic () function creates an input context object
4077 associated with input method $IM, and calls callback functions
4078 corresponding to #Minput_preedit_start, #Minput_status_start, and
4079 #Minput_status_draw in this order.
4082 If an input context is successfully created, minput_create_ic ()
4083 returns a pointer to it. Otherwise it returns @c NULL. */
4086 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4088 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4089 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4090 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4091 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4094 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4095 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4099 minput_create_ic (MInputMethod *im, void *arg)
4103 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4104 msymbol_name (im->name), msymbol_name (im->language));
4105 MSTRUCT_CALLOC (ic, MERROR_IM);
4108 ic->preedit = mtext ();
4109 ic->candidate_list = NULL;
4110 ic->produced = mtext ();
4111 ic->spot.x = ic->spot.y = 0;
4113 ic->plist = mplist ();
4114 if ((*im->driver.create_ic) (ic) < 0)
4116 MDEBUG_PRINT (" failed\n");
4117 M17N_OBJECT_UNREF (ic->preedit);
4118 M17N_OBJECT_UNREF (ic->produced);
4119 M17N_OBJECT_UNREF (ic->plist);
4124 if (im->driver.callback_list)
4126 minput__callback (ic, Minput_preedit_start);
4127 minput__callback (ic, Minput_status_start);
4128 minput__callback (ic, Minput_status_draw);
4131 MDEBUG_PRINT (" ok\n");
4138 @brief Destroy an input context.
4140 The minput_destroy_ic () function destroys the input context $IC,
4141 which must have been created by minput_create_ic (). It calls
4142 callback functions corresponding to #Minput_preedit_done,
4143 #Minput_status_done, and #Minput_candidates_done in this order. */
4146 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4148 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4149 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4150 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4151 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4152 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4156 minput_destroy_ic (MInputContext *ic)
4158 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4159 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4160 if (ic->im->driver.callback_list)
4162 minput__callback (ic, Minput_preedit_done);
4163 minput__callback (ic, Minput_status_done);
4164 minput__callback (ic, Minput_candidates_done);
4166 (*ic->im->driver.destroy_ic) (ic);
4167 M17N_OBJECT_UNREF (ic->preedit);
4168 M17N_OBJECT_UNREF (ic->produced);
4169 M17N_OBJECT_UNREF (ic->plist);
4170 MDEBUG_PRINT (" done\n");
4177 @brief Filter an input key.
4179 The minput_filter () function filters input key $KEY according to
4180 input context $IC, and calls callback functions corresponding to
4181 #Minput_preedit_draw, #Minput_status_draw, and
4182 #Minput_candidates_draw if the preedit text, the status, and the
4183 current candidate are changed respectively.
4185 To make the input method commit the current preedit text (if any)
4186 and shift to the initial state, call this function with #Mnil as
4189 To inform the input method about the focus-out event, call this
4190 function with #Minput_focus_out as $KEY.
4192 To inform the input method about the focus-in event, call this
4193 function with #Minput_focus_in as $KEY.
4195 To inform the input method about the focus-move event (i.e. input
4196 spot change within the same input context), call this function
4197 with #Minput_focus_move as $KEY.
4200 If $KEY is filtered out, this function returns 1. In that case,
4201 the caller should discard the key. Otherwise, it returns 0, and
4202 the caller should handle the key, for instance, by calling the
4203 function minput_lookup () with the same key. */
4206 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4208 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4209 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4210 #Minput_preedit_draw, #Minput_status_draw,
4211 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4214 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4215 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4216 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4217 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4219 @latexonly \IPAlabel{minput_filter} @endlatexonly
4223 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4230 ret = (*ic->im->driver.filter) (ic, key, arg);
4232 if (ic->im->driver.callback_list)
4234 if (ic->preedit_changed)
4235 minput__callback (ic, Minput_preedit_draw);
4236 if (ic->status_changed)
4237 minput__callback (ic, Minput_status_draw);
4238 if (ic->candidates_changed)
4239 minput__callback (ic, Minput_candidates_draw);
4248 @brief Look up a text produced in the input context.
4250 The minput_lookup () function looks up a text in the input context
4251 $IC. $KEY must be identical to the one that was used in the previous call of
4254 If a text was produced by the input method, it is concatenated
4257 This function calls #MInputDriver::lookup .
4260 If $KEY was correctly handled by the input method, this function
4261 returns 0. Otherwise, it returns -1, even though some text
4262 might be produced in $MT. */
4265 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4267 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4268 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4270 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4273 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4276 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4277 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4278 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4280 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4283 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4285 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4290 @brief Set the spot of the input context.
4292 The minput_set_spot () function sets the spot of input context $IC
4293 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4294 The semantics of these values depends on the input method driver.
4296 For instance, a driver designed to work in a CUI environment may
4297 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4298 $DESCENT . A driver designed to work in a window system may
4299 interpret $X and $Y as the pixel offsets relative to the origin of the
4300 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4301 descent pixels of the line at ($X . $Y ).
4303 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4305 $MT and $POS are the M-text and the character position at the spot.
4306 $MT may be @c NULL, in which case, the input method cannot get
4307 information about the text around the spot. */
4310 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4312 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4313 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4314 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4316 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4317 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4318 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4319 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4320 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4321 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4323 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4325 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4326 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4330 minput_set_spot (MInputContext *ic, int x, int y,
4331 int ascent, int descent, int fontsize,
4336 ic->spot.ascent = ascent;
4337 ic->spot.descent = descent;
4338 ic->spot.fontsize = fontsize;
4341 if (ic->im->driver.callback_list)
4342 minput__callback (ic, Minput_set_spot);
4347 @brief Toggle input method.
4349 The minput_toggle () function toggles the input method associated
4350 with input context $IC. */
4352 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4354 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4355 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4359 minput_toggle (MInputContext *ic)
4361 if (ic->im->driver.callback_list)
4362 minput__callback (ic, Minput_toggle);
4363 ic->active = ! ic->active;
4369 @brief Reset an input context.
4371 The minput_reset_ic () function resets input context $IC by
4372 calling a callback function corresponding to #Minput_reset. It
4373 resets the status of $IC to its initial one. As the
4374 current preedit text is deleted without commitment, if necessary,
4375 call minput_filter () with the arg @r key #Mnil to force the input
4376 method to commit the preedit in advance. */
4379 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4381 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4382 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4383 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4384 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4385 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4386 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4389 minput_reset_ic (MInputContext *ic)
4391 if (ic->im->driver.callback_list)
4392 minput__callback (ic, Minput_reset);
4398 @brief Get title and icon filename of an input method.
4400 The minput_get_title_icon () function returns a plist containing a
4401 title and icon filename (if any) of an input method specified by
4402 $LANGUAGE and $NAME.
4404 The first element of the plist has key #Mtext and the value is an
4405 M-text of the title for identifying the input method. The second
4406 element (if any) has key #Mtext and the value is an M-text of the
4407 icon image (absolute) filename for the same purpose.
4410 If there exists a specified input method and it defines an title,
4411 a plist is returned. Otherwise, NULL is returned. The caller
4412 must free the plist by m17n_object_unref (). */
4415 minput_get_title_icon (MSymbol language, MSymbol name)
4417 MInputMethodInfo *im_info;
4424 im_info = get_im_info (language, name, Mnil, Mtitle);
4425 if (! im_info || !im_info->title)
4427 mt = mtext_get_prop (im_info->title, 0, Mtext);
4429 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4432 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4435 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4436 (char *) MSYMBOL_NAME (name));
4437 file = mdatabase__find_file (buf);
4438 if (! file && language == Mt)
4440 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4441 file = mdatabase__find_file (buf);
4446 mplist_add (plist, Mtext, im_info->title);
4449 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4451 mplist_add (plist, Mtext, mt);
4452 M17N_OBJECT_UNREF (mt);
4460 @brief Get description text of an input method.
4462 The minput_get_description () function returns an M-text that
4463 describes the input method specified by $LANGUAGE and $NAME.
4466 If the specified input method has a description text, a pointer to
4467 #MText is returned. The caller has to free it by m17n_object_unref ().
4468 If the input method does not have a description text, @c NULL is
4471 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4473 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4474 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4476 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4477 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4478 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4479 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4482 minput_get_description (MSymbol language, MSymbol name)
4484 MInputMethodInfo *im_info;
4488 im_info = get_im_info (language, name, Mnil, Mdescription);
4489 if (! im_info || ! im_info->description)
4491 M17N_OBJECT_REF (im_info->description);
4492 return im_info->description;
4498 @brief Get information about input method command(s).
4500 The minput_get_command () function returns information about
4501 the command $COMMAND of the input method specified by $LANGUAGE and
4502 $NAME. An input method command is a pseudo key event to which one
4503 or more actual input key sequences are assigned.
4505 There are two kinds of commands, global and local. A global
4506 command has a global definition, and the description and the key
4507 assignment may be inherited by a local command. Each input method
4508 defines a local command which has a local key assignment. It may
4509 also declare a local command that inherits the definition of a
4510 global command of the same name.
4512 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4513 information about a global command. Otherwise information about a
4514 local command is returned.
4516 If $COMMAND is #Mnil, information about all commands is returned.
4518 The return value is a @e well-formed plist (#m17nPlist) of this
4521 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4523 @c NAME is a symbol representing the command name.
4525 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4526 command has no description.
4528 @c STATUS is a symbol representing how the key assignment is decided.
4529 The value is #Mnil (the default key assignment), #Mcustomized (the
4530 key assignment is customized by per-user configuration file), or
4531 #Mconfigured (the key assignment is set by the call of
4532 minput_config_command ()). For a local command only, it may also
4533 be #Minherited (the key assignment is inherited from the
4534 corresponding global command).
4536 @c KEYSEQ is a plist of one or more symbols representing a key
4537 sequence assigned to the command. If there's no KEYSEQ, the
4538 command is currently disabled (i.e. no key sequence can trigger
4539 actions of the command).
4541 If $COMMAND is not #Mnil, the first element of the returned plist
4542 contains the information about $COMMAND.
4546 If the requested information was found, a pointer to a non-empty
4547 plist is returned. As the plist is kept in the library, the
4548 caller must not modify nor free it.
4550 Otherwise (the specified input method or the specified command
4551 does not exist), @c NULL is returned. */
4553 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4555 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4556 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4557 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4558 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4560 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4561 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4562 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4563 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4564 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4566 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4567 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4570 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4572 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4575 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4577 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4579 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4582 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4583 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4584 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4585 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4586 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4587 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4589 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4590 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4591 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4592 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4594 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4595 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4599 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4600 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4603 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4608 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4610 /* Return a description of the command COMMAND of the input method */
4611 /* specified by LANGUAGE and NAME. */
4612 MPlist *cmd = minput_get_command (langauge, name, command);
4617 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4618 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4619 return (mplist_key (plist) == Mtext
4620 ? (MText *) mplist_value (plist)
4626 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4628 MInputMethodInfo *im_info;
4632 im_info = get_im_info (language, name, Mnil, Mcommand);
4634 || ! im_info->configured_cmds
4635 || MPLIST_TAIL_P (im_info->configured_cmds))
4637 if (command == Mnil)
4638 return im_info->configured_cmds;
4639 return mplist__assq (im_info->configured_cmds, command);
4645 @brief Configure the key sequence of an input method command.
4647 The minput_config_command () function assigns a list of key
4648 sequences $KEYSEQLIST to the command $COMMAND of the input method
4649 specified by $LANGUAGE and $NAME.
4651 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4652 sequences, and each key sequence must be a plist of symbols.
4654 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4656 If $KEYSEQLIST is NULL, the configuration of the command for the
4657 input method is canceled, and the default key sequences become
4658 effective. In such case, if $COMMAND is #Mnil, configurations for
4659 all commands of the input method are canceled.
4661 If $NAME is #Mnil, this function configures the key assignment of a
4662 global command, not that of a specific input method.
4664 The configuration takes effect for input methods opened or
4665 re-opened later in the current session. In order to make the
4666 configuration take effect for the future session, it must be saved
4667 in a per-user configuration file by the function
4668 minput_save_config ().
4672 If the operation was successful, this function returns 0,
4673 otherwise returns -1. The operation fails in these cases:
4675 <li>$KEYSEQLIST is not in a valid form.
4676 <li>$COMMAND is not available for the input method.
4677 <li>$LANGUAGE and $NAME do not specify an existing input method.
4681 minput_get_commands (), minput_save_config ().
4684 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4686 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4687 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4688 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4690 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4691 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4693 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4695 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4696 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4697 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4700 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4701 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4703 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4704 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4705 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4706 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4710 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4712 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4713 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4714 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4718 minput_get_commands (), minput_save_config ().
4722 /* Add "C-x u" to the "start" command of Unicode input method. */
4724 MSymbol start_command = msymbol ("start");
4725 MSymbol unicode = msymbol ("unicode");
4726 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4728 /* At first get the current key-sequence assignment. */
4729 cmd = mplist_get_command (Mt, unicode, start_command);
4732 /* The input method does not have the command "start". Here */
4733 /* should come some error handling code. */
4735 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract */
4736 /* the part (KEY-SEQUENCE ...). */
4737 plist = mplist_next (mplist_next (mplist_value (cmd)));
4738 /* Copy it because we should not modify it directly. */
4739 key_seq_list = mplist_copy (plist);
4740 m17n_object_unref (cmds);
4742 key_seq = mplist ();
4743 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4744 mplist_add (key_seq, Msymbo, msymbol ("u"));
4745 mplist_add (key_seq_list, Mplist, key_seq);
4746 m17n_object_unref (key_seq);
4748 minput_config_command (Mt, unicode, start_command, key_seq_list);
4749 m17n_object_unref (key_seq_list);
4754 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4757 MInputMethodInfo *im_info, *config;
4764 if (command == Mnil)
4765 MERROR (MERROR_IM, -1);
4766 MPLIST_DO (plist, keyseqlist)
4767 if (! MPLIST_PLIST_P (plist)
4768 || ! check_command_keyseq (plist))
4769 MERROR (MERROR_IM, -1);
4772 im_info = get_im_info (language, name, Mnil, Mcommand);
4774 MERROR (MERROR_IM, -1);
4777 || ! mplist__assq (im_info->cmds, command)))
4778 MERROR (MERROR_IM, -1);
4780 config = get_config_info (im_info);
4783 if (! im_config_list)
4784 im_config_list = mplist ();
4785 config = new_im_info (NULL, language, name, Mnil, im_config_list);
4786 config->cmds = mplist ();
4787 config->vars = mplist ();
4790 if (command == Mnil)
4792 MInputMethodInfo *custom = get_custom_info (im_info);
4794 mplist_set (config->cmds, Mnil, NULL);
4795 if (custom && custom->cmds)
4797 MPLIST_DO (plist, custom->cmds)
4799 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
4801 mplist_add (plist, Msymbol, command);
4802 mplist_push (config->cmds, Mplist, plist);
4803 M17N_OBJECT_UNREF (plist);
4809 plist = mplist__assq (config->cmds, command);
4812 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
4813 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
4814 if (! MPLIST_TAIL_P (plist))
4815 mplist_set (plist, Mnil, NULL); /* () */
4820 mplist_add (config->cmds, Mplist, plist);
4821 M17N_OBJECT_UNREF (plist);
4822 plist = mplist_add (plist, Msymbol, command);
4823 plist = MPLIST_NEXT (plist);
4829 plist = mplist_add (plist, Msymbol, Mnil);
4830 MPLIST_DO (keyseqlist, keyseqlist)
4832 pl = mplist_copy (MPLIST_VAL (keyseqlist));
4833 plist = mplist_add (plist, Mplist, pl);
4834 M17N_OBJECT_UNREF (pl);
4838 config_all_commands (im_info);
4839 im_info->tick = time (NULL);
4846 @brief Get information about input method variable(s).
4848 The minput_get_variable () function returns information about
4849 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
4850 An input method variable controls behavior of an input method.
4852 There are two kinds of variables, global and local. A global
4853 variable has a global definition, and the description and the value
4854 may be inherited by a local variable. Each input method defines a
4855 local variable which has local value. It may also declare a
4856 local variable that inherits definition of a global variable of
4859 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
4860 variable is returned. Otherwise information about a local variable
4863 If $VARIABLE is #Mnil, information about all variables is
4866 The return value is a @e well-formed plist (#m17nPlist) of this
4869 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
4871 @c NAME is a symbol representing the variable name.
4873 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
4874 variable has no description.
4876 @c STATUS is a symbol representing how the value is decided. The
4877 value is #Mnil (the default value), #Mcustomized (the value is
4878 customized by per-user configuration file), or #Mconfigured (the
4879 value is set by the call of minput_config_variable ()). For a
4880 local variable only, it may also be #Minherited (the value is
4881 inherited from the corresponding global variable).
4883 @c VALUE is the initial value of the variable. If the key of this
4884 element is #Mt, the variable has no initial value. Otherwise, the
4885 key is #Minteger, #Msymbol, or #Mtext and the value is of the
4888 @c VALID-VALUEs (if any) specify which values the variable can have.
4889 They have the same type (i.e. having the same key) as @c VALUE except
4890 for the case that VALUE is an integer. In that case, @c VALID-VALUE
4891 may be a plist of two integers specifying the range of possible
4894 If there no @c VALID-VALUE, the variable can have any value as long
4895 as the type is the same as @c VALUE.
4897 If $VARIABLE is not #Mnil, the first element of the returned plist
4898 contains the information about $VARIABLE.
4902 If the requested information was found, a pointer to a non-empty
4903 plist is returned. As the plist is kept in the library, the
4904 caller must not modify nor free it.
4906 Otherwise (the specified input method or the specified variable
4907 does not exist), @c NULL is returned. */
4909 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4911 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4912 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
4913 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
4915 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
4916 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
4917 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
4918 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
4921 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
4922 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
4924 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4926 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4928 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
4931 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4933 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
4936 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
4937 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
4938 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
4939 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
4940 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
4941 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
4943 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
4944 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
4945 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
4947 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
4948 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
4949 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
4950 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
4952 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
4955 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
4956 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4960 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4961 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4964 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4968 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
4970 MInputMethodInfo *im_info;
4974 im_info = get_im_info (language, name, Mnil, Mvariable);
4975 if (! im_info || ! im_info->configured_vars)
4977 if (variable == Mnil)
4978 return im_info->configured_vars;
4979 return mplist__assq (im_info->configured_vars, variable);
4985 @brief Configure the value of an input method variable.
4987 The minput_config_variable () function assigns $VALUE to the
4988 variable $VARIABLE of the input method specified by $LANGUAGE and
4991 If $VALUE is not NULL, it must be a plist of one element whose key
4992 is #Minteger, #Msymbol, or #Mtext, and the value is of the
4995 If $VALUE is NULL, a configuration for the variable for the input
4996 method is canceled, and the variable is initialized to the default
4997 value. In that case, if $VARIABLE is #Mnil, configurations for
4998 all variables of the input method are canceled.
5000 If $NAME is #Mnil, this function configure the value of global
5001 variable, not that of a specific input method.
5003 The configuration takes effect for input methods opened or
5004 re-opened later in the current session. To make the configuration
5005 take effect for the future session, it must be saved in a per-user
5006 configuration file by the function minput_save_config ().
5010 If the operation was successful, this function returns 0,
5011 otherwise returns -1. The operation fails in these cases:
5013 <li>$VALUE is not in a valid form, the type does not match the
5014 definition, or the value is our of range.
5015 <li>$VARIABLE is not available for the input method.
5016 <li>$LANGUAGE and $NAME do not specify an existing input method.
5020 minput_get_variable (), minput_save_config (). */
5022 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5024 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5025 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5027 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5028 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5030 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5031 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5032 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5034 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5035 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5037 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5038 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5039 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5040 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5044 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5046 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5047 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5048 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5052 minput_get_commands (), minput_save_config ().
5055 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5058 MInputMethodInfo *im_info, *config;
5063 im_info = get_im_info (language, name, Mnil, Mvariable);
5065 MERROR (MERROR_IM, -1);
5066 if (variable == Mnil)
5069 MERROR (MERROR_IM, -1);
5071 else if (! im_info->vars
5072 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5073 MERROR (MERROR_IM, -1);
5075 if (variable != Mnil && value)
5077 plist = MPLIST_PLIST (plist);
5078 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5079 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5080 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5081 if (MPLIST_KEY (plist) != Mt
5082 && ! check_variable_value (value, plist))
5083 MERROR (MERROR_IM, -1);
5086 config = get_config_info (im_info);
5089 if (! im_config_list)
5090 im_config_list = mplist ();
5091 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5092 config->cmds = mplist ();
5093 config->vars = mplist ();
5096 if (variable == Mnil)
5098 MInputMethodInfo *custom = get_custom_info (im_info);
5100 mplist_set (config->vars, Mnil, NULL);
5101 if (custom && custom->cmds)
5103 MPLIST_DO (plist, custom->vars)
5105 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5107 mplist_add (plist, Msymbol, variable);
5108 mplist_push (config->vars, Mplist, plist);
5109 M17N_OBJECT_UNREF (plist);
5115 plist = mplist__assq (config->vars, variable);
5118 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5119 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5120 if (! MPLIST_TAIL_P (plist))
5121 mplist_set (plist, Mnil ,NULL); /* () */
5126 mplist_add (config->vars, Mplist, plist);
5127 M17N_OBJECT_UNREF (plist);
5128 plist = mplist_add (plist, Msymbol, variable);
5129 plist = MPLIST_NEXT (plist);
5133 plist = mplist_add (plist, Msymbol, Mnil);
5134 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5137 config_all_variables (im_info);
5138 im_info->tick = time (NULL);
5145 @brief Get the name of per-user configuration file.
5147 The minput_config_file () function returns the absolute path name
5148 of per-user configuration file into which minput_save_config ()
5149 save configurations. It is usually @c "config.mic" under the
5150 directory @c ".m17n.d" of user's home directory. It is not assured
5151 that the file of the returned name exists nor is
5152 readable/writable. If minput_save_config () fails and returns -1,
5153 an application program might check the file, make it
5154 writable (if possible), and try minput_save_config () again.
5158 This function returns a string. As the string is kept in the
5159 library, the caller must not modify nor free it.
5162 minput_save_config ()
5165 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5167 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5168 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5169 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5170 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5171 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5172 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5173 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5178 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5179 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5182 minput_save_config ()
5186 minput_config_file ()
5190 return mdatabase__file (im_custom_mdb);
5196 @brief Save configurations in per-user configuration file.
5198 The minput_save_config () functions saves the configurations done
5199 so far in the current session into the per-user configuration
5204 If the operation was successful, 1 is returned. If the per-user
5205 configuration file is currently locked, 0 is returned. In that
5206 case, the caller may wait for a while and try again. If the
5207 configuration file is not writable, -1 is returned. In that case,
5208 the caller may check the name of the file by calling
5209 minput_config_file (), make it writable if possible, and try
5213 minput_config_file () */
5215 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5217 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5218 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5222 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5223 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5224 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5225 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5229 minput_config_file () */
5232 minput_save_config (void)
5234 MPlist *data, *tail, *plist, *p, *elt;
5238 ret = mdatabase__lock (im_custom_mdb);
5241 if (! im_config_list)
5243 update_custom_info ();
5244 if (! im_custom_list)
5245 im_custom_list = mplist ();
5246 data = tail = mplist ();
5248 MPLIST_DO (plist, im_config_list)
5250 MPlist *pl = MPLIST_PLIST (plist);
5251 MSymbol language, name, extra, command, variable;
5252 MInputMethodInfo *custom, *config;
5254 language = MPLIST_SYMBOL (pl);
5255 pl = MPLIST_NEXT (pl);
5256 name = MPLIST_SYMBOL (pl);
5257 pl = MPLIST_NEXT (pl);
5258 extra = MPLIST_SYMBOL (pl);
5259 pl = MPLIST_NEXT (pl);
5260 config = MPLIST_VAL (pl);
5261 custom = get_custom_info (config);
5263 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5265 MPLIST_DO (pl, config->cmds)
5267 elt = MPLIST_PLIST (pl);
5268 command = MPLIST_SYMBOL (elt);
5270 p = mplist__assq (custom->cmds, command);
5272 custom->cmds = mplist (), p = NULL;
5273 elt = MPLIST_NEXT (elt);
5274 if (MPLIST_TAIL_P (elt))
5277 mplist__pop_unref (p);
5281 elt = MPLIST_NEXT (elt);
5284 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5285 mplist_set (p, Mnil, NULL);
5286 mplist__conc (p, elt);
5290 p = MPLIST_PLIST (pl);
5291 mplist_add (custom->cmds, Mplist, p);
5296 MPLIST_DO (pl, config->vars)
5298 elt = MPLIST_PLIST (pl);
5299 variable = MPLIST_SYMBOL (elt);
5301 p = mplist__assq (custom->vars, variable);
5303 custom->vars = mplist (), p = NULL;
5304 elt = MPLIST_NEXT (elt);
5305 if (MPLIST_TAIL_P (elt))
5308 mplist__pop_unref (p);
5312 elt = MPLIST_NEXT (elt);
5315 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5316 mplist_set (p, Mnil, NULL);
5317 mplist__conc (p, elt);
5321 p = MPLIST_PLIST (pl);
5322 mplist_add (custom->vars, Mplist, p);
5327 M17N_OBJECT_UNREF (im_config_list);
5329 MPLIST_DO (plist, im_custom_list)
5331 MPlist *pl = MPLIST_PLIST (plist);
5332 MSymbol language, name, extra;
5333 MInputMethodInfo *custom, *im_info;
5335 language = MPLIST_SYMBOL (pl);
5336 pl = MPLIST_NEXT (pl);
5337 name = MPLIST_SYMBOL (pl);
5338 pl = MPLIST_NEXT (pl);
5339 extra = MPLIST_SYMBOL (pl);
5340 pl = MPLIST_NEXT (pl);
5341 custom = MPLIST_VAL (pl);
5342 im_info = lookup_im_info (im_info_list, language, name, extra);
5346 config_all_commands (im_info);
5348 config_all_variables (im_info);
5352 tail = mplist_add (tail, Mplist, elt);
5353 M17N_OBJECT_UNREF (elt);
5355 elt = mplist_add (elt, Mplist, pl);
5356 M17N_OBJECT_UNREF (pl);
5357 pl = mplist_add (pl, Msymbol, Minput_method);
5358 pl = mplist_add (pl, Msymbol, language);
5359 pl = mplist_add (pl, Msymbol, name);
5361 pl = mplist_add (pl, Msymbol, extra);
5362 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5365 elt = mplist_add (elt, Mplist, pl);
5366 M17N_OBJECT_UNREF (pl);
5367 pl = mplist_add (pl, Msymbol, Mcommand);
5368 MPLIST_DO (p, custom->cmds)
5369 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5371 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5374 elt = mplist_add (elt, Mplist, pl);
5375 M17N_OBJECT_UNREF (pl);
5376 pl = mplist_add (pl, Msymbol, Mvariable);
5377 MPLIST_DO (p, custom->vars)
5378 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5382 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5383 ret = mdatabase__save (im_custom_mdb, data);
5384 mdatabase__unlock (im_custom_mdb);
5385 M17N_OBJECT_UNREF (data);
5386 return (ret < 0 ? -1 : 1);
5392 @name Obsolete functions
5398 @brief Get a list of variables of an input method (obsolete).
5400 This function is obsolete. Use minput_get_variable () instead.
5402 The minput_get_variables () function returns a plist (#MPlist) of
5403 variables used to control the behavior of the input method
5404 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5405 (#m17nPlist) of the following format:
5408 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5409 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5413 @c VARNAME is a symbol representing the variable name.
5415 @c DOC-MTEXT is an M-text describing the variable.
5417 @c DEFAULT-VALUE is the default value of the variable. It is a
5418 symbol, integer, or M-text.
5420 @c VALUEs (if any) specifies the possible values of the variable.
5421 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5422 @c TO), where @c FROM and @c TO specifies a range of possible
5425 For instance, suppose an input method has the variables:
5427 @li name:intvar, description:"value is an integer",
5428 initial value:0, value-range:0..3,10,20
5430 @li name:symvar, description:"value is a symbol",
5431 initial value:nil, value-range:a, b, c, nil
5433 @li name:txtvar, description:"value is an M-text",
5434 initial value:empty text, no value-range (i.e. any text)
5436 Then, the returned plist is as follows.
5439 (intvar ("value is an integer" 0 (0 3) 10 20)
5440 symvar ("value is a symbol" nil a b c nil)
5441 txtvar ("value is an M-text" ""))
5445 If the input method uses any variables, a pointer to #MPlist is
5446 returned. As the plist is kept in the library, the caller must not
5447 modify nor free it. If the input method does not use any
5448 variable, @c NULL is returned. */
5450 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5452 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5453 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5454 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5458 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5459 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5463 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5465 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5467 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5470 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5471 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5472 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5474 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5476 @li name:intvar, ÀâÌÀ:"value is an integer",
5477 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5479 @li name:symvar, ÀâÌÀ:"value is a symbol",
5480 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5482 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5483 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5485 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5488 (intvar ("value is an integer" 0 (0 3) 10 20)
5489 symvar ("value is a symbol" nil a b c nil)
5490 txtvar ("value is an M-text" ""))
5494 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5495 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5496 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5499 minput_get_variables (MSymbol language, MSymbol name)
5501 MInputMethodInfo *im_info;
5506 im_info = get_im_info (language, name, Mnil, Mvariable);
5507 if (! im_info || ! im_info->configured_vars)
5510 M17N_OBJECT_UNREF (im_info->bc_vars);
5511 im_info->bc_vars = mplist ();
5512 MPLIST_DO (vars, im_info->configured_vars)
5514 MPlist *plist = MPLIST_PLIST (vars);
5515 MPlist *elt = mplist ();
5517 mplist_push (im_info->bc_vars, Mplist, elt);
5518 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5519 elt = MPLIST_NEXT (elt);
5520 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5521 M17N_OBJECT_UNREF (elt);
5523 return im_info->bc_vars;
5529 @brief Set the initial value of an input method variable.
5531 The minput_set_variable () function sets the initial value of
5532 input method variable $VARIABLE to $VALUE for the input method
5533 specified by $LANGUAGE and $NAME.
5535 By default, the initial value is 0.
5537 This setting gets effective in a newly opened input method.
5540 If the operation was successful, 0 is returned. Otherwise -1 is
5541 returned, and #merror_code is set to #MERROR_IM. */
5543 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5545 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5546 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5547 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5549 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5551 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5554 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5555 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5558 minput_set_variable (MSymbol language, MSymbol name,
5559 MSymbol variable, void *value)
5562 MInputMethodInfo *im_info;
5567 if (variable == Mnil)
5568 MERROR (MERROR_IM, -1);
5569 plist = minput_get_variable (language, name, variable);
5570 plist = MPLIST_PLIST (plist);
5571 plist = MPLIST_NEXT (plist);
5573 mplist_add (pl, MPLIST_KEY (plist), value);
5574 ret = minput_config_variable (language, name, variable, pl);
5575 M17N_OBJECT_UNREF (pl);
5578 im_info = get_im_info (language, name, Mnil, Mvariable);
5587 @brief Get information about input method commands.
5589 The minput_get_commands () function returns information about
5590 input method commands of the input method specified by $LANGUAGE
5591 and $NAME. An input method command is a pseudo key event to which
5592 one or more actual input key sequences are assigned.
5594 There are two kinds of commands, global and local. Global
5595 commands are used by multiple input methods for the same purpose,
5596 and have global key assignments. Local commands are used only by
5597 a specific input method, and have only local key assignments.
5599 Each input method may locally change key assignments for global
5600 commands. The global key assignment for a global command is
5601 effective only when the current input method does not have local
5602 key assignments for that command.
5604 If $NAME is #Mnil, information about global commands is returned.
5605 In this case $LANGUAGE is ignored.
5607 If $NAME is not #Mnil, information about those commands that have
5608 local key assignments in the input method specified by $LANGUAGE
5609 and $NAME is returned.
5612 If no input method commands are found, this function returns @c NULL.
5614 Otherwise, a pointer to a plist is returned. The key of each
5615 element in the plist is a symbol representing a command, and the
5616 value is a plist of the form COMMAND-INFO described below.
5618 The first element of COMMAND-INFO has the key #Mtext, and the
5619 value is an M-text describing the command.
5621 If there are no more elements, that means no key sequences are
5622 assigned to the command. Otherwise, each of the remaining
5623 elements has the key #Mplist, and the value is a plist whose keys are
5624 #Msymbol and values are symbols representing input keys, which are
5625 currently assigned to the command.
5627 As the returned plist is kept in the library, the caller must not
5628 modify nor free it. */
5630 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5632 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5633 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5634 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5635 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5637 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5638 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5639 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5640 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5642 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5643 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5644 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5647 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5648 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5650 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5651 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5655 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5657 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5658 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5659 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5661 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5662 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5663 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5666 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5667 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5668 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5669 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5670 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5672 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5673 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5676 minput_get_commands (MSymbol language, MSymbol name)
5678 MInputMethodInfo *im_info;
5683 im_info = get_im_info (language, name, Mnil, Mcommand);
5684 if (! im_info || ! im_info->configured_vars)
5686 M17N_OBJECT_UNREF (im_info->bc_cmds);
5687 im_info->bc_cmds = mplist ();
5688 MPLIST_DO (cmds, im_info->configured_cmds)
5690 MPlist *plist = MPLIST_PLIST (cmds);
5691 MPlist *elt = mplist ();
5693 mplist_push (im_info->bc_cmds, Mplist, elt);
5694 mplist_add (elt, MPLIST_SYMBOL (plist),
5695 mplist_copy (MPLIST_NEXT (plist)));
5696 M17N_OBJECT_UNREF (elt);
5698 return im_info->bc_cmds;
5704 @brief Assign a key sequence to an input method command (obsolete).
5706 This function is obsolete. Use minput_config_command () instead.
5708 The minput_assign_command_keys () function assigns input key
5709 sequence $KEYSEQ to input method command $COMMAND for the input
5710 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5711 key sequence is assigned globally no matter what $LANGUAGE is.
5712 Otherwise the key sequence is assigned locally.
5714 Each element of $KEYSEQ must have the key $Msymbol and the value
5715 must be a symbol representing an input key.
5717 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5718 globally or locally.
5720 This assignment gets effective in a newly opened input method.
5723 If the operation was successful, 0 is returned. Otherwise -1 is
5724 returned, and #merror_code is set to #MERROR_IM. */
5726 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5728 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5729 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5730 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5731 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5732 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5734 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5735 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5737 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5738 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5740 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5743 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5744 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5747 minput_assign_command_keys (MSymbol language, MSymbol name,
5748 MSymbol command, MPlist *keyseq)
5754 if (command == Mnil)
5755 MERROR (MERROR_IM, -1);
5760 if (! check_command_keyseq (keyseq))
5761 MERROR (MERROR_IM, -1);
5763 mplist_add (plist, Mplist, keyseq);
5768 ret = minput_config_command (language, name, command, keyseq);
5769 M17N_OBJECT_UNREF (keyseq);
5775 /*** @addtogroup m17nDebug */
5781 @brief Dump an input method.
5783 The mdebug_dump_im () function prints the input method $IM in a
5784 human readable way to the stderr. $INDENT specifies how many
5785 columns to indent the lines but the first one.
5788 This function returns $IM. */
5790 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
5792 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
5793 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
5796 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
5799 mdebug_dump_im (MInputMethod *im, int indent)
5801 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
5804 prefix = (char *) alloca (indent + 1);
5805 memset (prefix, 32, indent);
5806 prefix[indent] = '\0';
5808 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
5809 msymbol_name (im->name));
5810 mdebug_dump_mtext (im_info->title, 0, 0);
5811 if (im->name != Mnil)
5815 MPLIST_DO (state, im_info->states)
5817 fprintf (stderr, "\n%s ", prefix);
5818 dump_im_state (MPLIST_VAL (state), indent + 2);
5821 fprintf (stderr, ")");