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);
531 M17N_OBJECT_UNREF (ic_info->preceding_text);
533 M17N_OBJECT_UNREF (ic_info->following_text);
537 get_preceding_char (MInputContext *ic, int pos)
539 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
543 if (ic_info->preceding_text)
545 len = mtext_nchars (ic_info->preceding_text);
547 return mtext_ref_char (ic_info->preceding_text, len - pos);
549 mt = get_surrounding_text (ic, - pos);
552 len = mtext_nchars (mt);
553 if (ic_info->preceding_text)
555 if (mtext_nchars (ic_info->preceding_text) < len)
557 M17N_OBJECT_UNREF (ic_info->preceding_text);
558 ic_info->preceding_text = mt;
562 ic_info->preceding_text = mt;
565 return mtext_ref_char (ic_info->preceding_text, len - pos);
569 get_following_char (MInputContext *ic, int pos)
571 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
575 if (ic_info->following_text)
577 len = mtext_nchars (ic_info->following_text);
579 return mtext_ref_char (ic_info->following_text, pos - 1);
581 mt = get_surrounding_text (ic, pos);
584 len = mtext_nchars (mt);
585 if (ic_info->following_text)
587 if (mtext_nchars (ic_info->following_text) < len)
589 M17N_OBJECT_UNREF (ic_info->following_text);
590 ic_info->following_text = mt;
594 ic_info->following_text = mt;
597 return mtext_ref_char (ic_info->following_text, pos - 1);
601 surrounding_pos (MSymbol sym)
607 name = MSYMBOL_NAME (sym);
608 if ((name[1] == '-' || name[1] == '+')
609 && name[2] >= '1' && name[2] <= '9')
610 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
615 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
617 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
619 MText *preedit = ic->preedit;
620 int len = mtext_nchars (preedit);
624 if (MPLIST_INTEGER_P (arg))
625 return MPLIST_INTEGER (arg);
627 && (surrounding = surrounding_pos (MPLIST_SYMBOL (arg))) != 0)
628 return (surrounding < 0
629 ? get_preceding_char (ic, - surrounding)
630 : get_following_char (ic, surrounding));
631 code = marker_code (MPLIST_SYMBOL (arg));
634 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
638 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
641 return ic_info->key_head;
642 if (code >= '0' && code <= '9')
644 else if (code == '=')
645 code = ic->cursor_pos;
646 else if (code == '-' || code == '[')
647 code = ic->cursor_pos - 1;
648 else if (code == '+' || code == ']')
649 code = ic->cursor_pos + 1;
650 else if (code == '<')
652 else if (code == '>')
654 return (code >= 0 && code < len ? mtext_ref_char (preedit, code) : -1);
658 parse_expression (MPlist *plist)
662 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
664 if (! MPLIST_PLIST_P (plist))
666 plist = MPLIST_PLIST (plist);
667 op = MPLIST_SYMBOL (plist);
668 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
669 && op != Mand && op != Mor && op != Mnot
670 && op != Mless && op != Mgreater && op != Mequal
671 && op != Mless_equal && op != Mgreater_equal)
672 MERROR (MERROR_IM, -1);
673 MPLIST_DO (plist, MPLIST_NEXT (plist))
674 if (parse_expression (plist) < 0)
680 resolve_expression (MInputContext *ic, MPlist *plist)
685 if (MPLIST_INTEGER_P (plist))
686 return MPLIST_INTEGER (plist);
687 if (MPLIST_SYMBOL_P (plist))
688 return integer_value (ic, plist, NULL, 1);
689 if (! MPLIST_PLIST_P (plist))
691 plist = MPLIST_PLIST (plist);
692 if (! MPLIST_SYMBOL_P (plist))
694 op = MPLIST_SYMBOL (plist);
695 plist = MPLIST_NEXT (plist);
696 val = resolve_expression (ic, plist);
698 MPLIST_DO (plist, MPLIST_NEXT (plist))
699 val += resolve_expression (ic, plist);
700 else if (op == Mminus)
701 MPLIST_DO (plist, MPLIST_NEXT (plist))
702 val -= resolve_expression (ic, plist);
703 else if (op == Mstar)
704 MPLIST_DO (plist, MPLIST_NEXT (plist))
705 val *= resolve_expression (ic, plist);
706 else if (op == Mslash)
707 MPLIST_DO (plist, MPLIST_NEXT (plist))
708 val /= resolve_expression (ic, plist);
710 MPLIST_DO (plist, MPLIST_NEXT (plist))
711 val &= resolve_expression (ic, plist);
713 MPLIST_DO (plist, MPLIST_NEXT (plist))
714 val |= resolve_expression (ic, plist);
717 else if (op == Mless)
718 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
719 else if (op == Mequal)
720 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
721 else if (op == Mgreater)
722 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
723 else if (op == Mless_equal)
724 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
725 else if (op == Mgreater_equal)
726 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
730 /* Parse PLIST as an action list. PLIST should have this form:
731 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
732 Return 0 if successfully parsed, otherwise return -1. */
735 parse_action_list (MPlist *plist, MPlist *macros)
737 MPLIST_DO (plist, plist)
739 if (MPLIST_MTEXT_P (plist))
741 /* This is a short form of (insert MTEXT). */
742 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
743 MERROR (MERROR_IM, -1); */
745 else if (MPLIST_PLIST_P (plist)
746 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
747 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
751 /* This is a short form of (insert (GROUPS *)). */
752 MPLIST_DO (pl, MPLIST_PLIST (plist))
754 if (MPLIST_PLIST_P (pl))
758 MPLIST_DO (elt, MPLIST_PLIST (pl))
759 if (! MPLIST_MTEXT_P (elt)
760 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
761 MERROR (MERROR_IM, -1);
765 if (! MPLIST_MTEXT_P (pl)
766 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
767 MERROR (MERROR_IM, -1);
771 else if (MPLIST_INTEGER_P (plist))
773 int c = MPLIST_INTEGER (plist);
775 if (c < 0 || c > MCHAR_MAX)
776 MERROR (MERROR_IM, -1);
778 else if (MPLIST_PLIST_P (plist)
779 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
781 MPlist *pl = MPLIST_PLIST (plist);
782 MSymbol action_name = MPLIST_SYMBOL (pl);
784 pl = MPLIST_NEXT (pl);
786 if (action_name == Minsert)
788 if (MPLIST_MTEXT_P (pl))
790 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
791 MERROR (MERROR_IM, -1);
793 else if (MPLIST_PLIST_P (pl))
797 if (MPLIST_PLIST_P (pl))
801 MPLIST_DO (elt, MPLIST_PLIST (pl))
802 if (! MPLIST_MTEXT_P (elt)
803 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
804 MERROR (MERROR_IM, -1);
808 if (! MPLIST_MTEXT_P (pl)
809 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
810 MERROR (MERROR_IM, -1);
814 else if (! MPLIST_SYMBOL_P (pl))
815 MERROR (MERROR_IM, -1);
817 else if (action_name == Mselect
818 || action_name == Mdelete
819 || action_name == Mmove)
821 if (parse_expression (pl) < 0)
824 else if (action_name == Mmark
825 || action_name == Mcall
826 || action_name == Mshift)
828 if (! MPLIST_SYMBOL_P (pl))
829 MERROR (MERROR_IM, -1);
831 else if (action_name == Mundo)
833 if (! MPLIST_TAIL_P (pl))
835 if (! MPLIST_SYMBOL_P (pl)
836 && (! MPLIST_INTEGER_P (pl)
837 || MPLIST_INTEGER (pl) == 0))
838 MERROR (MERROR_IM, -1);
841 else if (action_name == Mpushback)
843 if (MPLIST_MTEXT_P (pl))
845 MText *mt = MPLIST_MTEXT (pl);
847 if (mtext_nchars (mt) != mtext_nbytes (mt))
848 MERROR (MERROR_IM, -1);
850 else if (MPLIST_PLIST_P (pl))
854 MPLIST_DO (p, MPLIST_PLIST (pl))
855 if (! MPLIST_SYMBOL_P (p))
856 MERROR (MERROR_IM, -1);
858 else if (! MPLIST_INTEGER_P (pl))
859 MERROR (MERROR_IM, -1);
861 else if (action_name == Mset || action_name == Madd
862 || action_name == Msub || action_name == Mmul
863 || action_name == Mdiv)
865 if (! MPLIST_SYMBOL_P (pl))
866 MERROR (MERROR_IM, -1);
867 if (parse_expression (MPLIST_NEXT (pl)) < 0)
870 else if (action_name == Mequal || action_name == Mless
871 || action_name == Mgreater || action_name == Mless_equal
872 || action_name == Mgreater_equal)
874 if (parse_expression (pl) < 0
875 || parse_expression (MPLIST_NEXT (pl)) < 0)
877 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
878 if (! MPLIST_PLIST_P (pl))
879 MERROR (MERROR_IM, -1);
880 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
881 MERROR (MERROR_IM, -1);
882 pl = MPLIST_NEXT (pl);
883 if (MPLIST_PLIST_P (pl)
884 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
885 MERROR (MERROR_IM, -1);
887 else if (action_name == Mshow || action_name == Mhide
888 || action_name == Mcommit || action_name == Munhandle)
890 else if (action_name == Mcond)
893 if (! MPLIST_PLIST_P (pl))
894 MERROR (MERROR_IM, -1);
896 else if (! macros || ! mplist_get (macros, action_name))
897 MERROR (MERROR_IM, -1);
899 else if (! MPLIST_SYMBOL_P (plist))
900 MERROR (MERROR_IM, -1);
907 resolve_command (MPlist *cmds, MSymbol command)
911 if (! cmds || ! (plist = mplist__assq (cmds, command)))
913 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
914 plist = MPLIST_NEXT (plist);
915 plist = MPLIST_NEXT (plist);
916 plist = MPLIST_NEXT (plist);
920 /* Load a translation into MAP from PLIST.
922 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
925 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
926 MPlist *branch_actions, MPlist *macros)
931 if (MPLIST_MTEXT_P (keylist))
933 MText *mt = MPLIST_MTEXT (keylist);
935 len = mtext_nchars (mt);
936 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
938 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
939 for (i = 0; i < len; i++)
940 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
946 if (MFAILP (MPLIST_PLIST_P (keylist)))
948 elt = MPLIST_PLIST (keylist);
949 len = MPLIST_LENGTH (elt);
950 if (MFAILP (len > 0))
952 keyseq = (MSymbol *) alloca (sizeof (int) * len);
953 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
955 if (MPLIST_INTEGER_P (elt))
957 int c = MPLIST_INTEGER (elt);
959 if (MFAILP (c >= 0 && c < 0x100))
961 keyseq[i] = one_char_symbol[c];
965 if (MFAILP (MPLIST_SYMBOL_P (elt)))
967 keyseq[i] = MPLIST_SYMBOL (elt);
972 for (i = 0; i < len; i++)
974 MIMMap *deeper = NULL;
977 deeper = mplist_get (map->submaps, keyseq[i]);
979 map->submaps = mplist ();
982 /* Fixme: It is better to make all deeper maps at once. */
983 MSTRUCT_CALLOC (deeper, MERROR_IM);
984 mplist_put (map->submaps, keyseq[i], deeper);
989 /* We reach a terminal map. */
991 || map->branch_actions)
992 /* This map is already defined. We avoid overriding it. */
995 if (! MPLIST_TAIL_P (map_actions))
997 if (parse_action_list (map_actions, macros) < 0)
998 MERROR (MERROR_IM, -1);
999 map->map_actions = map_actions;
1003 map->branch_actions = branch_actions;
1004 M17N_OBJECT_REF (branch_actions);
1010 /* Load a branch from PLIST into MAP. PLIST has this form:
1011 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1014 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1017 MPlist *branch_actions;
1019 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1021 map_name = MPLIST_SYMBOL (plist);
1022 plist = MPLIST_NEXT (plist);
1023 if (MPLIST_TAIL_P (plist))
1024 branch_actions = NULL;
1025 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1028 branch_actions = plist;
1029 if (map_name == Mnil)
1031 map->branch_actions = branch_actions;
1033 M17N_OBJECT_REF (branch_actions);
1035 else if (map_name == Mt)
1037 map->map_actions = branch_actions;
1039 M17N_OBJECT_REF (branch_actions);
1041 else if (im_info->maps
1042 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1044 MPLIST_DO (plist, plist)
1046 MPlist *keylist, *map_actions;
1048 if (! MPLIST_PLIST_P (plist))
1049 MERROR (MERROR_IM, -1);
1050 keylist = MPLIST_PLIST (plist);
1051 map_actions = MPLIST_NEXT (keylist);
1052 if (MPLIST_SYMBOL_P (keylist))
1054 MSymbol command = MPLIST_SYMBOL (keylist);
1057 if (MFAILP (command != Mat_reload))
1059 pl = resolve_command (im_info->configured_cmds, command);
1063 load_translation (map, pl, map_actions, branch_actions,
1067 load_translation (map, keylist, map_actions, branch_actions,
1075 /* Load a macro from PLIST into IM_INFO->macros.
1076 PLIST has this from:
1077 PLIST ::= ( MACRO-NAME ACTION * )
1078 IM_INFO->macros is a plist of macro names vs action list. */
1081 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1086 if (! MPLIST_SYMBOL_P (plist))
1087 MERROR (MERROR_IM, -1);
1088 name = MPLIST_SYMBOL (plist);
1089 plist = MPLIST_NEXT (plist);
1090 if (MPLIST_TAIL_P (plist)
1091 || parse_action_list (plist, im_info->macros) < 0)
1092 MERROR (MERROR_IM, -1);
1093 pl = mplist_get (im_info->macros, name);
1094 M17N_OBJECT_UNREF (pl);
1095 mplist_put (im_info->macros, name, plist);
1096 M17N_OBJECT_REF (plist);
1100 /* Load an external module from PLIST into IM_INFO->externals.
1101 PLIST has this form:
1102 PLIST ::= ( MODULE-NAME FUNCTION * )
1103 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1106 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1111 MIMExternalModule *external;
1115 if (MPLIST_MTEXT_P (plist))
1116 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1117 else if (MPLIST_SYMBOL_P (plist))
1118 module = MPLIST_SYMBOL (plist);
1119 module_file = alloca (strlen (MSYMBOL_NAME (module))
1120 + strlen (DLOPEN_SHLIB_EXT) + 1);
1121 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1123 handle = dlopen (module_file, RTLD_NOW);
1124 if (MFAILP (handle))
1126 fprintf (stderr, "%s\n", dlerror ());
1129 func_list = mplist ();
1130 MPLIST_DO (plist, MPLIST_NEXT (plist))
1132 if (! MPLIST_SYMBOL_P (plist))
1133 MERROR_GOTO (MERROR_IM, err_label);
1134 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1137 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1140 MSTRUCT_MALLOC (external, MERROR_IM);
1141 external->handle = handle;
1142 external->func_list = func_list;
1143 mplist_add (im_info->externals, module, external);
1148 M17N_OBJECT_UNREF (func_list);
1153 free_map (MIMMap *map, int top)
1158 M17N_OBJECT_UNREF (map->map_actions);
1161 MPLIST_DO (plist, map->submaps)
1162 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1163 M17N_OBJECT_UNREF (map->submaps);
1165 M17N_OBJECT_UNREF (map->branch_actions);
1170 free_state (void *object)
1172 MIMState *state = object;
1174 M17N_OBJECT_UNREF (state->title);
1176 free_map (state->map, 1);
1180 /** Load a state from PLIST into a newly allocated state object.
1181 PLIST has this form:
1182 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1183 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1184 Return the state object. */
1187 load_state (MInputMethodInfo *im_info, MPlist *plist)
1191 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1193 M17N_OBJECT (state, free_state, MERROR_IM);
1194 state->name = MPLIST_SYMBOL (plist);
1195 plist = MPLIST_NEXT (plist);
1196 if (MPLIST_MTEXT_P (plist))
1198 state->title = MPLIST_MTEXT (plist);
1199 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1200 Mlanguage, im_info->language);
1201 M17N_OBJECT_REF (state->title);
1202 plist = MPLIST_NEXT (plist);
1204 MSTRUCT_CALLOC (state->map, MERROR_IM);
1205 MPLIST_DO (plist, plist)
1207 if (MFAILP (MPLIST_PLIST_P (plist)))
1209 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1214 /* Return a newly created IM_INFO for an input method specified by
1215 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1217 static MInputMethodInfo *
1218 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1221 MInputMethodInfo *im_info;
1224 if (name == Mnil && extra == Mnil)
1225 language = Mt, extra = Mglobal;
1226 MSTRUCT_CALLOC (im_info, MERROR_IM);
1228 im_info->language = language;
1229 im_info->name = name;
1230 im_info->extra = extra;
1233 mplist_add (plist, Mplist, elt);
1234 M17N_OBJECT_UNREF (elt);
1235 elt = mplist_add (elt, Msymbol, language);
1236 elt = mplist_add (elt, Msymbol, name);
1237 elt = mplist_add (elt, Msymbol, extra);
1238 mplist_add (elt, Mt, im_info);
1244 fini_im_info (MInputMethodInfo *im_info)
1248 M17N_OBJECT_UNREF (im_info->cmds);
1249 M17N_OBJECT_UNREF (im_info->configured_cmds);
1250 M17N_OBJECT_UNREF (im_info->bc_cmds);
1251 M17N_OBJECT_UNREF (im_info->vars);
1252 M17N_OBJECT_UNREF (im_info->configured_vars);
1253 M17N_OBJECT_UNREF (im_info->bc_vars);
1254 M17N_OBJECT_UNREF (im_info->description);
1255 M17N_OBJECT_UNREF (im_info->title);
1256 if (im_info->states)
1258 MPLIST_DO (plist, im_info->states)
1260 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1262 M17N_OBJECT_UNREF (state);
1264 M17N_OBJECT_UNREF (im_info->states);
1267 if (im_info->macros)
1269 MPLIST_DO (plist, im_info->macros)
1270 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1271 M17N_OBJECT_UNREF (im_info->macros);
1274 if (im_info->externals)
1276 MPLIST_DO (plist, im_info->externals)
1278 MIMExternalModule *external = MPLIST_VAL (plist);
1280 dlclose (external->handle);
1281 M17N_OBJECT_UNREF (external->func_list);
1283 MPLIST_KEY (plist) = Mt;
1285 M17N_OBJECT_UNREF (im_info->externals);
1289 MPLIST_DO (plist, im_info->maps)
1291 MPlist *p = MPLIST_PLIST (plist);
1293 M17N_OBJECT_UNREF (p);
1295 M17N_OBJECT_UNREF (im_info->maps);
1302 free_im_info (MInputMethodInfo *im_info)
1304 fini_im_info (im_info);
1309 free_im_list (MPlist *plist)
1313 MPLIST_DO (pl, plist)
1315 MInputMethodInfo *im_info;
1317 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1318 im_info = MPLIST_VAL (elt);
1319 free_im_info (im_info);
1321 M17N_OBJECT_UNREF (plist);
1324 static MInputMethodInfo *
1325 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1327 if (name == Mnil && extra == Mnil)
1328 language = Mt, extra = Mglobal;
1329 while ((plist = mplist__assq (plist, language)))
1331 MPlist *elt = MPLIST_PLIST (plist);
1333 plist = MPLIST_NEXT (plist);
1334 elt = MPLIST_NEXT (elt);
1335 if (MPLIST_SYMBOL (elt) != name)
1337 elt = MPLIST_NEXT (elt);
1338 if (MPLIST_SYMBOL (elt) != extra)
1340 elt = MPLIST_NEXT (elt);
1341 return MPLIST_VAL (elt);
1346 static void load_im_info (MPlist *, MInputMethodInfo *);
1348 #define get_custom_info(im_info) \
1350 ? lookup_im_info (im_custom_list, (im_info)->language, \
1351 (im_info)->name, (im_info)->extra) \
1354 #define get_config_info(im_info) \
1356 ? lookup_im_info (im_config_list, (im_info)->language, \
1357 (im_info)->name, (im_info)->extra) \
1361 update_custom_info (void)
1367 if (mdatabase__check (im_custom_mdb) > 0)
1372 MDatabaseInfo *custom_dir_info;
1373 char custom_path[PATH_MAX + 1];
1375 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1376 if (! custom_dir_info->filename
1377 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1379 strcpy (custom_path, custom_dir_info->filename);
1380 strcat (custom_path, CUSTOM_FILE);
1381 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1387 free_im_list (im_custom_list);
1388 im_custom_list = NULL;
1390 plist = mdatabase_load (im_custom_mdb);
1393 im_custom_list = mplist ();
1395 MPLIST_DO (pl, plist)
1397 MSymbol language, name, extra;
1398 MInputMethodInfo *im_info;
1399 MPlist *im_data, *p;
1401 if (! MPLIST_PLIST_P (pl))
1403 p = MPLIST_PLIST (pl);
1404 im_data = MPLIST_NEXT (p);
1405 if (! MPLIST_PLIST_P (p))
1407 p = MPLIST_PLIST (p);
1408 if (! MPLIST_SYMBOL_P (p)
1409 || MPLIST_SYMBOL (p) != Minput_method)
1411 p = MPLIST_NEXT (p);
1412 if (! MPLIST_SYMBOL_P (p))
1414 language = MPLIST_SYMBOL (p);
1415 p = MPLIST_NEXT (p);
1416 if (! MPLIST_SYMBOL_P (p))
1418 name = MPLIST_SYMBOL (p);
1419 if (language == Mnil || name == Mnil)
1421 p = MPLIST_NEXT (p);
1422 if (MPLIST_TAIL_P (p))
1424 else if (MPLIST_SYMBOL_P (p))
1425 extra = MPLIST_SYMBOL (p);
1428 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1429 load_im_info (im_data, im_info);
1431 M17N_OBJECT_UNREF (plist);
1436 update_global_info (void)
1442 int ret = mdatabase__check (global_info->mdb);
1446 fini_im_info (global_info);
1450 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1452 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1454 if (! global_info->mdb
1455 || ! (plist = mdatabase_load (global_info->mdb)))
1458 load_im_info (plist, global_info);
1459 M17N_OBJECT_UNREF (plist);
1464 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1465 and EXTRA. KEY, if not Mnil, tells which kind of information about
1466 the input method is necessary, and the returned IM_INFO may contain
1467 only that information. */
1469 static MInputMethodInfo *
1470 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1473 MInputMethodInfo *im_info;
1476 if (name == Mnil && extra == Mnil)
1477 language = Mt, extra = Mglobal;
1478 im_info = lookup_im_info (im_info_list, language, name, extra);
1481 if (key == Mnil ? im_info->states != NULL
1482 : key == Mcommand ? im_info->cmds != NULL
1483 : key == Mvariable ? im_info->vars != NULL
1484 : key == Mtitle ? im_info->title != NULL
1485 : key == Mdescription ? im_info->description != NULL
1487 /* IM_INFO already contains required information. */
1489 /* We have not yet loaded required information. */
1493 mdb = mdatabase_find (Minput_method, language, name, extra);
1496 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1501 plist = mdatabase_load (im_info->mdb);
1505 mplist_push (load_im_info_keys, key, Mt);
1506 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1507 mplist_pop (load_im_info_keys);
1511 MERROR (MERROR_IM, im_info);
1512 update_global_info ();
1513 load_im_info (plist, im_info);
1514 M17N_OBJECT_UNREF (plist);
1517 if (! im_info->cmds)
1518 im_info->cmds = mplist ();
1519 if (! im_info->vars)
1520 im_info->vars = mplist ();
1522 if (! im_info->title
1523 && (key == Mnil || key == Mtitle))
1524 im_info->title = (name == Mnil ? mtext ()
1525 : mtext_from_data (MSYMBOL_NAME (name),
1526 MSYMBOL_NAMELEN (name),
1527 MTEXT_FORMAT_US_ASCII));
1531 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1532 If updated, but got unloadable, return -1. Otherwise, update
1533 contents of IM_INFO from the new database, and return 1. */
1536 reload_im_info (MInputMethodInfo *im_info)
1541 update_custom_info ();
1542 update_global_info ();
1543 check = mdatabase__check (im_info->mdb);
1546 plist = mdatabase_load (im_info->mdb);
1549 fini_im_info (im_info);
1550 load_im_info (plist, im_info);
1551 M17N_OBJECT_UNREF (plist);
1555 static MInputMethodInfo *
1556 get_im_info_by_tags (MPlist *plist)
1561 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1562 i++, plist = MPLIST_NEXT (plist))
1563 tag[i] = MPLIST_SYMBOL (plist);
1568 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1573 check_description (MPlist *plist)
1577 if (MPLIST_MTEXT_P (plist))
1579 if (MPLIST_PLIST_P (plist))
1581 MPlist *pl = MPLIST_PLIST (plist);
1583 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1585 pl =MPLIST_NEXT (pl);
1586 if (MFAILP (MPLIST_MTEXT_P (pl)))
1588 mt = MPLIST_MTEXT (pl);
1589 M17N_OBJECT_REF (mt);
1592 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1594 if (translated == (char *) MTEXT_DATA (mt))
1595 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1596 if (translated != (char *) MTEXT_DATA (mt))
1598 M17N_OBJECT_UNREF (mt);
1599 mt = mtext__from_data (translated, strlen (translated),
1600 MTEXT_FORMAT_UTF_8, 0);
1604 mplist_set (plist, Mtext, mt);
1605 M17N_OBJECT_UNREF (mt);
1608 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1614 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1618 check_command_keyseq (MPlist *keyseq)
1620 if (MPLIST_PLIST_P (keyseq))
1622 MPlist *p = MPLIST_PLIST (keyseq);
1625 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1629 if (MPLIST_MTEXT_P (keyseq))
1631 MText *mt = MPLIST_MTEXT (keyseq);
1634 for (i = 0; i < mtext_nchars (mt); i++)
1635 if (mtext_ref_char (mt, i) >= 256)
1642 /* Load command defitions from PLIST into IM_INFO->cmds.
1644 PLIST is well-formed and has this form;
1645 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1646 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1647 M-text or a plist of symbols.
1649 The returned list has the same form, but for each element...
1651 (1) If DESCRIPTION and the rest are omitted, the element is not
1652 stored in the returned list.
1654 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1655 description in global_info->cmds (if any). */
1658 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1662 im_info->cmds = tail = mplist ();
1664 MPLIST_DO (plist, MPLIST_NEXT (plist))
1666 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1669 if (MFAILP (MPLIST_PLIST_P (plist)))
1671 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1672 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1674 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1675 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1677 if (MFAILP (im_info != global_info))
1678 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1682 if (! check_description (p))
1683 mplist_set (p, Msymbol, Mnil);
1684 p = MPLIST_NEXT (p);
1685 while (! MPLIST_TAIL_P (p))
1687 if (MFAILP (check_command_keyseq (p)))
1688 mplist__pop_unref (p);
1690 p = MPLIST_NEXT (p);
1693 tail = mplist_add (tail, Mplist, pl);
1698 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1699 MPlist *config_cmds)
1701 MPlist *global = NULL, *custom = NULL, *config = NULL;
1704 MPlist *description = NULL, *keyseq;
1706 name = MPLIST_SYMBOL (plist);
1707 plist = MPLIST_NEXT (plist);
1708 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1709 description = plist;
1710 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1711 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1712 if (MPLIST_TAIL_P (plist))
1715 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1716 global = MPLIST_NEXT (MPLIST_PLIST (global));
1719 keyseq = MPLIST_NEXT (global);
1720 status = Minherited;
1730 keyseq = MPLIST_NEXT (plist);
1734 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1736 config = MPLIST_NEXT (MPLIST_PLIST (config));
1737 if (! MPLIST_TAIL_P (config))
1739 keyseq = MPLIST_NEXT (config);
1740 status = Mconfigured;
1743 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1745 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1746 if (! MPLIST_TAIL_P (custom))
1748 keyseq = MPLIST_NEXT (custom);
1749 status = Mcustomized;
1754 mplist_add (plist, Msymbol, name);
1756 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1758 mplist_add (plist, Msymbol, Mnil);
1759 mplist_add (plist, Msymbol, status);
1760 mplist__conc (plist, keyseq);
1765 config_all_commands (MInputMethodInfo *im_info)
1767 MPlist *global_cmds, *custom_cmds, *config_cmds;
1768 MInputMethodInfo *temp;
1769 MPlist *tail, *plist;
1771 M17N_OBJECT_UNREF (im_info->configured_cmds);
1773 if (MPLIST_TAIL_P (im_info->cmds)
1777 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1778 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1779 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1781 im_info->configured_cmds = tail = mplist ();
1782 MPLIST_DO (plist, im_info->cmds)
1784 MPlist *pl = config_command (MPLIST_PLIST (plist),
1785 global_cmds, custom_cmds, config_cmds);
1788 tail = mplist_add (tail, Mplist, pl);
1789 M17N_OBJECT_UNREF (pl);
1794 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1795 valid, return 0 if not. */
1798 check_variable_value (MPlist *val, MPlist *global)
1800 MSymbol type = MPLIST_KEY (val);
1801 MPlist *valids = MPLIST_NEXT (val);
1803 if (type != Minteger && type != Mtext && type != Msymbol)
1807 if (MPLIST_KEY (global) != Mt
1808 && MPLIST_KEY (global) != MPLIST_KEY (val))
1810 if (MPLIST_TAIL_P (valids))
1811 valids = MPLIST_NEXT (global);
1813 if (MPLIST_TAIL_P (valids))
1816 if (type == Minteger)
1818 int n = MPLIST_INTEGER (val);
1820 MPLIST_DO (valids, valids)
1822 if (MPLIST_INTEGER_P (valids))
1824 if (n == MPLIST_INTEGER (valids))
1827 else if (MPLIST_PLIST_P (valids))
1829 MPlist *p = MPLIST_PLIST (valids);
1830 int min_bound, max_bound;
1832 if (! MPLIST_INTEGER_P (p))
1833 MERROR (MERROR_IM, 0);
1834 min_bound = MPLIST_INTEGER (p);
1835 p = MPLIST_NEXT (p);
1836 if (! MPLIST_INTEGER_P (p))
1837 MERROR (MERROR_IM, 0);
1838 max_bound = MPLIST_INTEGER (p);
1839 if (n >= min_bound && n <= max_bound)
1844 else if (type == Msymbol)
1846 MSymbol sym = MPLIST_SYMBOL (val);
1848 MPLIST_DO (valids, valids)
1850 if (! MPLIST_SYMBOL_P (valids))
1851 MERROR (MERROR_IM, 0);
1852 if (sym == MPLIST_SYMBOL (valids))
1858 MText *mt = MPLIST_MTEXT (val);
1860 MPLIST_DO (valids, valids)
1862 if (! MPLIST_MTEXT_P (valids))
1863 MERROR (MERROR_IM, 0);
1864 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1869 return (MPLIST_TAIL_P (valids));
1872 /* Load variable defitions from PLIST into IM_INFO->vars.
1874 PLIST is well-formed and has this form;
1875 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1877 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1879 The returned list has the same form, but for each element...
1881 (1) If DESCRIPTION and the rest are omitted, the element is not
1882 stored in the returned list.
1884 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1885 description in global_info->vars (if any). */
1888 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1890 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1891 ? global_info->vars : NULL);
1894 im_info->vars = tail = mplist ();
1895 MPLIST_DO (plist, MPLIST_NEXT (plist))
1899 if (MFAILP (MPLIST_PLIST_P (plist)))
1901 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1902 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1904 if (im_info == global_info)
1906 /* Loading a global variable. */
1907 p = MPLIST_NEXT (pl);
1908 if (MPLIST_TAIL_P (p))
1909 mplist_add (p, Msymbol, Mnil);
1912 if (! check_description (p))
1913 mplist_set (p, Msymbol, Mnil);
1914 p = MPLIST_NEXT (p);
1915 if (MFAILP (! MPLIST_TAIL_P (p)
1916 && check_variable_value (p, NULL)))
1917 mplist_set (p, Mt, NULL);
1920 else if (im_info->mdb)
1922 /* Loading a local variable. */
1923 MSymbol name = MPLIST_SYMBOL (pl);
1924 MPlist *global = NULL;
1927 && (p = mplist__assq (global_vars, name)))
1929 /* P ::= ((NAME DESC ...) ...) */
1930 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1931 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1932 global = MPLIST_NEXT (p); /* P ::= (VALUE ...) */
1935 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1936 if (! MPLIST_TAIL_P (p))
1938 if (! check_description (p))
1939 mplist_set (p, Msymbol, Mnil);
1940 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1941 if (MFAILP (! MPLIST_TAIL_P (p)))
1942 mplist_set (p, Mt, NULL);
1945 MPlist *valid_values = MPLIST_NEXT (p);
1947 if (! MPLIST_TAIL_P (valid_values)
1948 ? MFAILP (check_variable_value (p, NULL))
1949 : global && MFAILP (check_variable_value (p, global)))
1950 mplist_set (p, Mt, NULL);
1956 /* Loading a variable customization. */
1957 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1958 if (MFAILP (! MPLIST_TAIL_P (p)))
1960 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1961 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1962 || MPLIST_MTEXT_P (p)))
1965 tail = mplist_add (tail, Mplist, pl);
1970 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
1971 MPlist *config_vars)
1973 MPlist *global = NULL, *custom = NULL, *config = NULL;
1974 MSymbol name = MPLIST_SYMBOL (plist);
1976 MPlist *description = NULL, *value, *valids;
1980 global = mplist__assq (global_vars, name);
1982 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
1985 plist = MPLIST_NEXT (plist);
1986 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1987 description = plist;
1989 description = global;
1991 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
1993 if (MPLIST_TAIL_P (plist))
1995 /* Inherit from global (if any). */
1999 if (MPLIST_KEY (value) == Mt)
2001 valids = MPLIST_NEXT (global);
2002 status = Minherited;
2014 value = plist = MPLIST_NEXT (plist);
2015 valids = MPLIST_NEXT (value);
2016 if (MPLIST_KEY (value) == Mt)
2018 if (! MPLIST_TAIL_P (valids))
2021 valids = MPLIST_NEXT (global);
2025 if (config_vars && (config = mplist__assq (config_vars, name)))
2027 config = MPLIST_NEXT (MPLIST_PLIST (config));
2028 if (! MPLIST_TAIL_P (config))
2030 value = MPLIST_NEXT (config);
2031 if (MFAILP (check_variable_value (value, global ? global : plist)))
2033 status = Mconfigured;
2036 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2038 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2039 if (! MPLIST_TAIL_P (custom))
2041 value = MPLIST_NEXT (custom);
2042 if (MFAILP (check_variable_value (value, global ? global : plist)))
2044 status = Mcustomized;
2049 mplist_add (plist, Msymbol, name);
2051 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2053 mplist_add (plist, Msymbol, Mnil);
2054 mplist_add (plist, Msymbol, status);
2056 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2058 mplist_add (plist, Mt, NULL);
2059 if (valids && ! MPLIST_TAIL_P (valids))
2060 mplist__conc (plist, valids);
2064 /* Return a configured variable definition list based on
2065 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2066 get it from global_info->vars. */
2069 config_all_variables (MInputMethodInfo *im_info)
2071 MPlist *global_vars, *custom_vars, *config_vars;
2072 MInputMethodInfo *temp;
2073 MPlist *tail, *plist;
2075 M17N_OBJECT_UNREF (im_info->configured_vars);
2077 if (MPLIST_TAIL_P (im_info->vars)
2081 global_vars = im_info != global_info ? global_info->vars : NULL;
2082 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2083 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2085 im_info->configured_vars = tail = mplist ();
2086 MPLIST_DO (plist, im_info->vars)
2088 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2089 global_vars, custom_vars, config_vars);
2092 tail = mplist_add (tail, Mplist, pl);
2093 M17N_OBJECT_UNREF (pl);
2098 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2099 CONFIG contains configuration information of the input method. */
2102 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2106 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2108 load_commands (im_info, MPLIST_PLIST (pl));
2109 config_all_commands (im_info);
2110 pl = mplist_pop (pl);
2111 M17N_OBJECT_UNREF (pl);
2114 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2116 load_variables (im_info, MPLIST_PLIST (pl));
2117 config_all_variables (im_info);
2118 pl = mplist_pop (pl);
2119 M17N_OBJECT_UNREF (pl);
2122 MPLIST_DO (plist, plist)
2123 if (MPLIST_PLIST_P (plist))
2125 MPlist *elt = MPLIST_PLIST (plist);
2128 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2130 key = MPLIST_SYMBOL (elt);
2135 elt = MPLIST_NEXT (elt);
2136 if (MFAILP (MPLIST_MTEXT_P (elt)))
2138 im_info->title = MPLIST_MTEXT (elt);
2139 M17N_OBJECT_REF (im_info->title);
2141 else if (key == Mmap)
2143 pl = mplist__from_alist (MPLIST_NEXT (elt));
2146 if (! im_info->maps)
2150 mplist__conc (im_info->maps, pl);
2151 M17N_OBJECT_UNREF (pl);
2154 else if (key == Mmacro)
2156 if (! im_info->macros)
2157 im_info->macros = mplist ();
2158 MPLIST_DO (elt, MPLIST_NEXT (elt))
2160 if (MFAILP (MPLIST_PLIST_P (elt)))
2162 load_macros (im_info, MPLIST_PLIST (elt));
2165 else if (key == Mmodule)
2167 if (! im_info->externals)
2168 im_info->externals = mplist ();
2169 MPLIST_DO (elt, MPLIST_NEXT (elt))
2171 if (MFAILP (MPLIST_PLIST_P (elt)))
2173 load_external_module (im_info, MPLIST_PLIST (elt));
2176 else if (key == Mstate)
2178 MPLIST_DO (elt, MPLIST_NEXT (elt))
2182 if (MFAILP (MPLIST_PLIST_P (elt)))
2184 pl = MPLIST_PLIST (elt);
2185 if (! im_info->states)
2186 im_info->states = mplist ();
2187 state = load_state (im_info, MPLIST_PLIST (elt));
2190 mplist_put (im_info->states, state->name, state);
2193 else if (key == Minclude)
2195 /* elt ::= include (tag1 tag2 ...) key item ... */
2197 MInputMethodInfo *temp;
2199 elt = MPLIST_NEXT (elt);
2200 if (MFAILP (MPLIST_PLIST_P (elt)))
2202 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2205 elt = MPLIST_NEXT (elt);
2206 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2208 key = MPLIST_SYMBOL (elt);
2209 elt = MPLIST_NEXT (elt);
2212 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2214 if (! im_info->maps)
2215 im_info->maps = mplist ();
2216 MPLIST_DO (pl, temp->maps)
2218 p = MPLIST_VAL (pl);
2219 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2220 M17N_OBJECT_REF (p);
2223 else if (key == Mmacro)
2225 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2227 if (! im_info->macros)
2228 im_info->macros = mplist ();
2229 MPLIST_DO (pl, temp->macros)
2231 p = MPLIST_VAL (pl);
2232 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2233 M17N_OBJECT_REF (p);
2236 else if (key == Mstate)
2238 if (! temp->states || MPLIST_TAIL_P (temp->states))
2240 if (! im_info->states)
2241 im_info->states = mplist ();
2242 MPLIST_DO (pl, temp->states)
2244 MIMState *state = MPLIST_VAL (pl);
2246 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2247 M17N_OBJECT_REF (state);
2251 else if (key == Mdescription)
2253 if (im_info->description)
2255 elt = MPLIST_NEXT (elt);
2256 if (! check_description (elt))
2258 im_info->description = MPLIST_MTEXT (elt);
2259 M17N_OBJECT_REF (im_info->description);
2262 im_info->tick = time (NULL);
2267 static int take_action_list (MInputContext *ic, MPlist *action_list);
2268 static void preedit_commit (MInputContext *ic);
2271 shift_state (MInputContext *ic, MSymbol state_name)
2273 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2274 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2275 MIMState *orig_state = ic_info->state, *state;
2277 /* Find a state to shift to. If not found, shift to the initial
2279 if (state_name == Mt)
2281 if (! ic_info->prev_state)
2283 state = ic_info->prev_state;
2285 else if (state_name == Mnil)
2287 state = (MIMState *) MPLIST_VAL (im_info->states);
2291 state = (MIMState *) mplist_get (im_info->states, state_name);
2293 state = (MIMState *) MPLIST_VAL (im_info->states);
2296 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2298 /* Enter the new state. */
2299 ic_info->state = state;
2300 ic_info->map = state->map;
2301 ic_info->state_key_head = ic_info->key_head;
2302 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2304 /* We have shifted to the initial state. */
2305 preedit_commit (ic);
2306 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2307 ic_info->state_pos = ic->cursor_pos;
2308 if (state != orig_state)
2310 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2311 ic_info->prev_state = NULL;
2313 ic_info->prev_state = orig_state;
2316 ic->status = state->title;
2318 ic->status = im_info->title;
2319 ic->status_changed = 1;
2320 if (ic_info->map == ic_info->state->map
2321 && ic_info->map->map_actions)
2323 MDEBUG_PRINT (" init-actions:");
2324 take_action_list (ic, ic_info->map->map_actions);
2329 /* Find a candidate group that contains a candidate number INDEX from
2330 PLIST. Set START_INDEX to the first candidate number of the group,
2331 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2332 candidate group number if they are non-NULL. If INDEX is -1, find
2333 the last candidate group. */
2336 find_candidates_group (MPlist *plist, int index,
2337 int *start_index, int *end_index, int *group_index)
2339 int i = 0, gidx = 0, len;
2341 MPLIST_DO (plist, plist)
2343 if (MPLIST_MTEXT_P (plist))
2344 len = mtext_nchars (MPLIST_MTEXT (plist));
2346 len = mplist_length (MPLIST_PLIST (plist));
2347 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2353 *end_index = i + len;
2355 *group_index = gidx;
2365 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2367 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2369 int nchars = mt ? mtext_nchars (mt) : 1;
2372 mtext_ins (ic->preedit, pos, mt);
2374 mtext_ins_char (ic->preedit, pos, c, 1);
2375 MPLIST_DO (markers, ic_info->markers)
2376 if (MPLIST_INTEGER (markers) > pos)
2377 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
2378 if (ic->cursor_pos >= pos)
2379 ic->cursor_pos += nchars;
2380 ic->preedit_changed = 1;
2385 preedit_delete (MInputContext *ic, int from, int to)
2387 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2390 mtext_del (ic->preedit, from, to);
2391 MPLIST_DO (markers, ic_info->markers)
2393 if (MPLIST_INTEGER (markers) > to)
2394 MPLIST_VAL (markers)
2395 = (void *) (MPLIST_INTEGER (markers) - (to - from));
2396 else if (MPLIST_INTEGER (markers) > from);
2397 MPLIST_VAL (markers) = (void *) from;
2399 if (ic->cursor_pos >= to)
2400 ic->cursor_pos -= to - from;
2401 else if (ic->cursor_pos > from)
2402 ic->cursor_pos = from;
2403 ic->preedit_changed = 1;
2407 preedit_commit (MInputContext *ic)
2409 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2410 int preedit_len = mtext_nchars (ic->preedit);
2412 if (preedit_len > 0)
2416 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2417 Mcandidate_list, NULL, 0);
2418 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2419 Mcandidate_index, NULL, 0);
2420 mtext_cat (ic->produced, ic->preedit);
2421 if ((mdebug__flag & mdebug_mask)
2422 && mtext_nchars (ic->preedit) > 0)
2426 MDEBUG_PRINT (" (produced");
2427 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2428 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2431 mtext_reset (ic->preedit);
2432 mtext_reset (ic_info->preedit_saved);
2433 MPLIST_DO (p, ic_info->markers)
2435 ic->cursor_pos = ic_info->state_pos = 0;
2436 ic->preedit_changed = 1;
2438 if (ic->candidate_list)
2440 M17N_OBJECT_UNREF (ic->candidate_list);
2441 ic->candidate_list = NULL;
2442 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2443 if (ic->candidate_show)
2445 ic->candidate_show = 0;
2446 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2449 memmove (ic_info->keys, ic_info->keys + ic_info->key_head,
2450 sizeof (int) * (ic_info->used - ic_info->key_head));
2451 ic_info->used -= ic_info->key_head;
2452 ic_info->state_key_head = ic_info->key_head = 0;
2456 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2458 int code = marker_code (sym);
2460 if (mt && (code == '[' || code == ']'))
2464 if (code == '[' && current > 0)
2466 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2470 else if (code == ']' && current < mtext_nchars (mt))
2472 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2478 return (code == '<' ? 0
2479 : code == '>' ? limit
2480 : code == '-' ? current - 1
2481 : code == '+' ? current + 1
2482 : code == '=' ? current
2483 : code - '0' > limit ? limit
2487 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2491 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2493 int from = mtext_property_start (prop);
2494 int to = mtext_property_end (prop);
2496 MPlist *candidate_list = mtext_property_value (prop);
2497 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2499 int ingroup_index = idx - start;
2502 preedit_delete (ic, from, to);
2503 if (MPLIST_MTEXT_P (group))
2505 mt = MPLIST_MTEXT (group);
2506 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
2514 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2515 i++, plist = MPLIST_NEXT (plist));
2516 mt = MPLIST_MTEXT (plist);
2517 preedit_insert (ic, from, mt, 0);
2518 to = from + mtext_nchars (mt);
2520 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2521 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2522 ic->cursor_pos = to;
2526 get_select_charset (MInputContextInfo * ic_info)
2528 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2531 if (! MPLIST_VAL (plist))
2533 sym = MPLIST_SYMBOL (plist);
2536 return MCHARSET (sym);
2540 adjust_candidates (MPlist *plist, MCharset *charset)
2544 /* plist ::= MTEXT ... | PLIST ... */
2545 plist = mplist_copy (plist);
2546 if (MPLIST_MTEXT_P (plist))
2549 while (! MPLIST_TAIL_P (pl))
2551 /* pl ::= MTEXT ... */
2552 MText *mt = MPLIST_MTEXT (pl);
2556 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2558 c = mtext_ref_char (mt, i);
2559 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2563 mt = mtext_dup (mt);
2564 mplist_set (pl, Mtext, mt);
2565 M17N_OBJECT_UNREF (mt);
2568 mtext_del (mt, i, i + 1);
2571 if (mtext_len (mt) > 0)
2572 pl = MPLIST_NEXT (pl);
2576 M17N_OBJECT_UNREF (mt);
2580 else /* MPLIST_PLIST_P (plist) */
2583 while (! MPLIST_TAIL_P (pl))
2585 /* pl ::= (MTEXT ...) ... */
2586 MPlist *p = MPLIST_PLIST (pl);
2588 /* p ::= MTEXT ... */
2592 while (! MPLIST_TAIL_P (p0))
2594 MText *mt = MPLIST_MTEXT (p0);
2597 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2599 c = mtext_ref_char (mt, i);
2600 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2605 p0 = MPLIST_NEXT (p0);
2612 p = mplist_copy (p);
2613 mplist_set (pl, Mplist, p);
2614 M17N_OBJECT_UNREF (p);
2618 p0 = MPLIST_NEXT (p0);
2621 M17N_OBJECT_UNREF (mt);
2624 if (! MPLIST_TAIL_P (p))
2625 pl = MPLIST_NEXT (pl);
2629 M17N_OBJECT_UNREF (p);
2633 if (MPLIST_TAIL_P (plist))
2635 M17N_OBJECT_UNREF (plist);
2642 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2644 MCharset *charset = get_select_charset (ic_info);
2649 plist = resolve_variable (ic_info, Mcandidates_group_size);
2650 column = MPLIST_INTEGER (plist);
2652 plist = MPLIST_PLIST (args);
2655 if (! (plist = adjust_candidates (plist, charset)))
2659 M17N_OBJECT_REF (plist);
2663 if (MPLIST_MTEXT_P (plist))
2665 MText *mt = MPLIST_MTEXT (plist);
2666 MPlist *next = MPLIST_NEXT (plist);
2668 if (MPLIST_TAIL_P (next))
2669 M17N_OBJECT_REF (mt);
2672 mt = mtext_dup (mt);
2673 while (! MPLIST_TAIL_P (next))
2675 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2676 next = MPLIST_NEXT (next);
2679 M17N_OBJECT_UNREF (plist);
2681 len = mtext_nchars (mt);
2683 mplist_add (plist, Mtext, mt);
2686 for (i = 0; i < len; i += column)
2688 int to = (i + column < len ? i + column : len);
2689 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2691 mplist_add (plist, Mtext, sub);
2692 M17N_OBJECT_UNREF (sub);
2695 M17N_OBJECT_UNREF (mt);
2697 else /* MPLIST_PLIST_P (plist) */
2699 MPlist *pl = MPLIST_PLIST (plist), *p;
2700 MPlist *next = MPLIST_NEXT (plist);
2703 if (MPLIST_TAIL_P (next))
2704 M17N_OBJECT_REF (pl);
2707 pl = mplist_copy (pl);
2708 while (! MPLIST_TAIL_P (next))
2710 p = mplist_copy (MPLIST_PLIST (next));
2711 pl = mplist__conc (pl, p);
2712 M17N_OBJECT_UNREF (p);
2713 next = MPLIST_NEXT (next);
2716 M17N_OBJECT_UNREF (plist);
2718 len = mplist_length (pl);
2720 mplist_add (plist, Mplist, pl);
2725 for (i = 0; i < len; i += column)
2728 mplist_add (plist, Mplist, p);
2729 M17N_OBJECT_UNREF (p);
2730 for (j = 0; j < column && i + j < len; j++)
2732 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
2733 p0 = MPLIST_NEXT (p0);
2737 M17N_OBJECT_UNREF (pl);
2746 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2748 MPlist *action = NULL;
2752 if (MPLIST_SYMBOL_P (action_list))
2754 MSymbol var = MPLIST_SYMBOL (action_list);
2757 MPLIST_DO (p, ic_info->vars)
2758 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2760 if (MPLIST_TAIL_P (p))
2762 action = MPLIST_NEXT (MPLIST_PLIST (p));
2763 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2766 if (MPLIST_PLIST_P (action_list))
2768 action = MPLIST_PLIST (action_list);
2769 if (MPLIST_SYMBOL_P (action))
2771 name = MPLIST_SYMBOL (action);
2772 args = MPLIST_NEXT (action);
2774 && MPLIST_PLIST_P (args))
2775 mplist_set (action, Msymbol, M_candidates);
2777 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2780 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2781 mplist_push (action, Msymbol, M_candidates);
2782 mplist_set (action_list, Mplist, action);
2783 M17N_OBJECT_UNREF (action);
2786 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2789 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2790 mplist_push (action, Msymbol, Minsert);
2791 mplist_set (action_list, Mplist, action);
2792 M17N_OBJECT_UNREF (action);
2797 /* Perform list of actions in ACTION_LIST for the current input
2798 context IC. If all actions are performed without error, return 0.
2799 Otherwise, return -1. */
2802 take_action_list (MInputContext *ic, MPlist *action_list)
2804 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2805 MPlist *candidate_list = ic->candidate_list;
2806 int candidate_index = ic->candidate_index;
2807 int candidate_show = ic->candidate_show;
2808 MTextProperty *prop;
2810 MPLIST_DO (action_list, action_list)
2812 MPlist *action = regularize_action (action_list, ic_info);
2818 name = MPLIST_SYMBOL (action);
2819 args = MPLIST_NEXT (action);
2821 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2822 if (name == Minsert)
2824 if (MPLIST_SYMBOL_P (args))
2826 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2827 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2830 if (MPLIST_MTEXT_P (args))
2831 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2832 else /* MPLIST_INTEGER_P (args)) */
2833 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2835 else if (name == M_candidates)
2837 MPlist *plist = get_candidate_list (ic_info, args);
2842 if (MPLIST_MTEXT_P (plist))
2844 preedit_insert (ic, ic->cursor_pos, NULL,
2845 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2850 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2852 preedit_insert (ic, ic->cursor_pos, mt, 0);
2853 len = mtext_nchars (mt);
2855 mtext_put_prop (ic->preedit,
2856 ic->cursor_pos - len, ic->cursor_pos,
2857 Mcandidate_list, plist);
2858 mtext_put_prop (ic->preedit,
2859 ic->cursor_pos - len, ic->cursor_pos,
2860 Mcandidate_index, (void *) 0);
2861 M17N_OBJECT_UNREF (plist);
2863 else if (name == Mselect)
2866 int code, idx, gindex;
2867 int pos = ic->cursor_pos;
2871 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2874 if (MPLIST_SYMBOL_P (args))
2876 code = marker_code (MPLIST_SYMBOL (args));
2882 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2883 group = find_candidates_group (mtext_property_value (prop), idx,
2884 &start, &end, &gindex);
2886 if (code != '[' && code != ']')
2890 ? new_index (NULL, ic->candidate_index - start,
2891 end - start - 1, MPLIST_SYMBOL (args),
2893 : MPLIST_INTEGER (args)));
2896 find_candidates_group (mtext_property_value (prop), -1,
2901 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2906 int ingroup_index = idx - start;
2909 group = mtext_property_value (prop);
2910 len = mplist_length (group);
2923 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2924 idx += (MPLIST_MTEXT_P (group)
2925 ? mtext_nchars (MPLIST_MTEXT (group))
2926 : mplist_length (MPLIST_PLIST (group)));
2927 len = (MPLIST_MTEXT_P (group)
2928 ? mtext_nchars (MPLIST_MTEXT (group))
2929 : mplist_length (MPLIST_PLIST (group)));
2930 if (ingroup_index >= len)
2931 ingroup_index = len - 1;
2932 idx += ingroup_index;
2934 update_candidate (ic, prop, idx);
2936 else if (name == Mshow)
2937 ic->candidate_show = 1;
2938 else if (name == Mhide)
2939 ic->candidate_show = 0;
2940 else if (name == Mdelete)
2942 int len = mtext_nchars (ic->preedit);
2946 if (MPLIST_SYMBOL_P (args)
2947 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
2949 delete_surrounding_text (ic, pos);
2953 to = (MPLIST_SYMBOL_P (args)
2954 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2956 : MPLIST_INTEGER (args));
2961 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
2962 if (to < ic->cursor_pos)
2963 preedit_delete (ic, to, ic->cursor_pos);
2964 else if (to > ic->cursor_pos)
2965 preedit_delete (ic, ic->cursor_pos, to);
2968 else if (name == Mmove)
2970 int len = mtext_nchars (ic->preedit);
2972 = (MPLIST_SYMBOL_P (args)
2973 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2975 : MPLIST_INTEGER (args));
2981 if (pos != ic->cursor_pos)
2983 ic->cursor_pos = pos;
2984 ic->preedit_changed = 1;
2987 else if (name == Mmark)
2989 int code = marker_code (MPLIST_SYMBOL (args));
2992 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
2993 (void *) ic->cursor_pos);
2995 else if (name == Mpushback)
2997 if (MPLIST_INTEGER_P (args))
2999 int num = MPLIST_INTEGER (args);
3002 ic_info->key_head -= num;
3004 ic_info->key_head = num;
3005 if (ic_info->key_head > ic_info->used)
3006 ic_info->key_head = ic_info->used;
3008 else if (MPLIST_MTEXT_P (args))
3010 MText *mt = MPLIST_MTEXT (args);
3011 int i, len = mtext_nchars (mt);
3014 ic_info->key_head--;
3015 for (i = 0; i < len; i++)
3017 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3018 if (ic_info->key_head + i < ic_info->used)
3019 ic_info->keys[ic_info->key_head + i] = key;
3021 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3026 MPlist *plist = MPLIST_PLIST (args), *pl;
3030 ic_info->key_head--;
3032 MPLIST_DO (pl, plist)
3034 key = MPLIST_SYMBOL (pl);
3035 if (ic_info->key_head < ic_info->used)
3036 ic_info->keys[ic_info->key_head + i] = key;
3038 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3043 else if (name == Mcall)
3045 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3046 MIMExternalFunc func = NULL;
3047 MSymbol module, func_name;
3048 MPlist *func_args, *val;
3051 module = MPLIST_SYMBOL (args);
3052 args = MPLIST_NEXT (args);
3053 func_name = MPLIST_SYMBOL (args);
3055 if (im_info->externals)
3057 MIMExternalModule *external
3058 = (MIMExternalModule *) mplist_get (im_info->externals,
3061 func = (MIMExternalFunc) mplist_get (external->func_list,
3066 func_args = mplist ();
3067 mplist_add (func_args, Mt, ic);
3068 MPLIST_DO (args, MPLIST_NEXT (args))
3072 if (MPLIST_KEY (args) == Msymbol
3073 && MPLIST_KEY (args) != Mnil
3074 && (code = marker_code (MPLIST_SYMBOL (args))) >= 0)
3076 code = new_index (ic, ic->cursor_pos,
3077 mtext_nchars (ic->preedit),
3078 MPLIST_SYMBOL (args), ic->preedit);
3079 mplist_add (func_args, Minteger, (void *) code);
3082 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3084 val = (func) (func_args);
3085 M17N_OBJECT_UNREF (func_args);
3086 if (val && ! MPLIST_TAIL_P (val))
3087 ret = take_action_list (ic, val);
3088 M17N_OBJECT_UNREF (val);
3092 else if (name == Mshift)
3094 shift_state (ic, MPLIST_SYMBOL (args));
3096 else if (name == Mundo)
3098 int intarg = (MPLIST_TAIL_P (args)
3100 : integer_value (ic, args, NULL, 0));
3102 mtext_reset (ic->preedit);
3103 mtext_reset (ic_info->preedit_saved);
3104 ic->cursor_pos = ic_info->state_pos = 0;
3105 ic_info->state_key_head = ic_info->key_head = 0;
3108 ic_info->used += intarg;
3110 ic_info->used = intarg;
3111 shift_state (ic, Mnil);
3114 else if (name == Mset || name == Madd || name == Msub
3115 || name == Mmul || name == Mdiv)
3117 MSymbol sym = MPLIST_SYMBOL (args);
3122 val1 = integer_value (ic, args, &value, 0);
3123 args = MPLIST_NEXT (args);
3124 val2 = resolve_expression (ic, args);
3126 val1 = val2, op = "=";
3127 else if (name == Madd)
3128 val1 += val2, op = "+=";
3129 else if (name == Msub)
3130 val1 -= val2, op = "-=";
3131 else if (name == Mmul)
3132 val1 *= val2, op = "*=";
3134 val1 /= val2, op = "/=";
3135 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3136 MSYMBOL_NAME (sym), op, val1, val1);
3138 mplist_set (value, Minteger, (void *) val1);
3140 else if (name == Mequal || name == Mless || name == Mgreater
3141 || name == Mless_equal || name == Mgreater_equal)
3144 MPlist *actions1, *actions2;
3147 val1 = resolve_expression (ic, args);
3148 args = MPLIST_NEXT (args);
3149 val2 = resolve_expression (ic, args);
3150 args = MPLIST_NEXT (args);
3151 actions1 = MPLIST_PLIST (args);
3152 args = MPLIST_NEXT (args);
3153 if (MPLIST_TAIL_P (args))
3156 actions2 = MPLIST_PLIST (args);
3157 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3158 if (name == Mequal ? val1 == val2
3159 : name == Mless ? val1 < val2
3160 : name == Mgreater ? val1 > val2
3161 : name == Mless_equal ? val1 <= val2
3164 MDEBUG_PRINT ("ok");
3165 ret = take_action_list (ic, actions1);
3169 MDEBUG_PRINT ("no");
3171 ret = take_action_list (ic, actions2);
3176 else if (name == Mcond)
3180 MPLIST_DO (args, args)
3185 if (! MPLIST_PLIST (args))
3187 cond = MPLIST_PLIST (args);
3188 if (resolve_expression (ic, cond) != 0)
3190 MDEBUG_PRINT1 ("(%dth)", idx);
3191 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3197 else if (name == Mcommit)
3199 preedit_commit (ic);
3201 else if (name == Munhandle)
3203 preedit_commit (ic);
3208 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3212 && (actions = mplist_get (im_info->macros, name)))
3214 if (take_action_list (ic, actions) < 0)
3220 M17N_OBJECT_UNREF (ic->candidate_list);
3221 if (ic->cursor_pos > 0
3222 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3225 ic->candidate_list = mtext_property_value (prop);
3226 M17N_OBJECT_REF (ic->candidate_list);
3228 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3230 ic->candidate_from = mtext_property_start (prop);
3231 ic->candidate_to = mtext_property_end (prop);
3234 if (candidate_list != ic->candidate_list)
3235 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3236 if (candidate_index != ic->candidate_index)
3237 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3238 if (candidate_show != ic->candidate_show)
3239 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3244 /* Handle the input key KEY in the current state and map specified in
3245 the input context IC. If KEY is handled correctly, return 0.
3246 Otherwise, return -1. */
3249 handle_key (MInputContext *ic)
3251 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3252 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3253 MIMMap *map = ic_info->map;
3254 MIMMap *submap = NULL;
3255 MSymbol key = ic_info->keys[ic_info->key_head];
3256 MSymbol alias = Mnil;
3259 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3260 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3264 submap = mplist_get (map->submaps, key);
3267 && (alias = msymbol_get (alias, M_key_alias))
3269 submap = mplist_get (map->submaps, alias);
3274 if (! alias || alias == key)
3275 MDEBUG_PRINT (" submap-found");
3277 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3278 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3279 ic->preedit_changed = 1;
3280 ic->cursor_pos = ic_info->state_pos;
3281 ic_info->key_head++;
3282 ic_info->map = map = submap;
3283 if (map->map_actions)
3285 MDEBUG_PRINT (" map-actions:");
3286 if (take_action_list (ic, map->map_actions) < 0)
3288 MDEBUG_PRINT ("\n");
3292 else if (map->submaps)
3294 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3296 MSymbol key = ic_info->keys[i];
3297 char *name = msymbol_name (key);
3299 if (! name[0] || ! name[1])
3300 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3304 /* If this is the terminal map or we have shifted to another
3305 state, perform branch actions (if any). */
3306 if (! map->submaps || map != ic_info->map)
3308 if (map->branch_actions)
3310 MDEBUG_PRINT (" branch-actions:");
3311 if (take_action_list (ic, map->branch_actions) < 0)
3313 MDEBUG_PRINT ("\n");
3317 /* If MAP is still not the root map, shift to the current
3319 if (ic_info->map != ic_info->state->map)
3320 shift_state (ic, ic_info->state->name);
3325 /* MAP can not handle KEY. */
3327 /* If MAP is the root map of the initial state, it means that
3328 the current input method can not handle KEY. */
3329 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3331 MDEBUG_PRINT (" unhandled\n");
3335 if (map != ic_info->state->map)
3337 /* If MAP is not the root map... */
3338 /* If MAP has branch actions, perform them. */
3339 if (map->branch_actions)
3341 MDEBUG_PRINT (" branch-actions:");
3342 if (take_action_list (ic, map->branch_actions) < 0)
3344 MDEBUG_PRINT ("\n");
3348 /* If MAP is still not the root map, shift to the current
3350 if (ic_info->map != ic_info->state->map)
3351 shift_state (ic, ic_info->state->name);
3355 /* MAP is the root map, perform branch actions (if any) or
3356 shift to the initial state. */
3357 if (map->branch_actions)
3359 MDEBUG_PRINT (" branch-actions:");
3360 if (take_action_list (ic, map->branch_actions) < 0)
3362 MDEBUG_PRINT ("\n");
3367 shift_state (ic, Mnil);
3370 MDEBUG_PRINT ("\n");
3374 /* Initialize IC->ic_info. */
3377 init_ic_info (MInputContext *ic)
3379 MInputMethodInfo *im_info = ic->im->info;
3380 MInputContextInfo *ic_info = ic->info;
3383 MLIST_INIT1 (ic_info, keys, 8);;
3385 ic_info->markers = mplist ();
3387 ic_info->vars = mplist ();
3388 if (im_info->configured_vars)
3389 MPLIST_DO (plist, im_info->configured_vars)
3391 MPlist *pl = MPLIST_PLIST (plist);
3392 MSymbol name = MPLIST_SYMBOL (pl);
3394 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3395 if (MPLIST_KEY (pl) != Mt)
3397 MPlist *p = mplist ();
3399 mplist_push (ic_info->vars, Mplist, p);
3400 M17N_OBJECT_UNREF (p);
3401 mplist_add (p, Msymbol, name);
3402 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3406 if (im_info->externals)
3408 MPlist *func_args = mplist (), *plist;
3410 mplist_add (func_args, Mt, ic);
3411 MPLIST_DO (plist, im_info->externals)
3413 MIMExternalModule *external = MPLIST_VAL (plist);
3414 MIMExternalFunc func
3415 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3420 M17N_OBJECT_UNREF (func_args);
3423 ic_info->preedit_saved = mtext ();
3424 ic_info->tick = im_info->tick;
3427 /* Finalize IC->ic_info. */
3430 fini_ic_info (MInputContext *ic)
3432 MInputMethodInfo *im_info = ic->im->info;
3433 MInputContextInfo *ic_info = ic->info;
3435 if (im_info->externals)
3437 MPlist *func_args = mplist (), *plist;
3439 mplist_add (func_args, Mt, ic);
3440 MPLIST_DO (plist, im_info->externals)
3442 MIMExternalModule *external = MPLIST_VAL (plist);
3443 MIMExternalFunc func
3444 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3449 M17N_OBJECT_UNREF (func_args);
3452 MLIST_FREE1 (ic_info, keys);
3453 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3454 M17N_OBJECT_UNREF (ic_info->markers);
3455 M17N_OBJECT_UNREF (ic_info->vars);
3456 M17N_OBJECT_UNREF (ic_info->preceding_text);
3457 M17N_OBJECT_UNREF (ic_info->following_text);
3459 memset (ic_info, 0, sizeof (MInputContextInfo));
3463 re_init_ic (MInputContext *ic, int reload)
3465 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3466 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3467 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3469 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3470 preedit_changed = mtext_nchars (ic->preedit) > 0;
3471 cursor_pos_changed = ic->cursor_pos > 0;
3472 candidates_changed = 0;
3473 if (ic->candidate_list)
3475 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3476 M17N_OBJECT_UNREF (ic->candidate_list);
3478 if (ic->candidate_show)
3480 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3481 ic->candidate_show = 0;
3483 if (ic->candidate_index > 0)
3485 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3486 ic->candidate_index = 0;
3487 ic->candidate_from = ic->candidate_to = 0;
3489 if (mtext_nchars (ic->produced) > 0)
3490 mtext_reset (ic->produced);
3491 if (mtext_nchars (ic->preedit) > 0)
3492 mtext_reset (ic->preedit);
3494 M17N_OBJECT_UNREF (ic->plist);
3495 ic->plist = mplist ();
3499 reload_im_info (im_info);
3501 shift_state (ic, Mnil);
3502 ic->status_changed = status_changed;
3503 ic->preedit_changed = preedit_changed;
3504 ic->cursor_pos_changed = cursor_pos_changed;
3505 ic->candidates_changed = candidates_changed;
3509 reset_ic (MInputContext *ic, MSymbol ignore)
3511 MDEBUG_PRINT ("\n [IM] reset\n");
3516 open_im (MInputMethod *im)
3518 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3521 MERROR (MERROR_IM, -1);
3528 close_im (MInputMethod *im)
3534 create_ic (MInputContext *ic)
3536 MInputContextInfo *ic_info;
3538 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3541 shift_state (ic, Mnil);
3546 destroy_ic (MInputContext *ic)
3553 check_reload (MInputContext *ic, MSymbol key)
3555 MInputMethodInfo *im_info = ic->im->info;
3556 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3560 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3564 MPLIST_DO (plist, plist)
3566 MSymbol this_key, alias;
3568 if (MPLIST_MTEXT_P (plist))
3570 MText *mt = MPLIST_MTEXT (plist);
3571 int c = mtext_ref_char (mt, 0);
3575 this_key = one_char_symbol[c];
3579 MPlist *pl = MPLIST_PLIST (plist);
3581 this_key = MPLIST_SYMBOL (pl);
3585 && (alias = msymbol_get (alias, M_key_alias))
3586 && alias != this_key);
3590 if (MPLIST_TAIL_P (plist))
3593 MDEBUG_PRINT ("\n [IM] reload");
3599 /** Handle the input key KEY in the current state and map of IC->info.
3600 If KEY is handled but no text is produced, return 0, otherwise
3606 filter (MInputContext *ic, MSymbol key, void *arg)
3608 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3609 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3612 if (check_reload (ic, key))
3615 if (! ic_info->state)
3617 ic_info->key_unhandled = 1;
3620 mtext_reset (ic->produced);
3621 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3622 M17N_OBJECT_UNREF (ic_info->preceding_text);
3623 M17N_OBJECT_UNREF (ic_info->following_text);
3624 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3625 ic_info->key_unhandled = 0;
3628 if (handle_key (ic) < 0)
3630 /* KEY was not handled. Delete it from the current key sequence. */
3631 if (ic_info->used > 0)
3633 memmove (ic_info->keys, ic_info->keys + 1,
3634 sizeof (int) * (ic_info->used - 1));
3637 /* This forces returning 1. */
3638 ic_info->key_unhandled = 1;
3644 reset_ic (ic, Mnil);
3645 ic_info->key_unhandled = 1;
3648 /* Break the loop if all keys were handled. */
3649 } while (ic_info->key_head < ic_info->used);
3651 /* If the current map is the root of the initial state, we should
3652 produce any preedit text in ic->produced. */
3653 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map
3654 && mtext_nchars (ic->preedit) > 0)
3655 shift_state (ic, ((MIMState *) MPLIST_VAL (im_info->states))->name);
3657 if (mtext_nchars (ic->produced) > 0)
3659 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3662 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3663 Mlanguage, ic->im->language);
3666 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3670 /** Return 1 if the last event or key was not handled, otherwise
3673 There is no need of looking up because ic->produced should already
3674 contain the produced text (if any).
3679 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3681 mtext_cat (mt, ic->produced);
3682 mtext_reset (ic->produced);
3683 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3687 /* Input method command handler. */
3689 /* List of all (global and local) commands.
3690 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3691 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3692 Global commands are stored as (t (t COMMAND ...)) */
3695 /* Input method variable handler. */
3698 /* Support functions for mdebug_dump_im. */
3701 dump_im_map (MPlist *map_list, int indent)
3704 MSymbol key = MPLIST_KEY (map_list);
3705 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3707 prefix = (char *) alloca (indent + 1);
3708 memset (prefix, 32, indent);
3709 prefix[indent] = '\0';
3711 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3712 if (map->map_actions)
3713 mdebug_dump_plist (map->map_actions, indent + 2);
3716 MPLIST_DO (map_list, map->submaps)
3718 fprintf (stderr, "\n%s ", prefix);
3719 dump_im_map (map_list, indent + 2);
3722 if (map->branch_actions)
3724 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3725 mdebug_dump_plist (map->branch_actions, indent + 4);
3726 fprintf (stderr, ")");
3728 fprintf (stderr, ")");
3733 dump_im_state (MIMState *state, int indent)
3738 prefix = (char *) alloca (indent + 1);
3739 memset (prefix, 32, indent);
3740 prefix[indent] = '\0';
3742 fprintf (stderr, "(%s", msymbol_name (state->name));
3743 if (state->map->submaps)
3745 MPLIST_DO (map_list, state->map->submaps)
3747 fprintf (stderr, "\n%s ", prefix);
3748 dump_im_map (map_list, indent + 2);
3751 fprintf (stderr, ")");
3759 Minput_driver = msymbol ("input-driver");
3761 Minput_preedit_start = msymbol ("input-preedit-start");
3762 Minput_preedit_done = msymbol ("input-preedit-done");
3763 Minput_preedit_draw = msymbol ("input-preedit-draw");
3764 Minput_status_start = msymbol ("input-status-start");
3765 Minput_status_done = msymbol ("input-status-done");
3766 Minput_status_draw = msymbol ("input-status-draw");
3767 Minput_candidates_start = msymbol ("input-candidates-start");
3768 Minput_candidates_done = msymbol ("input-candidates-done");
3769 Minput_candidates_draw = msymbol ("input-candidates-draw");
3770 Minput_set_spot = msymbol ("input-set-spot");
3771 Minput_focus_move = msymbol ("input-focus-move");
3772 Minput_focus_in = msymbol ("input-focus-in");
3773 Minput_focus_out = msymbol ("input-focus-out");
3774 Minput_toggle = msymbol ("input-toggle");
3775 Minput_reset = msymbol ("input-reset");
3776 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3777 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3778 Mcustomized = msymbol ("customized");
3779 Mconfigured = msymbol ("configured");
3780 Minherited = msymbol ("inherited");
3782 minput_default_driver.open_im = open_im;
3783 minput_default_driver.close_im = close_im;
3784 minput_default_driver.create_ic = create_ic;
3785 minput_default_driver.destroy_ic = destroy_ic;
3786 minput_default_driver.filter = filter;
3787 minput_default_driver.lookup = lookup;
3788 minput_default_driver.callback_list = mplist ();
3789 mplist_put (minput_default_driver.callback_list, Minput_reset,
3791 minput_driver = &minput_default_driver;
3793 fully_initialized = 0;
3800 if (fully_initialized)
3802 free_im_list (im_info_list);
3804 free_im_list (im_custom_list);
3806 free_im_list (im_config_list);
3807 M17N_OBJECT_UNREF (load_im_info_keys);
3810 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3811 M17N_OBJECT_UNREF (minput_driver->callback_list);
3816 minput__callback (MInputContext *ic, MSymbol command)
3818 MInputCallbackFunc func;
3820 if (! ic->im->driver.callback_list)
3822 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3826 (func) (ic, command);
3831 minput__char_to_key (int c)
3833 if (c < 0 || c >= 0x100)
3836 return one_char_symbol[c];
3840 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3845 /*** @addtogroup m17nInputMethod */
3850 @name Variables: Predefined symbols for callback commands.
3852 These are the predefined symbols that are used as the @c COMMAND
3853 argument of callback functions of an input method driver (see
3854 #MInputDriver::callback_list).
3856 Most of them do not require extra argument nor return any value;
3857 exceptions are these:
3859 Minput_get_surrounding_text: When a callback function assigned for
3860 this command is called, the first element of #MInputContext::plist
3861 has key #Minteger and the value specifies which portion of the
3862 surrounding text should be retrieved. If the value is positive,
3863 it specifies the number of characters following the current cursor
3864 position. If the value is negative, the absolute value specifies
3865 the number of characters preceding the current cursor position.
3867 If the surrounding text is currently supported, the callback
3868 function must set the key of this element to #Mtext and the value
3869 to the retrieved M-text. The length of the M-text may be shorter
3870 than the requested number of characters, if the available text is
3871 not that long. The length can be zero in the worst case. Or, the
3872 length may be longer if an application thinks it is more efficient
3873 to return that length.
3875 If the surrounding text is not currently supported, the callback
3876 function should return without changing the first element of
3877 #MInputContext::plist.
3879 Minput_delete_surrounding_text: When a callback function assigned
3880 for this command is called, the first element of
3881 #MInputContext::plist has key #Minteger and the value specifies
3882 which portion of the surrounding text should be deleted in the
3883 same way as the case of Minput_get_surrounding_text. The callback
3884 function must delete the specified text. It should not alter
3885 #MInputContext::plist. */
3887 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3889 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3890 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3892 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
3894 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
3895 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
3896 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
3897 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
3898 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
3901 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
3902 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
3903 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
3904 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
3905 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
3907 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
3908 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѲ½¤µ¤»¤ë¤³¤È¤Ê¤¯ÊÖ¤µ¤Ê¤¯¤Æ
3911 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
3912 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
3913 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
3914 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
3915 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
3916 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
3920 MSymbol Minput_preedit_start;
3921 MSymbol Minput_preedit_done;
3922 MSymbol Minput_preedit_draw;
3923 MSymbol Minput_status_start;
3924 MSymbol Minput_status_done;
3925 MSymbol Minput_status_draw;
3926 MSymbol Minput_candidates_start;
3927 MSymbol Minput_candidates_done;
3928 MSymbol Minput_candidates_draw;
3929 MSymbol Minput_set_spot;
3930 MSymbol Minput_toggle;
3931 MSymbol Minput_reset;
3932 MSymbol Minput_get_surrounding_text;
3933 MSymbol Minput_delete_surrounding_text;
3939 @name Variables: Predefined symbols for special input events.
3941 These are the predefined symbols that are used as the @c KEY
3942 argument of minput_filter (). */
3944 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3946 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
3951 MSymbol Minput_focus_out;
3952 MSymbol Minput_focus_in;
3953 MSymbol Minput_focus_move;
3959 @name Variables: Predefined symbols used in input method information.
3961 These are the predefined symbols describing status of input method
3962 command and variable, and are used in a return value of
3963 minput_get_command () and minput_get_variable (). */
3965 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3967 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
3968 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
3972 MSymbol Mcustomized;
3973 MSymbol Mconfigured;
3979 @brief The default driver for internal input methods.
3981 The variable #minput_default_driver is the default driver for
3982 internal input methods.
3984 The member MInputDriver::open_im () searches the m17n database for
3985 an input method that matches the tag \< #Minput_method, $LANGUAGE,
3986 $NAME\> and loads it.
3988 The member MInputDriver::callback_list () is @c NULL. Thus, it is
3989 programmers responsibility to set it to a plist of proper callback
3990 functions. Otherwise, no feedback information (e.g. preedit text)
3991 can be shown to users.
3993 The macro M17N_INIT () sets the variable #minput_driver to the
3994 pointer to this driver so that all internal input methods use it.
3996 Therefore, unless @c minput_driver is set differently, the driver
3997 dependent arguments $ARG of the functions whose name begins with
3998 "minput_" are all ignored. */
4000 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4002 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4004 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4005 \< #Minput_method, $LANGUAGE, $NAME\>
4006 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4008 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4009 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4010 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4011 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4013 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4014 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4016 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4017 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4019 MInputDriver minput_default_driver;
4023 @brief The driver for internal input methods.
4025 The variable #minput_driver is a pointer to the input method
4026 driver that is used by internal input methods. The macro
4027 M17N_INIT () initializes it to a pointer to #minput_default_driver
4028 if <m17n<EM></EM>.h> is included. */
4030 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4032 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4033 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4034 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4035 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4037 MInputDriver *minput_driver;
4039 MSymbol Minput_driver;
4044 @brief Open an input method.
4046 The minput_open_im () function opens an input method whose
4047 language and name match $LANGUAGE and $NAME, and returns a pointer
4048 to the input method object newly allocated.
4050 This function at first decides a driver for the input method as
4053 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4054 #minput_driver is used.
4056 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4057 driver pointed to by the property value is used to open the input
4058 method. If $NAME has no such a property, @c NULL is returned.
4060 Then, the member MInputDriver::open_im () of the driver is
4063 $ARG is set in the member @c arg of the structure MInputMethod so
4064 that the driver can refer to it. */
4066 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4068 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4069 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4071 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4073 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4074 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4076 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4077 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4078 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4080 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4082 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4084 @latexonly \IPAlabel{minput_open} @endlatexonly
4089 minput_open_im (MSymbol language, MSymbol name, void *arg)
4092 MInputDriver *driver;
4096 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4097 msymbol_name (language), msymbol_name (name));
4099 driver = minput_driver;
4102 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4104 MERROR (MERROR_IM, NULL);
4107 MSTRUCT_CALLOC (im, MERROR_IM);
4108 im->language = language;
4111 im->driver = *driver;
4112 if ((*im->driver.open_im) (im) < 0)
4114 MDEBUG_PRINT (" failed\n");
4118 MDEBUG_PRINT (" ok\n");
4125 @brief Close an input method.
4127 The minput_close_im () function closes the input method $IM, which
4128 must have been created by minput_open_im (). */
4131 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4133 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4134 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4137 minput_close_im (MInputMethod *im)
4139 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4140 msymbol_name (im->name), msymbol_name (im->language));
4141 (*im->driver.close_im) (im);
4143 MDEBUG_PRINT (" done\n");
4149 @brief Create an input context.
4151 The minput_create_ic () function creates an input context object
4152 associated with input method $IM, and calls callback functions
4153 corresponding to #Minput_preedit_start, #Minput_status_start, and
4154 #Minput_status_draw in this order.
4157 If an input context is successfully created, minput_create_ic ()
4158 returns a pointer to it. Otherwise it returns @c NULL. */
4161 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4163 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4164 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4165 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4166 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4169 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4170 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4174 minput_create_ic (MInputMethod *im, void *arg)
4178 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4179 msymbol_name (im->name), msymbol_name (im->language));
4180 MSTRUCT_CALLOC (ic, MERROR_IM);
4183 ic->preedit = mtext ();
4184 ic->candidate_list = NULL;
4185 ic->produced = mtext ();
4186 ic->spot.x = ic->spot.y = 0;
4188 ic->plist = mplist ();
4189 if ((*im->driver.create_ic) (ic) < 0)
4191 MDEBUG_PRINT (" failed\n");
4192 M17N_OBJECT_UNREF (ic->preedit);
4193 M17N_OBJECT_UNREF (ic->produced);
4194 M17N_OBJECT_UNREF (ic->plist);
4199 if (im->driver.callback_list)
4201 minput__callback (ic, Minput_preedit_start);
4202 minput__callback (ic, Minput_status_start);
4203 minput__callback (ic, Minput_status_draw);
4206 MDEBUG_PRINT (" ok\n");
4213 @brief Destroy an input context.
4215 The minput_destroy_ic () function destroys the input context $IC,
4216 which must have been created by minput_create_ic (). It calls
4217 callback functions corresponding to #Minput_preedit_done,
4218 #Minput_status_done, and #Minput_candidates_done in this order. */
4221 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4223 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4224 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4225 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4226 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4227 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4231 minput_destroy_ic (MInputContext *ic)
4233 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4234 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4235 if (ic->im->driver.callback_list)
4237 minput__callback (ic, Minput_preedit_done);
4238 minput__callback (ic, Minput_status_done);
4239 minput__callback (ic, Minput_candidates_done);
4241 (*ic->im->driver.destroy_ic) (ic);
4242 M17N_OBJECT_UNREF (ic->preedit);
4243 M17N_OBJECT_UNREF (ic->produced);
4244 M17N_OBJECT_UNREF (ic->plist);
4245 MDEBUG_PRINT (" done\n");
4252 @brief Filter an input key.
4254 The minput_filter () function filters input key $KEY according to
4255 input context $IC, and calls callback functions corresponding to
4256 #Minput_preedit_draw, #Minput_status_draw, and
4257 #Minput_candidates_draw if the preedit text, the status, and the
4258 current candidate are changed respectively.
4260 To make the input method commit the current preedit text (if any)
4261 and shift to the initial state, call this function with #Mnil as
4264 To inform the input method about the focus-out event, call this
4265 function with #Minput_focus_out as $KEY.
4267 To inform the input method about the focus-in event, call this
4268 function with #Minput_focus_in as $KEY.
4270 To inform the input method about the focus-move event (i.e. input
4271 spot change within the same input context), call this function
4272 with #Minput_focus_move as $KEY.
4275 If $KEY is filtered out, this function returns 1. In that case,
4276 the caller should discard the key. Otherwise, it returns 0, and
4277 the caller should handle the key, for instance, by calling the
4278 function minput_lookup () with the same key. */
4281 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4283 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4284 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4285 #Minput_preedit_draw, #Minput_status_draw,
4286 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4289 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4290 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4291 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4292 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4294 @latexonly \IPAlabel{minput_filter} @endlatexonly
4298 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4305 ret = (*ic->im->driver.filter) (ic, key, arg);
4307 if (ic->im->driver.callback_list)
4309 if (ic->preedit_changed)
4310 minput__callback (ic, Minput_preedit_draw);
4311 if (ic->status_changed)
4312 minput__callback (ic, Minput_status_draw);
4313 if (ic->candidates_changed)
4314 minput__callback (ic, Minput_candidates_draw);
4323 @brief Look up a text produced in the input context.
4325 The minput_lookup () function looks up a text in the input context
4326 $IC. $KEY must be identical to the one that was used in the previous call of
4329 If a text was produced by the input method, it is concatenated
4332 This function calls #MInputDriver::lookup .
4335 If $KEY was correctly handled by the input method, this function
4336 returns 0. Otherwise, it returns -1, even though some text
4337 might be produced in $MT. */
4340 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4342 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4343 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4345 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4348 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4351 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4352 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4353 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4355 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4358 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4360 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4365 @brief Set the spot of the input context.
4367 The minput_set_spot () function sets the spot of input context $IC
4368 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4369 The semantics of these values depends on the input method driver.
4371 For instance, a driver designed to work in a CUI environment may
4372 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4373 $DESCENT . A driver designed to work in a window system may
4374 interpret $X and $Y as the pixel offsets relative to the origin of the
4375 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4376 descent pixels of the line at ($X . $Y ).
4378 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4380 $MT and $POS are the M-text and the character position at the spot.
4381 $MT may be @c NULL, in which case, the input method cannot get
4382 information about the text around the spot. */
4385 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4387 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4388 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4389 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4391 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4392 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4393 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4394 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4395 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4396 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4398 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4400 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4401 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4405 minput_set_spot (MInputContext *ic, int x, int y,
4406 int ascent, int descent, int fontsize,
4411 ic->spot.ascent = ascent;
4412 ic->spot.descent = descent;
4413 ic->spot.fontsize = fontsize;
4416 if (ic->im->driver.callback_list)
4417 minput__callback (ic, Minput_set_spot);
4422 @brief Toggle input method.
4424 The minput_toggle () function toggles the input method associated
4425 with input context $IC. */
4427 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4429 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4430 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4434 minput_toggle (MInputContext *ic)
4436 if (ic->im->driver.callback_list)
4437 minput__callback (ic, Minput_toggle);
4438 ic->active = ! ic->active;
4444 @brief Reset an input context.
4446 The minput_reset_ic () function resets input context $IC by
4447 calling a callback function corresponding to #Minput_reset. It
4448 resets the status of $IC to its initial one. As the
4449 current preedit text is deleted without commitment, if necessary,
4450 call minput_filter () with the arg @r key #Mnil to force the input
4451 method to commit the preedit in advance. */
4454 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4456 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4457 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4458 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4459 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4460 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4461 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4464 minput_reset_ic (MInputContext *ic)
4466 if (ic->im->driver.callback_list)
4467 minput__callback (ic, Minput_reset);
4473 @brief Get title and icon filename of an input method.
4475 The minput_get_title_icon () function returns a plist containing a
4476 title and icon filename (if any) of an input method specified by
4477 $LANGUAGE and $NAME.
4479 The first element of the plist has key #Mtext and the value is an
4480 M-text of the title for identifying the input method. The second
4481 element (if any) has key #Mtext and the value is an M-text of the
4482 icon image (absolute) filename for the same purpose.
4485 If there exists a specified input method and it defines an title,
4486 a plist is returned. Otherwise, NULL is returned. The caller
4487 must free the plist by m17n_object_unref (). */
4489 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4491 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4492 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4495 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4496 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4497 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¤ÎÀäÂÐ¥Õ¥¡¥¤¥ë¥Í¡¼¥à¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4500 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4501 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4502 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4505 minput_get_title_icon (MSymbol language, MSymbol name)
4507 MInputMethodInfo *im_info;
4514 im_info = get_im_info (language, name, Mnil, Mtitle);
4515 if (! im_info || !im_info->title)
4517 mt = mtext_get_prop (im_info->title, 0, Mtext);
4519 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4522 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4525 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4526 (char *) MSYMBOL_NAME (name));
4527 file = mdatabase__find_file (buf);
4528 if (! file && language == Mt)
4530 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4531 file = mdatabase__find_file (buf);
4536 mplist_add (plist, Mtext, im_info->title);
4539 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4541 mplist_add (plist, Mtext, mt);
4542 M17N_OBJECT_UNREF (mt);
4550 @brief Get description text of an input method.
4552 The minput_get_description () function returns an M-text that
4553 describes the input method specified by $LANGUAGE and $NAME.
4556 If the specified input method has a description text, a pointer to
4557 #MText is returned. The caller has to free it by m17n_object_unref ().
4558 If the input method does not have a description text, @c NULL is
4561 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4563 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4564 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4566 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4567 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4568 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4569 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4572 minput_get_description (MSymbol language, MSymbol name)
4574 MInputMethodInfo *im_info;
4582 extra = language, language = Mt;
4584 im_info = get_im_info (language, name, extra, Mdescription);
4585 if (! im_info || ! im_info->description)
4587 M17N_OBJECT_REF (im_info->description);
4588 return im_info->description;
4594 @brief Get information about input method command(s).
4596 The minput_get_command () function returns information about
4597 the command $COMMAND of the input method specified by $LANGUAGE and
4598 $NAME. An input method command is a pseudo key event to which one
4599 or more actual input key sequences are assigned.
4601 There are two kinds of commands, global and local. A global
4602 command has a global definition, and the description and the key
4603 assignment may be inherited by a local command. Each input method
4604 defines a local command which has a local key assignment. It may
4605 also declare a local command that inherits the definition of a
4606 global command of the same name.
4608 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4609 information about a global command. Otherwise information about a
4610 local command is returned.
4612 If $COMMAND is #Mnil, information about all commands is returned.
4614 The return value is a @e well-formed plist (#m17nPlist) of this
4617 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4619 @c NAME is a symbol representing the command name.
4621 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4622 command has no description.
4624 @c STATUS is a symbol representing how the key assignment is decided.
4625 The value is #Mnil (the default key assignment), #Mcustomized (the
4626 key assignment is customized by per-user configuration file), or
4627 #Mconfigured (the key assignment is set by the call of
4628 minput_config_command ()). For a local command only, it may also
4629 be #Minherited (the key assignment is inherited from the
4630 corresponding global command).
4632 @c KEYSEQ is a plist of one or more symbols representing a key
4633 sequence assigned to the command. If there's no KEYSEQ, the
4634 command is currently disabled (i.e. no key sequence can trigger
4635 actions of the command).
4637 If $COMMAND is not #Mnil, the first element of the returned plist
4638 contains the information about $COMMAND.
4642 If the requested information was found, a pointer to a non-empty
4643 plist is returned. As the plist is kept in the library, the
4644 caller must not modify nor free it.
4646 Otherwise (the specified input method or the specified command
4647 does not exist), @c NULL is returned. */
4649 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4651 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4652 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4653 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4654 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4656 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4657 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4658 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4659 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4660 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4662 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4663 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4666 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4668 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4671 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4673 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4675 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4678 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4679 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4680 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4681 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4682 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4683 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4685 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4686 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4687 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4688 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4690 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4691 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4695 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4696 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4699 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4704 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4706 /* Return a description of the command COMMAND of the input method
4707 specified by LANGUAGE and NAME. */
4708 MPlist *cmd = minput_get_command (langauge, name, command);
4713 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4714 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4715 return (mplist_key (plist) == Mtext
4716 ? (MText *) mplist_value (plist)
4722 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4724 MInputMethodInfo *im_info;
4728 im_info = get_im_info (language, name, Mnil, Mcommand);
4730 || ! im_info->configured_cmds
4731 || MPLIST_TAIL_P (im_info->configured_cmds))
4733 if (command == Mnil)
4734 return im_info->configured_cmds;
4735 return mplist__assq (im_info->configured_cmds, command);
4741 @brief Configure the key sequence of an input method command.
4743 The minput_config_command () function assigns a list of key
4744 sequences $KEYSEQLIST to the command $COMMAND of the input method
4745 specified by $LANGUAGE and $NAME.
4747 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4748 sequences, and each key sequence must be a plist of symbols.
4750 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4752 If $KEYSEQLIST is NULL, the configuration of the command for the
4753 input method is canceled, and the default key sequences become
4754 effective. In such case, if $COMMAND is #Mnil, configurations for
4755 all commands of the input method are canceled.
4757 If $NAME is #Mnil, this function configures the key assignment of a
4758 global command, not that of a specific input method.
4760 The configuration takes effect for input methods opened or
4761 re-opened later in the current session. In order to make the
4762 configuration take effect for the future session, it must be saved
4763 in a per-user configuration file by the function
4764 minput_save_config ().
4768 If the operation was successful, this function returns 0,
4769 otherwise returns -1. The operation fails in these cases:
4771 <li>$KEYSEQLIST is not in a valid form.
4772 <li>$COMMAND is not available for the input method.
4773 <li>$LANGUAGE and $NAME do not specify an existing input method.
4777 minput_get_commands (), minput_save_config ().
4780 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4782 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4783 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4784 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4786 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4787 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4789 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4791 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4792 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4793 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4796 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4797 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4799 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4800 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4801 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4802 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4806 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4808 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4809 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4810 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4814 minput_get_commands (), minput_save_config ().
4818 /* Add "C-x u" to the "start" command of Unicode input method. */
4820 MSymbol start_command = msymbol ("start");
4821 MSymbol unicode = msymbol ("unicode");
4822 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4824 /* At first get the current key-sequence assignment. */
4825 cmd = mplist_get_command (Mt, unicode, start_command);
4828 /* The input method does not have the command "start". Here
4829 should come some error handling code. */
4831 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4832 the part (KEY-SEQUENCE ...). */
4833 plist = mplist_next (mplist_next (mplist_value (cmd)));
4834 /* Copy it because we should not modify it directly. */
4835 key_seq_list = mplist_copy (plist);
4836 m17n_object_unref (cmds);
4838 key_seq = mplist ();
4839 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4840 mplist_add (key_seq, Msymbol, msymbol ("u"));
4841 mplist_add (key_seq_list, Mplist, key_seq);
4842 m17n_object_unref (key_seq);
4844 minput_config_command (Mt, unicode, start_command, key_seq_list);
4845 m17n_object_unref (key_seq_list);
4850 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4853 MInputMethodInfo *im_info, *config;
4860 if (command == Mnil)
4861 MERROR (MERROR_IM, -1);
4862 MPLIST_DO (plist, keyseqlist)
4863 if (! MPLIST_PLIST_P (plist)
4864 || ! check_command_keyseq (plist))
4865 MERROR (MERROR_IM, -1);
4868 im_info = get_im_info (language, name, Mnil, Mcommand);
4870 MERROR (MERROR_IM, -1);
4873 || ! mplist__assq (im_info->cmds, command)))
4874 MERROR (MERROR_IM, -1);
4876 config = get_config_info (im_info);
4879 if (! im_config_list)
4880 im_config_list = mplist ();
4881 config = new_im_info (NULL, language, name, Mnil, im_config_list);
4882 config->cmds = mplist ();
4883 config->vars = mplist ();
4886 if (command == Mnil)
4888 MInputMethodInfo *custom = get_custom_info (im_info);
4890 mplist_set (config->cmds, Mnil, NULL);
4891 if (custom && custom->cmds)
4893 MPLIST_DO (plist, custom->cmds)
4895 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
4897 mplist_add (plist, Msymbol, command);
4898 mplist_push (config->cmds, Mplist, plist);
4899 M17N_OBJECT_UNREF (plist);
4905 plist = mplist__assq (config->cmds, command);
4908 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
4909 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
4910 if (! MPLIST_TAIL_P (plist))
4911 mplist_set (plist, Mnil, NULL); /* () */
4916 mplist_add (config->cmds, Mplist, plist);
4917 M17N_OBJECT_UNREF (plist);
4918 plist = mplist_add (plist, Msymbol, command);
4919 plist = MPLIST_NEXT (plist);
4925 plist = mplist_add (plist, Msymbol, Mnil);
4926 MPLIST_DO (keyseqlist, keyseqlist)
4928 pl = mplist_copy (MPLIST_VAL (keyseqlist));
4929 plist = mplist_add (plist, Mplist, pl);
4930 M17N_OBJECT_UNREF (pl);
4934 config_all_commands (im_info);
4935 im_info->tick = time (NULL);
4942 @brief Get information about input method variable(s).
4944 The minput_get_variable () function returns information about
4945 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
4946 An input method variable controls behavior of an input method.
4948 There are two kinds of variables, global and local. A global
4949 variable has a global definition, and the description and the value
4950 may be inherited by a local variable. Each input method defines a
4951 local variable which has local value. It may also declare a
4952 local variable that inherits definition of a global variable of
4955 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
4956 variable is returned. Otherwise information about a local variable
4959 If $VARIABLE is #Mnil, information about all variables is
4962 The return value is a @e well-formed plist (#m17nPlist) of this
4965 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
4967 @c NAME is a symbol representing the variable name.
4969 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
4970 variable has no description.
4972 @c STATUS is a symbol representing how the value is decided. The
4973 value is #Mnil (the default value), #Mcustomized (the value is
4974 customized by per-user configuration file), or #Mconfigured (the
4975 value is set by the call of minput_config_variable ()). For a
4976 local variable only, it may also be #Minherited (the value is
4977 inherited from the corresponding global variable).
4979 @c VALUE is the initial value of the variable. If the key of this
4980 element is #Mt, the variable has no initial value. Otherwise, the
4981 key is #Minteger, #Msymbol, or #Mtext and the value is of the
4984 @c VALID-VALUEs (if any) specify which values the variable can have.
4985 They have the same type (i.e. having the same key) as @c VALUE except
4986 for the case that VALUE is an integer. In that case, @c VALID-VALUE
4987 may be a plist of two integers specifying the range of possible
4990 If there no @c VALID-VALUE, the variable can have any value as long
4991 as the type is the same as @c VALUE.
4993 If $VARIABLE is not #Mnil, the first element of the returned plist
4994 contains the information about $VARIABLE.
4998 If the requested information was found, a pointer to a non-empty
4999 plist is returned. As the plist is kept in the library, the
5000 caller must not modify nor free it.
5002 Otherwise (the specified input method or the specified variable
5003 does not exist), @c NULL is returned. */
5005 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5007 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5008 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5009 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5011 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5012 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5013 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5014 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5017 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5018 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5020 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5022 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5024 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5027 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5029 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5032 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5033 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5034 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5035 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5036 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5037 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5039 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5040 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5041 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5043 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5044 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5045 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5046 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5048 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5051 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5052 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5056 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5057 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5060 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5064 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5066 MInputMethodInfo *im_info;
5070 im_info = get_im_info (language, name, Mnil, Mvariable);
5071 if (! im_info || ! im_info->configured_vars)
5073 if (variable == Mnil)
5074 return im_info->configured_vars;
5075 return mplist__assq (im_info->configured_vars, variable);
5081 @brief Configure the value of an input method variable.
5083 The minput_config_variable () function assigns $VALUE to the
5084 variable $VARIABLE of the input method specified by $LANGUAGE and
5087 If $VALUE is not NULL, it must be a plist of one element whose key
5088 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5091 If $VALUE is NULL, a configuration for the variable for the input
5092 method is canceled, and the variable is initialized to the default
5093 value. In that case, if $VARIABLE is #Mnil, configurations for
5094 all variables of the input method are canceled.
5096 If $NAME is #Mnil, this function configure the value of global
5097 variable, not that of a specific input method.
5099 The configuration takes effect for input methods opened or
5100 re-opened later in the current session. To make the configuration
5101 take effect for the future session, it must be saved in a per-user
5102 configuration file by the function minput_save_config ().
5106 If the operation was successful, this function returns 0,
5107 otherwise returns -1. The operation fails in these cases:
5109 <li>$VALUE is not in a valid form, the type does not match the
5110 definition, or the value is our of range.
5111 <li>$VARIABLE is not available for the input method.
5112 <li>$LANGUAGE and $NAME do not specify an existing input method.
5116 minput_get_variable (), minput_save_config (). */
5118 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5120 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5121 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5123 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5124 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5126 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5127 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5128 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5130 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5131 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5133 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5134 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5135 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5136 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5140 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5142 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5143 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5144 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5148 minput_get_commands (), minput_save_config ().
5151 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5154 MInputMethodInfo *im_info, *config;
5159 im_info = get_im_info (language, name, Mnil, Mvariable);
5161 MERROR (MERROR_IM, -1);
5162 if (variable == Mnil)
5165 MERROR (MERROR_IM, -1);
5167 else if (! im_info->vars
5168 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5169 MERROR (MERROR_IM, -1);
5171 if (variable != Mnil && value)
5173 plist = MPLIST_PLIST (plist);
5174 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5175 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5176 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5177 if (MPLIST_KEY (plist) != Mt
5178 && ! check_variable_value (value, plist))
5179 MERROR (MERROR_IM, -1);
5182 config = get_config_info (im_info);
5185 if (! im_config_list)
5186 im_config_list = mplist ();
5187 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5188 config->cmds = mplist ();
5189 config->vars = mplist ();
5192 if (variable == Mnil)
5194 MInputMethodInfo *custom = get_custom_info (im_info);
5196 mplist_set (config->vars, Mnil, NULL);
5197 if (custom && custom->cmds)
5199 MPLIST_DO (plist, custom->vars)
5201 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5203 mplist_add (plist, Msymbol, variable);
5204 mplist_push (config->vars, Mplist, plist);
5205 M17N_OBJECT_UNREF (plist);
5211 plist = mplist__assq (config->vars, variable);
5214 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5215 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5216 if (! MPLIST_TAIL_P (plist))
5217 mplist_set (plist, Mnil ,NULL); /* () */
5222 mplist_add (config->vars, Mplist, plist);
5223 M17N_OBJECT_UNREF (plist);
5224 plist = mplist_add (plist, Msymbol, variable);
5225 plist = MPLIST_NEXT (plist);
5229 plist = mplist_add (plist, Msymbol, Mnil);
5230 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5233 config_all_variables (im_info);
5234 im_info->tick = time (NULL);
5241 @brief Get the name of per-user configuration file.
5243 The minput_config_file () function returns the absolute path name
5244 of per-user configuration file into which minput_save_config ()
5245 save configurations. It is usually @c "config.mic" under the
5246 directory @c ".m17n.d" of user's home directory. It is not assured
5247 that the file of the returned name exists nor is
5248 readable/writable. If minput_save_config () fails and returns -1,
5249 an application program might check the file, make it
5250 writable (if possible), and try minput_save_config () again.
5254 This function returns a string. As the string is kept in the
5255 library, the caller must not modify nor free it.
5258 minput_save_config ()
5261 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5263 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5264 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5265 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5266 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5267 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5268 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5269 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5274 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5275 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5278 minput_save_config ()
5282 minput_config_file ()
5286 return mdatabase__file (im_custom_mdb);
5292 @brief Save configurations in per-user configuration file.
5294 The minput_save_config () function saves the configurations done
5295 so far in the current session into the per-user configuration
5300 If the operation was successful, 1 is returned. If the per-user
5301 configuration file is currently locked, 0 is returned. In that
5302 case, the caller may wait for a while and try again. If the
5303 configuration file is not writable, -1 is returned. In that case,
5304 the caller may check the name of the file by calling
5305 minput_config_file (), make it writable if possible, and try
5309 minput_config_file () */
5311 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5313 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5314 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5318 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5319 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5320 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5321 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5325 minput_config_file () */
5328 minput_save_config (void)
5330 MPlist *data, *tail, *plist, *p, *elt;
5334 ret = mdatabase__lock (im_custom_mdb);
5337 if (! im_config_list)
5339 update_custom_info ();
5340 if (! im_custom_list)
5341 im_custom_list = mplist ();
5342 data = tail = mplist ();
5344 MPLIST_DO (plist, im_config_list)
5346 MPlist *pl = MPLIST_PLIST (plist);
5347 MSymbol language, name, extra, command, variable;
5348 MInputMethodInfo *custom, *config;
5350 language = MPLIST_SYMBOL (pl);
5351 pl = MPLIST_NEXT (pl);
5352 name = MPLIST_SYMBOL (pl);
5353 pl = MPLIST_NEXT (pl);
5354 extra = MPLIST_SYMBOL (pl);
5355 pl = MPLIST_NEXT (pl);
5356 config = MPLIST_VAL (pl);
5357 custom = get_custom_info (config);
5359 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5361 MPLIST_DO (pl, config->cmds)
5363 elt = MPLIST_PLIST (pl);
5364 command = MPLIST_SYMBOL (elt);
5366 p = mplist__assq (custom->cmds, command);
5368 custom->cmds = mplist (), p = NULL;
5369 elt = MPLIST_NEXT (elt);
5370 if (MPLIST_TAIL_P (elt))
5373 mplist__pop_unref (p);
5377 elt = MPLIST_NEXT (elt);
5380 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5381 mplist_set (p, Mnil, NULL);
5382 mplist__conc (p, elt);
5386 p = MPLIST_PLIST (pl);
5387 mplist_add (custom->cmds, Mplist, p);
5392 MPLIST_DO (pl, config->vars)
5394 elt = MPLIST_PLIST (pl);
5395 variable = MPLIST_SYMBOL (elt);
5397 p = mplist__assq (custom->vars, variable);
5399 custom->vars = mplist (), p = NULL;
5400 elt = MPLIST_NEXT (elt);
5401 if (MPLIST_TAIL_P (elt))
5404 mplist__pop_unref (p);
5408 elt = MPLIST_NEXT (elt);
5411 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5412 mplist_set (p, Mnil, NULL);
5413 mplist__conc (p, elt);
5417 p = MPLIST_PLIST (pl);
5418 mplist_add (custom->vars, Mplist, p);
5423 M17N_OBJECT_UNREF (im_config_list);
5425 MPLIST_DO (plist, im_custom_list)
5427 MPlist *pl = MPLIST_PLIST (plist);
5428 MSymbol language, name, extra;
5429 MInputMethodInfo *custom, *im_info;
5431 language = MPLIST_SYMBOL (pl);
5432 pl = MPLIST_NEXT (pl);
5433 name = MPLIST_SYMBOL (pl);
5434 pl = MPLIST_NEXT (pl);
5435 extra = MPLIST_SYMBOL (pl);
5436 pl = MPLIST_NEXT (pl);
5437 custom = MPLIST_VAL (pl);
5438 im_info = lookup_im_info (im_info_list, language, name, extra);
5442 config_all_commands (im_info);
5444 config_all_variables (im_info);
5448 tail = mplist_add (tail, Mplist, elt);
5449 M17N_OBJECT_UNREF (elt);
5451 elt = mplist_add (elt, Mplist, pl);
5452 M17N_OBJECT_UNREF (pl);
5453 pl = mplist_add (pl, Msymbol, Minput_method);
5454 pl = mplist_add (pl, Msymbol, language);
5455 pl = mplist_add (pl, Msymbol, name);
5457 pl = mplist_add (pl, Msymbol, extra);
5458 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5461 elt = mplist_add (elt, Mplist, pl);
5462 M17N_OBJECT_UNREF (pl);
5463 pl = mplist_add (pl, Msymbol, Mcommand);
5464 MPLIST_DO (p, custom->cmds)
5465 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5467 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5470 elt = mplist_add (elt, Mplist, pl);
5471 M17N_OBJECT_UNREF (pl);
5472 pl = mplist_add (pl, Msymbol, Mvariable);
5473 MPLIST_DO (p, custom->vars)
5474 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5478 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5479 ret = mdatabase__save (im_custom_mdb, data);
5480 mdatabase__unlock (im_custom_mdb);
5481 M17N_OBJECT_UNREF (data);
5482 return (ret < 0 ? -1 : 1);
5488 @name Obsolete functions
5491 @name Obsolete ¤Ê´Ø¿ô
5497 @brief Get a list of variables of an input method (obsolete).
5499 This function is obsolete. Use minput_get_variable () instead.
5501 The minput_get_variables () function returns a plist (#MPlist) of
5502 variables used to control the behavior of the input method
5503 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5504 (#m17nPlist) of the following format:
5507 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5508 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5512 @c VARNAME is a symbol representing the variable name.
5514 @c DOC-MTEXT is an M-text describing the variable.
5516 @c DEFAULT-VALUE is the default value of the variable. It is a
5517 symbol, integer, or M-text.
5519 @c VALUEs (if any) specifies the possible values of the variable.
5520 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5521 @c TO), where @c FROM and @c TO specifies a range of possible
5524 For instance, suppose an input method has the variables:
5526 @li name:intvar, description:"value is an integer",
5527 initial value:0, value-range:0..3,10,20
5529 @li name:symvar, description:"value is a symbol",
5530 initial value:nil, value-range:a, b, c, nil
5532 @li name:txtvar, description:"value is an M-text",
5533 initial value:empty text, no value-range (i.e. any text)
5535 Then, the returned plist is as follows.
5538 (intvar ("value is an integer" 0 (0 3) 10 20)
5539 symvar ("value is a symbol" nil a b c nil)
5540 txtvar ("value is an M-text" ""))
5544 If the input method uses any variables, a pointer to #MPlist is
5545 returned. As the plist is kept in the library, the caller must not
5546 modify nor free it. If the input method does not use any
5547 variable, @c NULL is returned. */
5549 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5551 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5552 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5553 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5557 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5558 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5562 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5564 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5566 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5569 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5570 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5571 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5573 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5575 @li name:intvar, ÀâÌÀ:"value is an integer",
5576 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5578 @li name:symvar, ÀâÌÀ:"value is a symbol",
5579 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5581 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5582 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5584 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5587 (intvar ("value is an integer" 0 (0 3) 10 20)
5588 symvar ("value is a symbol" nil a b c nil)
5589 txtvar ("value is an M-text" ""))
5593 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5594 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5595 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5598 minput_get_variables (MSymbol language, MSymbol name)
5600 MInputMethodInfo *im_info;
5605 im_info = get_im_info (language, name, Mnil, Mvariable);
5606 if (! im_info || ! im_info->configured_vars)
5609 M17N_OBJECT_UNREF (im_info->bc_vars);
5610 im_info->bc_vars = mplist ();
5611 MPLIST_DO (vars, im_info->configured_vars)
5613 MPlist *plist = MPLIST_PLIST (vars);
5614 MPlist *elt = mplist ();
5616 mplist_push (im_info->bc_vars, Mplist, elt);
5617 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5618 elt = MPLIST_NEXT (elt);
5619 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5620 M17N_OBJECT_UNREF (elt);
5622 return im_info->bc_vars;
5628 @brief Set the initial value of an input method variable.
5630 The minput_set_variable () function sets the initial value of
5631 input method variable $VARIABLE to $VALUE for the input method
5632 specified by $LANGUAGE and $NAME.
5634 By default, the initial value is 0.
5636 This setting gets effective in a newly opened input method.
5639 If the operation was successful, 0 is returned. Otherwise -1 is
5640 returned, and #merror_code is set to #MERROR_IM. */
5642 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5644 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5645 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5646 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5648 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5650 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5653 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5654 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5657 minput_set_variable (MSymbol language, MSymbol name,
5658 MSymbol variable, void *value)
5661 MInputMethodInfo *im_info;
5666 if (variable == Mnil)
5667 MERROR (MERROR_IM, -1);
5668 plist = minput_get_variable (language, name, variable);
5669 plist = MPLIST_PLIST (plist);
5670 plist = MPLIST_NEXT (plist);
5672 mplist_add (pl, MPLIST_KEY (plist), value);
5673 ret = minput_config_variable (language, name, variable, pl);
5674 M17N_OBJECT_UNREF (pl);
5677 im_info = get_im_info (language, name, Mnil, Mvariable);
5686 @brief Get information about input method commands.
5688 The minput_get_commands () function returns information about
5689 input method commands of the input method specified by $LANGUAGE
5690 and $NAME. An input method command is a pseudo key event to which
5691 one or more actual input key sequences are assigned.
5693 There are two kinds of commands, global and local. Global
5694 commands are used by multiple input methods for the same purpose,
5695 and have global key assignments. Local commands are used only by
5696 a specific input method, and have only local key assignments.
5698 Each input method may locally change key assignments for global
5699 commands. The global key assignment for a global command is
5700 effective only when the current input method does not have local
5701 key assignments for that command.
5703 If $NAME is #Mnil, information about global commands is returned.
5704 In this case $LANGUAGE is ignored.
5706 If $NAME is not #Mnil, information about those commands that have
5707 local key assignments in the input method specified by $LANGUAGE
5708 and $NAME is returned.
5711 If no input method commands are found, this function returns @c NULL.
5713 Otherwise, a pointer to a plist is returned. The key of each
5714 element in the plist is a symbol representing a command, and the
5715 value is a plist of the form COMMAND-INFO described below.
5717 The first element of COMMAND-INFO has the key #Mtext, and the
5718 value is an M-text describing the command.
5720 If there are no more elements, that means no key sequences are
5721 assigned to the command. Otherwise, each of the remaining
5722 elements has the key #Mplist, and the value is a plist whose keys are
5723 #Msymbol and values are symbols representing input keys, which are
5724 currently assigned to the command.
5726 As the returned plist is kept in the library, the caller must not
5727 modify nor free it. */
5729 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5731 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5732 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5733 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5734 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5736 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5737 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5738 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5739 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5741 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5742 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5743 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5746 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5747 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5749 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5750 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5754 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5756 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5757 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5758 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5760 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5761 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5762 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5765 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5766 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5767 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5768 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5769 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5771 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5772 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5775 minput_get_commands (MSymbol language, MSymbol name)
5777 MInputMethodInfo *im_info;
5782 im_info = get_im_info (language, name, Mnil, Mcommand);
5783 if (! im_info || ! im_info->configured_vars)
5785 M17N_OBJECT_UNREF (im_info->bc_cmds);
5786 im_info->bc_cmds = mplist ();
5787 MPLIST_DO (cmds, im_info->configured_cmds)
5789 MPlist *plist = MPLIST_PLIST (cmds);
5790 MPlist *elt = mplist ();
5792 mplist_push (im_info->bc_cmds, Mplist, elt);
5793 mplist_add (elt, MPLIST_SYMBOL (plist),
5794 mplist_copy (MPLIST_NEXT (plist)));
5795 M17N_OBJECT_UNREF (elt);
5797 return im_info->bc_cmds;
5803 @brief Assign a key sequence to an input method command (obsolete).
5805 This function is obsolete. Use minput_config_command () instead.
5807 The minput_assign_command_keys () function assigns input key
5808 sequence $KEYSEQ to input method command $COMMAND for the input
5809 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5810 key sequence is assigned globally no matter what $LANGUAGE is.
5811 Otherwise the key sequence is assigned locally.
5813 Each element of $KEYSEQ must have the key $Msymbol and the value
5814 must be a symbol representing an input key.
5816 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5817 globally or locally.
5819 This assignment gets effective in a newly opened input method.
5822 If the operation was successful, 0 is returned. Otherwise -1 is
5823 returned, and #merror_code is set to #MERROR_IM. */
5825 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5827 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5828 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5829 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5830 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5831 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5833 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5834 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5836 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5837 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5839 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5842 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5843 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5846 minput_assign_command_keys (MSymbol language, MSymbol name,
5847 MSymbol command, MPlist *keyseq)
5853 if (command == Mnil)
5854 MERROR (MERROR_IM, -1);
5859 if (! check_command_keyseq (keyseq))
5860 MERROR (MERROR_IM, -1);
5862 mplist_add (plist, Mplist, keyseq);
5867 ret = minput_config_command (language, name, command, keyseq);
5868 M17N_OBJECT_UNREF (keyseq);
5875 /*** @addtogroup m17nDebug */
5881 @brief Dump an input method.
5883 The mdebug_dump_im () function prints the input method $IM in a
5884 human readable way to the stderr. $INDENT specifies how many
5885 columns to indent the lines but the first one.
5888 This function returns $IM. */
5890 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
5892 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
5893 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
5896 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
5899 mdebug_dump_im (MInputMethod *im, int indent)
5901 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
5904 prefix = (char *) alloca (indent + 1);
5905 memset (prefix, 32, indent);
5906 prefix[indent] = '\0';
5908 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
5909 msymbol_name (im->name));
5910 mdebug_dump_mtext (im_info->title, 0, 0);
5911 if (im->name != Mnil)
5915 MPLIST_DO (state, im_info->states)
5917 fprintf (stderr, "\n%s ", prefix);
5918 dump_im_state (MPLIST_VAL (state), indent + 2);
5921 fprintf (stderr, ")");