1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
156 #include "m17n-gui.h"
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_mask = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mundo = msymbol ("undo");
406 Mcall = msymbol ("call");
407 Mshift = msymbol ("shift");
408 Mselect = msymbol ("select");
409 Mshow = msymbol ("show");
410 Mhide = msymbol ("hide");
411 Mcommit = msymbol ("commit");
412 Munhandle = msymbol ("unhandle");
413 Mset = msymbol ("set");
414 Madd = msymbol ("add");
415 Msub = msymbol ("sub");
416 Mmul = msymbol ("mul");
417 Mdiv = msymbol ("div");
418 Mequal = msymbol ("=");
419 Mless = msymbol ("<");
420 Mgreater = msymbol (">");
421 Mless_equal = msymbol ("<=");
422 Mgreater_equal = msymbol (">=");
423 Mcond = msymbol ("cond");
424 Mplus = msymbol ("+");
425 Mminus = msymbol ("-");
426 Mstar = msymbol ("*");
427 Mslash = msymbol ("/");
428 Mand = msymbol ("&");
430 Mnot = msymbol ("!");
432 Mat_reload = msymbol ("@reload");
434 Mcandidates_group_size = msymbol ("candidates-group-size");
435 Mcandidates_charset = msymbol ("candidates-charset");
437 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
438 Mcandidate_index = msymbol (" candidate-index");
440 Minit = msymbol ("init");
441 Mfini = msymbol ("fini");
443 Mdescription = msymbol ("description");
444 Mcommand = msymbol ("command");
445 Mvariable = msymbol ("variable");
446 Mglobal = msymbol ("global");
447 Mconfig = msymbol ("config");
448 M_gettext = msymbol ("_");
450 load_im_info_keys = mplist ();
451 mplist_add (load_im_info_keys, Mstate, Mnil);
452 mplist_push (load_im_info_keys, Mmap, Mnil);
454 im_info_list = mplist ();
455 im_config_list = im_custom_list = NULL;
456 im_custom_mdb = NULL;
457 update_custom_info ();
459 update_global_info ();
461 fully_initialized = 1;
464 #define MINPUT__INIT() \
466 if (! fully_initialized) \
467 fully_initialize (); \
472 marker_code (MSymbol sym)
478 name = MSYMBOL_NAME (sym);
479 return ((name[0] == '@'
480 && ((name[1] >= '0' && name[1] <= '9')
481 || name[1] == '<' || name[1] == '>'
482 || name[1] == '=' || name[1] == '+' || name[1] == '-'
483 || name[1] == '[' || name[1] == ']'
491 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
493 MPlist *plist = mplist__assq (ic_info->vars, var);
497 plist = MPLIST_PLIST (plist);
498 return MPLIST_NEXT (plist);
502 mplist_push (ic_info->vars, Mplist, plist);
503 M17N_OBJECT_UNREF (plist);
504 plist = mplist_add (plist, Msymbol, var);
505 plist = mplist_add (plist, Minteger, (void *) 0);
510 get_surrounding_text (MInputContext *ic, int len)
514 mplist_push (ic->plist, Minteger, (void *) len);
515 if (minput__callback (ic, Minput_get_surrounding_text) >= 0
516 && MPLIST_MTEXT_P (ic->plist))
517 mt = MPLIST_MTEXT (ic->plist);
518 mplist_pop (ic->plist);
523 delete_surrounding_text (MInputContext *ic, int pos)
525 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
527 mplist_push (ic->plist, Minteger, (void *) pos);
528 minput__callback (ic, Minput_delete_surrounding_text);
529 mplist_pop (ic->plist);
532 M17N_OBJECT_UNREF (ic_info->preceding_text);
533 ic_info->preceding_text = NULL;
537 M17N_OBJECT_UNREF (ic_info->following_text);
538 ic_info->following_text = NULL;
543 get_preceding_char (MInputContext *ic, int pos)
545 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
549 if (ic_info->preceding_text)
551 len = mtext_nchars (ic_info->preceding_text);
553 return mtext_ref_char (ic_info->preceding_text, len - pos);
555 mt = get_surrounding_text (ic, - pos);
558 len = mtext_nchars (mt);
559 if (ic_info->preceding_text)
561 if (mtext_nchars (ic_info->preceding_text) < len)
563 M17N_OBJECT_UNREF (ic_info->preceding_text);
564 ic_info->preceding_text = mt;
568 ic_info->preceding_text = mt;
571 return mtext_ref_char (ic_info->preceding_text, len - pos);
575 get_following_char (MInputContext *ic, int pos)
577 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
581 if (ic_info->following_text)
583 len = mtext_nchars (ic_info->following_text);
585 return mtext_ref_char (ic_info->following_text, pos - 1);
587 mt = get_surrounding_text (ic, pos);
590 len = mtext_nchars (mt);
591 if (ic_info->following_text)
593 if (mtext_nchars (ic_info->following_text) < len)
595 M17N_OBJECT_UNREF (ic_info->following_text);
596 ic_info->following_text = mt;
600 ic_info->following_text = mt;
603 return mtext_ref_char (ic_info->following_text, pos - 1);
607 surrounding_pos (MSymbol sym)
613 name = MSYMBOL_NAME (sym);
614 if ((name[1] == '-' || name[1] == '+')
615 && name[2] >= '1' && name[2] <= '9')
616 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
621 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
623 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
625 MText *preedit = ic->preedit;
626 int len = mtext_nchars (preedit);
630 if (MPLIST_INTEGER_P (arg))
631 return MPLIST_INTEGER (arg);
633 && (surrounding = surrounding_pos (MPLIST_SYMBOL (arg))) != 0)
634 return (surrounding < 0
635 ? get_preceding_char (ic, - surrounding)
636 : get_following_char (ic, surrounding));
637 code = marker_code (MPLIST_SYMBOL (arg));
640 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
644 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
647 return ic_info->key_head;
648 if (code >= '0' && code <= '9')
650 else if (code == '=')
651 code = ic->cursor_pos;
652 else if (code == '-' || code == '[')
653 code = ic->cursor_pos - 1;
654 else if (code == '+' || code == ']')
655 code = ic->cursor_pos + 1;
656 else if (code == '<')
658 else if (code == '>')
660 return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
664 parse_expression (MPlist *plist)
668 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
670 if (! MPLIST_PLIST_P (plist))
672 plist = MPLIST_PLIST (plist);
673 op = MPLIST_SYMBOL (plist);
674 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
675 && op != Mand && op != Mor && op != Mnot
676 && op != Mless && op != Mgreater && op != Mequal
677 && op != Mless_equal && op != Mgreater_equal)
678 MERROR (MERROR_IM, -1);
679 MPLIST_DO (plist, MPLIST_NEXT (plist))
680 if (parse_expression (plist) < 0)
686 resolve_expression (MInputContext *ic, MPlist *plist)
691 if (MPLIST_INTEGER_P (plist))
692 return MPLIST_INTEGER (plist);
693 if (MPLIST_SYMBOL_P (plist))
694 return integer_value (ic, plist, NULL, 1);
695 if (! MPLIST_PLIST_P (plist))
697 plist = MPLIST_PLIST (plist);
698 if (! MPLIST_SYMBOL_P (plist))
700 op = MPLIST_SYMBOL (plist);
701 plist = MPLIST_NEXT (plist);
702 val = resolve_expression (ic, plist);
704 MPLIST_DO (plist, MPLIST_NEXT (plist))
705 val += resolve_expression (ic, plist);
706 else if (op == Mminus)
707 MPLIST_DO (plist, MPLIST_NEXT (plist))
708 val -= resolve_expression (ic, plist);
709 else if (op == Mstar)
710 MPLIST_DO (plist, MPLIST_NEXT (plist))
711 val *= resolve_expression (ic, plist);
712 else if (op == Mslash)
713 MPLIST_DO (plist, MPLIST_NEXT (plist))
714 val /= resolve_expression (ic, plist);
716 MPLIST_DO (plist, MPLIST_NEXT (plist))
717 val &= resolve_expression (ic, plist);
719 MPLIST_DO (plist, MPLIST_NEXT (plist))
720 val |= resolve_expression (ic, plist);
723 else if (op == Mless)
724 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
725 else if (op == Mequal)
726 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
727 else if (op == Mgreater)
728 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
729 else if (op == Mless_equal)
730 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
731 else if (op == Mgreater_equal)
732 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
736 /* Parse PLIST as an action list. PLIST should have this form:
737 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
738 Return 0 if successfully parsed, otherwise return -1. */
741 parse_action_list (MPlist *plist, MPlist *macros)
743 MPLIST_DO (plist, plist)
745 if (MPLIST_MTEXT_P (plist))
747 /* This is a short form of (insert MTEXT). */
748 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
749 MERROR (MERROR_IM, -1); */
751 else if (MPLIST_PLIST_P (plist)
752 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
753 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
757 /* This is a short form of (insert (GROUPS *)). */
758 MPLIST_DO (pl, MPLIST_PLIST (plist))
760 if (MPLIST_PLIST_P (pl))
764 MPLIST_DO (elt, MPLIST_PLIST (pl))
765 if (! MPLIST_MTEXT_P (elt)
766 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
767 MERROR (MERROR_IM, -1);
771 if (! MPLIST_MTEXT_P (pl)
772 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
773 MERROR (MERROR_IM, -1);
777 else if (MPLIST_INTEGER_P (plist))
779 int c = MPLIST_INTEGER (plist);
781 if (c < 0 || c > MCHAR_MAX)
782 MERROR (MERROR_IM, -1);
784 else if (MPLIST_PLIST_P (plist)
785 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
787 MPlist *pl = MPLIST_PLIST (plist);
788 MSymbol action_name = MPLIST_SYMBOL (pl);
790 pl = MPLIST_NEXT (pl);
792 if (action_name == Minsert)
794 if (MPLIST_MTEXT_P (pl))
796 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
797 MERROR (MERROR_IM, -1);
799 else if (MPLIST_PLIST_P (pl))
803 if (MPLIST_PLIST_P (pl))
807 MPLIST_DO (elt, MPLIST_PLIST (pl))
808 if (! MPLIST_MTEXT_P (elt)
809 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
810 MERROR (MERROR_IM, -1);
814 if (! MPLIST_MTEXT_P (pl)
815 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
816 MERROR (MERROR_IM, -1);
820 else if (! MPLIST_SYMBOL_P (pl))
821 MERROR (MERROR_IM, -1);
823 else if (action_name == Mselect
824 || action_name == Mdelete
825 || action_name == Mmove)
827 if (parse_expression (pl) < 0)
830 else if (action_name == Mmark
831 || action_name == Mcall
832 || action_name == Mshift)
834 if (! MPLIST_SYMBOL_P (pl))
835 MERROR (MERROR_IM, -1);
837 else if (action_name == Mundo)
839 if (! MPLIST_TAIL_P (pl))
841 if (! MPLIST_SYMBOL_P (pl)
842 && (! MPLIST_INTEGER_P (pl)
843 || MPLIST_INTEGER (pl) == 0))
844 MERROR (MERROR_IM, -1);
847 else if (action_name == Mpushback)
849 if (MPLIST_MTEXT_P (pl))
851 MText *mt = MPLIST_MTEXT (pl);
853 if (mtext_nchars (mt) != mtext_nbytes (mt))
854 MERROR (MERROR_IM, -1);
856 else if (MPLIST_PLIST_P (pl))
860 MPLIST_DO (p, MPLIST_PLIST (pl))
861 if (! MPLIST_SYMBOL_P (p))
862 MERROR (MERROR_IM, -1);
864 else if (! MPLIST_INTEGER_P (pl))
865 MERROR (MERROR_IM, -1);
867 else if (action_name == Mset || action_name == Madd
868 || action_name == Msub || action_name == Mmul
869 || action_name == Mdiv)
871 if (! MPLIST_SYMBOL_P (pl))
872 MERROR (MERROR_IM, -1);
873 if (parse_expression (MPLIST_NEXT (pl)) < 0)
876 else if (action_name == Mequal || action_name == Mless
877 || action_name == Mgreater || action_name == Mless_equal
878 || action_name == Mgreater_equal)
880 if (parse_expression (pl) < 0
881 || parse_expression (MPLIST_NEXT (pl)) < 0)
883 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
884 if (! MPLIST_PLIST_P (pl))
885 MERROR (MERROR_IM, -1);
886 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
887 MERROR (MERROR_IM, -1);
888 pl = MPLIST_NEXT (pl);
889 if (MPLIST_PLIST_P (pl)
890 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
891 MERROR (MERROR_IM, -1);
893 else if (action_name == Mshow || action_name == Mhide
894 || action_name == Mcommit || action_name == Munhandle)
896 else if (action_name == Mcond)
899 if (! MPLIST_PLIST_P (pl))
900 MERROR (MERROR_IM, -1);
902 else if (! macros || ! mplist_get (macros, action_name))
903 MERROR (MERROR_IM, -1);
905 else if (! MPLIST_SYMBOL_P (plist))
906 MERROR (MERROR_IM, -1);
913 resolve_command (MPlist *cmds, MSymbol command)
917 if (! cmds || ! (plist = mplist__assq (cmds, command)))
919 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
920 plist = MPLIST_NEXT (plist);
921 plist = MPLIST_NEXT (plist);
922 plist = MPLIST_NEXT (plist);
926 /* Load a translation into MAP from PLIST.
928 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
931 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
932 MPlist *branch_actions, MPlist *macros)
937 if (MPLIST_MTEXT_P (keylist))
939 MText *mt = MPLIST_MTEXT (keylist);
941 len = mtext_nchars (mt);
942 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
944 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
945 for (i = 0; i < len; i++)
946 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
952 if (MFAILP (MPLIST_PLIST_P (keylist)))
954 elt = MPLIST_PLIST (keylist);
955 len = MPLIST_LENGTH (elt);
956 if (MFAILP (len > 0))
958 keyseq = (MSymbol *) alloca (sizeof (int) * len);
959 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
961 if (MPLIST_INTEGER_P (elt))
963 int c = MPLIST_INTEGER (elt);
965 if (MFAILP (c >= 0 && c < 0x100))
967 keyseq[i] = one_char_symbol[c];
971 if (MFAILP (MPLIST_SYMBOL_P (elt)))
973 keyseq[i] = MPLIST_SYMBOL (elt);
978 for (i = 0; i < len; i++)
980 MIMMap *deeper = NULL;
983 deeper = mplist_get (map->submaps, keyseq[i]);
985 map->submaps = mplist ();
988 /* Fixme: It is better to make all deeper maps at once. */
989 MSTRUCT_CALLOC (deeper, MERROR_IM);
990 mplist_put (map->submaps, keyseq[i], deeper);
995 /* We reach a terminal map. */
997 || map->branch_actions)
998 /* This map is already defined. We avoid overriding it. */
1001 if (! MPLIST_TAIL_P (map_actions))
1003 if (parse_action_list (map_actions, macros) < 0)
1004 MERROR (MERROR_IM, -1);
1005 map->map_actions = map_actions;
1009 map->branch_actions = branch_actions;
1010 M17N_OBJECT_REF (branch_actions);
1016 /* Load a branch from PLIST into MAP. PLIST has this form:
1017 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1020 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1023 MPlist *branch_actions;
1025 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1027 map_name = MPLIST_SYMBOL (plist);
1028 plist = MPLIST_NEXT (plist);
1029 if (MPLIST_TAIL_P (plist))
1030 branch_actions = NULL;
1031 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1034 branch_actions = plist;
1035 if (map_name == Mnil)
1037 map->branch_actions = branch_actions;
1039 M17N_OBJECT_REF (branch_actions);
1041 else if (map_name == Mt)
1043 map->map_actions = branch_actions;
1045 M17N_OBJECT_REF (branch_actions);
1047 else if (im_info->maps
1048 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1050 MPLIST_DO (plist, plist)
1052 MPlist *keylist, *map_actions;
1054 if (! MPLIST_PLIST_P (plist))
1055 MERROR (MERROR_IM, -1);
1056 keylist = MPLIST_PLIST (plist);
1057 map_actions = MPLIST_NEXT (keylist);
1058 if (MPLIST_SYMBOL_P (keylist))
1060 MSymbol command = MPLIST_SYMBOL (keylist);
1063 if (MFAILP (command != Mat_reload))
1065 pl = resolve_command (im_info->configured_cmds, command);
1069 load_translation (map, pl, map_actions, branch_actions,
1073 load_translation (map, keylist, map_actions, branch_actions,
1081 /* Load a macro from PLIST into IM_INFO->macros.
1082 PLIST has this from:
1083 PLIST ::= ( MACRO-NAME ACTION * )
1084 IM_INFO->macros is a plist of macro names vs action list. */
1087 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1092 if (! MPLIST_SYMBOL_P (plist))
1093 MERROR (MERROR_IM, -1);
1094 name = MPLIST_SYMBOL (plist);
1095 plist = MPLIST_NEXT (plist);
1096 if (MPLIST_TAIL_P (plist)
1097 || parse_action_list (plist, im_info->macros) < 0)
1098 MERROR (MERROR_IM, -1);
1099 pl = mplist_get (im_info->macros, name);
1100 M17N_OBJECT_UNREF (pl);
1101 mplist_put (im_info->macros, name, plist);
1102 M17N_OBJECT_REF (plist);
1106 /* Load an external module from PLIST into IM_INFO->externals.
1107 PLIST has this form:
1108 PLIST ::= ( MODULE-NAME FUNCTION * )
1109 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1112 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1117 MIMExternalModule *external;
1121 if (MPLIST_MTEXT_P (plist))
1122 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1123 else if (MPLIST_SYMBOL_P (plist))
1124 module = MPLIST_SYMBOL (plist);
1125 module_file = alloca (strlen (MSYMBOL_NAME (module))
1126 + strlen (DLOPEN_SHLIB_EXT) + 1);
1127 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1129 handle = dlopen (module_file, RTLD_NOW);
1130 if (MFAILP (handle))
1132 fprintf (stderr, "%s\n", dlerror ());
1135 func_list = mplist ();
1136 MPLIST_DO (plist, MPLIST_NEXT (plist))
1138 if (! MPLIST_SYMBOL_P (plist))
1139 MERROR_GOTO (MERROR_IM, err_label);
1140 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1143 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1146 MSTRUCT_MALLOC (external, MERROR_IM);
1147 external->handle = handle;
1148 external->func_list = func_list;
1149 mplist_add (im_info->externals, module, external);
1154 M17N_OBJECT_UNREF (func_list);
1159 free_map (MIMMap *map, int top)
1164 M17N_OBJECT_UNREF (map->map_actions);
1167 MPLIST_DO (plist, map->submaps)
1168 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1169 M17N_OBJECT_UNREF (map->submaps);
1171 M17N_OBJECT_UNREF (map->branch_actions);
1176 free_state (void *object)
1178 MIMState *state = object;
1180 M17N_OBJECT_UNREF (state->title);
1182 free_map (state->map, 1);
1186 /** Load a state from PLIST into a newly allocated state object.
1187 PLIST has this form:
1188 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1189 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1190 Return the state object. */
1193 load_state (MInputMethodInfo *im_info, MPlist *plist)
1197 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1199 M17N_OBJECT (state, free_state, MERROR_IM);
1200 state->name = MPLIST_SYMBOL (plist);
1201 plist = MPLIST_NEXT (plist);
1202 if (MPLIST_MTEXT_P (plist))
1204 state->title = MPLIST_MTEXT (plist);
1205 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1206 Mlanguage, im_info->language);
1207 M17N_OBJECT_REF (state->title);
1208 plist = MPLIST_NEXT (plist);
1210 MSTRUCT_CALLOC (state->map, MERROR_IM);
1211 MPLIST_DO (plist, plist)
1213 if (MFAILP (MPLIST_PLIST_P (plist)))
1215 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1220 /* Return a newly created IM_INFO for an input method specified by
1221 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1223 static MInputMethodInfo *
1224 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1227 MInputMethodInfo *im_info;
1230 if (name == Mnil && extra == Mnil)
1231 language = Mt, extra = Mglobal;
1232 MSTRUCT_CALLOC (im_info, MERROR_IM);
1234 im_info->language = language;
1235 im_info->name = name;
1236 im_info->extra = extra;
1239 mplist_add (plist, Mplist, elt);
1240 M17N_OBJECT_UNREF (elt);
1241 elt = mplist_add (elt, Msymbol, language);
1242 elt = mplist_add (elt, Msymbol, name);
1243 elt = mplist_add (elt, Msymbol, extra);
1244 mplist_add (elt, Mt, im_info);
1250 fini_im_info (MInputMethodInfo *im_info)
1254 M17N_OBJECT_UNREF (im_info->cmds);
1255 M17N_OBJECT_UNREF (im_info->configured_cmds);
1256 M17N_OBJECT_UNREF (im_info->bc_cmds);
1257 M17N_OBJECT_UNREF (im_info->vars);
1258 M17N_OBJECT_UNREF (im_info->configured_vars);
1259 M17N_OBJECT_UNREF (im_info->bc_vars);
1260 M17N_OBJECT_UNREF (im_info->description);
1261 M17N_OBJECT_UNREF (im_info->title);
1262 if (im_info->states)
1264 MPLIST_DO (plist, im_info->states)
1266 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1268 M17N_OBJECT_UNREF (state);
1270 M17N_OBJECT_UNREF (im_info->states);
1273 if (im_info->macros)
1275 MPLIST_DO (plist, im_info->macros)
1276 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1277 M17N_OBJECT_UNREF (im_info->macros);
1280 if (im_info->externals)
1282 MPLIST_DO (plist, im_info->externals)
1284 MIMExternalModule *external = MPLIST_VAL (plist);
1286 dlclose (external->handle);
1287 M17N_OBJECT_UNREF (external->func_list);
1289 MPLIST_KEY (plist) = Mt;
1291 M17N_OBJECT_UNREF (im_info->externals);
1295 MPLIST_DO (plist, im_info->maps)
1297 MPlist *p = MPLIST_PLIST (plist);
1299 M17N_OBJECT_UNREF (p);
1301 M17N_OBJECT_UNREF (im_info->maps);
1308 free_im_info (MInputMethodInfo *im_info)
1310 fini_im_info (im_info);
1315 free_im_list (MPlist *plist)
1319 MPLIST_DO (pl, plist)
1321 MInputMethodInfo *im_info;
1323 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1324 im_info = MPLIST_VAL (elt);
1325 free_im_info (im_info);
1327 M17N_OBJECT_UNREF (plist);
1330 static MInputMethodInfo *
1331 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1333 if (name == Mnil && extra == Mnil)
1334 language = Mt, extra = Mglobal;
1335 while ((plist = mplist__assq (plist, language)))
1337 MPlist *elt = MPLIST_PLIST (plist);
1339 plist = MPLIST_NEXT (plist);
1340 elt = MPLIST_NEXT (elt);
1341 if (MPLIST_SYMBOL (elt) != name)
1343 elt = MPLIST_NEXT (elt);
1344 if (MPLIST_SYMBOL (elt) != extra)
1346 elt = MPLIST_NEXT (elt);
1347 return MPLIST_VAL (elt);
1352 static void load_im_info (MPlist *, MInputMethodInfo *);
1354 #define get_custom_info(im_info) \
1356 ? lookup_im_info (im_custom_list, (im_info)->language, \
1357 (im_info)->name, (im_info)->extra) \
1360 #define get_config_info(im_info) \
1362 ? lookup_im_info (im_config_list, (im_info)->language, \
1363 (im_info)->name, (im_info)->extra) \
1367 update_custom_info (void)
1373 if (mdatabase__check (im_custom_mdb) > 0)
1378 MDatabaseInfo *custom_dir_info;
1379 char custom_path[PATH_MAX + 1];
1381 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1382 if (! custom_dir_info->filename
1383 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1385 strcpy (custom_path, custom_dir_info->filename);
1386 strcat (custom_path, CUSTOM_FILE);
1387 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1393 free_im_list (im_custom_list);
1394 im_custom_list = NULL;
1396 plist = mdatabase_load (im_custom_mdb);
1399 im_custom_list = mplist ();
1401 MPLIST_DO (pl, plist)
1403 MSymbol language, name, extra;
1404 MInputMethodInfo *im_info;
1405 MPlist *im_data, *p;
1407 if (! MPLIST_PLIST_P (pl))
1409 p = MPLIST_PLIST (pl);
1410 im_data = MPLIST_NEXT (p);
1411 if (! MPLIST_PLIST_P (p))
1413 p = MPLIST_PLIST (p);
1414 if (! MPLIST_SYMBOL_P (p)
1415 || MPLIST_SYMBOL (p) != Minput_method)
1417 p = MPLIST_NEXT (p);
1418 if (! MPLIST_SYMBOL_P (p))
1420 language = MPLIST_SYMBOL (p);
1421 p = MPLIST_NEXT (p);
1422 if (! MPLIST_SYMBOL_P (p))
1424 name = MPLIST_SYMBOL (p);
1425 if (language == Mnil || name == Mnil)
1427 p = MPLIST_NEXT (p);
1428 if (MPLIST_TAIL_P (p))
1430 else if (MPLIST_SYMBOL_P (p))
1431 extra = MPLIST_SYMBOL (p);
1434 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1435 load_im_info (im_data, im_info);
1437 M17N_OBJECT_UNREF (plist);
1442 update_global_info (void)
1448 int ret = mdatabase__check (global_info->mdb);
1452 fini_im_info (global_info);
1456 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1458 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1460 if (! global_info->mdb
1461 || ! (plist = mdatabase_load (global_info->mdb)))
1464 load_im_info (plist, global_info);
1465 M17N_OBJECT_UNREF (plist);
1470 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1471 and EXTRA. KEY, if not Mnil, tells which kind of information about
1472 the input method is necessary, and the returned IM_INFO may contain
1473 only that information. */
1475 static MInputMethodInfo *
1476 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1479 MInputMethodInfo *im_info;
1482 if (name == Mnil && extra == Mnil)
1483 language = Mt, extra = Mglobal;
1484 im_info = lookup_im_info (im_info_list, language, name, extra);
1487 if (key == Mnil ? im_info->states != NULL
1488 : key == Mcommand ? im_info->cmds != NULL
1489 : key == Mvariable ? im_info->vars != NULL
1490 : key == Mtitle ? im_info->title != NULL
1491 : key == Mdescription ? im_info->description != NULL
1493 /* IM_INFO already contains required information. */
1495 /* We have not yet loaded required information. */
1499 mdb = mdatabase_find (Minput_method, language, name, extra);
1502 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1507 plist = mdatabase_load (im_info->mdb);
1511 mplist_push (load_im_info_keys, key, Mt);
1512 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1513 mplist_pop (load_im_info_keys);
1517 MERROR (MERROR_IM, im_info);
1518 update_global_info ();
1519 load_im_info (plist, im_info);
1520 M17N_OBJECT_UNREF (plist);
1523 if (! im_info->cmds)
1524 im_info->cmds = mplist ();
1525 if (! im_info->vars)
1526 im_info->vars = mplist ();
1528 if (! im_info->title
1529 && (key == Mnil || key == Mtitle))
1530 im_info->title = (name == Mnil ? mtext ()
1531 : mtext_from_data (MSYMBOL_NAME (name),
1532 MSYMBOL_NAMELEN (name),
1533 MTEXT_FORMAT_US_ASCII));
1537 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1538 If updated, but got unloadable, return -1. Otherwise, update
1539 contents of IM_INFO from the new database, and return 1. */
1542 reload_im_info (MInputMethodInfo *im_info)
1547 update_custom_info ();
1548 update_global_info ();
1549 check = mdatabase__check (im_info->mdb);
1552 plist = mdatabase_load (im_info->mdb);
1555 fini_im_info (im_info);
1556 load_im_info (plist, im_info);
1557 M17N_OBJECT_UNREF (plist);
1561 static MInputMethodInfo *
1562 get_im_info_by_tags (MPlist *plist)
1567 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1568 i++, plist = MPLIST_NEXT (plist))
1569 tag[i] = MPLIST_SYMBOL (plist);
1574 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1579 check_description (MPlist *plist)
1583 if (MPLIST_MTEXT_P (plist))
1585 if (MPLIST_PLIST_P (plist))
1587 MPlist *pl = MPLIST_PLIST (plist);
1589 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1591 pl =MPLIST_NEXT (pl);
1592 if (MFAILP (MPLIST_MTEXT_P (pl)))
1594 mt = MPLIST_MTEXT (pl);
1595 M17N_OBJECT_REF (mt);
1598 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1600 if (translated == (char *) MTEXT_DATA (mt))
1601 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1602 if (translated != (char *) MTEXT_DATA (mt))
1604 M17N_OBJECT_UNREF (mt);
1605 mt = mtext__from_data (translated, strlen (translated),
1606 MTEXT_FORMAT_UTF_8, 0);
1610 mplist_set (plist, Mtext, mt);
1611 M17N_OBJECT_UNREF (mt);
1614 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1620 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1624 check_command_keyseq (MPlist *keyseq)
1626 if (MPLIST_PLIST_P (keyseq))
1628 MPlist *p = MPLIST_PLIST (keyseq);
1631 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1635 if (MPLIST_MTEXT_P (keyseq))
1637 MText *mt = MPLIST_MTEXT (keyseq);
1640 for (i = 0; i < mtext_nchars (mt); i++)
1641 if (mtext_ref_char (mt, i) >= 256)
1648 /* Load command defitions from PLIST into IM_INFO->cmds.
1650 PLIST is well-formed and has this form;
1651 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1652 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1653 M-text or a plist of symbols.
1655 The returned list has the same form, but for each element...
1657 (1) If DESCRIPTION and the rest are omitted, the element is not
1658 stored in the returned list.
1660 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1661 description in global_info->cmds (if any). */
1664 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1668 im_info->cmds = tail = mplist ();
1670 MPLIST_DO (plist, MPLIST_NEXT (plist))
1672 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1675 if (MFAILP (MPLIST_PLIST_P (plist)))
1677 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1678 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1680 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1681 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1683 if (MFAILP (im_info != global_info))
1684 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1688 if (! check_description (p))
1689 mplist_set (p, Msymbol, Mnil);
1690 p = MPLIST_NEXT (p);
1691 while (! MPLIST_TAIL_P (p))
1693 if (MFAILP (check_command_keyseq (p)))
1694 mplist__pop_unref (p);
1696 p = MPLIST_NEXT (p);
1699 tail = mplist_add (tail, Mplist, pl);
1704 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1705 MPlist *config_cmds)
1707 MPlist *global = NULL, *custom = NULL, *config = NULL;
1710 MPlist *description = NULL, *keyseq;
1712 name = MPLIST_SYMBOL (plist);
1713 plist = MPLIST_NEXT (plist);
1714 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1715 description = plist;
1716 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1717 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1718 if (MPLIST_TAIL_P (plist))
1721 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1722 global = MPLIST_NEXT (MPLIST_PLIST (global));
1725 keyseq = MPLIST_NEXT (global);
1726 status = Minherited;
1736 keyseq = MPLIST_NEXT (plist);
1740 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1742 config = MPLIST_NEXT (MPLIST_PLIST (config));
1743 if (! MPLIST_TAIL_P (config))
1745 keyseq = MPLIST_NEXT (config);
1746 status = Mconfigured;
1749 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1751 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1752 if (! MPLIST_TAIL_P (custom))
1754 keyseq = MPLIST_NEXT (custom);
1755 status = Mcustomized;
1760 mplist_add (plist, Msymbol, name);
1762 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1764 mplist_add (plist, Msymbol, Mnil);
1765 mplist_add (plist, Msymbol, status);
1766 mplist__conc (plist, keyseq);
1771 config_all_commands (MInputMethodInfo *im_info)
1773 MPlist *global_cmds, *custom_cmds, *config_cmds;
1774 MInputMethodInfo *temp;
1775 MPlist *tail, *plist;
1777 M17N_OBJECT_UNREF (im_info->configured_cmds);
1779 if (MPLIST_TAIL_P (im_info->cmds)
1783 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1784 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1785 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1787 im_info->configured_cmds = tail = mplist ();
1788 MPLIST_DO (plist, im_info->cmds)
1790 MPlist *pl = config_command (MPLIST_PLIST (plist),
1791 global_cmds, custom_cmds, config_cmds);
1794 tail = mplist_add (tail, Mplist, pl);
1795 M17N_OBJECT_UNREF (pl);
1800 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1801 valid, return 0 if not. */
1804 check_variable_value (MPlist *val, MPlist *global)
1806 MSymbol type = MPLIST_KEY (val);
1807 MPlist *valids = MPLIST_NEXT (val);
1809 if (type != Minteger && type != Mtext && type != Msymbol)
1813 if (MPLIST_KEY (global) != Mt
1814 && MPLIST_KEY (global) != MPLIST_KEY (val))
1816 if (MPLIST_TAIL_P (valids))
1817 valids = MPLIST_NEXT (global);
1819 if (MPLIST_TAIL_P (valids))
1822 if (type == Minteger)
1824 int n = MPLIST_INTEGER (val);
1826 MPLIST_DO (valids, valids)
1828 if (MPLIST_INTEGER_P (valids))
1830 if (n == MPLIST_INTEGER (valids))
1833 else if (MPLIST_PLIST_P (valids))
1835 MPlist *p = MPLIST_PLIST (valids);
1836 int min_bound, max_bound;
1838 if (! MPLIST_INTEGER_P (p))
1839 MERROR (MERROR_IM, 0);
1840 min_bound = MPLIST_INTEGER (p);
1841 p = MPLIST_NEXT (p);
1842 if (! MPLIST_INTEGER_P (p))
1843 MERROR (MERROR_IM, 0);
1844 max_bound = MPLIST_INTEGER (p);
1845 if (n >= min_bound && n <= max_bound)
1850 else if (type == Msymbol)
1852 MSymbol sym = MPLIST_SYMBOL (val);
1854 MPLIST_DO (valids, valids)
1856 if (! MPLIST_SYMBOL_P (valids))
1857 MERROR (MERROR_IM, 0);
1858 if (sym == MPLIST_SYMBOL (valids))
1864 MText *mt = MPLIST_MTEXT (val);
1866 MPLIST_DO (valids, valids)
1868 if (! MPLIST_MTEXT_P (valids))
1869 MERROR (MERROR_IM, 0);
1870 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1875 return (MPLIST_TAIL_P (valids));
1878 /* Load variable defitions from PLIST into IM_INFO->vars.
1880 PLIST is well-formed and has this form;
1881 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1883 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1885 The returned list has the same form, but for each element...
1887 (1) If DESCRIPTION and the rest are omitted, the element is not
1888 stored in the returned list.
1890 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1891 description in global_info->vars (if any). */
1894 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1896 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1897 ? global_info->vars : NULL);
1900 im_info->vars = tail = mplist ();
1901 MPLIST_DO (plist, MPLIST_NEXT (plist))
1905 if (MFAILP (MPLIST_PLIST_P (plist)))
1907 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1908 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1910 if (im_info == global_info)
1912 /* Loading a global variable. */
1913 p = MPLIST_NEXT (pl);
1914 if (MPLIST_TAIL_P (p))
1915 mplist_add (p, Msymbol, Mnil);
1918 if (! check_description (p))
1919 mplist_set (p, Msymbol, Mnil);
1920 p = MPLIST_NEXT (p);
1921 if (MFAILP (! MPLIST_TAIL_P (p)
1922 && check_variable_value (p, NULL)))
1923 mplist_set (p, Mt, NULL);
1926 else if (im_info->mdb)
1928 /* Loading a local variable. */
1929 MSymbol name = MPLIST_SYMBOL (pl);
1930 MPlist *global = NULL;
1933 && (p = mplist__assq (global_vars, name)))
1935 /* P ::= ((NAME DESC ...) ...) */
1936 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1937 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1938 global = MPLIST_NEXT (p); /* P ::= (VALUE ...) */
1941 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1942 if (! MPLIST_TAIL_P (p))
1944 if (! check_description (p))
1945 mplist_set (p, Msymbol, Mnil);
1946 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1947 if (MFAILP (! MPLIST_TAIL_P (p)))
1948 mplist_set (p, Mt, NULL);
1951 MPlist *valid_values = MPLIST_NEXT (p);
1953 if (! MPLIST_TAIL_P (valid_values)
1954 ? MFAILP (check_variable_value (p, NULL))
1955 : global && MFAILP (check_variable_value (p, global)))
1956 mplist_set (p, Mt, NULL);
1962 /* Loading a variable customization. */
1963 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1964 if (MFAILP (! MPLIST_TAIL_P (p)))
1966 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1967 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1968 || MPLIST_MTEXT_P (p)))
1971 tail = mplist_add (tail, Mplist, pl);
1976 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
1977 MPlist *config_vars)
1979 MPlist *global = NULL, *custom = NULL, *config = NULL;
1980 MSymbol name = MPLIST_SYMBOL (plist);
1982 MPlist *description = NULL, *value, *valids;
1986 global = mplist__assq (global_vars, name);
1988 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
1991 plist = MPLIST_NEXT (plist);
1992 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1993 description = plist;
1995 description = global;
1997 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
1999 if (MPLIST_TAIL_P (plist))
2001 /* Inherit from global (if any). */
2005 if (MPLIST_KEY (value) == Mt)
2007 valids = MPLIST_NEXT (global);
2008 status = Minherited;
2020 value = plist = MPLIST_NEXT (plist);
2021 valids = MPLIST_NEXT (value);
2022 if (MPLIST_KEY (value) == Mt)
2024 if (! MPLIST_TAIL_P (valids))
2027 valids = MPLIST_NEXT (global);
2031 if (config_vars && (config = mplist__assq (config_vars, name)))
2033 config = MPLIST_NEXT (MPLIST_PLIST (config));
2034 if (! MPLIST_TAIL_P (config))
2036 value = MPLIST_NEXT (config);
2037 if (MFAILP (check_variable_value (value, global ? global : plist)))
2039 status = Mconfigured;
2042 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2044 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2045 if (! MPLIST_TAIL_P (custom))
2047 value = MPLIST_NEXT (custom);
2048 if (MFAILP (check_variable_value (value, global ? global : plist)))
2050 status = Mcustomized;
2055 mplist_add (plist, Msymbol, name);
2057 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2059 mplist_add (plist, Msymbol, Mnil);
2060 mplist_add (plist, Msymbol, status);
2062 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2064 mplist_add (plist, Mt, NULL);
2065 if (valids && ! MPLIST_TAIL_P (valids))
2066 mplist__conc (plist, valids);
2070 /* Return a configured variable definition list based on
2071 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2072 get it from global_info->vars. */
2075 config_all_variables (MInputMethodInfo *im_info)
2077 MPlist *global_vars, *custom_vars, *config_vars;
2078 MInputMethodInfo *temp;
2079 MPlist *tail, *plist;
2081 M17N_OBJECT_UNREF (im_info->configured_vars);
2083 if (MPLIST_TAIL_P (im_info->vars)
2087 global_vars = im_info != global_info ? global_info->vars : NULL;
2088 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2089 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2091 im_info->configured_vars = tail = mplist ();
2092 MPLIST_DO (plist, im_info->vars)
2094 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2095 global_vars, custom_vars, config_vars);
2098 tail = mplist_add (tail, Mplist, pl);
2099 M17N_OBJECT_UNREF (pl);
2104 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2105 CONFIG contains configuration information of the input method. */
2108 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2112 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2114 load_commands (im_info, MPLIST_PLIST (pl));
2115 config_all_commands (im_info);
2116 pl = mplist_pop (pl);
2117 M17N_OBJECT_UNREF (pl);
2120 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2122 load_variables (im_info, MPLIST_PLIST (pl));
2123 config_all_variables (im_info);
2124 pl = mplist_pop (pl);
2125 M17N_OBJECT_UNREF (pl);
2128 MPLIST_DO (plist, plist)
2129 if (MPLIST_PLIST_P (plist))
2131 MPlist *elt = MPLIST_PLIST (plist);
2134 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2136 key = MPLIST_SYMBOL (elt);
2141 elt = MPLIST_NEXT (elt);
2142 if (MFAILP (MPLIST_MTEXT_P (elt)))
2144 im_info->title = MPLIST_MTEXT (elt);
2145 M17N_OBJECT_REF (im_info->title);
2147 else if (key == Mmap)
2149 pl = mplist__from_alist (MPLIST_NEXT (elt));
2152 if (! im_info->maps)
2156 mplist__conc (im_info->maps, pl);
2157 M17N_OBJECT_UNREF (pl);
2160 else if (key == Mmacro)
2162 if (! im_info->macros)
2163 im_info->macros = mplist ();
2164 MPLIST_DO (elt, MPLIST_NEXT (elt))
2166 if (MFAILP (MPLIST_PLIST_P (elt)))
2168 load_macros (im_info, MPLIST_PLIST (elt));
2171 else if (key == Mmodule)
2173 if (! im_info->externals)
2174 im_info->externals = mplist ();
2175 MPLIST_DO (elt, MPLIST_NEXT (elt))
2177 if (MFAILP (MPLIST_PLIST_P (elt)))
2179 load_external_module (im_info, MPLIST_PLIST (elt));
2182 else if (key == Mstate)
2184 MPLIST_DO (elt, MPLIST_NEXT (elt))
2188 if (MFAILP (MPLIST_PLIST_P (elt)))
2190 pl = MPLIST_PLIST (elt);
2191 if (! im_info->states)
2192 im_info->states = mplist ();
2193 state = load_state (im_info, MPLIST_PLIST (elt));
2196 mplist_put (im_info->states, state->name, state);
2199 else if (key == Minclude)
2201 /* elt ::= include (tag1 tag2 ...) key item ... */
2203 MInputMethodInfo *temp;
2205 elt = MPLIST_NEXT (elt);
2206 if (MFAILP (MPLIST_PLIST_P (elt)))
2208 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2211 elt = MPLIST_NEXT (elt);
2212 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2214 key = MPLIST_SYMBOL (elt);
2215 elt = MPLIST_NEXT (elt);
2218 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2220 if (! im_info->maps)
2221 im_info->maps = mplist ();
2222 MPLIST_DO (pl, temp->maps)
2224 p = MPLIST_VAL (pl);
2225 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2226 M17N_OBJECT_REF (p);
2229 else if (key == Mmacro)
2231 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2233 if (! im_info->macros)
2234 im_info->macros = mplist ();
2235 MPLIST_DO (pl, temp->macros)
2237 p = MPLIST_VAL (pl);
2238 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2239 M17N_OBJECT_REF (p);
2242 else if (key == Mstate)
2244 if (! temp->states || MPLIST_TAIL_P (temp->states))
2246 if (! im_info->states)
2247 im_info->states = mplist ();
2248 MPLIST_DO (pl, temp->states)
2250 MIMState *state = MPLIST_VAL (pl);
2252 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2253 M17N_OBJECT_REF (state);
2257 else if (key == Mdescription)
2259 if (im_info->description)
2261 elt = MPLIST_NEXT (elt);
2262 if (! check_description (elt))
2264 im_info->description = MPLIST_MTEXT (elt);
2265 M17N_OBJECT_REF (im_info->description);
2268 im_info->tick = time (NULL);
2273 static int take_action_list (MInputContext *ic, MPlist *action_list);
2274 static void preedit_commit (MInputContext *ic);
2277 shift_state (MInputContext *ic, MSymbol state_name)
2279 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2280 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2281 MIMState *orig_state = ic_info->state, *state;
2283 /* Find a state to shift to. If not found, shift to the initial
2285 if (state_name == Mt)
2287 if (! ic_info->prev_state)
2289 state = ic_info->prev_state;
2291 else if (state_name == Mnil)
2293 state = (MIMState *) MPLIST_VAL (im_info->states);
2297 state = (MIMState *) mplist_get (im_info->states, state_name);
2299 state = (MIMState *) MPLIST_VAL (im_info->states);
2302 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2304 /* Enter the new state. */
2305 ic_info->state = state;
2306 ic_info->map = state->map;
2307 ic_info->state_key_head = ic_info->key_head;
2308 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2310 /* We have shifted to the initial state. */
2311 preedit_commit (ic);
2312 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2313 ic_info->state_pos = ic->cursor_pos;
2314 if (state != orig_state)
2316 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2318 /* Shifted to the initial state. */
2319 ic_info->prev_state = NULL;
2320 M17N_OBJECT_UNREF (ic_info->vars_saved);
2321 ic_info->vars_saved = mplist_copy (ic_info->vars);
2324 ic_info->prev_state = orig_state;
2327 ic->status = state->title;
2329 ic->status = im_info->title;
2330 ic->status_changed = 1;
2331 if (ic_info->map == ic_info->state->map
2332 && ic_info->map->map_actions)
2334 MDEBUG_PRINT (" init-actions:");
2335 take_action_list (ic, ic_info->map->map_actions);
2340 /* Find a candidate group that contains a candidate number INDEX from
2341 PLIST. Set START_INDEX to the first candidate number of the group,
2342 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2343 candidate group number if they are non-NULL. If INDEX is -1, find
2344 the last candidate group. */
2347 find_candidates_group (MPlist *plist, int index,
2348 int *start_index, int *end_index, int *group_index)
2350 int i = 0, gidx = 0, len;
2352 MPLIST_DO (plist, plist)
2354 if (MPLIST_MTEXT_P (plist))
2355 len = mtext_nchars (MPLIST_MTEXT (plist));
2357 len = mplist_length (MPLIST_PLIST (plist));
2358 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2364 *end_index = i + len;
2366 *group_index = gidx;
2376 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2378 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2380 int nchars = mt ? mtext_nchars (mt) : 1;
2383 mtext_ins (ic->preedit, pos, mt);
2385 mtext_ins_char (ic->preedit, pos, c, 1);
2386 MPLIST_DO (markers, ic_info->markers)
2387 if (MPLIST_INTEGER (markers) > pos)
2388 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
2389 if (ic->cursor_pos >= pos)
2390 ic->cursor_pos += nchars;
2391 ic->preedit_changed = 1;
2396 preedit_delete (MInputContext *ic, int from, int to)
2398 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2401 mtext_del (ic->preedit, from, to);
2402 MPLIST_DO (markers, ic_info->markers)
2404 if (MPLIST_INTEGER (markers) > to)
2405 MPLIST_VAL (markers)
2406 = (void *) (MPLIST_INTEGER (markers) - (to - from));
2407 else if (MPLIST_INTEGER (markers) > from);
2408 MPLIST_VAL (markers) = (void *) from;
2410 if (ic->cursor_pos >= to)
2411 ic->cursor_pos -= to - from;
2412 else if (ic->cursor_pos > from)
2413 ic->cursor_pos = from;
2414 ic->preedit_changed = 1;
2418 preedit_commit (MInputContext *ic)
2420 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2421 int preedit_len = mtext_nchars (ic->preedit);
2423 if (preedit_len > 0)
2427 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2428 Mcandidate_list, NULL, 0);
2429 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2430 Mcandidate_index, NULL, 0);
2431 mtext_cat (ic->produced, ic->preedit);
2432 mtext_reset (ic->preedit);
2433 mtext_reset (ic_info->preedit_saved);
2434 MPLIST_DO (p, ic_info->markers)
2436 ic->cursor_pos = ic_info->state_pos = 0;
2437 ic->preedit_changed = 1;
2439 if (ic->candidate_list)
2441 M17N_OBJECT_UNREF (ic->candidate_list);
2442 ic->candidate_list = NULL;
2443 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2444 if (ic->candidate_show)
2446 ic->candidate_show = 0;
2447 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2453 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2455 int code = marker_code (sym);
2457 if (mt && (code == '[' || code == ']'))
2461 if (code == '[' && current > 0)
2463 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2467 else if (code == ']' && current < mtext_nchars (mt))
2469 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2475 return (code == '<' ? 0
2476 : code == '>' ? limit
2477 : code == '-' ? current - 1
2478 : code == '+' ? current + 1
2479 : code == '=' ? current
2480 : code - '0' > limit ? limit
2484 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2488 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2490 int from = mtext_property_start (prop);
2491 int to = mtext_property_end (prop);
2493 MPlist *candidate_list = mtext_property_value (prop);
2494 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2496 int ingroup_index = idx - start;
2499 preedit_delete (ic, from, to);
2500 if (MPLIST_MTEXT_P (group))
2502 mt = MPLIST_MTEXT (group);
2503 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
2511 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2512 i++, plist = MPLIST_NEXT (plist));
2513 mt = MPLIST_MTEXT (plist);
2514 preedit_insert (ic, from, mt, 0);
2515 to = from + mtext_nchars (mt);
2517 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2518 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2519 ic->cursor_pos = to;
2523 get_select_charset (MInputContextInfo * ic_info)
2525 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2528 if (! MPLIST_VAL (plist))
2530 sym = MPLIST_SYMBOL (plist);
2533 return MCHARSET (sym);
2537 adjust_candidates (MPlist *plist, MCharset *charset)
2541 /* plist ::= MTEXT ... | PLIST ... */
2542 plist = mplist_copy (plist);
2543 if (MPLIST_MTEXT_P (plist))
2546 while (! MPLIST_TAIL_P (pl))
2548 /* pl ::= MTEXT ... */
2549 MText *mt = MPLIST_MTEXT (pl);
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)
2560 mt = mtext_dup (mt);
2561 mplist_set (pl, Mtext, mt);
2562 M17N_OBJECT_UNREF (mt);
2565 mtext_del (mt, i, i + 1);
2568 if (mtext_len (mt) > 0)
2569 pl = MPLIST_NEXT (pl);
2573 M17N_OBJECT_UNREF (mt);
2577 else /* MPLIST_PLIST_P (plist) */
2580 while (! MPLIST_TAIL_P (pl))
2582 /* pl ::= (MTEXT ...) ... */
2583 MPlist *p = MPLIST_PLIST (pl);
2585 /* p ::= MTEXT ... */
2589 while (! MPLIST_TAIL_P (p0))
2591 MText *mt = MPLIST_MTEXT (p0);
2594 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2596 c = mtext_ref_char (mt, i);
2597 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2602 p0 = MPLIST_NEXT (p0);
2609 p = mplist_copy (p);
2610 mplist_set (pl, Mplist, p);
2611 M17N_OBJECT_UNREF (p);
2615 p0 = MPLIST_NEXT (p0);
2618 M17N_OBJECT_UNREF (mt);
2621 if (! MPLIST_TAIL_P (p))
2622 pl = MPLIST_NEXT (pl);
2626 M17N_OBJECT_UNREF (p);
2630 if (MPLIST_TAIL_P (plist))
2632 M17N_OBJECT_UNREF (plist);
2639 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2641 MCharset *charset = get_select_charset (ic_info);
2646 plist = resolve_variable (ic_info, Mcandidates_group_size);
2647 column = MPLIST_INTEGER (plist);
2649 plist = MPLIST_PLIST (args);
2651 plist = adjust_candidates (plist, charset);
2653 if (plist && column > 0)
2655 if (MPLIST_MTEXT_P (plist))
2657 MText *mt = MPLIST_MTEXT (plist);
2658 MPlist *next = MPLIST_NEXT (plist);
2660 if (MPLIST_TAIL_P (next))
2661 M17N_OBJECT_REF (mt);
2664 mt = mtext_dup (mt);
2665 while (! MPLIST_TAIL_P (next))
2667 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2668 next = MPLIST_NEXT (next);
2671 M17N_OBJECT_UNREF (plist);
2673 len = mtext_nchars (mt);
2675 mplist_add (plist, Mtext, mt);
2678 for (i = 0; i < len; i += column)
2680 int to = (i + column < len ? i + column : len);
2681 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2683 mplist_add (plist, Mtext, sub);
2684 M17N_OBJECT_UNREF (sub);
2687 M17N_OBJECT_UNREF (mt);
2689 else /* MPLIST_PLIST_P (plist) */
2691 MPlist *pl = MPLIST_PLIST (plist), *p;
2692 MPlist *next = MPLIST_NEXT (plist);
2695 if (MPLIST_TAIL_P (next))
2696 M17N_OBJECT_REF (pl);
2699 pl = mplist_copy (pl);
2700 while (! MPLIST_TAIL_P (next))
2702 p = mplist_copy (MPLIST_PLIST (next));
2703 pl = mplist__conc (pl, p);
2704 M17N_OBJECT_UNREF (p);
2705 next = MPLIST_NEXT (next);
2708 M17N_OBJECT_UNREF (plist);
2710 len = mplist_length (pl);
2712 mplist_add (plist, Mplist, pl);
2717 for (i = 0; i < len; i += column)
2720 mplist_add (plist, Mplist, p);
2721 M17N_OBJECT_UNREF (p);
2722 for (j = 0; j < column && i + j < len; j++)
2724 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
2725 p0 = MPLIST_NEXT (p0);
2729 M17N_OBJECT_UNREF (pl);
2738 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2740 MPlist *action = NULL;
2744 if (MPLIST_SYMBOL_P (action_list))
2746 MSymbol var = MPLIST_SYMBOL (action_list);
2749 MPLIST_DO (p, ic_info->vars)
2750 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2752 if (MPLIST_TAIL_P (p))
2754 action = MPLIST_NEXT (MPLIST_PLIST (p));
2755 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2758 if (MPLIST_PLIST_P (action_list))
2760 action = MPLIST_PLIST (action_list);
2761 if (MPLIST_SYMBOL_P (action))
2763 name = MPLIST_SYMBOL (action);
2764 args = MPLIST_NEXT (action);
2766 && MPLIST_PLIST_P (args))
2767 mplist_set (action, Msymbol, M_candidates);
2769 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2772 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2773 mplist_push (action, Msymbol, M_candidates);
2774 mplist_set (action_list, Mplist, action);
2775 M17N_OBJECT_UNREF (action);
2778 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2781 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2782 mplist_push (action, Msymbol, Minsert);
2783 mplist_set (action_list, Mplist, action);
2784 M17N_OBJECT_UNREF (action);
2789 /* Perform list of actions in ACTION_LIST for the current input
2790 context IC. If all actions are performed without error, return 0.
2791 Otherwise, return -1. */
2794 take_action_list (MInputContext *ic, MPlist *action_list)
2796 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2797 MPlist *candidate_list = ic->candidate_list;
2798 int candidate_index = ic->candidate_index;
2799 int candidate_show = ic->candidate_show;
2800 MTextProperty *prop;
2802 MPLIST_DO (action_list, action_list)
2804 MPlist *action = regularize_action (action_list, ic_info);
2810 name = MPLIST_SYMBOL (action);
2811 args = MPLIST_NEXT (action);
2813 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2814 if (name == Minsert)
2816 if (MPLIST_SYMBOL_P (args))
2818 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2819 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2822 if (MPLIST_MTEXT_P (args))
2823 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2824 else /* MPLIST_INTEGER_P (args)) */
2825 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2827 else if (name == M_candidates)
2829 MPlist *plist = get_candidate_list (ic_info, args);
2834 if (MPLIST_MTEXT_P (plist))
2836 preedit_insert (ic, ic->cursor_pos, NULL,
2837 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2842 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2844 preedit_insert (ic, ic->cursor_pos, mt, 0);
2845 len = mtext_nchars (mt);
2847 mtext_put_prop (ic->preedit,
2848 ic->cursor_pos - len, ic->cursor_pos,
2849 Mcandidate_list, plist);
2850 mtext_put_prop (ic->preedit,
2851 ic->cursor_pos - len, ic->cursor_pos,
2852 Mcandidate_index, (void *) 0);
2854 else if (name == Mselect)
2857 int code, idx, gindex;
2858 int pos = ic->cursor_pos;
2862 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2865 if (MPLIST_SYMBOL_P (args))
2867 code = marker_code (MPLIST_SYMBOL (args));
2873 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2874 group = find_candidates_group (mtext_property_value (prop), idx,
2875 &start, &end, &gindex);
2877 if (code != '[' && code != ']')
2881 ? new_index (NULL, ic->candidate_index - start,
2882 end - start - 1, MPLIST_SYMBOL (args),
2884 : MPLIST_INTEGER (args)));
2887 find_candidates_group (mtext_property_value (prop), -1,
2892 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2897 int ingroup_index = idx - start;
2900 group = mtext_property_value (prop);
2901 len = mplist_length (group);
2914 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2915 idx += (MPLIST_MTEXT_P (group)
2916 ? mtext_nchars (MPLIST_MTEXT (group))
2917 : mplist_length (MPLIST_PLIST (group)));
2918 len = (MPLIST_MTEXT_P (group)
2919 ? mtext_nchars (MPLIST_MTEXT (group))
2920 : mplist_length (MPLIST_PLIST (group)));
2921 if (ingroup_index >= len)
2922 ingroup_index = len - 1;
2923 idx += ingroup_index;
2925 update_candidate (ic, prop, idx);
2927 else if (name == Mshow)
2928 ic->candidate_show = 1;
2929 else if (name == Mhide)
2930 ic->candidate_show = 0;
2931 else if (name == Mdelete)
2933 int len = mtext_nchars (ic->preedit);
2937 if (MPLIST_SYMBOL_P (args)
2938 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
2940 delete_surrounding_text (ic, pos);
2944 to = (MPLIST_SYMBOL_P (args)
2945 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2947 : MPLIST_INTEGER (args));
2952 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
2953 if (to < ic->cursor_pos)
2954 preedit_delete (ic, to, ic->cursor_pos);
2955 else if (to > ic->cursor_pos)
2956 preedit_delete (ic, ic->cursor_pos, to);
2959 else if (name == Mmove)
2961 int len = mtext_nchars (ic->preedit);
2963 = (MPLIST_SYMBOL_P (args)
2964 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2966 : MPLIST_INTEGER (args));
2972 if (pos != ic->cursor_pos)
2974 ic->cursor_pos = pos;
2975 ic->preedit_changed = 1;
2978 else if (name == Mmark)
2980 int code = marker_code (MPLIST_SYMBOL (args));
2983 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
2984 (void *) ic->cursor_pos);
2986 else if (name == Mpushback)
2988 if (MPLIST_INTEGER_P (args))
2990 int num = MPLIST_INTEGER (args);
2993 ic_info->key_head -= num;
2995 ic_info->key_head = num;
2996 if (ic_info->key_head > ic_info->used)
2997 ic_info->key_head = ic_info->used;
2999 else if (MPLIST_MTEXT_P (args))
3001 MText *mt = MPLIST_MTEXT (args);
3002 int i, len = mtext_nchars (mt);
3005 ic_info->key_head--;
3006 for (i = 0; i < len; i++)
3008 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3009 if (ic_info->key_head + i < ic_info->used)
3010 ic_info->keys[ic_info->key_head + i] = key;
3012 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3017 MPlist *plist = MPLIST_PLIST (args), *pl;
3021 ic_info->key_head--;
3023 MPLIST_DO (pl, plist)
3025 key = MPLIST_SYMBOL (pl);
3026 if (ic_info->key_head < ic_info->used)
3027 ic_info->keys[ic_info->key_head + i] = key;
3029 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3034 else if (name == Mcall)
3036 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3037 MIMExternalFunc func = NULL;
3038 MSymbol module, func_name;
3039 MPlist *func_args, *val;
3042 module = MPLIST_SYMBOL (args);
3043 args = MPLIST_NEXT (args);
3044 func_name = MPLIST_SYMBOL (args);
3046 if (im_info->externals)
3048 MIMExternalModule *external
3049 = (MIMExternalModule *) mplist_get (im_info->externals,
3052 func = (MIMExternalFunc) mplist_get (external->func_list,
3057 func_args = mplist ();
3058 mplist_add (func_args, Mt, ic);
3059 MPLIST_DO (args, MPLIST_NEXT (args))
3063 if (MPLIST_KEY (args) == Msymbol
3064 && MPLIST_KEY (args) != Mnil
3065 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
3067 code = new_index (ic, ic->cursor_pos,
3068 mtext_nchars (ic->preedit),
3069 MPLIST_SYMBOL (args), ic->preedit);
3070 mplist_add (func_args, Minteger, (void *) code);
3073 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3075 val = (func) (func_args);
3076 M17N_OBJECT_UNREF (func_args);
3077 if (val && ! MPLIST_TAIL_P (val))
3078 ret = take_action_list (ic, val);
3079 M17N_OBJECT_UNREF (val);
3083 else if (name == Mshift)
3085 shift_state (ic, MPLIST_SYMBOL (args));
3087 else if (name == Mundo)
3089 int intarg = (MPLIST_TAIL_P (args)
3091 : integer_value (ic, args, NULL, 0));
3093 mtext_reset (ic->preedit);
3094 mtext_reset (ic_info->preedit_saved);
3095 mtext_reset (ic->produced);
3096 M17N_OBJECT_UNREF (ic_info->vars);
3097 ic_info->vars = mplist_copy (ic_info->vars_saved);
3098 ic->cursor_pos = ic_info->state_pos = 0;
3099 ic_info->state_key_head = ic_info->key_head = 0;
3101 shift_state (ic, Mnil);
3104 if (MPLIST_TAIL_P (args))
3109 ic_info->used += intarg;
3112 ic_info->used = intarg;
3115 else if (name == Mset || name == Madd || name == Msub
3116 || name == Mmul || name == Mdiv)
3118 MSymbol sym = MPLIST_SYMBOL (args);
3123 val1 = integer_value (ic, args, &value, 0);
3124 args = MPLIST_NEXT (args);
3125 val2 = resolve_expression (ic, args);
3127 val1 = val2, op = "=";
3128 else if (name == Madd)
3129 val1 += val2, op = "+=";
3130 else if (name == Msub)
3131 val1 -= val2, op = "-=";
3132 else if (name == Mmul)
3133 val1 *= val2, op = "*=";
3135 val1 /= val2, op = "/=";
3136 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3137 MSYMBOL_NAME (sym), op, val1, val1);
3139 mplist_set (value, Minteger, (void *) val1);
3141 else if (name == Mequal || name == Mless || name == Mgreater
3142 || name == Mless_equal || name == Mgreater_equal)
3145 MPlist *actions1, *actions2;
3148 val1 = resolve_expression (ic, args);
3149 args = MPLIST_NEXT (args);
3150 val2 = resolve_expression (ic, args);
3151 args = MPLIST_NEXT (args);
3152 actions1 = MPLIST_PLIST (args);
3153 args = MPLIST_NEXT (args);
3154 if (MPLIST_TAIL_P (args))
3157 actions2 = MPLIST_PLIST (args);
3158 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3159 if (name == Mequal ? val1 == val2
3160 : name == Mless ? val1 < val2
3161 : name == Mgreater ? val1 > val2
3162 : name == Mless_equal ? val1 <= val2
3165 MDEBUG_PRINT ("ok");
3166 ret = take_action_list (ic, actions1);
3170 MDEBUG_PRINT ("no");
3172 ret = take_action_list (ic, actions2);
3177 else if (name == Mcond)
3181 MPLIST_DO (args, args)
3186 if (! MPLIST_PLIST (args))
3188 cond = MPLIST_PLIST (args);
3189 if (resolve_expression (ic, cond) != 0)
3191 MDEBUG_PRINT1 ("(%dth)", idx);
3192 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3198 else if (name == Mcommit)
3200 preedit_commit (ic);
3202 else if (name == Munhandle)
3204 preedit_commit (ic);
3209 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3213 && (actions = mplist_get (im_info->macros, name)))
3215 if (take_action_list (ic, actions) < 0)
3221 if (ic->candidate_list)
3223 M17N_OBJECT_UNREF (ic->candidate_list);
3224 ic->candidate_list = NULL;
3226 if (ic->cursor_pos > 0
3227 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3230 ic->candidate_list = mtext_property_value (prop);
3231 M17N_OBJECT_REF (ic->candidate_list);
3233 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3235 ic->candidate_from = mtext_property_start (prop);
3236 ic->candidate_to = mtext_property_end (prop);
3239 if (candidate_list != ic->candidate_list)
3240 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3241 if (candidate_index != ic->candidate_index)
3242 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3243 if (candidate_show != ic->candidate_show)
3244 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3249 /* Handle the input key KEY in the current state and map specified in
3250 the input context IC. If KEY is handled correctly, return 0.
3251 Otherwise, return -1. */
3254 handle_key (MInputContext *ic)
3256 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3257 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3258 MIMMap *map = ic_info->map;
3259 MIMMap *submap = NULL;
3260 MSymbol key = ic_info->keys[ic_info->key_head];
3261 MSymbol alias = Mnil;
3264 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3265 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3269 submap = mplist_get (map->submaps, key);
3272 && (alias = msymbol_get (alias, M_key_alias))
3274 submap = mplist_get (map->submaps, alias);
3279 if (! alias || alias == key)
3280 MDEBUG_PRINT (" submap-found");
3282 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3283 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3284 ic->preedit_changed = 1;
3285 ic->cursor_pos = ic_info->state_pos;
3286 ic_info->key_head++;
3287 ic_info->map = map = submap;
3288 if (map->map_actions)
3290 MDEBUG_PRINT (" map-actions:");
3291 if (take_action_list (ic, map->map_actions) < 0)
3293 MDEBUG_PRINT ("\n");
3297 else if (map->submaps)
3299 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3301 MSymbol key = ic_info->keys[i];
3302 char *name = msymbol_name (key);
3304 if (! name[0] || ! name[1])
3305 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3309 /* If this is the terminal map or we have shifted to another
3310 state, perform branch actions (if any). */
3311 if (! map->submaps || map != ic_info->map)
3313 if (map->branch_actions)
3315 MDEBUG_PRINT (" branch-actions:");
3316 if (take_action_list (ic, map->branch_actions) < 0)
3318 MDEBUG_PRINT ("\n");
3322 /* If MAP is still not the root map, shift to the current
3324 if (ic_info->map != ic_info->state->map)
3325 shift_state (ic, ic_info->state->name);
3330 /* MAP can not handle KEY. */
3332 /* If MAP is the root map of the initial state, it means that
3333 the current input method can not handle KEY. */
3334 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3336 MDEBUG_PRINT (" unhandled\n");
3340 if (map != ic_info->state->map)
3342 /* If MAP is not the root map... */
3343 /* If MAP has branch actions, perform them. */
3344 if (map->branch_actions)
3346 MDEBUG_PRINT (" branch-actions:");
3347 if (take_action_list (ic, map->branch_actions) < 0)
3349 MDEBUG_PRINT ("\n");
3353 /* If MAP is still not the root map, shift to the current
3355 if (ic_info->map != ic_info->state->map)
3356 shift_state (ic, ic_info->state->name);
3360 /* MAP is the root map, perform branch actions (if any) or
3361 shift to the initial state. */
3362 if (map->branch_actions)
3364 MDEBUG_PRINT (" branch-actions:");
3365 if (take_action_list (ic, map->branch_actions) < 0)
3367 MDEBUG_PRINT ("\n");
3372 shift_state (ic, Mnil);
3375 MDEBUG_PRINT ("\n");
3379 /* Initialize IC->ic_info. */
3382 init_ic_info (MInputContext *ic)
3384 MInputMethodInfo *im_info = ic->im->info;
3385 MInputContextInfo *ic_info = ic->info;
3388 MLIST_INIT1 (ic_info, keys, 8);;
3390 ic_info->markers = mplist ();
3392 ic_info->vars = mplist ();
3393 if (im_info->configured_vars)
3394 MPLIST_DO (plist, im_info->configured_vars)
3396 MPlist *pl = MPLIST_PLIST (plist);
3397 MSymbol name = MPLIST_SYMBOL (pl);
3399 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3400 if (MPLIST_KEY (pl) != Mt)
3402 MPlist *p = mplist ();
3404 mplist_push (ic_info->vars, Mplist, p);
3405 M17N_OBJECT_UNREF (p);
3406 mplist_add (p, Msymbol, name);
3407 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3410 ic_info->vars_saved = mplist_copy (ic_info->vars);
3412 if (im_info->externals)
3414 MPlist *func_args = mplist (), *plist;
3416 mplist_add (func_args, Mt, ic);
3417 MPLIST_DO (plist, im_info->externals)
3419 MIMExternalModule *external = MPLIST_VAL (plist);
3420 MIMExternalFunc func
3421 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3426 M17N_OBJECT_UNREF (func_args);
3429 ic_info->preedit_saved = mtext ();
3430 ic_info->tick = im_info->tick;
3433 /* Finalize IC->ic_info. */
3436 fini_ic_info (MInputContext *ic)
3438 MInputMethodInfo *im_info = ic->im->info;
3439 MInputContextInfo *ic_info = ic->info;
3441 if (im_info->externals)
3443 MPlist *func_args = mplist (), *plist;
3445 mplist_add (func_args, Mt, ic);
3446 MPLIST_DO (plist, im_info->externals)
3448 MIMExternalModule *external = MPLIST_VAL (plist);
3449 MIMExternalFunc func
3450 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3455 M17N_OBJECT_UNREF (func_args);
3458 MLIST_FREE1 (ic_info, keys);
3459 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3460 M17N_OBJECT_UNREF (ic_info->markers);
3461 M17N_OBJECT_UNREF (ic_info->vars);
3462 M17N_OBJECT_UNREF (ic_info->vars_saved);
3463 M17N_OBJECT_UNREF (ic_info->preceding_text);
3464 M17N_OBJECT_UNREF (ic_info->following_text);
3466 memset (ic_info, 0, sizeof (MInputContextInfo));
3470 re_init_ic (MInputContext *ic, int reload)
3472 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3473 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3474 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3476 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3477 preedit_changed = mtext_nchars (ic->preedit) > 0;
3478 cursor_pos_changed = ic->cursor_pos > 0;
3479 candidates_changed = 0;
3480 if (ic->candidate_list)
3482 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3483 M17N_OBJECT_UNREF (ic->candidate_list);
3484 ic->candidate_list = NULL;
3486 if (ic->candidate_show)
3488 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3489 ic->candidate_show = 0;
3491 if (ic->candidate_index > 0)
3493 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3494 ic->candidate_index = 0;
3495 ic->candidate_from = ic->candidate_to = 0;
3497 if (mtext_nchars (ic->produced) > 0)
3498 mtext_reset (ic->produced);
3499 if (mtext_nchars (ic->preedit) > 0)
3500 mtext_reset (ic->preedit);
3502 M17N_OBJECT_UNREF (ic->plist);
3503 ic->plist = mplist ();
3507 reload_im_info (im_info);
3509 shift_state (ic, Mnil);
3510 ic->status_changed = status_changed;
3511 ic->preedit_changed = preedit_changed;
3512 ic->cursor_pos_changed = cursor_pos_changed;
3513 ic->candidates_changed = candidates_changed;
3517 reset_ic (MInputContext *ic, MSymbol ignore)
3519 MDEBUG_PRINT ("\n [IM] reset\n");
3524 open_im (MInputMethod *im)
3526 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3529 MERROR (MERROR_IM, -1);
3536 close_im (MInputMethod *im)
3542 create_ic (MInputContext *ic)
3544 MInputContextInfo *ic_info;
3546 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3549 shift_state (ic, Mnil);
3554 destroy_ic (MInputContext *ic)
3561 check_reload (MInputContext *ic, MSymbol key)
3563 MInputMethodInfo *im_info = ic->im->info;
3564 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3568 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3572 MPLIST_DO (plist, plist)
3574 MSymbol this_key, alias;
3576 if (MPLIST_MTEXT_P (plist))
3578 MText *mt = MPLIST_MTEXT (plist);
3579 int c = mtext_ref_char (mt, 0);
3583 this_key = one_char_symbol[c];
3587 MPlist *pl = MPLIST_PLIST (plist);
3589 this_key = MPLIST_SYMBOL (pl);
3593 && (alias = msymbol_get (alias, M_key_alias))
3594 && alias != this_key);
3598 if (MPLIST_TAIL_P (plist))
3601 MDEBUG_PRINT ("\n [IM] reload");
3607 /** Handle the input key KEY in the current state and map of IC->info.
3608 If KEY is handled but no text is produced, return 0, otherwise
3614 filter (MInputContext *ic, MSymbol key, void *arg)
3616 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3617 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3620 if (check_reload (ic, key))
3623 if (! ic_info->state)
3625 ic_info->key_unhandled = 1;
3628 mtext_reset (ic->produced);
3629 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3630 M17N_OBJECT_UNREF (ic_info->preceding_text);
3631 M17N_OBJECT_UNREF (ic_info->following_text);
3632 ic_info->preceding_text = ic_info->following_text = NULL;
3633 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3634 ic_info->key_unhandled = 0;
3637 if (handle_key (ic) < 0)
3639 /* KEY was not handled. Delete it from the current key sequence. */
3640 if (ic_info->used > 0)
3642 memmove (ic_info->keys, ic_info->keys + 1,
3643 sizeof (int) * (ic_info->used - 1));
3645 if (ic_info->state_key_head > 0)
3646 ic_info->state_key_head--;
3648 /* This forces returning 1. */
3649 ic_info->key_unhandled = 1;
3655 reset_ic (ic, Mnil);
3656 ic_info->key_unhandled = 1;
3659 /* Break the loop if all keys were handled. */
3660 } while (ic_info->key_head < ic_info->used);
3662 /* If the current map is the root of the initial state, we should
3663 produce any preedit text in ic->produced. */
3664 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3665 preedit_commit (ic);
3667 if (mtext_nchars (ic->produced) > 0)
3669 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3671 if (mdebug__flag & mdebug_mask)
3673 MDEBUG_PRINT (" (produced");
3674 for (i = 0; i < mtext_nchars (ic->produced); i++)
3675 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3680 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3681 Mlanguage, ic->im->language);
3682 if (ic_info->state_key_head > 0)
3684 memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head,
3685 sizeof (int) * (ic_info->used - ic_info->state_key_head));
3686 ic_info->used -= ic_info->state_key_head;
3687 ic_info->key_head -= ic_info->state_key_head;
3688 ic_info->state_key_head = 0;
3692 if (ic_info->key_unhandled)
3695 ic_info->key_head = ic_info->state_key_head = 0;
3698 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3702 /** Return 1 if the last event or key was not handled, otherwise
3705 There is no need of looking up because ic->produced should already
3706 contain the produced text (if any).
3711 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3713 mtext_cat (mt, ic->produced);
3714 mtext_reset (ic->produced);
3715 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3719 /* Input method command handler. */
3721 /* List of all (global and local) commands.
3722 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3723 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3724 Global commands are stored as (t (t COMMAND ...)) */
3727 /* Input method variable handler. */
3730 /* Support functions for mdebug_dump_im. */
3733 dump_im_map (MPlist *map_list, int indent)
3736 MSymbol key = MPLIST_KEY (map_list);
3737 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3739 prefix = (char *) alloca (indent + 1);
3740 memset (prefix, 32, indent);
3741 prefix[indent] = '\0';
3743 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3744 if (map->map_actions)
3745 mdebug_dump_plist (map->map_actions, indent + 2);
3748 MPLIST_DO (map_list, map->submaps)
3750 fprintf (stderr, "\n%s ", prefix);
3751 dump_im_map (map_list, indent + 2);
3754 if (map->branch_actions)
3756 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3757 mdebug_dump_plist (map->branch_actions, indent + 4);
3758 fprintf (stderr, ")");
3760 fprintf (stderr, ")");
3765 dump_im_state (MIMState *state, int indent)
3770 prefix = (char *) alloca (indent + 1);
3771 memset (prefix, 32, indent);
3772 prefix[indent] = '\0';
3774 fprintf (stderr, "(%s", msymbol_name (state->name));
3775 if (state->map->submaps)
3777 MPLIST_DO (map_list, state->map->submaps)
3779 fprintf (stderr, "\n%s ", prefix);
3780 dump_im_map (map_list, indent + 2);
3783 fprintf (stderr, ")");
3791 Minput_driver = msymbol ("input-driver");
3793 Minput_preedit_start = msymbol ("input-preedit-start");
3794 Minput_preedit_done = msymbol ("input-preedit-done");
3795 Minput_preedit_draw = msymbol ("input-preedit-draw");
3796 Minput_status_start = msymbol ("input-status-start");
3797 Minput_status_done = msymbol ("input-status-done");
3798 Minput_status_draw = msymbol ("input-status-draw");
3799 Minput_candidates_start = msymbol ("input-candidates-start");
3800 Minput_candidates_done = msymbol ("input-candidates-done");
3801 Minput_candidates_draw = msymbol ("input-candidates-draw");
3802 Minput_set_spot = msymbol ("input-set-spot");
3803 Minput_focus_move = msymbol ("input-focus-move");
3804 Minput_focus_in = msymbol ("input-focus-in");
3805 Minput_focus_out = msymbol ("input-focus-out");
3806 Minput_toggle = msymbol ("input-toggle");
3807 Minput_reset = msymbol ("input-reset");
3808 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3809 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3810 Mcustomized = msymbol ("customized");
3811 Mconfigured = msymbol ("configured");
3812 Minherited = msymbol ("inherited");
3814 minput_default_driver.open_im = open_im;
3815 minput_default_driver.close_im = close_im;
3816 minput_default_driver.create_ic = create_ic;
3817 minput_default_driver.destroy_ic = destroy_ic;
3818 minput_default_driver.filter = filter;
3819 minput_default_driver.lookup = lookup;
3820 minput_default_driver.callback_list = mplist ();
3821 mplist_put (minput_default_driver.callback_list, Minput_reset,
3823 minput_driver = &minput_default_driver;
3825 fully_initialized = 0;
3832 if (fully_initialized)
3834 free_im_list (im_info_list);
3836 free_im_list (im_custom_list);
3838 free_im_list (im_config_list);
3839 M17N_OBJECT_UNREF (load_im_info_keys);
3842 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3843 M17N_OBJECT_UNREF (minput_driver->callback_list);
3848 minput__callback (MInputContext *ic, MSymbol command)
3850 MInputCallbackFunc func;
3852 if (! ic->im->driver.callback_list)
3854 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3858 (func) (ic, command);
3863 minput__char_to_key (int c)
3865 if (c < 0 || c >= 0x100)
3868 return one_char_symbol[c];
3872 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3877 /*** @addtogroup m17nInputMethod */
3882 @name Variables: Predefined symbols for callback commands.
3884 These are the predefined symbols that are used as the @c COMMAND
3885 argument of callback functions of an input method driver (see
3886 #MInputDriver::callback_list).
3888 Most of them do not require extra argument nor return any value;
3889 exceptions are these:
3891 Minput_get_surrounding_text: When a callback function assigned for
3892 this command is called, the first element of #MInputContext::plist
3893 has key #Minteger and the value specifies which portion of the
3894 surrounding text should be retrieved. If the value is positive,
3895 it specifies the number of characters following the current cursor
3896 position. If the value is negative, the absolute value specifies
3897 the number of characters preceding the current cursor position.
3899 If the surrounding text is currently supported, the callback
3900 function must set the key of this element to #Mtext and the value
3901 to the retrieved M-text. The length of the M-text may be shorter
3902 than the requested number of characters, if the available text is
3903 not that long. The length can be zero in the worst case. Or, the
3904 length may be longer if an application thinks it is more efficient
3905 to return that length.
3907 If the surrounding text is not currently supported, the callback
3908 function should return without changing the first element of
3909 #MInputContext::plist.
3911 Minput_delete_surrounding_text: When a callback function assigned
3912 for this command is called, the first element of
3913 #MInputContext::plist has key #Minteger and the value specifies
3914 which portion of the surrounding text should be deleted in the
3915 same way as the case of Minput_get_surrounding_text. The callback
3916 function must delete the specified text. It should not alter
3917 #MInputContext::plist. */
3919 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3921 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3922 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3924 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
3926 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
3927 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
3928 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
3929 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
3930 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
3933 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
3934 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
3935 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
3936 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
3937 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
3939 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
3940 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѲ½¤µ¤»¤ë¤³¤È¤Ê¤¯ÊÖ¤µ¤Ê¤¯¤Æ
3943 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
3944 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
3945 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
3946 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
3947 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
3948 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
3952 MSymbol Minput_preedit_start;
3953 MSymbol Minput_preedit_done;
3954 MSymbol Minput_preedit_draw;
3955 MSymbol Minput_status_start;
3956 MSymbol Minput_status_done;
3957 MSymbol Minput_status_draw;
3958 MSymbol Minput_candidates_start;
3959 MSymbol Minput_candidates_done;
3960 MSymbol Minput_candidates_draw;
3961 MSymbol Minput_set_spot;
3962 MSymbol Minput_toggle;
3963 MSymbol Minput_reset;
3964 MSymbol Minput_get_surrounding_text;
3965 MSymbol Minput_delete_surrounding_text;
3971 @name Variables: Predefined symbols for special input events.
3973 These are the predefined symbols that are used as the @c KEY
3974 argument of minput_filter (). */
3976 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3978 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
3983 MSymbol Minput_focus_out;
3984 MSymbol Minput_focus_in;
3985 MSymbol Minput_focus_move;
3991 @name Variables: Predefined symbols used in input method information.
3993 These are the predefined symbols describing status of input method
3994 command and variable, and are used in a return value of
3995 minput_get_command () and minput_get_variable (). */
3997 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3999 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4000 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4004 MSymbol Mcustomized;
4005 MSymbol Mconfigured;
4011 @brief The default driver for internal input methods.
4013 The variable #minput_default_driver is the default driver for
4014 internal input methods.
4016 The member MInputDriver::open_im () searches the m17n database for
4017 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4018 $NAME\> and loads it.
4020 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4021 programmers responsibility to set it to a plist of proper callback
4022 functions. Otherwise, no feedback information (e.g. preedit text)
4023 can be shown to users.
4025 The macro M17N_INIT () sets the variable #minput_driver to the
4026 pointer to this driver so that all internal input methods use it.
4028 Therefore, unless @c minput_driver is set differently, the driver
4029 dependent arguments $ARG of the functions whose name begins with
4030 "minput_" are all ignored. */
4032 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4034 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4036 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4037 \< #Minput_method, $LANGUAGE, $NAME\>
4038 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4040 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4041 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4042 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4043 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4045 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4046 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4048 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4049 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4051 MInputDriver minput_default_driver;
4055 @brief The driver for internal input methods.
4057 The variable #minput_driver is a pointer to the input method
4058 driver that is used by internal input methods. The macro
4059 M17N_INIT () initializes it to a pointer to #minput_default_driver
4060 if <m17n<EM></EM>.h> is included. */
4062 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4064 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4065 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4066 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4067 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4069 MInputDriver *minput_driver;
4071 MSymbol Minput_driver;
4086 @brief Open an input method.
4088 The minput_open_im () function opens an input method whose
4089 language and name match $LANGUAGE and $NAME, and returns a pointer
4090 to the input method object newly allocated.
4092 This function at first decides a driver for the input method as
4095 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4096 #minput_driver is used.
4098 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4099 driver pointed to by the property value is used to open the input
4100 method. If $NAME has no such a property, @c NULL is returned.
4102 Then, the member MInputDriver::open_im () of the driver is
4105 $ARG is set in the member @c arg of the structure MInputMethod so
4106 that the driver can refer to it. */
4108 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4110 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4111 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4113 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4115 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4116 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4118 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4119 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4120 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4122 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4124 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4126 @latexonly \IPAlabel{minput_open} @endlatexonly
4131 minput_open_im (MSymbol language, MSymbol name, void *arg)
4134 MInputDriver *driver;
4138 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4139 msymbol_name (language), msymbol_name (name));
4141 driver = minput_driver;
4144 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4146 MERROR (MERROR_IM, NULL);
4149 MSTRUCT_CALLOC (im, MERROR_IM);
4150 im->language = language;
4153 im->driver = *driver;
4154 if ((*im->driver.open_im) (im) < 0)
4156 MDEBUG_PRINT (" failed\n");
4160 MDEBUG_PRINT (" ok\n");
4167 @brief Close an input method.
4169 The minput_close_im () function closes the input method $IM, which
4170 must have been created by minput_open_im (). */
4173 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4175 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4176 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4179 minput_close_im (MInputMethod *im)
4181 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4182 msymbol_name (im->name), msymbol_name (im->language));
4183 (*im->driver.close_im) (im);
4185 MDEBUG_PRINT (" done\n");
4191 @brief Create an input context.
4193 The minput_create_ic () function creates an input context object
4194 associated with input method $IM, and calls callback functions
4195 corresponding to #Minput_preedit_start, #Minput_status_start, and
4196 #Minput_status_draw in this order.
4199 If an input context is successfully created, minput_create_ic ()
4200 returns a pointer to it. Otherwise it returns @c NULL. */
4203 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4205 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4206 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4207 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4208 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4211 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4212 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4216 minput_create_ic (MInputMethod *im, void *arg)
4220 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4221 msymbol_name (im->name), msymbol_name (im->language));
4222 MSTRUCT_CALLOC (ic, MERROR_IM);
4225 ic->preedit = mtext ();
4226 ic->candidate_list = NULL;
4227 ic->produced = mtext ();
4228 ic->spot.x = ic->spot.y = 0;
4230 ic->plist = mplist ();
4231 if ((*im->driver.create_ic) (ic) < 0)
4233 MDEBUG_PRINT (" failed\n");
4234 M17N_OBJECT_UNREF (ic->preedit);
4235 M17N_OBJECT_UNREF (ic->produced);
4236 M17N_OBJECT_UNREF (ic->plist);
4241 if (im->driver.callback_list)
4243 minput__callback (ic, Minput_preedit_start);
4244 minput__callback (ic, Minput_status_start);
4245 minput__callback (ic, Minput_status_draw);
4248 MDEBUG_PRINT (" ok\n");
4255 @brief Destroy an input context.
4257 The minput_destroy_ic () function destroys the input context $IC,
4258 which must have been created by minput_create_ic (). It calls
4259 callback functions corresponding to #Minput_preedit_done,
4260 #Minput_status_done, and #Minput_candidates_done in this order. */
4263 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4265 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4266 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4267 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4268 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4269 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4273 minput_destroy_ic (MInputContext *ic)
4275 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4276 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4277 if (ic->im->driver.callback_list)
4279 minput__callback (ic, Minput_preedit_done);
4280 minput__callback (ic, Minput_status_done);
4281 minput__callback (ic, Minput_candidates_done);
4283 (*ic->im->driver.destroy_ic) (ic);
4284 M17N_OBJECT_UNREF (ic->preedit);
4285 M17N_OBJECT_UNREF (ic->produced);
4286 M17N_OBJECT_UNREF (ic->plist);
4287 MDEBUG_PRINT (" done\n");
4294 @brief Filter an input key.
4296 The minput_filter () function filters input key $KEY according to
4297 input context $IC, and calls callback functions corresponding to
4298 #Minput_preedit_draw, #Minput_status_draw, and
4299 #Minput_candidates_draw if the preedit text, the status, and the
4300 current candidate are changed respectively.
4302 To make the input method commit the current preedit text (if any)
4303 and shift to the initial state, call this function with #Mnil as
4306 To inform the input method about the focus-out event, call this
4307 function with #Minput_focus_out as $KEY.
4309 To inform the input method about the focus-in event, call this
4310 function with #Minput_focus_in as $KEY.
4312 To inform the input method about the focus-move event (i.e. input
4313 spot change within the same input context), call this function
4314 with #Minput_focus_move as $KEY.
4317 If $KEY is filtered out, this function returns 1. In that case,
4318 the caller should discard the key. Otherwise, it returns 0, and
4319 the caller should handle the key, for instance, by calling the
4320 function minput_lookup () with the same key. */
4323 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4325 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4326 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4327 #Minput_preedit_draw, #Minput_status_draw,
4328 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4331 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4332 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4333 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4334 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4336 @latexonly \IPAlabel{minput_filter} @endlatexonly
4340 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4347 ret = (*ic->im->driver.filter) (ic, key, arg);
4349 if (ic->im->driver.callback_list)
4351 if (ic->preedit_changed)
4352 minput__callback (ic, Minput_preedit_draw);
4353 if (ic->status_changed)
4354 minput__callback (ic, Minput_status_draw);
4355 if (ic->candidates_changed)
4356 minput__callback (ic, Minput_candidates_draw);
4365 @brief Look up a text produced in the input context.
4367 The minput_lookup () function looks up a text in the input context
4368 $IC. $KEY must be identical to the one that was used in the previous call of
4371 If a text was produced by the input method, it is concatenated
4374 This function calls #MInputDriver::lookup .
4377 If $KEY was correctly handled by the input method, this function
4378 returns 0. Otherwise, it returns -1, even though some text
4379 might be produced in $MT. */
4382 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4384 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4385 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4387 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4390 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4393 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4394 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4395 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4397 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4400 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4402 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4407 @brief Set the spot of the input context.
4409 The minput_set_spot () function sets the spot of input context $IC
4410 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4411 The semantics of these values depends on the input method driver.
4413 For instance, a driver designed to work in a CUI environment may
4414 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4415 $DESCENT . A driver designed to work in a window system may
4416 interpret $X and $Y as the pixel offsets relative to the origin of the
4417 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4418 descent pixels of the line at ($X . $Y ).
4420 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4422 $MT and $POS are the M-text and the character position at the spot.
4423 $MT may be @c NULL, in which case, the input method cannot get
4424 information about the text around the spot. */
4427 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4429 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4430 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4431 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4433 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4434 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4435 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4436 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4437 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4438 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4440 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4442 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4443 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4447 minput_set_spot (MInputContext *ic, int x, int y,
4448 int ascent, int descent, int fontsize,
4453 ic->spot.ascent = ascent;
4454 ic->spot.descent = descent;
4455 ic->spot.fontsize = fontsize;
4458 if (ic->im->driver.callback_list)
4459 minput__callback (ic, Minput_set_spot);
4464 @brief Toggle input method.
4466 The minput_toggle () function toggles the input method associated
4467 with input context $IC. */
4469 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4471 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4472 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4476 minput_toggle (MInputContext *ic)
4478 if (ic->im->driver.callback_list)
4479 minput__callback (ic, Minput_toggle);
4480 ic->active = ! ic->active;
4486 @brief Reset an input context.
4488 The minput_reset_ic () function resets input context $IC by
4489 calling a callback function corresponding to #Minput_reset. It
4490 resets the status of $IC to its initial one. As the
4491 current preedit text is deleted without commitment, if necessary,
4492 call minput_filter () with the arg @r key #Mnil to force the input
4493 method to commit the preedit in advance. */
4496 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4498 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4499 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4500 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4501 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4502 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4503 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4506 minput_reset_ic (MInputContext *ic)
4508 if (ic->im->driver.callback_list)
4509 minput__callback (ic, Minput_reset);
4515 @brief Get title and icon filename of an input method.
4517 The minput_get_title_icon () function returns a plist containing a
4518 title and icon filename (if any) of an input method specified by
4519 $LANGUAGE and $NAME.
4521 The first element of the plist has key #Mtext and the value is an
4522 M-text of the title for identifying the input method. The second
4523 element (if any) has key #Mtext and the value is an M-text of the
4524 icon image (absolute) filename for the same purpose.
4527 If there exists a specified input method and it defines an title,
4528 a plist is returned. Otherwise, NULL is returned. The caller
4529 must free the plist by m17n_object_unref (). */
4531 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4533 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4534 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4537 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4538 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4539 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¤ÎÀäÂÐ¥Õ¥¡¥¤¥ë¥Í¡¼¥à¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4542 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4543 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4544 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4547 minput_get_title_icon (MSymbol language, MSymbol name)
4549 MInputMethodInfo *im_info;
4556 im_info = get_im_info (language, name, Mnil, Mtitle);
4557 if (! im_info || !im_info->title)
4559 mt = mtext_get_prop (im_info->title, 0, Mtext);
4561 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4564 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4567 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4568 (char *) MSYMBOL_NAME (name));
4569 file = mdatabase__find_file (buf);
4570 if (! file && language == Mt)
4572 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4573 file = mdatabase__find_file (buf);
4578 mplist_add (plist, Mtext, im_info->title);
4581 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4583 mplist_add (plist, Mtext, mt);
4584 M17N_OBJECT_UNREF (mt);
4592 @brief Get description text of an input method.
4594 The minput_get_description () function returns an M-text that
4595 describes the input method specified by $LANGUAGE and $NAME.
4598 If the specified input method has a description text, a pointer to
4599 #MText is returned. The caller has to free it by m17n_object_unref ().
4600 If the input method does not have a description text, @c NULL is
4603 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4605 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4606 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4608 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4609 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4610 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4611 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4614 minput_get_description (MSymbol language, MSymbol name)
4616 MInputMethodInfo *im_info;
4624 extra = language, language = Mt;
4626 im_info = get_im_info (language, name, extra, Mdescription);
4627 if (! im_info || ! im_info->description)
4629 M17N_OBJECT_REF (im_info->description);
4630 return im_info->description;
4636 @brief Get information about input method command(s).
4638 The minput_get_command () function returns information about
4639 the command $COMMAND of the input method specified by $LANGUAGE and
4640 $NAME. An input method command is a pseudo key event to which one
4641 or more actual input key sequences are assigned.
4643 There are two kinds of commands, global and local. A global
4644 command has a global definition, and the description and the key
4645 assignment may be inherited by a local command. Each input method
4646 defines a local command which has a local key assignment. It may
4647 also declare a local command that inherits the definition of a
4648 global command of the same name.
4650 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4651 information about a global command. Otherwise information about a
4652 local command is returned.
4654 If $COMMAND is #Mnil, information about all commands is returned.
4656 The return value is a @e well-formed plist (#m17nPlist) of this
4659 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4661 @c NAME is a symbol representing the command name.
4663 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4664 command has no description.
4666 @c STATUS is a symbol representing how the key assignment is decided.
4667 The value is #Mnil (the default key assignment), #Mcustomized (the
4668 key assignment is customized by per-user configuration file), or
4669 #Mconfigured (the key assignment is set by the call of
4670 minput_config_command ()). For a local command only, it may also
4671 be #Minherited (the key assignment is inherited from the
4672 corresponding global command).
4674 @c KEYSEQ is a plist of one or more symbols representing a key
4675 sequence assigned to the command. If there's no KEYSEQ, the
4676 command is currently disabled (i.e. no key sequence can trigger
4677 actions of the command).
4679 If $COMMAND is not #Mnil, the first element of the returned plist
4680 contains the information about $COMMAND.
4684 If the requested information was found, a pointer to a non-empty
4685 plist is returned. As the plist is kept in the library, the
4686 caller must not modify nor free it.
4688 Otherwise (the specified input method or the specified command
4689 does not exist), @c NULL is returned. */
4691 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4693 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4694 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4695 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4696 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4698 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4699 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4700 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4701 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4702 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4704 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4705 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4708 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4710 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4713 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4715 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4717 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4720 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4721 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4722 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4723 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4724 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4725 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4727 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4728 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4729 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4730 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4732 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4733 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4737 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4738 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4741 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4746 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4748 /* Return a description of the command COMMAND of the input method
4749 specified by LANGUAGE and NAME. */
4750 MPlist *cmd = minput_get_command (langauge, name, command);
4755 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4756 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4757 return (mplist_key (plist) == Mtext
4758 ? (MText *) mplist_value (plist)
4764 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4766 MInputMethodInfo *im_info;
4770 im_info = get_im_info (language, name, Mnil, Mcommand);
4772 || ! im_info->configured_cmds
4773 || MPLIST_TAIL_P (im_info->configured_cmds))
4775 if (command == Mnil)
4776 return im_info->configured_cmds;
4777 return mplist__assq (im_info->configured_cmds, command);
4783 @brief Configure the key sequence of an input method command.
4785 The minput_config_command () function assigns a list of key
4786 sequences $KEYSEQLIST to the command $COMMAND of the input method
4787 specified by $LANGUAGE and $NAME.
4789 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4790 sequences, and each key sequence must be a plist of symbols.
4792 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4794 If $KEYSEQLIST is NULL, the configuration of the command for the
4795 input method is canceled, and the default key sequences become
4796 effective. In such case, if $COMMAND is #Mnil, configurations for
4797 all commands of the input method are canceled.
4799 If $NAME is #Mnil, this function configures the key assignment of a
4800 global command, not that of a specific input method.
4802 The configuration takes effect for input methods opened or
4803 re-opened later in the current session. In order to make the
4804 configuration take effect for the future session, it must be saved
4805 in a per-user configuration file by the function
4806 minput_save_config ().
4810 If the operation was successful, this function returns 0,
4811 otherwise returns -1. The operation fails in these cases:
4813 <li>$KEYSEQLIST is not in a valid form.
4814 <li>$COMMAND is not available for the input method.
4815 <li>$LANGUAGE and $NAME do not specify an existing input method.
4819 minput_get_commands (), minput_save_config ().
4822 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4824 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4825 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4826 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4828 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4829 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4831 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4833 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4834 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4835 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4838 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4839 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4841 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4842 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4843 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4844 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4848 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4850 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4851 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4852 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4856 minput_get_commands (), minput_save_config ().
4860 /* Add "C-x u" to the "start" command of Unicode input method. */
4862 MSymbol start_command = msymbol ("start");
4863 MSymbol unicode = msymbol ("unicode");
4864 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4866 /* At first get the current key-sequence assignment. */
4867 cmd = mplist_get_command (Mt, unicode, start_command);
4870 /* The input method does not have the command "start". Here
4871 should come some error handling code. */
4873 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4874 the part (KEY-SEQUENCE ...). */
4875 plist = mplist_next (mplist_next (mplist_value (cmd)));
4876 /* Copy it because we should not modify it directly. */
4877 key_seq_list = mplist_copy (plist);
4878 m17n_object_unref (cmds);
4880 key_seq = mplist ();
4881 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4882 mplist_add (key_seq, Msymbol, msymbol ("u"));
4883 mplist_add (key_seq_list, Mplist, key_seq);
4884 m17n_object_unref (key_seq);
4886 minput_config_command (Mt, unicode, start_command, key_seq_list);
4887 m17n_object_unref (key_seq_list);
4892 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4895 MInputMethodInfo *im_info, *config;
4902 if (command == Mnil)
4903 MERROR (MERROR_IM, -1);
4904 MPLIST_DO (plist, keyseqlist)
4905 if (! MPLIST_PLIST_P (plist)
4906 || ! check_command_keyseq (plist))
4907 MERROR (MERROR_IM, -1);
4910 im_info = get_im_info (language, name, Mnil, Mcommand);
4912 MERROR (MERROR_IM, -1);
4915 || ! mplist__assq (im_info->cmds, command)))
4916 MERROR (MERROR_IM, -1);
4918 config = get_config_info (im_info);
4921 if (! im_config_list)
4922 im_config_list = mplist ();
4923 config = new_im_info (NULL, language, name, Mnil, im_config_list);
4924 config->cmds = mplist ();
4925 config->vars = mplist ();
4928 if (command == Mnil)
4930 MInputMethodInfo *custom = get_custom_info (im_info);
4932 mplist_set (config->cmds, Mnil, NULL);
4933 if (custom && custom->cmds)
4935 MPLIST_DO (plist, custom->cmds)
4937 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
4939 mplist_add (plist, Msymbol, command);
4940 mplist_push (config->cmds, Mplist, plist);
4941 M17N_OBJECT_UNREF (plist);
4947 plist = mplist__assq (config->cmds, command);
4950 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
4951 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
4952 if (! MPLIST_TAIL_P (plist))
4953 mplist_set (plist, Mnil, NULL); /* () */
4958 mplist_add (config->cmds, Mplist, plist);
4959 M17N_OBJECT_UNREF (plist);
4960 plist = mplist_add (plist, Msymbol, command);
4961 plist = MPLIST_NEXT (plist);
4967 plist = mplist_add (plist, Msymbol, Mnil);
4968 MPLIST_DO (keyseqlist, keyseqlist)
4970 pl = mplist_copy (MPLIST_VAL (keyseqlist));
4971 plist = mplist_add (plist, Mplist, pl);
4972 M17N_OBJECT_UNREF (pl);
4976 config_all_commands (im_info);
4977 im_info->tick = time (NULL);
4984 @brief Get information about input method variable(s).
4986 The minput_get_variable () function returns information about
4987 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
4988 An input method variable controls behavior of an input method.
4990 There are two kinds of variables, global and local. A global
4991 variable has a global definition, and the description and the value
4992 may be inherited by a local variable. Each input method defines a
4993 local variable which has local value. It may also declare a
4994 local variable that inherits definition of a global variable of
4997 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
4998 variable is returned. Otherwise information about a local variable
5001 If $VARIABLE is #Mnil, information about all variables is
5004 The return value is a @e well-formed plist (#m17nPlist) of this
5007 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5009 @c NAME is a symbol representing the variable name.
5011 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5012 variable has no description.
5014 @c STATUS is a symbol representing how the value is decided. The
5015 value is #Mnil (the default value), #Mcustomized (the value is
5016 customized by per-user configuration file), or #Mconfigured (the
5017 value is set by the call of minput_config_variable ()). For a
5018 local variable only, it may also be #Minherited (the value is
5019 inherited from the corresponding global variable).
5021 @c VALUE is the initial value of the variable. If the key of this
5022 element is #Mt, the variable has no initial value. Otherwise, the
5023 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5026 @c VALID-VALUEs (if any) specify which values the variable can have.
5027 They have the same type (i.e. having the same key) as @c VALUE except
5028 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5029 may be a plist of two integers specifying the range of possible
5032 If there no @c VALID-VALUE, the variable can have any value as long
5033 as the type is the same as @c VALUE.
5035 If $VARIABLE is not #Mnil, the first element of the returned plist
5036 contains the information about $VARIABLE.
5040 If the requested information was found, a pointer to a non-empty
5041 plist is returned. As the plist is kept in the library, the
5042 caller must not modify nor free it.
5044 Otherwise (the specified input method or the specified variable
5045 does not exist), @c NULL is returned. */
5047 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5049 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5050 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5051 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5053 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5054 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5055 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5056 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5059 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5060 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5062 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5064 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5066 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5069 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5071 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5074 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5075 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5076 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5077 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5078 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5079 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5081 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5082 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5083 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5085 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5086 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5087 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5088 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5090 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5093 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5094 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5098 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5099 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5102 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5106 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5108 MInputMethodInfo *im_info;
5112 im_info = get_im_info (language, name, Mnil, Mvariable);
5113 if (! im_info || ! im_info->configured_vars)
5115 if (variable == Mnil)
5116 return im_info->configured_vars;
5117 return mplist__assq (im_info->configured_vars, variable);
5123 @brief Configure the value of an input method variable.
5125 The minput_config_variable () function assigns $VALUE to the
5126 variable $VARIABLE of the input method specified by $LANGUAGE and
5129 If $VALUE is not NULL, it must be a plist of one element whose key
5130 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5133 If $VALUE is NULL, a configuration for the variable for the input
5134 method is canceled, and the variable is initialized to the default
5135 value. In that case, if $VARIABLE is #Mnil, configurations for
5136 all variables of the input method are canceled.
5138 If $NAME is #Mnil, this function configure the value of global
5139 variable, not that of a specific input method.
5141 The configuration takes effect for input methods opened or
5142 re-opened later in the current session. To make the configuration
5143 take effect for the future session, it must be saved in a per-user
5144 configuration file by the function minput_save_config ().
5148 If the operation was successful, this function returns 0,
5149 otherwise returns -1. The operation fails in these cases:
5151 <li>$VALUE is not in a valid form, the type does not match the
5152 definition, or the value is our of range.
5153 <li>$VARIABLE is not available for the input method.
5154 <li>$LANGUAGE and $NAME do not specify an existing input method.
5158 minput_get_variable (), minput_save_config (). */
5160 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5162 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5163 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5165 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5166 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5168 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5169 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5170 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5172 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5173 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5175 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5176 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5177 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5178 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5182 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5184 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5185 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5186 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5190 minput_get_commands (), minput_save_config ().
5193 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5196 MInputMethodInfo *im_info, *config;
5201 im_info = get_im_info (language, name, Mnil, Mvariable);
5203 MERROR (MERROR_IM, -1);
5204 if (variable == Mnil)
5207 MERROR (MERROR_IM, -1);
5209 else if (! im_info->vars
5210 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5211 MERROR (MERROR_IM, -1);
5213 if (variable != Mnil && value)
5215 plist = MPLIST_PLIST (plist);
5216 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5217 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5218 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5219 if (MPLIST_KEY (plist) != Mt
5220 && ! check_variable_value (value, plist))
5221 MERROR (MERROR_IM, -1);
5224 config = get_config_info (im_info);
5227 if (! im_config_list)
5228 im_config_list = mplist ();
5229 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5230 config->cmds = mplist ();
5231 config->vars = mplist ();
5234 if (variable == Mnil)
5236 MInputMethodInfo *custom = get_custom_info (im_info);
5238 mplist_set (config->vars, Mnil, NULL);
5239 if (custom && custom->cmds)
5241 MPLIST_DO (plist, custom->vars)
5243 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5245 mplist_add (plist, Msymbol, variable);
5246 mplist_push (config->vars, Mplist, plist);
5247 M17N_OBJECT_UNREF (plist);
5253 plist = mplist__assq (config->vars, variable);
5256 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5257 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5258 if (! MPLIST_TAIL_P (plist))
5259 mplist_set (plist, Mnil ,NULL); /* () */
5264 mplist_add (config->vars, Mplist, plist);
5265 M17N_OBJECT_UNREF (plist);
5266 plist = mplist_add (plist, Msymbol, variable);
5267 plist = MPLIST_NEXT (plist);
5271 plist = mplist_add (plist, Msymbol, Mnil);
5272 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5275 config_all_variables (im_info);
5276 im_info->tick = time (NULL);
5283 @brief Get the name of per-user configuration file.
5285 The minput_config_file () function returns the absolute path name
5286 of per-user configuration file into which minput_save_config ()
5287 save configurations. It is usually @c "config.mic" under the
5288 directory @c ".m17n.d" of user's home directory. It is not assured
5289 that the file of the returned name exists nor is
5290 readable/writable. If minput_save_config () fails and returns -1,
5291 an application program might check the file, make it
5292 writable (if possible), and try minput_save_config () again.
5296 This function returns a string. As the string is kept in the
5297 library, the caller must not modify nor free it.
5300 minput_save_config ()
5303 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5305 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5306 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5307 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5308 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5309 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5310 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5311 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5316 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5317 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5320 minput_save_config ()
5324 minput_config_file ()
5328 return mdatabase__file (im_custom_mdb);
5334 @brief Save configurations in per-user configuration file.
5336 The minput_save_config () function saves the configurations done
5337 so far in the current session into the per-user configuration
5342 If the operation was successful, 1 is returned. If the per-user
5343 configuration file is currently locked, 0 is returned. In that
5344 case, the caller may wait for a while and try again. If the
5345 configuration file is not writable, -1 is returned. In that case,
5346 the caller may check the name of the file by calling
5347 minput_config_file (), make it writable if possible, and try
5351 minput_config_file () */
5353 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5355 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5356 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5360 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5361 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5362 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5363 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5367 minput_config_file () */
5370 minput_save_config (void)
5372 MPlist *data, *tail, *plist, *p, *elt;
5376 ret = mdatabase__lock (im_custom_mdb);
5379 if (! im_config_list)
5381 update_custom_info ();
5382 if (! im_custom_list)
5383 im_custom_list = mplist ();
5384 data = tail = mplist ();
5386 MPLIST_DO (plist, im_config_list)
5388 MPlist *pl = MPLIST_PLIST (plist);
5389 MSymbol language, name, extra, command, variable;
5390 MInputMethodInfo *custom, *config;
5392 language = MPLIST_SYMBOL (pl);
5393 pl = MPLIST_NEXT (pl);
5394 name = MPLIST_SYMBOL (pl);
5395 pl = MPLIST_NEXT (pl);
5396 extra = MPLIST_SYMBOL (pl);
5397 pl = MPLIST_NEXT (pl);
5398 config = MPLIST_VAL (pl);
5399 custom = get_custom_info (config);
5401 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5403 MPLIST_DO (pl, config->cmds)
5405 elt = MPLIST_PLIST (pl);
5406 command = MPLIST_SYMBOL (elt);
5408 p = mplist__assq (custom->cmds, command);
5410 custom->cmds = mplist (), p = NULL;
5411 elt = MPLIST_NEXT (elt);
5412 if (MPLIST_TAIL_P (elt))
5415 mplist__pop_unref (p);
5419 elt = MPLIST_NEXT (elt);
5422 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5423 mplist_set (p, Mnil, NULL);
5424 mplist__conc (p, elt);
5428 p = MPLIST_PLIST (pl);
5429 mplist_add (custom->cmds, Mplist, p);
5434 MPLIST_DO (pl, config->vars)
5436 elt = MPLIST_PLIST (pl);
5437 variable = MPLIST_SYMBOL (elt);
5439 p = mplist__assq (custom->vars, variable);
5441 custom->vars = mplist (), p = NULL;
5442 elt = MPLIST_NEXT (elt);
5443 if (MPLIST_TAIL_P (elt))
5446 mplist__pop_unref (p);
5450 elt = MPLIST_NEXT (elt);
5453 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5454 mplist_set (p, Mnil, NULL);
5455 mplist__conc (p, elt);
5459 p = MPLIST_PLIST (pl);
5460 mplist_add (custom->vars, Mplist, p);
5465 M17N_OBJECT_UNREF (im_config_list);
5467 MPLIST_DO (plist, im_custom_list)
5469 MPlist *pl = MPLIST_PLIST (plist);
5470 MSymbol language, name, extra;
5471 MInputMethodInfo *custom, *im_info;
5473 language = MPLIST_SYMBOL (pl);
5474 pl = MPLIST_NEXT (pl);
5475 name = MPLIST_SYMBOL (pl);
5476 pl = MPLIST_NEXT (pl);
5477 extra = MPLIST_SYMBOL (pl);
5478 pl = MPLIST_NEXT (pl);
5479 custom = MPLIST_VAL (pl);
5480 im_info = lookup_im_info (im_info_list, language, name, extra);
5484 config_all_commands (im_info);
5486 config_all_variables (im_info);
5490 tail = mplist_add (tail, Mplist, elt);
5491 M17N_OBJECT_UNREF (elt);
5493 elt = mplist_add (elt, Mplist, pl);
5494 M17N_OBJECT_UNREF (pl);
5495 pl = mplist_add (pl, Msymbol, Minput_method);
5496 pl = mplist_add (pl, Msymbol, language);
5497 pl = mplist_add (pl, Msymbol, name);
5499 pl = mplist_add (pl, Msymbol, extra);
5500 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5503 elt = mplist_add (elt, Mplist, pl);
5504 M17N_OBJECT_UNREF (pl);
5505 pl = mplist_add (pl, Msymbol, Mcommand);
5506 MPLIST_DO (p, custom->cmds)
5507 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5509 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5512 elt = mplist_add (elt, Mplist, pl);
5513 M17N_OBJECT_UNREF (pl);
5514 pl = mplist_add (pl, Msymbol, Mvariable);
5515 MPLIST_DO (p, custom->vars)
5516 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5520 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5521 ret = mdatabase__save (im_custom_mdb, data);
5522 mdatabase__unlock (im_custom_mdb);
5523 M17N_OBJECT_UNREF (data);
5524 return (ret < 0 ? -1 : 1);
5531 @name Obsolete functions
5534 @name Obsolete ¤Ê´Ø¿ô
5540 @brief Get a list of variables of an input method (obsolete).
5542 This function is obsolete. Use minput_get_variable () instead.
5544 The minput_get_variables () function returns a plist (#MPlist) of
5545 variables used to control the behavior of the input method
5546 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5547 (#m17nPlist) of the following format:
5550 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5551 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5555 @c VARNAME is a symbol representing the variable name.
5557 @c DOC-MTEXT is an M-text describing the variable.
5559 @c DEFAULT-VALUE is the default value of the variable. It is a
5560 symbol, integer, or M-text.
5562 @c VALUEs (if any) specifies the possible values of the variable.
5563 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5564 @c TO), where @c FROM and @c TO specifies a range of possible
5567 For instance, suppose an input method has the variables:
5569 @li name:intvar, description:"value is an integer",
5570 initial value:0, value-range:0..3,10,20
5572 @li name:symvar, description:"value is a symbol",
5573 initial value:nil, value-range:a, b, c, nil
5575 @li name:txtvar, description:"value is an M-text",
5576 initial value:empty text, no value-range (i.e. any text)
5578 Then, the returned plist is as follows.
5581 (intvar ("value is an integer" 0 (0 3) 10 20)
5582 symvar ("value is a symbol" nil a b c nil)
5583 txtvar ("value is an M-text" ""))
5587 If the input method uses any variables, a pointer to #MPlist is
5588 returned. As the plist is kept in the library, the caller must not
5589 modify nor free it. If the input method does not use any
5590 variable, @c NULL is returned. */
5592 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5594 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5595 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5596 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5600 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5601 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5605 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5607 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5609 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5612 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5613 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5614 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5616 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5618 @li name:intvar, ÀâÌÀ:"value is an integer",
5619 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5621 @li name:symvar, ÀâÌÀ:"value is a symbol",
5622 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5624 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5625 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5627 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5630 (intvar ("value is an integer" 0 (0 3) 10 20)
5631 symvar ("value is a symbol" nil a b c nil)
5632 txtvar ("value is an M-text" ""))
5636 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5637 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5638 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5641 minput_get_variables (MSymbol language, MSymbol name)
5643 MInputMethodInfo *im_info;
5648 im_info = get_im_info (language, name, Mnil, Mvariable);
5649 if (! im_info || ! im_info->configured_vars)
5652 M17N_OBJECT_UNREF (im_info->bc_vars);
5653 im_info->bc_vars = mplist ();
5654 MPLIST_DO (vars, im_info->configured_vars)
5656 MPlist *plist = MPLIST_PLIST (vars);
5657 MPlist *elt = mplist ();
5659 mplist_push (im_info->bc_vars, Mplist, elt);
5660 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5661 elt = MPLIST_NEXT (elt);
5662 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5663 M17N_OBJECT_UNREF (elt);
5665 return im_info->bc_vars;
5671 @brief Set the initial value of an input method variable.
5673 The minput_set_variable () function sets the initial value of
5674 input method variable $VARIABLE to $VALUE for the input method
5675 specified by $LANGUAGE and $NAME.
5677 By default, the initial value is 0.
5679 This setting gets effective in a newly opened input method.
5682 If the operation was successful, 0 is returned. Otherwise -1 is
5683 returned, and #merror_code is set to #MERROR_IM. */
5685 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5687 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5688 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5689 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5691 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5693 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5696 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5697 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5700 minput_set_variable (MSymbol language, MSymbol name,
5701 MSymbol variable, void *value)
5704 MInputMethodInfo *im_info;
5709 if (variable == Mnil)
5710 MERROR (MERROR_IM, -1);
5711 plist = minput_get_variable (language, name, variable);
5712 plist = MPLIST_PLIST (plist);
5713 plist = MPLIST_NEXT (plist);
5715 mplist_add (pl, MPLIST_KEY (plist), value);
5716 ret = minput_config_variable (language, name, variable, pl);
5717 M17N_OBJECT_UNREF (pl);
5720 im_info = get_im_info (language, name, Mnil, Mvariable);
5729 @brief Get information about input method commands.
5731 The minput_get_commands () function returns information about
5732 input method commands of the input method specified by $LANGUAGE
5733 and $NAME. An input method command is a pseudo key event to which
5734 one or more actual input key sequences are assigned.
5736 There are two kinds of commands, global and local. Global
5737 commands are used by multiple input methods for the same purpose,
5738 and have global key assignments. Local commands are used only by
5739 a specific input method, and have only local key assignments.
5741 Each input method may locally change key assignments for global
5742 commands. The global key assignment for a global command is
5743 effective only when the current input method does not have local
5744 key assignments for that command.
5746 If $NAME is #Mnil, information about global commands is returned.
5747 In this case $LANGUAGE is ignored.
5749 If $NAME is not #Mnil, information about those commands that have
5750 local key assignments in the input method specified by $LANGUAGE
5751 and $NAME is returned.
5754 If no input method commands are found, this function returns @c NULL.
5756 Otherwise, a pointer to a plist is returned. The key of each
5757 element in the plist is a symbol representing a command, and the
5758 value is a plist of the form COMMAND-INFO described below.
5760 The first element of COMMAND-INFO has the key #Mtext, and the
5761 value is an M-text describing the command.
5763 If there are no more elements, that means no key sequences are
5764 assigned to the command. Otherwise, each of the remaining
5765 elements has the key #Mplist, and the value is a plist whose keys are
5766 #Msymbol and values are symbols representing input keys, which are
5767 currently assigned to the command.
5769 As the returned plist is kept in the library, the caller must not
5770 modify nor free it. */
5772 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5774 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5775 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5776 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5777 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5779 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5780 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5781 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5782 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5784 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5785 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5786 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5789 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5790 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5792 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5793 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5797 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5799 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5800 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5801 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5803 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5804 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5805 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5808 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5809 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5810 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5811 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5812 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5814 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5815 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5818 minput_get_commands (MSymbol language, MSymbol name)
5820 MInputMethodInfo *im_info;
5825 im_info = get_im_info (language, name, Mnil, Mcommand);
5826 if (! im_info || ! im_info->configured_vars)
5828 M17N_OBJECT_UNREF (im_info->bc_cmds);
5829 im_info->bc_cmds = mplist ();
5830 MPLIST_DO (cmds, im_info->configured_cmds)
5832 MPlist *plist = MPLIST_PLIST (cmds);
5833 MPlist *elt = mplist ();
5835 mplist_push (im_info->bc_cmds, Mplist, elt);
5836 mplist_add (elt, MPLIST_SYMBOL (plist),
5837 mplist_copy (MPLIST_NEXT (plist)));
5838 M17N_OBJECT_UNREF (elt);
5840 return im_info->bc_cmds;
5846 @brief Assign a key sequence to an input method command (obsolete).
5848 This function is obsolete. Use minput_config_command () instead.
5850 The minput_assign_command_keys () function assigns input key
5851 sequence $KEYSEQ to input method command $COMMAND for the input
5852 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5853 key sequence is assigned globally no matter what $LANGUAGE is.
5854 Otherwise the key sequence is assigned locally.
5856 Each element of $KEYSEQ must have the key $Msymbol and the value
5857 must be a symbol representing an input key.
5859 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5860 globally or locally.
5862 This assignment gets effective in a newly opened input method.
5865 If the operation was successful, 0 is returned. Otherwise -1 is
5866 returned, and #merror_code is set to #MERROR_IM. */
5868 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5870 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5871 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5872 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5873 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5874 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5876 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5877 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5879 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5880 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5882 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5885 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5886 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5889 minput_assign_command_keys (MSymbol language, MSymbol name,
5890 MSymbol command, MPlist *keyseq)
5896 if (command == Mnil)
5897 MERROR (MERROR_IM, -1);
5902 if (! check_command_keyseq (keyseq))
5903 MERROR (MERROR_IM, -1);
5905 mplist_add (plist, Mplist, keyseq);
5910 ret = minput_config_command (language, name, command, keyseq);
5911 M17N_OBJECT_UNREF (keyseq);
5918 /*** @addtogroup m17nDebug */
5924 @brief Dump an input method.
5926 The mdebug_dump_im () function prints the input method $IM in a
5927 human readable way to the stderr. $INDENT specifies how many
5928 columns to indent the lines but the first one.
5931 This function returns $IM. */
5933 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
5935 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
5936 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
5939 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
5942 mdebug_dump_im (MInputMethod *im, int indent)
5944 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
5947 prefix = (char *) alloca (indent + 1);
5948 memset (prefix, 32, indent);
5949 prefix[indent] = '\0';
5951 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
5952 msymbol_name (im->name));
5953 mdebug_dump_mtext (im_info->title, 0, 0);
5954 if (im->name != Mnil)
5958 MPLIST_DO (state, im_info->states)
5960 fprintf (stderr, "\n%s ", prefix);
5961 dump_im_state (MPLIST_VAL (state), indent + 2);
5964 fprintf (stderr, ")");