1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
156 #include "m17n-gui.h"
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_mask = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mundo = msymbol ("undo");
406 Mcall = msymbol ("call");
407 Mshift = msymbol ("shift");
408 Mselect = msymbol ("select");
409 Mshow = msymbol ("show");
410 Mhide = msymbol ("hide");
411 Mcommit = msymbol ("commit");
412 Munhandle = msymbol ("unhandle");
413 Mset = msymbol ("set");
414 Madd = msymbol ("add");
415 Msub = msymbol ("sub");
416 Mmul = msymbol ("mul");
417 Mdiv = msymbol ("div");
418 Mequal = msymbol ("=");
419 Mless = msymbol ("<");
420 Mgreater = msymbol (">");
421 Mless_equal = msymbol ("<=");
422 Mgreater_equal = msymbol (">=");
423 Mcond = msymbol ("cond");
424 Mplus = msymbol ("+");
425 Mminus = msymbol ("-");
426 Mstar = msymbol ("*");
427 Mslash = msymbol ("/");
428 Mand = msymbol ("&");
430 Mnot = msymbol ("!");
432 Mat_reload = msymbol ("@reload");
434 Mcandidates_group_size = msymbol ("candidates-group-size");
435 Mcandidates_charset = msymbol ("candidates-charset");
437 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
438 Mcandidate_index = msymbol (" candidate-index");
440 Minit = msymbol ("init");
441 Mfini = msymbol ("fini");
443 Mdescription = msymbol ("description");
444 Mcommand = msymbol ("command");
445 Mvariable = msymbol ("variable");
446 Mglobal = msymbol ("global");
447 Mconfig = msymbol ("config");
448 M_gettext = msymbol ("_");
450 load_im_info_keys = mplist ();
451 mplist_add (load_im_info_keys, Mstate, Mnil);
452 mplist_push (load_im_info_keys, Mmap, Mnil);
454 im_info_list = mplist ();
455 im_config_list = im_custom_list = NULL;
456 im_custom_mdb = NULL;
457 update_custom_info ();
459 update_global_info ();
461 fully_initialized = 1;
464 #define MINPUT__INIT() \
466 if (! fully_initialized) \
467 fully_initialize (); \
472 marker_code (MSymbol sym, int surrounding)
478 name = MSYMBOL_NAME (sym);
479 return (name[0] != '@' ? -1
480 : (((name[1] >= '0' && name[1] <= '9')
481 || name[1] == '<' || name[1] == '>' || name[1] == '='
482 || name[1] == '[' || name[1] == ']'
484 && name[2] == '\0') ? name[1]
485 : (name[1] != '+' && name[1] != '-') ? -1
486 : (name[2] == '\0' || surrounding) ? name[1]
492 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
494 MPlist *plist = mplist__assq (ic_info->vars, var);
498 plist = MPLIST_PLIST (plist);
499 return MPLIST_NEXT (plist);
503 mplist_push (ic_info->vars, Mplist, plist);
504 M17N_OBJECT_UNREF (plist);
505 plist = mplist_add (plist, Msymbol, var);
506 plist = mplist_add (plist, Minteger, (void *) 0);
511 get_surrounding_text (MInputContext *ic, int len)
515 mplist_push (ic->plist, Minteger, (void *) len);
516 if (minput__callback (ic, Minput_get_surrounding_text) >= 0
517 && MPLIST_MTEXT_P (ic->plist))
518 mt = MPLIST_MTEXT (ic->plist);
519 mplist_pop (ic->plist);
524 delete_surrounding_text (MInputContext *ic, int pos)
526 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
528 mplist_push (ic->plist, Minteger, (void *) pos);
529 minput__callback (ic, Minput_delete_surrounding_text);
530 mplist_pop (ic->plist);
533 M17N_OBJECT_UNREF (ic_info->preceding_text);
534 ic_info->preceding_text = NULL;
538 M17N_OBJECT_UNREF (ic_info->following_text);
539 ic_info->following_text = NULL;
544 get_preceding_char (MInputContext *ic, int pos)
546 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
550 if (pos && ic_info->preceding_text)
552 len = mtext_nchars (ic_info->preceding_text);
554 return mtext_ref_char (ic_info->preceding_text, len - pos);
556 mt = get_surrounding_text (ic, - pos);
559 len = mtext_nchars (mt);
560 if (ic_info->preceding_text)
562 if (mtext_nchars (ic_info->preceding_text) < len)
564 M17N_OBJECT_UNREF (ic_info->preceding_text);
565 ic_info->preceding_text = mt;
569 ic_info->preceding_text = mt;
572 return mtext_ref_char (ic_info->preceding_text, len - pos);
576 get_following_char (MInputContext *ic, int pos)
578 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
582 if (ic_info->following_text)
584 len = mtext_nchars (ic_info->following_text);
586 return mtext_ref_char (ic_info->following_text, pos - 1);
588 mt = get_surrounding_text (ic, pos);
591 len = mtext_nchars (mt);
592 if (ic_info->following_text)
594 if (mtext_nchars (ic_info->following_text) < len)
596 M17N_OBJECT_UNREF (ic_info->following_text);
597 ic_info->following_text = mt;
601 ic_info->following_text = mt;
604 return mtext_ref_char (ic_info->following_text, pos - 1);
608 surrounding_pos (MSymbol sym)
614 name = MSYMBOL_NAME (sym);
616 && (name[1] == '-' || name[1] == '+')
617 && name[2] >= '1' && name[2] <= '9')
618 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
623 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
625 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
627 MText *preedit = ic->preedit;
628 int len = mtext_nchars (preedit);
632 if (MPLIST_INTEGER_P (arg))
633 return MPLIST_INTEGER (arg);
635 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
638 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
642 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
645 return ic_info->key_head;
646 if ((code == '-' || code == '+'))
648 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
652 pos = atoi (name + 1);
654 return get_preceding_char (ic, 0);
655 pos = ic->cursor_pos + pos;
657 return get_preceding_char (ic, - pos);
659 return get_following_char (ic, pos - len + 1);
662 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
664 else if (code >= '0' && code <= '9')
666 else if (code == '=')
667 pos = ic->cursor_pos;
668 else if (code == '[')
669 pos = ic->cursor_pos - 1;
670 else if (code == ']')
671 pos = ic->cursor_pos + 1;
672 else if (code == '<')
674 else if (code == '>')
676 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
680 parse_expression (MPlist *plist)
684 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
686 if (! MPLIST_PLIST_P (plist))
688 plist = MPLIST_PLIST (plist);
689 op = MPLIST_SYMBOL (plist);
690 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
691 && op != Mand && op != Mor && op != Mnot
692 && op != Mless && op != Mgreater && op != Mequal
693 && op != Mless_equal && op != Mgreater_equal)
694 MERROR (MERROR_IM, -1);
695 MPLIST_DO (plist, MPLIST_NEXT (plist))
696 if (parse_expression (plist) < 0)
702 resolve_expression (MInputContext *ic, MPlist *plist)
707 if (MPLIST_INTEGER_P (plist))
708 return MPLIST_INTEGER (plist);
709 if (MPLIST_SYMBOL_P (plist))
710 return integer_value (ic, plist, NULL, 1);
711 if (! MPLIST_PLIST_P (plist))
713 plist = MPLIST_PLIST (plist);
714 if (! MPLIST_SYMBOL_P (plist))
716 op = MPLIST_SYMBOL (plist);
717 plist = MPLIST_NEXT (plist);
718 val = resolve_expression (ic, plist);
720 MPLIST_DO (plist, MPLIST_NEXT (plist))
721 val += resolve_expression (ic, plist);
722 else if (op == Mminus)
723 MPLIST_DO (plist, MPLIST_NEXT (plist))
724 val -= resolve_expression (ic, plist);
725 else if (op == Mstar)
726 MPLIST_DO (plist, MPLIST_NEXT (plist))
727 val *= resolve_expression (ic, plist);
728 else if (op == Mslash)
729 MPLIST_DO (plist, MPLIST_NEXT (plist))
730 val /= resolve_expression (ic, plist);
732 MPLIST_DO (plist, MPLIST_NEXT (plist))
733 val &= resolve_expression (ic, plist);
735 MPLIST_DO (plist, MPLIST_NEXT (plist))
736 val |= resolve_expression (ic, plist);
739 else if (op == Mless)
740 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
741 else if (op == Mequal)
742 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
743 else if (op == Mgreater)
744 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
745 else if (op == Mless_equal)
746 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
747 else if (op == Mgreater_equal)
748 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
752 /* Parse PLIST as an action list. PLIST should have this form:
753 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
754 Return 0 if successfully parsed, otherwise return -1. */
757 parse_action_list (MPlist *plist, MPlist *macros)
759 MPLIST_DO (plist, plist)
761 if (MPLIST_MTEXT_P (plist))
763 /* This is a short form of (insert MTEXT). */
764 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
765 MERROR (MERROR_IM, -1); */
767 else if (MPLIST_PLIST_P (plist)
768 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
769 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
773 /* This is a short form of (insert (GROUPS *)). */
774 MPLIST_DO (pl, MPLIST_PLIST (plist))
776 if (MPLIST_PLIST_P (pl))
780 MPLIST_DO (elt, MPLIST_PLIST (pl))
781 if (! MPLIST_MTEXT_P (elt)
782 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
783 MERROR (MERROR_IM, -1);
787 if (! MPLIST_MTEXT_P (pl)
788 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
789 MERROR (MERROR_IM, -1);
793 else if (MPLIST_INTEGER_P (plist))
795 int c = MPLIST_INTEGER (plist);
797 if (c < 0 || c > MCHAR_MAX)
798 MERROR (MERROR_IM, -1);
800 else if (MPLIST_PLIST_P (plist)
801 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
803 MPlist *pl = MPLIST_PLIST (plist);
804 MSymbol action_name = MPLIST_SYMBOL (pl);
806 pl = MPLIST_NEXT (pl);
808 if (action_name == Minsert)
810 if (MPLIST_MTEXT_P (pl))
812 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
813 MERROR (MERROR_IM, -1);
815 else if (MPLIST_PLIST_P (pl))
819 if (MPLIST_PLIST_P (pl))
823 MPLIST_DO (elt, MPLIST_PLIST (pl))
824 if (! MPLIST_MTEXT_P (elt)
825 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
826 MERROR (MERROR_IM, -1);
830 if (! MPLIST_MTEXT_P (pl)
831 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
832 MERROR (MERROR_IM, -1);
836 else if (! MPLIST_SYMBOL_P (pl))
837 MERROR (MERROR_IM, -1);
839 else if (action_name == Mselect
840 || action_name == Mdelete
841 || action_name == Mmove)
843 if (parse_expression (pl) < 0)
846 else if (action_name == Mmark
847 || action_name == Mcall
848 || action_name == Mshift)
850 if (! MPLIST_SYMBOL_P (pl))
851 MERROR (MERROR_IM, -1);
853 else if (action_name == Mundo)
855 if (! MPLIST_TAIL_P (pl))
857 if (! MPLIST_SYMBOL_P (pl)
858 && (! MPLIST_INTEGER_P (pl)
859 || MPLIST_INTEGER (pl) == 0))
860 MERROR (MERROR_IM, -1);
863 else if (action_name == Mpushback)
865 if (MPLIST_MTEXT_P (pl))
867 MText *mt = MPLIST_MTEXT (pl);
869 if (mtext_nchars (mt) != mtext_nbytes (mt))
870 MERROR (MERROR_IM, -1);
872 else if (MPLIST_PLIST_P (pl))
876 MPLIST_DO (p, MPLIST_PLIST (pl))
877 if (! MPLIST_SYMBOL_P (p))
878 MERROR (MERROR_IM, -1);
880 else if (! MPLIST_INTEGER_P (pl))
881 MERROR (MERROR_IM, -1);
883 else if (action_name == Mset || action_name == Madd
884 || action_name == Msub || action_name == Mmul
885 || action_name == Mdiv)
887 if (! MPLIST_SYMBOL_P (pl))
888 MERROR (MERROR_IM, -1);
889 if (parse_expression (MPLIST_NEXT (pl)) < 0)
892 else if (action_name == Mequal || action_name == Mless
893 || action_name == Mgreater || action_name == Mless_equal
894 || action_name == Mgreater_equal)
896 if (parse_expression (pl) < 0
897 || parse_expression (MPLIST_NEXT (pl)) < 0)
899 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
900 if (! MPLIST_PLIST_P (pl))
901 MERROR (MERROR_IM, -1);
902 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
903 MERROR (MERROR_IM, -1);
904 pl = MPLIST_NEXT (pl);
905 if (MPLIST_PLIST_P (pl)
906 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
907 MERROR (MERROR_IM, -1);
909 else if (action_name == Mshow || action_name == Mhide
910 || action_name == Mcommit || action_name == Munhandle)
912 else if (action_name == Mcond)
915 if (! MPLIST_PLIST_P (pl))
916 MERROR (MERROR_IM, -1);
918 else if (! macros || ! mplist_get (macros, action_name))
919 MERROR (MERROR_IM, -1);
921 else if (! MPLIST_SYMBOL_P (plist))
922 MERROR (MERROR_IM, -1);
929 resolve_command (MPlist *cmds, MSymbol command)
933 if (! cmds || ! (plist = mplist__assq (cmds, command)))
935 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
936 plist = MPLIST_NEXT (plist);
937 plist = MPLIST_NEXT (plist);
938 plist = MPLIST_NEXT (plist);
942 /* Load a translation into MAP from PLIST.
944 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
947 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
948 MPlist *branch_actions, MPlist *macros)
953 if (MPLIST_MTEXT_P (keylist))
955 MText *mt = MPLIST_MTEXT (keylist);
957 len = mtext_nchars (mt);
958 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
960 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
961 for (i = 0; i < len; i++)
962 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
968 if (MFAILP (MPLIST_PLIST_P (keylist)))
970 elt = MPLIST_PLIST (keylist);
971 len = MPLIST_LENGTH (elt);
972 if (MFAILP (len > 0))
974 keyseq = (MSymbol *) alloca (sizeof (int) * len);
975 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
977 if (MPLIST_INTEGER_P (elt))
979 int c = MPLIST_INTEGER (elt);
981 if (MFAILP (c >= 0 && c < 0x100))
983 keyseq[i] = one_char_symbol[c];
987 if (MFAILP (MPLIST_SYMBOL_P (elt)))
989 keyseq[i] = MPLIST_SYMBOL (elt);
994 for (i = 0; i < len; i++)
996 MIMMap *deeper = NULL;
999 deeper = mplist_get (map->submaps, keyseq[i]);
1001 map->submaps = mplist ();
1004 /* Fixme: It is better to make all deeper maps at once. */
1005 MSTRUCT_CALLOC (deeper, MERROR_IM);
1006 mplist_put (map->submaps, keyseq[i], deeper);
1011 /* We reach a terminal map. */
1012 if (map->map_actions
1013 || map->branch_actions)
1014 /* This map is already defined. We avoid overriding it. */
1017 if (! MPLIST_TAIL_P (map_actions))
1019 if (parse_action_list (map_actions, macros) < 0)
1020 MERROR (MERROR_IM, -1);
1021 map->map_actions = map_actions;
1025 map->branch_actions = branch_actions;
1026 M17N_OBJECT_REF (branch_actions);
1032 /* Load a branch from PLIST into MAP. PLIST has this form:
1033 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1036 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1039 MPlist *branch_actions;
1041 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1043 map_name = MPLIST_SYMBOL (plist);
1044 plist = MPLIST_NEXT (plist);
1045 if (MPLIST_TAIL_P (plist))
1046 branch_actions = NULL;
1047 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1050 branch_actions = plist;
1051 if (map_name == Mnil)
1053 map->branch_actions = branch_actions;
1055 M17N_OBJECT_REF (branch_actions);
1057 else if (map_name == Mt)
1059 map->map_actions = branch_actions;
1061 M17N_OBJECT_REF (branch_actions);
1063 else if (im_info->maps
1064 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1066 MPLIST_DO (plist, plist)
1068 MPlist *keylist, *map_actions;
1070 if (! MPLIST_PLIST_P (plist))
1071 MERROR (MERROR_IM, -1);
1072 keylist = MPLIST_PLIST (plist);
1073 map_actions = MPLIST_NEXT (keylist);
1074 if (MPLIST_SYMBOL_P (keylist))
1076 MSymbol command = MPLIST_SYMBOL (keylist);
1079 if (MFAILP (command != Mat_reload))
1081 pl = resolve_command (im_info->configured_cmds, command);
1085 load_translation (map, pl, map_actions, branch_actions,
1089 load_translation (map, keylist, map_actions, branch_actions,
1097 /* Load a macro from PLIST into IM_INFO->macros.
1098 PLIST has this from:
1099 PLIST ::= ( MACRO-NAME ACTION * )
1100 IM_INFO->macros is a plist of macro names vs action list. */
1103 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1108 if (! MPLIST_SYMBOL_P (plist))
1109 MERROR (MERROR_IM, -1);
1110 name = MPLIST_SYMBOL (plist);
1111 plist = MPLIST_NEXT (plist);
1112 if (MPLIST_TAIL_P (plist)
1113 || parse_action_list (plist, im_info->macros) < 0)
1114 MERROR (MERROR_IM, -1);
1115 pl = mplist_get (im_info->macros, name);
1116 M17N_OBJECT_UNREF (pl);
1117 mplist_put (im_info->macros, name, plist);
1118 M17N_OBJECT_REF (plist);
1122 /* Load an external module from PLIST into IM_INFO->externals.
1123 PLIST has this form:
1124 PLIST ::= ( MODULE-NAME FUNCTION * )
1125 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1128 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1133 MIMExternalModule *external;
1137 if (MPLIST_MTEXT_P (plist))
1138 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1139 else if (MPLIST_SYMBOL_P (plist))
1140 module = MPLIST_SYMBOL (plist);
1141 module_file = alloca (strlen (MSYMBOL_NAME (module))
1142 + strlen (DLOPEN_SHLIB_EXT) + 1);
1143 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1145 handle = dlopen (module_file, RTLD_NOW);
1146 if (MFAILP (handle))
1148 fprintf (stderr, "%s\n", dlerror ());
1151 func_list = mplist ();
1152 MPLIST_DO (plist, MPLIST_NEXT (plist))
1154 if (! MPLIST_SYMBOL_P (plist))
1155 MERROR_GOTO (MERROR_IM, err_label);
1156 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1159 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1162 MSTRUCT_MALLOC (external, MERROR_IM);
1163 external->handle = handle;
1164 external->func_list = func_list;
1165 mplist_add (im_info->externals, module, external);
1170 M17N_OBJECT_UNREF (func_list);
1175 free_map (MIMMap *map, int top)
1180 M17N_OBJECT_UNREF (map->map_actions);
1183 MPLIST_DO (plist, map->submaps)
1184 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1185 M17N_OBJECT_UNREF (map->submaps);
1187 M17N_OBJECT_UNREF (map->branch_actions);
1192 free_state (void *object)
1194 MIMState *state = object;
1196 M17N_OBJECT_UNREF (state->title);
1198 free_map (state->map, 1);
1202 /** Load a state from PLIST into a newly allocated state object.
1203 PLIST has this form:
1204 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1205 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1206 Return the state object. */
1209 load_state (MInputMethodInfo *im_info, MPlist *plist)
1213 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1215 M17N_OBJECT (state, free_state, MERROR_IM);
1216 state->name = MPLIST_SYMBOL (plist);
1217 plist = MPLIST_NEXT (plist);
1218 if (MPLIST_MTEXT_P (plist))
1220 state->title = MPLIST_MTEXT (plist);
1221 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1222 Mlanguage, im_info->language);
1223 M17N_OBJECT_REF (state->title);
1224 plist = MPLIST_NEXT (plist);
1226 MSTRUCT_CALLOC (state->map, MERROR_IM);
1227 MPLIST_DO (plist, plist)
1229 if (MFAILP (MPLIST_PLIST_P (plist)))
1231 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1236 /* Return a newly created IM_INFO for an input method specified by
1237 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1239 static MInputMethodInfo *
1240 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1243 MInputMethodInfo *im_info;
1246 if (name == Mnil && extra == Mnil)
1247 language = Mt, extra = Mglobal;
1248 MSTRUCT_CALLOC (im_info, MERROR_IM);
1250 im_info->language = language;
1251 im_info->name = name;
1252 im_info->extra = extra;
1255 mplist_add (plist, Mplist, elt);
1256 M17N_OBJECT_UNREF (elt);
1257 elt = mplist_add (elt, Msymbol, language);
1258 elt = mplist_add (elt, Msymbol, name);
1259 elt = mplist_add (elt, Msymbol, extra);
1260 mplist_add (elt, Mt, im_info);
1266 fini_im_info (MInputMethodInfo *im_info)
1270 M17N_OBJECT_UNREF (im_info->cmds);
1271 M17N_OBJECT_UNREF (im_info->configured_cmds);
1272 M17N_OBJECT_UNREF (im_info->bc_cmds);
1273 M17N_OBJECT_UNREF (im_info->vars);
1274 M17N_OBJECT_UNREF (im_info->configured_vars);
1275 M17N_OBJECT_UNREF (im_info->bc_vars);
1276 M17N_OBJECT_UNREF (im_info->description);
1277 M17N_OBJECT_UNREF (im_info->title);
1278 if (im_info->states)
1280 MPLIST_DO (plist, im_info->states)
1282 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1284 M17N_OBJECT_UNREF (state);
1286 M17N_OBJECT_UNREF (im_info->states);
1289 if (im_info->macros)
1291 MPLIST_DO (plist, im_info->macros)
1292 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1293 M17N_OBJECT_UNREF (im_info->macros);
1296 if (im_info->externals)
1298 MPLIST_DO (plist, im_info->externals)
1300 MIMExternalModule *external = MPLIST_VAL (plist);
1302 dlclose (external->handle);
1303 M17N_OBJECT_UNREF (external->func_list);
1305 MPLIST_KEY (plist) = Mt;
1307 M17N_OBJECT_UNREF (im_info->externals);
1311 MPLIST_DO (plist, im_info->maps)
1313 MPlist *p = MPLIST_PLIST (plist);
1315 M17N_OBJECT_UNREF (p);
1317 M17N_OBJECT_UNREF (im_info->maps);
1324 free_im_info (MInputMethodInfo *im_info)
1326 fini_im_info (im_info);
1331 free_im_list (MPlist *plist)
1335 MPLIST_DO (pl, plist)
1337 MInputMethodInfo *im_info;
1339 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1340 im_info = MPLIST_VAL (elt);
1341 free_im_info (im_info);
1343 M17N_OBJECT_UNREF (plist);
1346 static MInputMethodInfo *
1347 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1349 if (name == Mnil && extra == Mnil)
1350 language = Mt, extra = Mglobal;
1351 while ((plist = mplist__assq (plist, language)))
1353 MPlist *elt = MPLIST_PLIST (plist);
1355 plist = MPLIST_NEXT (plist);
1356 elt = MPLIST_NEXT (elt);
1357 if (MPLIST_SYMBOL (elt) != name)
1359 elt = MPLIST_NEXT (elt);
1360 if (MPLIST_SYMBOL (elt) != extra)
1362 elt = MPLIST_NEXT (elt);
1363 return MPLIST_VAL (elt);
1368 static void load_im_info (MPlist *, MInputMethodInfo *);
1370 #define get_custom_info(im_info) \
1372 ? lookup_im_info (im_custom_list, (im_info)->language, \
1373 (im_info)->name, (im_info)->extra) \
1376 #define get_config_info(im_info) \
1378 ? lookup_im_info (im_config_list, (im_info)->language, \
1379 (im_info)->name, (im_info)->extra) \
1383 update_custom_info (void)
1389 if (mdatabase__check (im_custom_mdb) > 0)
1394 MDatabaseInfo *custom_dir_info;
1395 char custom_path[PATH_MAX + 1];
1397 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1398 if (! custom_dir_info->filename
1399 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1401 strcpy (custom_path, custom_dir_info->filename);
1402 strcat (custom_path, CUSTOM_FILE);
1403 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1409 free_im_list (im_custom_list);
1410 im_custom_list = NULL;
1412 plist = mdatabase_load (im_custom_mdb);
1415 im_custom_list = mplist ();
1417 MPLIST_DO (pl, plist)
1419 MSymbol language, name, extra;
1420 MInputMethodInfo *im_info;
1421 MPlist *im_data, *p;
1423 if (! MPLIST_PLIST_P (pl))
1425 p = MPLIST_PLIST (pl);
1426 im_data = MPLIST_NEXT (p);
1427 if (! MPLIST_PLIST_P (p))
1429 p = MPLIST_PLIST (p);
1430 if (! MPLIST_SYMBOL_P (p)
1431 || MPLIST_SYMBOL (p) != Minput_method)
1433 p = MPLIST_NEXT (p);
1434 if (! MPLIST_SYMBOL_P (p))
1436 language = MPLIST_SYMBOL (p);
1437 p = MPLIST_NEXT (p);
1438 if (! MPLIST_SYMBOL_P (p))
1440 name = MPLIST_SYMBOL (p);
1441 if (language == Mnil || name == Mnil)
1443 p = MPLIST_NEXT (p);
1444 if (MPLIST_TAIL_P (p))
1446 else if (MPLIST_SYMBOL_P (p))
1447 extra = MPLIST_SYMBOL (p);
1450 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1451 load_im_info (im_data, im_info);
1453 M17N_OBJECT_UNREF (plist);
1458 update_global_info (void)
1464 int ret = mdatabase__check (global_info->mdb);
1468 fini_im_info (global_info);
1472 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1474 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1476 if (! global_info->mdb
1477 || ! (plist = mdatabase_load (global_info->mdb)))
1480 load_im_info (plist, global_info);
1481 M17N_OBJECT_UNREF (plist);
1486 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1487 and EXTRA. KEY, if not Mnil, tells which kind of information about
1488 the input method is necessary, and the returned IM_INFO may contain
1489 only that information. */
1491 static MInputMethodInfo *
1492 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1495 MInputMethodInfo *im_info;
1498 if (name == Mnil && extra == Mnil)
1499 language = Mt, extra = Mglobal;
1500 im_info = lookup_im_info (im_info_list, language, name, extra);
1503 if (key == Mnil ? im_info->states != NULL
1504 : key == Mcommand ? im_info->cmds != NULL
1505 : key == Mvariable ? im_info->vars != NULL
1506 : key == Mtitle ? im_info->title != NULL
1507 : key == Mdescription ? im_info->description != NULL
1509 /* IM_INFO already contains required information. */
1511 /* We have not yet loaded required information. */
1515 mdb = mdatabase_find (Minput_method, language, name, extra);
1518 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1523 plist = mdatabase_load (im_info->mdb);
1527 mplist_push (load_im_info_keys, key, Mt);
1528 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1529 mplist_pop (load_im_info_keys);
1533 MERROR (MERROR_IM, im_info);
1534 update_global_info ();
1535 load_im_info (plist, im_info);
1536 M17N_OBJECT_UNREF (plist);
1539 if (! im_info->cmds)
1540 im_info->cmds = mplist ();
1541 if (! im_info->vars)
1542 im_info->vars = mplist ();
1544 if (! im_info->title
1545 && (key == Mnil || key == Mtitle))
1546 im_info->title = (name == Mnil ? mtext ()
1547 : mtext_from_data (MSYMBOL_NAME (name),
1548 MSYMBOL_NAMELEN (name),
1549 MTEXT_FORMAT_US_ASCII));
1553 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1554 If updated, but got unloadable, return -1. Otherwise, update
1555 contents of IM_INFO from the new database, and return 1. */
1558 reload_im_info (MInputMethodInfo *im_info)
1563 update_custom_info ();
1564 update_global_info ();
1565 check = mdatabase__check (im_info->mdb);
1568 plist = mdatabase_load (im_info->mdb);
1571 fini_im_info (im_info);
1572 load_im_info (plist, im_info);
1573 M17N_OBJECT_UNREF (plist);
1577 static MInputMethodInfo *
1578 get_im_info_by_tags (MPlist *plist)
1583 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1584 i++, plist = MPLIST_NEXT (plist))
1585 tag[i] = MPLIST_SYMBOL (plist);
1590 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1595 check_description (MPlist *plist)
1599 if (MPLIST_MTEXT_P (plist))
1601 if (MPLIST_PLIST_P (plist))
1603 MPlist *pl = MPLIST_PLIST (plist);
1605 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1607 pl =MPLIST_NEXT (pl);
1608 if (MFAILP (MPLIST_MTEXT_P (pl)))
1610 mt = MPLIST_MTEXT (pl);
1611 M17N_OBJECT_REF (mt);
1614 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1616 if (translated == (char *) MTEXT_DATA (mt))
1617 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1618 if (translated != (char *) MTEXT_DATA (mt))
1620 M17N_OBJECT_UNREF (mt);
1621 mt = mtext__from_data (translated, strlen (translated),
1622 MTEXT_FORMAT_UTF_8, 0);
1626 mplist_set (plist, Mtext, mt);
1627 M17N_OBJECT_UNREF (mt);
1630 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1636 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1640 check_command_keyseq (MPlist *keyseq)
1642 if (MPLIST_PLIST_P (keyseq))
1644 MPlist *p = MPLIST_PLIST (keyseq);
1647 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1651 if (MPLIST_MTEXT_P (keyseq))
1653 MText *mt = MPLIST_MTEXT (keyseq);
1656 for (i = 0; i < mtext_nchars (mt); i++)
1657 if (mtext_ref_char (mt, i) >= 256)
1664 /* Load command defitions from PLIST into IM_INFO->cmds.
1666 PLIST is well-formed and has this form;
1667 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1668 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1669 M-text or a plist of symbols.
1671 The returned list has the same form, but for each element...
1673 (1) If DESCRIPTION and the rest are omitted, the element is not
1674 stored in the returned list.
1676 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1677 description in global_info->cmds (if any). */
1680 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1684 im_info->cmds = tail = mplist ();
1686 MPLIST_DO (plist, MPLIST_NEXT (plist))
1688 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1691 if (MFAILP (MPLIST_PLIST_P (plist)))
1693 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1694 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1696 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1697 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1699 if (MFAILP (im_info != global_info))
1700 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1704 if (! check_description (p))
1705 mplist_set (p, Msymbol, Mnil);
1706 p = MPLIST_NEXT (p);
1707 while (! MPLIST_TAIL_P (p))
1709 if (MFAILP (check_command_keyseq (p)))
1710 mplist__pop_unref (p);
1712 p = MPLIST_NEXT (p);
1715 tail = mplist_add (tail, Mplist, pl);
1720 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1721 MPlist *config_cmds)
1723 MPlist *global = NULL, *custom = NULL, *config = NULL;
1726 MPlist *description = NULL, *keyseq;
1728 name = MPLIST_SYMBOL (plist);
1729 plist = MPLIST_NEXT (plist);
1730 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1731 description = plist;
1732 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1733 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1734 if (MPLIST_TAIL_P (plist))
1737 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1738 global = MPLIST_NEXT (MPLIST_PLIST (global));
1741 keyseq = MPLIST_NEXT (global);
1742 status = Minherited;
1752 keyseq = MPLIST_NEXT (plist);
1756 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1758 config = MPLIST_NEXT (MPLIST_PLIST (config));
1759 if (! MPLIST_TAIL_P (config))
1761 keyseq = MPLIST_NEXT (config);
1762 status = Mconfigured;
1765 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1767 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1768 if (! MPLIST_TAIL_P (custom))
1770 keyseq = MPLIST_NEXT (custom);
1771 status = Mcustomized;
1776 mplist_add (plist, Msymbol, name);
1778 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1780 mplist_add (plist, Msymbol, Mnil);
1781 mplist_add (plist, Msymbol, status);
1782 mplist__conc (plist, keyseq);
1787 config_all_commands (MInputMethodInfo *im_info)
1789 MPlist *global_cmds, *custom_cmds, *config_cmds;
1790 MInputMethodInfo *temp;
1791 MPlist *tail, *plist;
1793 M17N_OBJECT_UNREF (im_info->configured_cmds);
1795 if (MPLIST_TAIL_P (im_info->cmds)
1799 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1800 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1801 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1803 im_info->configured_cmds = tail = mplist ();
1804 MPLIST_DO (plist, im_info->cmds)
1806 MPlist *pl = config_command (MPLIST_PLIST (plist),
1807 global_cmds, custom_cmds, config_cmds);
1810 tail = mplist_add (tail, Mplist, pl);
1811 M17N_OBJECT_UNREF (pl);
1816 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1817 valid, return 0 if not. */
1820 check_variable_value (MPlist *val, MPlist *global)
1822 MSymbol type = MPLIST_KEY (val);
1823 MPlist *valids = MPLIST_NEXT (val);
1825 if (type != Minteger && type != Mtext && type != Msymbol)
1829 if (MPLIST_KEY (global) != Mt
1830 && MPLIST_KEY (global) != MPLIST_KEY (val))
1832 if (MPLIST_TAIL_P (valids))
1833 valids = MPLIST_NEXT (global);
1835 if (MPLIST_TAIL_P (valids))
1838 if (type == Minteger)
1840 int n = MPLIST_INTEGER (val);
1842 MPLIST_DO (valids, valids)
1844 if (MPLIST_INTEGER_P (valids))
1846 if (n == MPLIST_INTEGER (valids))
1849 else if (MPLIST_PLIST_P (valids))
1851 MPlist *p = MPLIST_PLIST (valids);
1852 int min_bound, max_bound;
1854 if (! MPLIST_INTEGER_P (p))
1855 MERROR (MERROR_IM, 0);
1856 min_bound = MPLIST_INTEGER (p);
1857 p = MPLIST_NEXT (p);
1858 if (! MPLIST_INTEGER_P (p))
1859 MERROR (MERROR_IM, 0);
1860 max_bound = MPLIST_INTEGER (p);
1861 if (n >= min_bound && n <= max_bound)
1866 else if (type == Msymbol)
1868 MSymbol sym = MPLIST_SYMBOL (val);
1870 MPLIST_DO (valids, valids)
1872 if (! MPLIST_SYMBOL_P (valids))
1873 MERROR (MERROR_IM, 0);
1874 if (sym == MPLIST_SYMBOL (valids))
1880 MText *mt = MPLIST_MTEXT (val);
1882 MPLIST_DO (valids, valids)
1884 if (! MPLIST_MTEXT_P (valids))
1885 MERROR (MERROR_IM, 0);
1886 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1891 return (MPLIST_TAIL_P (valids));
1894 /* Load variable defitions from PLIST into IM_INFO->vars.
1896 PLIST is well-formed and has this form;
1897 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1899 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1901 The returned list has the same form, but for each element...
1903 (1) If DESCRIPTION and the rest are omitted, the element is not
1904 stored in the returned list.
1906 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1907 description in global_info->vars (if any). */
1910 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1912 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1913 ? global_info->vars : NULL);
1916 im_info->vars = tail = mplist ();
1917 MPLIST_DO (plist, MPLIST_NEXT (plist))
1921 if (MFAILP (MPLIST_PLIST_P (plist)))
1923 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1924 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1926 if (im_info == global_info)
1928 /* Loading a global variable. */
1929 p = MPLIST_NEXT (pl);
1930 if (MPLIST_TAIL_P (p))
1931 mplist_add (p, Msymbol, Mnil);
1934 if (! check_description (p))
1935 mplist_set (p, Msymbol, Mnil);
1936 p = MPLIST_NEXT (p);
1937 if (MFAILP (! MPLIST_TAIL_P (p)
1938 && check_variable_value (p, NULL)))
1939 mplist_set (p, Mt, NULL);
1942 else if (im_info->mdb)
1944 /* Loading a local variable. */
1945 MSymbol name = MPLIST_SYMBOL (pl);
1946 MPlist *global = NULL;
1949 && (p = mplist__assq (global_vars, name)))
1951 /* P ::= ((NAME DESC ...) ...) */
1952 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1953 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1954 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1957 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1958 if (! MPLIST_TAIL_P (p))
1960 if (! check_description (p))
1961 mplist_set (p, Msymbol, Mnil);
1962 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1963 if (MFAILP (! MPLIST_TAIL_P (p)))
1964 mplist_set (p, Mt, NULL);
1967 MPlist *valid_values = MPLIST_NEXT (p);
1969 if (! MPLIST_TAIL_P (valid_values)
1970 ? MFAILP (check_variable_value (p, NULL))
1971 : global && MFAILP (check_variable_value (p, global)))
1972 mplist_set (p, Mt, NULL);
1978 /* Loading a variable customization. */
1979 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1980 if (MFAILP (! MPLIST_TAIL_P (p)))
1982 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1983 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1984 || MPLIST_MTEXT_P (p)))
1987 tail = mplist_add (tail, Mplist, pl);
1992 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
1993 MPlist *config_vars)
1995 MPlist *global = NULL, *custom = NULL, *config = NULL;
1996 MSymbol name = MPLIST_SYMBOL (plist);
1998 MPlist *description = NULL, *value, *valids;
2002 global = mplist__assq (global_vars, name);
2004 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2007 plist = MPLIST_NEXT (plist);
2008 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2009 description = plist;
2011 description = global;
2013 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2015 if (MPLIST_TAIL_P (plist))
2017 /* Inherit from global (if any). */
2021 if (MPLIST_KEY (value) == Mt)
2023 valids = MPLIST_NEXT (global);
2024 status = Minherited;
2036 value = plist = MPLIST_NEXT (plist);
2037 valids = MPLIST_NEXT (value);
2038 if (MPLIST_KEY (value) == Mt)
2040 if (! MPLIST_TAIL_P (valids))
2043 valids = MPLIST_NEXT (global);
2047 if (config_vars && (config = mplist__assq (config_vars, name)))
2049 config = MPLIST_NEXT (MPLIST_PLIST (config));
2050 if (! MPLIST_TAIL_P (config))
2052 value = MPLIST_NEXT (config);
2053 if (MFAILP (check_variable_value (value, global ? global : plist)))
2055 status = Mconfigured;
2058 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2060 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2061 if (! MPLIST_TAIL_P (custom))
2063 value = MPLIST_NEXT (custom);
2064 if (MFAILP (check_variable_value (value, global ? global : plist)))
2066 status = Mcustomized;
2071 mplist_add (plist, Msymbol, name);
2073 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2075 mplist_add (plist, Msymbol, Mnil);
2076 mplist_add (plist, Msymbol, status);
2078 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2080 mplist_add (plist, Mt, NULL);
2081 if (valids && ! MPLIST_TAIL_P (valids))
2082 mplist__conc (plist, valids);
2086 /* Return a configured variable definition list based on
2087 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2088 get it from global_info->vars. */
2091 config_all_variables (MInputMethodInfo *im_info)
2093 MPlist *global_vars, *custom_vars, *config_vars;
2094 MInputMethodInfo *temp;
2095 MPlist *tail, *plist;
2097 M17N_OBJECT_UNREF (im_info->configured_vars);
2099 if (MPLIST_TAIL_P (im_info->vars)
2103 global_vars = im_info != global_info ? global_info->vars : NULL;
2104 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2105 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2107 im_info->configured_vars = tail = mplist ();
2108 MPLIST_DO (plist, im_info->vars)
2110 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2111 global_vars, custom_vars, config_vars);
2114 tail = mplist_add (tail, Mplist, pl);
2115 M17N_OBJECT_UNREF (pl);
2120 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2121 CONFIG contains configuration information of the input method. */
2124 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2128 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2130 load_commands (im_info, MPLIST_PLIST (pl));
2131 config_all_commands (im_info);
2132 pl = mplist_pop (pl);
2133 M17N_OBJECT_UNREF (pl);
2136 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2138 load_variables (im_info, MPLIST_PLIST (pl));
2139 config_all_variables (im_info);
2140 pl = mplist_pop (pl);
2141 M17N_OBJECT_UNREF (pl);
2144 MPLIST_DO (plist, plist)
2145 if (MPLIST_PLIST_P (plist))
2147 MPlist *elt = MPLIST_PLIST (plist);
2150 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2152 key = MPLIST_SYMBOL (elt);
2157 elt = MPLIST_NEXT (elt);
2158 if (MFAILP (MPLIST_MTEXT_P (elt)))
2160 im_info->title = MPLIST_MTEXT (elt);
2161 M17N_OBJECT_REF (im_info->title);
2163 else if (key == Mmap)
2165 pl = mplist__from_alist (MPLIST_NEXT (elt));
2168 if (! im_info->maps)
2172 mplist__conc (im_info->maps, pl);
2173 M17N_OBJECT_UNREF (pl);
2176 else if (key == Mmacro)
2178 if (! im_info->macros)
2179 im_info->macros = mplist ();
2180 MPLIST_DO (elt, MPLIST_NEXT (elt))
2182 if (MFAILP (MPLIST_PLIST_P (elt)))
2184 load_macros (im_info, MPLIST_PLIST (elt));
2187 else if (key == Mmodule)
2189 if (! im_info->externals)
2190 im_info->externals = mplist ();
2191 MPLIST_DO (elt, MPLIST_NEXT (elt))
2193 if (MFAILP (MPLIST_PLIST_P (elt)))
2195 load_external_module (im_info, MPLIST_PLIST (elt));
2198 else if (key == Mstate)
2200 MPLIST_DO (elt, MPLIST_NEXT (elt))
2204 if (MFAILP (MPLIST_PLIST_P (elt)))
2206 pl = MPLIST_PLIST (elt);
2207 if (! im_info->states)
2208 im_info->states = mplist ();
2209 state = load_state (im_info, MPLIST_PLIST (elt));
2212 mplist_put (im_info->states, state->name, state);
2215 else if (key == Minclude)
2217 /* elt ::= include (tag1 tag2 ...) key item ... */
2219 MInputMethodInfo *temp;
2221 elt = MPLIST_NEXT (elt);
2222 if (MFAILP (MPLIST_PLIST_P (elt)))
2224 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2227 elt = MPLIST_NEXT (elt);
2228 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2230 key = MPLIST_SYMBOL (elt);
2231 elt = MPLIST_NEXT (elt);
2234 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2236 if (! im_info->maps)
2237 im_info->maps = mplist ();
2238 MPLIST_DO (pl, temp->maps)
2240 p = MPLIST_VAL (pl);
2241 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2242 M17N_OBJECT_REF (p);
2245 else if (key == Mmacro)
2247 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2249 if (! im_info->macros)
2250 im_info->macros = mplist ();
2251 MPLIST_DO (pl, temp->macros)
2253 p = MPLIST_VAL (pl);
2254 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2255 M17N_OBJECT_REF (p);
2258 else if (key == Mstate)
2260 if (! temp->states || MPLIST_TAIL_P (temp->states))
2262 if (! im_info->states)
2263 im_info->states = mplist ();
2264 MPLIST_DO (pl, temp->states)
2266 MIMState *state = MPLIST_VAL (pl);
2268 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2269 M17N_OBJECT_REF (state);
2273 else if (key == Mdescription)
2275 if (im_info->description)
2277 elt = MPLIST_NEXT (elt);
2278 if (! check_description (elt))
2280 im_info->description = MPLIST_MTEXT (elt);
2281 M17N_OBJECT_REF (im_info->description);
2284 im_info->tick = time (NULL);
2289 static int take_action_list (MInputContext *ic, MPlist *action_list);
2290 static void preedit_commit (MInputContext *ic);
2293 shift_state (MInputContext *ic, MSymbol state_name)
2295 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2296 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2297 MIMState *orig_state = ic_info->state, *state;
2299 /* Find a state to shift to. If not found, shift to the initial
2301 if (state_name == Mt)
2303 if (! ic_info->prev_state)
2305 state = ic_info->prev_state;
2307 else if (state_name == Mnil)
2309 state = (MIMState *) MPLIST_VAL (im_info->states);
2313 state = (MIMState *) mplist_get (im_info->states, state_name);
2315 state = (MIMState *) MPLIST_VAL (im_info->states);
2318 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2320 /* Enter the new state. */
2321 ic_info->state = state;
2322 ic_info->map = state->map;
2323 ic_info->state_key_head = ic_info->key_head;
2324 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2326 /* We have shifted to the initial state. */
2327 preedit_commit (ic);
2328 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2329 ic_info->state_pos = ic->cursor_pos;
2330 if (state != orig_state)
2332 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2334 /* Shifted to the initial state. */
2335 ic_info->prev_state = NULL;
2336 M17N_OBJECT_UNREF (ic_info->vars_saved);
2337 ic_info->vars_saved = mplist_copy (ic_info->vars);
2340 ic_info->prev_state = orig_state;
2343 ic->status = state->title;
2345 ic->status = im_info->title;
2346 ic->status_changed = 1;
2347 if (ic_info->map == ic_info->state->map
2348 && ic_info->map->map_actions)
2350 MDEBUG_PRINT (" init-actions:");
2351 take_action_list (ic, ic_info->map->map_actions);
2356 /* Find a candidate group that contains a candidate number INDEX from
2357 PLIST. Set START_INDEX to the first candidate number of the group,
2358 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2359 candidate group number if they are non-NULL. If INDEX is -1, find
2360 the last candidate group. */
2363 find_candidates_group (MPlist *plist, int index,
2364 int *start_index, int *end_index, int *group_index)
2366 int i = 0, gidx = 0, len;
2368 MPLIST_DO (plist, plist)
2370 if (MPLIST_MTEXT_P (plist))
2371 len = mtext_nchars (MPLIST_MTEXT (plist));
2373 len = mplist_length (MPLIST_PLIST (plist));
2374 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2380 *end_index = i + len;
2382 *group_index = gidx;
2392 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2394 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2396 int nchars = mt ? mtext_nchars (mt) : 1;
2399 mtext_ins (ic->preedit, pos, mt);
2401 mtext_ins_char (ic->preedit, pos, c, 1);
2402 MPLIST_DO (markers, ic_info->markers)
2403 if (MPLIST_INTEGER (markers) > pos)
2404 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
2405 if (ic->cursor_pos >= pos)
2406 ic->cursor_pos += nchars;
2407 ic->preedit_changed = 1;
2412 preedit_delete (MInputContext *ic, int from, int to)
2414 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2417 mtext_del (ic->preedit, from, to);
2418 MPLIST_DO (markers, ic_info->markers)
2420 if (MPLIST_INTEGER (markers) > to)
2421 MPLIST_VAL (markers)
2422 = (void *) (MPLIST_INTEGER (markers) - (to - from));
2423 else if (MPLIST_INTEGER (markers) > from)
2424 MPLIST_VAL (markers) = (void *) from;
2426 if (ic->cursor_pos >= to)
2427 ic->cursor_pos -= to - from;
2428 else if (ic->cursor_pos > from)
2429 ic->cursor_pos = from;
2430 ic->preedit_changed = 1;
2434 preedit_commit (MInputContext *ic)
2436 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2437 int preedit_len = mtext_nchars (ic->preedit);
2439 if (preedit_len > 0)
2443 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2444 Mcandidate_list, NULL, 0);
2445 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2446 Mcandidate_index, NULL, 0);
2447 mtext_cat (ic->produced, ic->preedit);
2448 mtext_reset (ic->preedit);
2449 mtext_reset (ic_info->preedit_saved);
2450 MPLIST_DO (p, ic_info->markers)
2452 ic->cursor_pos = ic_info->state_pos = 0;
2453 ic->preedit_changed = 1;
2455 if (ic->candidate_list)
2457 M17N_OBJECT_UNREF (ic->candidate_list);
2458 ic->candidate_list = NULL;
2459 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2460 if (ic->candidate_show)
2462 ic->candidate_show = 0;
2463 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2469 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2471 int code = marker_code (sym, 0);
2473 if (mt && (code == '[' || code == ']'))
2477 if (code == '[' && current > 0)
2479 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2483 else if (code == ']' && current < mtext_nchars (mt))
2485 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2491 return (code == '<' ? 0
2492 : code == '>' ? limit
2493 : code == '-' ? current - 1
2494 : code == '+' ? current + 1
2495 : code == '=' ? current
2496 : code - '0' > limit ? limit
2500 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2504 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2506 int from = mtext_property_start (prop);
2507 int to = mtext_property_end (prop);
2509 MPlist *candidate_list = mtext_property_value (prop);
2510 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2512 int ingroup_index = idx - start;
2515 preedit_delete (ic, from, to);
2516 if (MPLIST_MTEXT_P (group))
2518 mt = MPLIST_MTEXT (group);
2519 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
2527 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2528 i++, plist = MPLIST_NEXT (plist));
2529 mt = MPLIST_MTEXT (plist);
2530 preedit_insert (ic, from, mt, 0);
2531 to = from + mtext_nchars (mt);
2533 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2534 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2535 ic->cursor_pos = to;
2539 get_select_charset (MInputContextInfo * ic_info)
2541 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2544 if (! MPLIST_VAL (plist))
2546 sym = MPLIST_SYMBOL (plist);
2549 return MCHARSET (sym);
2553 adjust_candidates (MPlist *plist, MCharset *charset)
2557 /* plist ::= MTEXT ... | PLIST ... */
2558 plist = mplist_copy (plist);
2559 if (MPLIST_MTEXT_P (plist))
2562 while (! MPLIST_TAIL_P (pl))
2564 /* pl ::= MTEXT ... */
2565 MText *mt = MPLIST_MTEXT (pl);
2569 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2571 c = mtext_ref_char (mt, i);
2572 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2576 mt = mtext_dup (mt);
2577 mplist_set (pl, Mtext, mt);
2578 M17N_OBJECT_UNREF (mt);
2581 mtext_del (mt, i, i + 1);
2584 if (mtext_len (mt) > 0)
2585 pl = MPLIST_NEXT (pl);
2589 M17N_OBJECT_UNREF (mt);
2593 else /* MPLIST_PLIST_P (plist) */
2596 while (! MPLIST_TAIL_P (pl))
2598 /* pl ::= (MTEXT ...) ... */
2599 MPlist *p = MPLIST_PLIST (pl);
2601 /* p ::= MTEXT ... */
2605 while (! MPLIST_TAIL_P (p0))
2607 MText *mt = MPLIST_MTEXT (p0);
2610 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2612 c = mtext_ref_char (mt, i);
2613 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2618 p0 = MPLIST_NEXT (p0);
2625 p = mplist_copy (p);
2626 mplist_set (pl, Mplist, p);
2627 M17N_OBJECT_UNREF (p);
2631 p0 = MPLIST_NEXT (p0);
2634 M17N_OBJECT_UNREF (mt);
2637 if (! MPLIST_TAIL_P (p))
2638 pl = MPLIST_NEXT (pl);
2642 M17N_OBJECT_UNREF (p);
2646 if (MPLIST_TAIL_P (plist))
2648 M17N_OBJECT_UNREF (plist);
2655 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2657 MCharset *charset = get_select_charset (ic_info);
2662 plist = resolve_variable (ic_info, Mcandidates_group_size);
2663 column = MPLIST_INTEGER (plist);
2665 plist = MPLIST_PLIST (args);
2667 plist = adjust_candidates (plist, charset);
2669 if (plist && column > 0)
2671 if (MPLIST_MTEXT_P (plist))
2673 MText *mt = MPLIST_MTEXT (plist);
2674 MPlist *next = MPLIST_NEXT (plist);
2676 if (MPLIST_TAIL_P (next))
2677 M17N_OBJECT_REF (mt);
2680 mt = mtext_dup (mt);
2681 while (! MPLIST_TAIL_P (next))
2683 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2684 next = MPLIST_NEXT (next);
2687 M17N_OBJECT_UNREF (plist);
2689 len = mtext_nchars (mt);
2691 mplist_add (plist, Mtext, mt);
2694 for (i = 0; i < len; i += column)
2696 int to = (i + column < len ? i + column : len);
2697 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2699 mplist_add (plist, Mtext, sub);
2700 M17N_OBJECT_UNREF (sub);
2703 M17N_OBJECT_UNREF (mt);
2705 else /* MPLIST_PLIST_P (plist) */
2707 MPlist *pl = MPLIST_PLIST (plist), *p;
2708 MPlist *next = MPLIST_NEXT (plist);
2711 if (MPLIST_TAIL_P (next))
2712 M17N_OBJECT_REF (pl);
2715 pl = mplist_copy (pl);
2716 while (! MPLIST_TAIL_P (next))
2718 p = mplist_copy (MPLIST_PLIST (next));
2719 pl = mplist__conc (pl, p);
2720 M17N_OBJECT_UNREF (p);
2721 next = MPLIST_NEXT (next);
2724 M17N_OBJECT_UNREF (plist);
2726 len = mplist_length (pl);
2728 mplist_add (plist, Mplist, pl);
2733 for (i = 0; i < len; i += column)
2736 mplist_add (plist, Mplist, p);
2737 M17N_OBJECT_UNREF (p);
2738 for (j = 0; j < column && i + j < len; j++)
2740 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
2741 p0 = MPLIST_NEXT (p0);
2745 M17N_OBJECT_UNREF (pl);
2754 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2756 MPlist *action = NULL;
2760 if (MPLIST_SYMBOL_P (action_list))
2762 MSymbol var = MPLIST_SYMBOL (action_list);
2765 MPLIST_DO (p, ic_info->vars)
2766 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2768 if (MPLIST_TAIL_P (p))
2770 action = MPLIST_NEXT (MPLIST_PLIST (p));
2771 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2774 if (MPLIST_PLIST_P (action_list))
2776 action = MPLIST_PLIST (action_list);
2777 if (MPLIST_SYMBOL_P (action))
2779 name = MPLIST_SYMBOL (action);
2780 args = MPLIST_NEXT (action);
2782 && MPLIST_PLIST_P (args))
2783 mplist_set (action, Msymbol, M_candidates);
2785 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2788 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2789 mplist_push (action, Msymbol, M_candidates);
2790 mplist_set (action_list, Mplist, action);
2791 M17N_OBJECT_UNREF (action);
2794 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2797 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2798 mplist_push (action, Msymbol, Minsert);
2799 mplist_set (action_list, Mplist, action);
2800 M17N_OBJECT_UNREF (action);
2805 /* Perform list of actions in ACTION_LIST for the current input
2806 context IC. If all actions are performed without error, return 0.
2807 Otherwise, return -1. */
2810 take_action_list (MInputContext *ic, MPlist *action_list)
2812 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2813 MPlist *candidate_list = ic->candidate_list;
2814 int candidate_index = ic->candidate_index;
2815 int candidate_show = ic->candidate_show;
2816 MTextProperty *prop;
2818 MPLIST_DO (action_list, action_list)
2820 MPlist *action = regularize_action (action_list, ic_info);
2826 name = MPLIST_SYMBOL (action);
2827 args = MPLIST_NEXT (action);
2829 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2830 if (name == Minsert)
2832 if (MPLIST_SYMBOL_P (args))
2834 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2835 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2838 if (MPLIST_MTEXT_P (args))
2839 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2840 else /* MPLIST_INTEGER_P (args)) */
2841 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2843 else if (name == M_candidates)
2845 MPlist *plist = get_candidate_list (ic_info, args);
2850 if (MPLIST_MTEXT_P (plist))
2852 preedit_insert (ic, ic->cursor_pos, NULL,
2853 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2858 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2860 preedit_insert (ic, ic->cursor_pos, mt, 0);
2861 len = mtext_nchars (mt);
2863 mtext_put_prop (ic->preedit,
2864 ic->cursor_pos - len, ic->cursor_pos,
2865 Mcandidate_list, plist);
2866 mtext_put_prop (ic->preedit,
2867 ic->cursor_pos - len, ic->cursor_pos,
2868 Mcandidate_index, (void *) 0);
2870 else if (name == Mselect)
2873 int code, idx, gindex;
2874 int pos = ic->cursor_pos;
2876 int idx_decided = 0;
2879 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
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);
2885 if (MPLIST_SYMBOL_P (args))
2887 code = marker_code (MPLIST_SYMBOL (args), 0);
2890 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2891 if (! MPLIST_INTEGER_P (args))
2893 idx = start + MPLIST_INTEGER (args);
2894 if (idx < start || idx >= end)
2902 if (code != '[' && code != ']')
2907 ? new_index (NULL, ic->candidate_index - start,
2908 end - start - 1, MPLIST_SYMBOL (args),
2910 : MPLIST_INTEGER (args)));
2913 find_candidates_group (mtext_property_value (prop), -1,
2918 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2923 int ingroup_index = idx - start;
2926 group = mtext_property_value (prop);
2927 len = mplist_length (group);
2940 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2941 idx += (MPLIST_MTEXT_P (group)
2942 ? mtext_nchars (MPLIST_MTEXT (group))
2943 : mplist_length (MPLIST_PLIST (group)));
2944 len = (MPLIST_MTEXT_P (group)
2945 ? mtext_nchars (MPLIST_MTEXT (group))
2946 : mplist_length (MPLIST_PLIST (group)));
2947 if (ingroup_index >= len)
2948 ingroup_index = len - 1;
2949 idx += ingroup_index;
2951 update_candidate (ic, prop, idx);
2952 MDEBUG_PRINT1 ("(%d)", idx);
2954 else if (name == Mshow)
2955 ic->candidate_show = 1;
2956 else if (name == Mhide)
2957 ic->candidate_show = 0;
2958 else if (name == Mdelete)
2960 int len = mtext_nchars (ic->preedit);
2964 if (MPLIST_SYMBOL_P (args)
2965 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
2967 to = ic->cursor_pos + pos;
2970 delete_surrounding_text (ic, to);
2975 delete_surrounding_text (ic, to - len);
2981 to = (MPLIST_SYMBOL_P (args)
2982 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2984 : MPLIST_INTEGER (args));
2990 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
2991 if (to < ic->cursor_pos)
2992 preedit_delete (ic, to, ic->cursor_pos);
2993 else if (to > ic->cursor_pos)
2994 preedit_delete (ic, ic->cursor_pos, to);
2996 else if (name == Mmove)
2998 int len = mtext_nchars (ic->preedit);
3000 = (MPLIST_SYMBOL_P (args)
3001 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3003 : MPLIST_INTEGER (args));
3009 if (pos != ic->cursor_pos)
3011 ic->cursor_pos = pos;
3012 ic->preedit_changed = 1;
3014 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3016 else if (name == Mmark)
3018 int code = marker_code (MPLIST_SYMBOL (args), 0);
3022 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3023 (void *) ic->cursor_pos);
3024 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3027 else if (name == Mpushback)
3029 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3033 if (MPLIST_SYMBOL_P (args))
3035 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3036 if (MPLIST_INTEGER_P (args))
3037 num = MPLIST_INTEGER (args);
3042 num = MPLIST_INTEGER (args);
3045 ic_info->key_head -= num;
3047 ic_info->key_head = 0;
3049 ic_info->key_head = - num;
3050 if (ic_info->key_head > ic_info->used)
3051 ic_info->key_head = ic_info->used;
3053 else if (MPLIST_MTEXT_P (args))
3055 MText *mt = MPLIST_MTEXT (args);
3056 int i, len = mtext_nchars (mt);
3059 ic_info->key_head--;
3060 for (i = 0; i < len; i++)
3062 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3063 if (ic_info->key_head + i < ic_info->used)
3064 ic_info->keys[ic_info->key_head + i] = key;
3066 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3071 MPlist *plist = MPLIST_PLIST (args), *pl;
3075 ic_info->key_head--;
3077 MPLIST_DO (pl, plist)
3079 key = MPLIST_SYMBOL (pl);
3080 if (ic_info->key_head < ic_info->used)
3081 ic_info->keys[ic_info->key_head + i] = key;
3083 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3088 else if (name == Mcall)
3090 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3091 MIMExternalFunc func = NULL;
3092 MSymbol module, func_name;
3093 MPlist *func_args, *val;
3096 module = MPLIST_SYMBOL (args);
3097 args = MPLIST_NEXT (args);
3098 func_name = MPLIST_SYMBOL (args);
3100 if (im_info->externals)
3102 MIMExternalModule *external
3103 = (MIMExternalModule *) mplist_get (im_info->externals,
3106 func = (MIMExternalFunc) mplist_get (external->func_list,
3111 func_args = mplist ();
3112 mplist_add (func_args, Mt, ic);
3113 MPLIST_DO (args, MPLIST_NEXT (args))
3117 if (MPLIST_KEY (args) == Msymbol
3118 && MPLIST_KEY (args) != Mnil
3119 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3121 code = new_index (ic, ic->cursor_pos,
3122 mtext_nchars (ic->preedit),
3123 MPLIST_SYMBOL (args), ic->preedit);
3124 mplist_add (func_args, Minteger, (void *) code);
3127 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3129 val = (func) (func_args);
3130 M17N_OBJECT_UNREF (func_args);
3131 if (val && ! MPLIST_TAIL_P (val))
3132 ret = take_action_list (ic, val);
3133 M17N_OBJECT_UNREF (val);
3137 else if (name == Mshift)
3139 shift_state (ic, MPLIST_SYMBOL (args));
3141 else if (name == Mundo)
3143 int intarg = (MPLIST_TAIL_P (args)
3145 : integer_value (ic, args, NULL, 0));
3147 mtext_reset (ic->preedit);
3148 mtext_reset (ic_info->preedit_saved);
3149 mtext_reset (ic->produced);
3150 M17N_OBJECT_UNREF (ic_info->vars);
3151 ic_info->vars = mplist_copy (ic_info->vars_saved);
3152 ic->cursor_pos = ic_info->state_pos = 0;
3153 ic_info->state_key_head = ic_info->key_head = 0;
3155 shift_state (ic, Mnil);
3158 if (MPLIST_TAIL_P (args))
3163 ic_info->used += intarg;
3166 ic_info->used = intarg;
3169 else if (name == Mset || name == Madd || name == Msub
3170 || name == Mmul || name == Mdiv)
3172 MSymbol sym = MPLIST_SYMBOL (args);
3177 val1 = integer_value (ic, args, &value, 0);
3178 args = MPLIST_NEXT (args);
3179 val2 = resolve_expression (ic, args);
3181 val1 = val2, op = "=";
3182 else if (name == Madd)
3183 val1 += val2, op = "+=";
3184 else if (name == Msub)
3185 val1 -= val2, op = "-=";
3186 else if (name == Mmul)
3187 val1 *= val2, op = "*=";
3189 val1 /= val2, op = "/=";
3190 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3191 MSYMBOL_NAME (sym), op, val1, val1);
3193 mplist_set (value, Minteger, (void *) val1);
3195 else if (name == Mequal || name == Mless || name == Mgreater
3196 || name == Mless_equal || name == Mgreater_equal)
3199 MPlist *actions1, *actions2;
3202 val1 = resolve_expression (ic, args);
3203 args = MPLIST_NEXT (args);
3204 val2 = resolve_expression (ic, args);
3205 args = MPLIST_NEXT (args);
3206 actions1 = MPLIST_PLIST (args);
3207 args = MPLIST_NEXT (args);
3208 if (MPLIST_TAIL_P (args))
3211 actions2 = MPLIST_PLIST (args);
3212 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3213 if (name == Mequal ? val1 == val2
3214 : name == Mless ? val1 < val2
3215 : name == Mgreater ? val1 > val2
3216 : name == Mless_equal ? val1 <= val2
3219 MDEBUG_PRINT ("ok");
3220 ret = take_action_list (ic, actions1);
3224 MDEBUG_PRINT ("no");
3226 ret = take_action_list (ic, actions2);
3231 else if (name == Mcond)
3235 MPLIST_DO (args, args)
3240 if (! MPLIST_PLIST (args))
3242 cond = MPLIST_PLIST (args);
3243 if (resolve_expression (ic, cond) != 0)
3245 MDEBUG_PRINT1 ("(%dth)", idx);
3246 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3252 else if (name == Mcommit)
3254 preedit_commit (ic);
3256 else if (name == Munhandle)
3258 preedit_commit (ic);
3263 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3267 && (actions = mplist_get (im_info->macros, name)))
3269 if (take_action_list (ic, actions) < 0)
3275 if (ic->candidate_list)
3277 M17N_OBJECT_UNREF (ic->candidate_list);
3278 ic->candidate_list = NULL;
3280 if (ic->cursor_pos > 0
3281 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3284 ic->candidate_list = mtext_property_value (prop);
3285 M17N_OBJECT_REF (ic->candidate_list);
3287 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3289 ic->candidate_from = mtext_property_start (prop);
3290 ic->candidate_to = mtext_property_end (prop);
3293 if (candidate_list != ic->candidate_list)
3294 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3295 if (candidate_index != ic->candidate_index)
3296 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3297 if (candidate_show != ic->candidate_show)
3298 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3303 /* Handle the input key KEY in the current state and map specified in
3304 the input context IC. If KEY is handled correctly, return 0.
3305 Otherwise, return -1. */
3308 handle_key (MInputContext *ic)
3310 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3311 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3312 MIMMap *map = ic_info->map;
3313 MIMMap *submap = NULL;
3314 MSymbol key = ic_info->keys[ic_info->key_head];
3315 MSymbol alias = Mnil;
3318 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3319 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3323 submap = mplist_get (map->submaps, key);
3326 && (alias = msymbol_get (alias, M_key_alias))
3328 submap = mplist_get (map->submaps, alias);
3333 if (! alias || alias == key)
3334 MDEBUG_PRINT (" submap-found");
3336 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3337 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3338 ic->preedit_changed = 1;
3339 ic->cursor_pos = ic_info->state_pos;
3340 ic_info->key_head++;
3341 ic_info->map = map = submap;
3342 if (map->map_actions)
3344 MDEBUG_PRINT (" map-actions:");
3345 if (take_action_list (ic, map->map_actions) < 0)
3347 MDEBUG_PRINT ("\n");
3351 else if (map->submaps)
3353 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3355 MSymbol key = ic_info->keys[i];
3356 char *name = msymbol_name (key);
3358 if (! name[0] || ! name[1])
3359 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3363 /* If this is the terminal map or we have shifted to another
3364 state, perform branch actions (if any). */
3365 if (! map->submaps || map != ic_info->map)
3367 if (map->branch_actions)
3369 MDEBUG_PRINT (" branch-actions:");
3370 if (take_action_list (ic, map->branch_actions) < 0)
3372 MDEBUG_PRINT ("\n");
3376 /* If MAP is still not the root map, shift to the current
3378 if (ic_info->map != ic_info->state->map)
3379 shift_state (ic, ic_info->state->name);
3384 /* MAP can not handle KEY. */
3386 /* If MAP is the root map of the initial state, it means that
3387 the current input method can not handle KEY. */
3388 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3390 MDEBUG_PRINT (" unhandled\n");
3394 if (map != ic_info->state->map)
3396 /* If MAP is not the root map... */
3397 /* If MAP has branch actions, perform them. */
3398 if (map->branch_actions)
3400 MDEBUG_PRINT (" branch-actions:");
3401 if (take_action_list (ic, map->branch_actions) < 0)
3403 MDEBUG_PRINT ("\n");
3407 /* If MAP is still not the root map, shift to the current
3409 if (ic_info->map != ic_info->state->map)
3410 shift_state (ic, ic_info->state->name);
3414 /* MAP is the root map, perform branch actions (if any) or
3415 shift to the initial state. */
3416 if (map->branch_actions)
3418 MDEBUG_PRINT (" branch-actions:");
3419 if (take_action_list (ic, map->branch_actions) < 0)
3421 MDEBUG_PRINT ("\n");
3426 shift_state (ic, Mnil);
3429 MDEBUG_PRINT ("\n");
3433 /* Initialize IC->ic_info. */
3436 init_ic_info (MInputContext *ic)
3438 MInputMethodInfo *im_info = ic->im->info;
3439 MInputContextInfo *ic_info = ic->info;
3442 MLIST_INIT1 (ic_info, keys, 8);;
3444 ic_info->markers = mplist ();
3446 ic_info->vars = mplist ();
3447 if (im_info->configured_vars)
3448 MPLIST_DO (plist, im_info->configured_vars)
3450 MPlist *pl = MPLIST_PLIST (plist);
3451 MSymbol name = MPLIST_SYMBOL (pl);
3453 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3454 if (MPLIST_KEY (pl) != Mt)
3456 MPlist *p = mplist ();
3458 mplist_push (ic_info->vars, Mplist, p);
3459 M17N_OBJECT_UNREF (p);
3460 mplist_add (p, Msymbol, name);
3461 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3464 ic_info->vars_saved = mplist_copy (ic_info->vars);
3466 if (im_info->externals)
3468 MPlist *func_args = mplist (), *plist;
3470 mplist_add (func_args, Mt, ic);
3471 MPLIST_DO (plist, im_info->externals)
3473 MIMExternalModule *external = MPLIST_VAL (plist);
3474 MIMExternalFunc func
3475 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3480 M17N_OBJECT_UNREF (func_args);
3483 ic_info->preedit_saved = mtext ();
3484 ic_info->tick = im_info->tick;
3487 /* Finalize IC->ic_info. */
3490 fini_ic_info (MInputContext *ic)
3492 MInputMethodInfo *im_info = ic->im->info;
3493 MInputContextInfo *ic_info = ic->info;
3495 if (im_info->externals)
3497 MPlist *func_args = mplist (), *plist;
3499 mplist_add (func_args, Mt, ic);
3500 MPLIST_DO (plist, im_info->externals)
3502 MIMExternalModule *external = MPLIST_VAL (plist);
3503 MIMExternalFunc func
3504 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3509 M17N_OBJECT_UNREF (func_args);
3512 MLIST_FREE1 (ic_info, keys);
3513 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3514 M17N_OBJECT_UNREF (ic_info->markers);
3515 M17N_OBJECT_UNREF (ic_info->vars);
3516 M17N_OBJECT_UNREF (ic_info->vars_saved);
3517 M17N_OBJECT_UNREF (ic_info->preceding_text);
3518 M17N_OBJECT_UNREF (ic_info->following_text);
3520 memset (ic_info, 0, sizeof (MInputContextInfo));
3524 re_init_ic (MInputContext *ic, int reload)
3526 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3527 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3528 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3530 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3531 preedit_changed = mtext_nchars (ic->preedit) > 0;
3532 cursor_pos_changed = ic->cursor_pos > 0;
3533 candidates_changed = 0;
3534 if (ic->candidate_list)
3536 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3537 M17N_OBJECT_UNREF (ic->candidate_list);
3538 ic->candidate_list = NULL;
3540 if (ic->candidate_show)
3542 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3543 ic->candidate_show = 0;
3545 if (ic->candidate_index > 0)
3547 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3548 ic->candidate_index = 0;
3549 ic->candidate_from = ic->candidate_to = 0;
3551 if (mtext_nchars (ic->produced) > 0)
3552 mtext_reset (ic->produced);
3553 if (mtext_nchars (ic->preedit) > 0)
3554 mtext_reset (ic->preedit);
3556 M17N_OBJECT_UNREF (ic->plist);
3557 ic->plist = mplist ();
3561 reload_im_info (im_info);
3563 shift_state (ic, Mnil);
3564 ic->status_changed = status_changed;
3565 ic->preedit_changed = preedit_changed;
3566 ic->cursor_pos_changed = cursor_pos_changed;
3567 ic->candidates_changed = candidates_changed;
3571 reset_ic (MInputContext *ic, MSymbol ignore)
3573 MDEBUG_PRINT ("\n [IM] reset\n");
3578 open_im (MInputMethod *im)
3580 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3583 MERROR (MERROR_IM, -1);
3590 close_im (MInputMethod *im)
3596 create_ic (MInputContext *ic)
3598 MInputContextInfo *ic_info;
3600 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3603 shift_state (ic, Mnil);
3608 destroy_ic (MInputContext *ic)
3615 check_reload (MInputContext *ic, MSymbol key)
3617 MInputMethodInfo *im_info = ic->im->info;
3618 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3622 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3626 MPLIST_DO (plist, plist)
3628 MSymbol this_key, alias;
3630 if (MPLIST_MTEXT_P (plist))
3632 MText *mt = MPLIST_MTEXT (plist);
3633 int c = mtext_ref_char (mt, 0);
3637 this_key = one_char_symbol[c];
3641 MPlist *pl = MPLIST_PLIST (plist);
3643 this_key = MPLIST_SYMBOL (pl);
3647 && (alias = msymbol_get (alias, M_key_alias))
3648 && alias != this_key);
3652 if (MPLIST_TAIL_P (plist))
3655 MDEBUG_PRINT ("\n [IM] reload");
3661 /** Handle the input key KEY in the current state and map of IC->info.
3662 If KEY is handled but no text is produced, return 0, otherwise
3668 filter (MInputContext *ic, MSymbol key, void *arg)
3670 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3671 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3674 if (check_reload (ic, key))
3677 if (! ic_info->state)
3679 ic_info->key_unhandled = 1;
3682 mtext_reset (ic->produced);
3683 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3684 M17N_OBJECT_UNREF (ic_info->preceding_text);
3685 M17N_OBJECT_UNREF (ic_info->following_text);
3686 ic_info->preceding_text = ic_info->following_text = NULL;
3687 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3688 ic_info->key_unhandled = 0;
3691 if (handle_key (ic) < 0)
3693 /* KEY was not handled. Delete it from the current key sequence. */
3694 if (ic_info->used > 0)
3696 memmove (ic_info->keys, ic_info->keys + 1,
3697 sizeof (int) * (ic_info->used - 1));
3699 if (ic_info->state_key_head > 0)
3700 ic_info->state_key_head--;
3702 /* This forces returning 1. */
3703 ic_info->key_unhandled = 1;
3709 reset_ic (ic, Mnil);
3710 ic_info->key_unhandled = 1;
3713 /* Break the loop if all keys were handled. */
3714 } while (ic_info->key_head < ic_info->used);
3716 /* If the current map is the root of the initial state, we should
3717 produce any preedit text in ic->produced. */
3718 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3719 preedit_commit (ic);
3721 if (mtext_nchars (ic->produced) > 0)
3723 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3725 if (mdebug__flag & mdebug_mask)
3727 MDEBUG_PRINT (" (produced");
3728 for (i = 0; i < mtext_nchars (ic->produced); i++)
3729 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3734 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3735 Mlanguage, ic->im->language);
3736 if (ic_info->state_key_head > 0)
3738 memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head,
3739 sizeof (int) * (ic_info->used - ic_info->state_key_head));
3740 ic_info->used -= ic_info->state_key_head;
3741 ic_info->key_head -= ic_info->state_key_head;
3742 ic_info->state_key_head = 0;
3746 if (ic_info->key_unhandled)
3749 ic_info->key_head = ic_info->state_key_head = 0;
3752 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3756 /** Return 1 if the last event or key was not handled, otherwise
3759 There is no need of looking up because ic->produced should already
3760 contain the produced text (if any).
3765 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3767 mtext_cat (mt, ic->produced);
3768 mtext_reset (ic->produced);
3769 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3773 /* Input method command handler. */
3775 /* List of all (global and local) commands.
3776 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3777 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3778 Global commands are stored as (t (t COMMAND ...)) */
3781 /* Input method variable handler. */
3784 /* Support functions for mdebug_dump_im. */
3787 dump_im_map (MPlist *map_list, int indent)
3790 MSymbol key = MPLIST_KEY (map_list);
3791 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3793 prefix = (char *) alloca (indent + 1);
3794 memset (prefix, 32, indent);
3795 prefix[indent] = '\0';
3797 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3798 if (map->map_actions)
3799 mdebug_dump_plist (map->map_actions, indent + 2);
3802 MPLIST_DO (map_list, map->submaps)
3804 fprintf (stderr, "\n%s ", prefix);
3805 dump_im_map (map_list, indent + 2);
3808 if (map->branch_actions)
3810 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3811 mdebug_dump_plist (map->branch_actions, indent + 4);
3812 fprintf (stderr, ")");
3814 fprintf (stderr, ")");
3819 dump_im_state (MIMState *state, int indent)
3824 prefix = (char *) alloca (indent + 1);
3825 memset (prefix, 32, indent);
3826 prefix[indent] = '\0';
3828 fprintf (stderr, "(%s", msymbol_name (state->name));
3829 if (state->map->submaps)
3831 MPLIST_DO (map_list, state->map->submaps)
3833 fprintf (stderr, "\n%s ", prefix);
3834 dump_im_map (map_list, indent + 2);
3837 fprintf (stderr, ")");
3845 Minput_driver = msymbol ("input-driver");
3847 Minput_preedit_start = msymbol ("input-preedit-start");
3848 Minput_preedit_done = msymbol ("input-preedit-done");
3849 Minput_preedit_draw = msymbol ("input-preedit-draw");
3850 Minput_status_start = msymbol ("input-status-start");
3851 Minput_status_done = msymbol ("input-status-done");
3852 Minput_status_draw = msymbol ("input-status-draw");
3853 Minput_candidates_start = msymbol ("input-candidates-start");
3854 Minput_candidates_done = msymbol ("input-candidates-done");
3855 Minput_candidates_draw = msymbol ("input-candidates-draw");
3856 Minput_set_spot = msymbol ("input-set-spot");
3857 Minput_focus_move = msymbol ("input-focus-move");
3858 Minput_focus_in = msymbol ("input-focus-in");
3859 Minput_focus_out = msymbol ("input-focus-out");
3860 Minput_toggle = msymbol ("input-toggle");
3861 Minput_reset = msymbol ("input-reset");
3862 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3863 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3864 Mcustomized = msymbol ("customized");
3865 Mconfigured = msymbol ("configured");
3866 Minherited = msymbol ("inherited");
3868 minput_default_driver.open_im = open_im;
3869 minput_default_driver.close_im = close_im;
3870 minput_default_driver.create_ic = create_ic;
3871 minput_default_driver.destroy_ic = destroy_ic;
3872 minput_default_driver.filter = filter;
3873 minput_default_driver.lookup = lookup;
3874 minput_default_driver.callback_list = mplist ();
3875 mplist_put (minput_default_driver.callback_list, Minput_reset,
3877 minput_driver = &minput_default_driver;
3879 fully_initialized = 0;
3886 if (fully_initialized)
3888 free_im_list (im_info_list);
3890 free_im_list (im_custom_list);
3892 free_im_list (im_config_list);
3893 M17N_OBJECT_UNREF (load_im_info_keys);
3896 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3897 M17N_OBJECT_UNREF (minput_driver->callback_list);
3902 minput__callback (MInputContext *ic, MSymbol command)
3904 MInputCallbackFunc func;
3906 if (! ic->im->driver.callback_list)
3908 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3912 (func) (ic, command);
3917 minput__char_to_key (int c)
3919 if (c < 0 || c >= 0x100)
3922 return one_char_symbol[c];
3926 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3931 /*** @addtogroup m17nInputMethod */
3936 @name Variables: Predefined symbols for callback commands.
3938 These are the predefined symbols that are used as the @c COMMAND
3939 argument of callback functions of an input method driver (see
3940 #MInputDriver::callback_list).
3942 Most of them do not require extra argument nor return any value;
3943 exceptions are these:
3945 Minput_get_surrounding_text: When a callback function assigned for
3946 this command is called, the first element of #MInputContext::plist
3947 has key #Minteger and the value specifies which portion of the
3948 surrounding text should be retrieved. If the value is positive,
3949 it specifies the number of characters following the current cursor
3950 position. If the value is negative, the absolute value specifies
3951 the number of characters preceding the current cursor position.
3953 If the surrounding text is currently supported, the callback
3954 function must set the key of this element to #Mtext and the value
3955 to the retrieved M-text. The length of the M-text may be shorter
3956 than the requested number of characters, if the available text is
3957 not that long. The length can be zero in the worst case. Or, the
3958 length may be longer if an application thinks it is more efficient
3959 to return that length.
3961 If the surrounding text is not currently supported, the callback
3962 function should return without changing the first element of
3963 #MInputContext::plist.
3965 Minput_delete_surrounding_text: When a callback function assigned
3966 for this command is called, the first element of
3967 #MInputContext::plist has key #Minteger and the value specifies
3968 which portion of the surrounding text should be deleted in the
3969 same way as the case of Minput_get_surrounding_text. The callback
3970 function must delete the specified text. It should not alter
3971 #MInputContext::plist. */
3973 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3975 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3976 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3978 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
3980 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
3981 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
3982 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
3983 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
3984 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
3987 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
3988 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
3989 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
3990 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
3991 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
3993 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
3994 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѲ½¤µ¤»¤ë¤³¤È¤Ê¤¯ÊÖ¤µ¤Ê¤¯¤Æ
3997 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
3998 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
3999 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4000 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4001 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4002 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4006 MSymbol Minput_preedit_start;
4007 MSymbol Minput_preedit_done;
4008 MSymbol Minput_preedit_draw;
4009 MSymbol Minput_status_start;
4010 MSymbol Minput_status_done;
4011 MSymbol Minput_status_draw;
4012 MSymbol Minput_candidates_start;
4013 MSymbol Minput_candidates_done;
4014 MSymbol Minput_candidates_draw;
4015 MSymbol Minput_set_spot;
4016 MSymbol Minput_toggle;
4017 MSymbol Minput_reset;
4018 MSymbol Minput_get_surrounding_text;
4019 MSymbol Minput_delete_surrounding_text;
4025 @name Variables: Predefined symbols for special input events.
4027 These are the predefined symbols that are used as the @c KEY
4028 argument of minput_filter (). */
4030 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4032 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4037 MSymbol Minput_focus_out;
4038 MSymbol Minput_focus_in;
4039 MSymbol Minput_focus_move;
4045 @name Variables: Predefined symbols used in input method information.
4047 These are the predefined symbols describing status of input method
4048 command and variable, and are used in a return value of
4049 minput_get_command () and minput_get_variable (). */
4051 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4053 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4054 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4058 MSymbol Mcustomized;
4059 MSymbol Mconfigured;
4065 @brief The default driver for internal input methods.
4067 The variable #minput_default_driver is the default driver for
4068 internal input methods.
4070 The member MInputDriver::open_im () searches the m17n database for
4071 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4072 $NAME\> and loads it.
4074 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4075 programmers responsibility to set it to a plist of proper callback
4076 functions. Otherwise, no feedback information (e.g. preedit text)
4077 can be shown to users.
4079 The macro M17N_INIT () sets the variable #minput_driver to the
4080 pointer to this driver so that all internal input methods use it.
4082 Therefore, unless @c minput_driver is set differently, the driver
4083 dependent arguments $ARG of the functions whose name begins with
4084 "minput_" are all ignored. */
4086 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4088 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4090 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4091 \< #Minput_method, $LANGUAGE, $NAME\>
4092 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4094 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4095 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4096 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4097 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4099 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4100 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4102 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4103 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4105 MInputDriver minput_default_driver;
4109 @brief The driver for internal input methods.
4111 The variable #minput_driver is a pointer to the input method
4112 driver that is used by internal input methods. The macro
4113 M17N_INIT () initializes it to a pointer to #minput_default_driver
4114 if <m17n<EM></EM>.h> is included. */
4116 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4118 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4119 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4120 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4121 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4123 MInputDriver *minput_driver;
4125 MSymbol Minput_driver;
4140 @brief Open an input method.
4142 The minput_open_im () function opens an input method whose
4143 language and name match $LANGUAGE and $NAME, and returns a pointer
4144 to the input method object newly allocated.
4146 This function at first decides a driver for the input method as
4149 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4150 #minput_driver is used.
4152 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4153 driver pointed to by the property value is used to open the input
4154 method. If $NAME has no such a property, @c NULL is returned.
4156 Then, the member MInputDriver::open_im () of the driver is
4159 $ARG is set in the member @c arg of the structure MInputMethod so
4160 that the driver can refer to it. */
4162 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4164 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4165 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4167 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4169 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4170 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4172 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4173 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4174 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4176 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4178 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4180 @latexonly \IPAlabel{minput_open} @endlatexonly
4185 minput_open_im (MSymbol language, MSymbol name, void *arg)
4188 MInputDriver *driver;
4192 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4193 msymbol_name (language), msymbol_name (name));
4195 driver = minput_driver;
4198 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4200 MERROR (MERROR_IM, NULL);
4203 MSTRUCT_CALLOC (im, MERROR_IM);
4204 im->language = language;
4207 im->driver = *driver;
4208 if ((*im->driver.open_im) (im) < 0)
4210 MDEBUG_PRINT (" failed\n");
4214 MDEBUG_PRINT (" ok\n");
4221 @brief Close an input method.
4223 The minput_close_im () function closes the input method $IM, which
4224 must have been created by minput_open_im (). */
4227 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4229 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4230 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4233 minput_close_im (MInputMethod *im)
4235 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4236 msymbol_name (im->name), msymbol_name (im->language));
4237 (*im->driver.close_im) (im);
4239 MDEBUG_PRINT (" done\n");
4245 @brief Create an input context.
4247 The minput_create_ic () function creates an input context object
4248 associated with input method $IM, and calls callback functions
4249 corresponding to #Minput_preedit_start, #Minput_status_start, and
4250 #Minput_status_draw in this order.
4253 If an input context is successfully created, minput_create_ic ()
4254 returns a pointer to it. Otherwise it returns @c NULL. */
4257 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4259 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4260 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4261 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4262 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4265 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4266 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4270 minput_create_ic (MInputMethod *im, void *arg)
4274 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4275 msymbol_name (im->name), msymbol_name (im->language));
4276 MSTRUCT_CALLOC (ic, MERROR_IM);
4279 ic->preedit = mtext ();
4280 ic->candidate_list = NULL;
4281 ic->produced = mtext ();
4282 ic->spot.x = ic->spot.y = 0;
4284 ic->plist = mplist ();
4285 if ((*im->driver.create_ic) (ic) < 0)
4287 MDEBUG_PRINT (" failed\n");
4288 M17N_OBJECT_UNREF (ic->preedit);
4289 M17N_OBJECT_UNREF (ic->produced);
4290 M17N_OBJECT_UNREF (ic->plist);
4295 if (im->driver.callback_list)
4297 minput__callback (ic, Minput_preedit_start);
4298 minput__callback (ic, Minput_status_start);
4299 minput__callback (ic, Minput_status_draw);
4302 MDEBUG_PRINT (" ok\n");
4309 @brief Destroy an input context.
4311 The minput_destroy_ic () function destroys the input context $IC,
4312 which must have been created by minput_create_ic (). It calls
4313 callback functions corresponding to #Minput_preedit_done,
4314 #Minput_status_done, and #Minput_candidates_done in this order. */
4317 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4319 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4320 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4321 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4322 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4323 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4327 minput_destroy_ic (MInputContext *ic)
4329 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4330 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4331 if (ic->im->driver.callback_list)
4333 minput__callback (ic, Minput_preedit_done);
4334 minput__callback (ic, Minput_status_done);
4335 minput__callback (ic, Minput_candidates_done);
4337 (*ic->im->driver.destroy_ic) (ic);
4338 M17N_OBJECT_UNREF (ic->preedit);
4339 M17N_OBJECT_UNREF (ic->produced);
4340 M17N_OBJECT_UNREF (ic->plist);
4341 MDEBUG_PRINT (" done\n");
4348 @brief Filter an input key.
4350 The minput_filter () function filters input key $KEY according to
4351 input context $IC, and calls callback functions corresponding to
4352 #Minput_preedit_draw, #Minput_status_draw, and
4353 #Minput_candidates_draw if the preedit text, the status, and the
4354 current candidate are changed respectively.
4356 To make the input method commit the current preedit text (if any)
4357 and shift to the initial state, call this function with #Mnil as
4360 To inform the input method about the focus-out event, call this
4361 function with #Minput_focus_out as $KEY.
4363 To inform the input method about the focus-in event, call this
4364 function with #Minput_focus_in as $KEY.
4366 To inform the input method about the focus-move event (i.e. input
4367 spot change within the same input context), call this function
4368 with #Minput_focus_move as $KEY.
4371 If $KEY is filtered out, this function returns 1. In that case,
4372 the caller should discard the key. Otherwise, it returns 0, and
4373 the caller should handle the key, for instance, by calling the
4374 function minput_lookup () with the same key. */
4377 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4379 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4380 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4381 #Minput_preedit_draw, #Minput_status_draw,
4382 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4385 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4386 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4387 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4388 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4390 @latexonly \IPAlabel{minput_filter} @endlatexonly
4394 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4401 ret = (*ic->im->driver.filter) (ic, key, arg);
4403 if (ic->im->driver.callback_list)
4405 if (ic->preedit_changed)
4406 minput__callback (ic, Minput_preedit_draw);
4407 if (ic->status_changed)
4408 minput__callback (ic, Minput_status_draw);
4409 if (ic->candidates_changed)
4410 minput__callback (ic, Minput_candidates_draw);
4419 @brief Look up a text produced in the input context.
4421 The minput_lookup () function looks up a text in the input context
4422 $IC. $KEY must be identical to the one that was used in the previous call of
4425 If a text was produced by the input method, it is concatenated
4428 This function calls #MInputDriver::lookup .
4431 If $KEY was correctly handled by the input method, this function
4432 returns 0. Otherwise, it returns -1, even though some text
4433 might be produced in $MT. */
4436 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4438 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4439 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4441 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4444 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4447 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4448 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4449 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4451 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4454 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4456 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4461 @brief Set the spot of the input context.
4463 The minput_set_spot () function sets the spot of input context $IC
4464 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4465 The semantics of these values depends on the input method driver.
4467 For instance, a driver designed to work in a CUI environment may
4468 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4469 $DESCENT . A driver designed to work in a window system may
4470 interpret $X and $Y as the pixel offsets relative to the origin of the
4471 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4472 descent pixels of the line at ($X . $Y ).
4474 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4476 $MT and $POS are the M-text and the character position at the spot.
4477 $MT may be @c NULL, in which case, the input method cannot get
4478 information about the text around the spot. */
4481 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4483 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4484 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4485 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4487 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4488 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4489 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4490 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4491 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4492 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4494 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4496 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4497 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4501 minput_set_spot (MInputContext *ic, int x, int y,
4502 int ascent, int descent, int fontsize,
4507 ic->spot.ascent = ascent;
4508 ic->spot.descent = descent;
4509 ic->spot.fontsize = fontsize;
4512 if (ic->im->driver.callback_list)
4513 minput__callback (ic, Minput_set_spot);
4518 @brief Toggle input method.
4520 The minput_toggle () function toggles the input method associated
4521 with input context $IC. */
4523 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4525 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4526 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4530 minput_toggle (MInputContext *ic)
4532 if (ic->im->driver.callback_list)
4533 minput__callback (ic, Minput_toggle);
4534 ic->active = ! ic->active;
4540 @brief Reset an input context.
4542 The minput_reset_ic () function resets input context $IC by
4543 calling a callback function corresponding to #Minput_reset. It
4544 resets the status of $IC to its initial one. As the
4545 current preedit text is deleted without commitment, if necessary,
4546 call minput_filter () with the arg @r key #Mnil to force the input
4547 method to commit the preedit in advance. */
4550 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4552 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4553 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4554 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4555 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4556 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4557 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4560 minput_reset_ic (MInputContext *ic)
4562 if (ic->im->driver.callback_list)
4563 minput__callback (ic, Minput_reset);
4569 @brief Get title and icon filename of an input method.
4571 The minput_get_title_icon () function returns a plist containing a
4572 title and icon filename (if any) of an input method specified by
4573 $LANGUAGE and $NAME.
4575 The first element of the plist has key #Mtext and the value is an
4576 M-text of the title for identifying the input method. The second
4577 element (if any) has key #Mtext and the value is an M-text of the
4578 icon image (absolute) filename for the same purpose.
4581 If there exists a specified input method and it defines an title,
4582 a plist is returned. Otherwise, NULL is returned. The caller
4583 must free the plist by m17n_object_unref (). */
4585 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4587 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4588 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4591 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4592 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4593 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¤ÎÀäÂÐ¥Õ¥¡¥¤¥ë¥Í¡¼¥à¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4596 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4597 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4598 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4601 minput_get_title_icon (MSymbol language, MSymbol name)
4603 MInputMethodInfo *im_info;
4610 im_info = get_im_info (language, name, Mnil, Mtitle);
4611 if (! im_info || !im_info->title)
4613 mt = mtext_get_prop (im_info->title, 0, Mtext);
4615 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4618 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4621 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4622 (char *) MSYMBOL_NAME (name));
4623 file = mdatabase__find_file (buf);
4624 if (! file && language == Mt)
4626 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4627 file = mdatabase__find_file (buf);
4632 mplist_add (plist, Mtext, im_info->title);
4635 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4637 mplist_add (plist, Mtext, mt);
4638 M17N_OBJECT_UNREF (mt);
4646 @brief Get description text of an input method.
4648 The minput_get_description () function returns an M-text that
4649 describes the input method specified by $LANGUAGE and $NAME.
4652 If the specified input method has a description text, a pointer to
4653 #MText is returned. The caller has to free it by m17n_object_unref ().
4654 If the input method does not have a description text, @c NULL is
4657 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4659 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4660 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4662 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4663 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4664 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4665 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4668 minput_get_description (MSymbol language, MSymbol name)
4670 MInputMethodInfo *im_info;
4678 extra = language, language = Mt;
4680 im_info = get_im_info (language, name, extra, Mdescription);
4681 if (! im_info || ! im_info->description)
4683 M17N_OBJECT_REF (im_info->description);
4684 return im_info->description;
4690 @brief Get information about input method command(s).
4692 The minput_get_command () function returns information about
4693 the command $COMMAND of the input method specified by $LANGUAGE and
4694 $NAME. An input method command is a pseudo key event to which one
4695 or more actual input key sequences are assigned.
4697 There are two kinds of commands, global and local. A global
4698 command has a global definition, and the description and the key
4699 assignment may be inherited by a local command. Each input method
4700 defines a local command which has a local key assignment. It may
4701 also declare a local command that inherits the definition of a
4702 global command of the same name.
4704 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4705 information about a global command. Otherwise information about a
4706 local command is returned.
4708 If $COMMAND is #Mnil, information about all commands is returned.
4710 The return value is a @e well-formed plist (#m17nPlist) of this
4713 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4715 @c NAME is a symbol representing the command name.
4717 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4718 command has no description.
4720 @c STATUS is a symbol representing how the key assignment is decided.
4721 The value is #Mnil (the default key assignment), #Mcustomized (the
4722 key assignment is customized by per-user configuration file), or
4723 #Mconfigured (the key assignment is set by the call of
4724 minput_config_command ()). For a local command only, it may also
4725 be #Minherited (the key assignment is inherited from the
4726 corresponding global command).
4728 @c KEYSEQ is a plist of one or more symbols representing a key
4729 sequence assigned to the command. If there's no KEYSEQ, the
4730 command is currently disabled (i.e. no key sequence can trigger
4731 actions of the command).
4733 If $COMMAND is not #Mnil, the first element of the returned plist
4734 contains the information about $COMMAND.
4738 If the requested information was found, a pointer to a non-empty
4739 plist is returned. As the plist is kept in the library, the
4740 caller must not modify nor free it.
4742 Otherwise (the specified input method or the specified command
4743 does not exist), @c NULL is returned. */
4745 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4747 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4748 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4749 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4750 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4752 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4753 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4754 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4755 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4756 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4758 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4759 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4762 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4764 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4767 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4769 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4771 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4774 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4775 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4776 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4777 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4778 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4779 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4781 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4782 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4783 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4784 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4786 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4787 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4791 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4792 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4795 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4800 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4802 /* Return a description of the command COMMAND of the input method
4803 specified by LANGUAGE and NAME. */
4804 MPlist *cmd = minput_get_command (langauge, name, command);
4809 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4810 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4811 return (mplist_key (plist) == Mtext
4812 ? (MText *) mplist_value (plist)
4818 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4820 MInputMethodInfo *im_info;
4824 im_info = get_im_info (language, name, Mnil, Mcommand);
4826 || ! im_info->configured_cmds
4827 || MPLIST_TAIL_P (im_info->configured_cmds))
4829 if (command == Mnil)
4830 return im_info->configured_cmds;
4831 return mplist__assq (im_info->configured_cmds, command);
4837 @brief Configure the key sequence of an input method command.
4839 The minput_config_command () function assigns a list of key
4840 sequences $KEYSEQLIST to the command $COMMAND of the input method
4841 specified by $LANGUAGE and $NAME.
4843 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4844 sequences, and each key sequence must be a plist of symbols.
4846 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4848 If $KEYSEQLIST is NULL, the configuration of the command for the
4849 input method is canceled, and the default key sequences become
4850 effective. In such case, if $COMMAND is #Mnil, configurations for
4851 all commands of the input method are canceled.
4853 If $NAME is #Mnil, this function configures the key assignment of a
4854 global command, not that of a specific input method.
4856 The configuration takes effect for input methods opened or
4857 re-opened later in the current session. In order to make the
4858 configuration take effect for the future session, it must be saved
4859 in a per-user configuration file by the function
4860 minput_save_config ().
4864 If the operation was successful, this function returns 0,
4865 otherwise returns -1. The operation fails in these cases:
4867 <li>$KEYSEQLIST is not in a valid form.
4868 <li>$COMMAND is not available for the input method.
4869 <li>$LANGUAGE and $NAME do not specify an existing input method.
4873 minput_get_commands (), minput_save_config ().
4876 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4878 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4879 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4880 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4882 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4883 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4885 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4887 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4888 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4889 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4892 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4893 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4895 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4896 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4897 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4898 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4902 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4904 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4905 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4906 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4910 minput_get_commands (), minput_save_config ().
4914 /* Add "C-x u" to the "start" command of Unicode input method. */
4916 MSymbol start_command = msymbol ("start");
4917 MSymbol unicode = msymbol ("unicode");
4918 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4920 /* At first get the current key-sequence assignment. */
4921 cmd = mplist_get_command (Mt, unicode, start_command);
4924 /* The input method does not have the command "start". Here
4925 should come some error handling code. */
4927 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4928 the part (KEY-SEQUENCE ...). */
4929 plist = mplist_next (mplist_next (mplist_value (cmd)));
4930 /* Copy it because we should not modify it directly. */
4931 key_seq_list = mplist_copy (plist);
4932 m17n_object_unref (cmds);
4934 key_seq = mplist ();
4935 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4936 mplist_add (key_seq, Msymbol, msymbol ("u"));
4937 mplist_add (key_seq_list, Mplist, key_seq);
4938 m17n_object_unref (key_seq);
4940 minput_config_command (Mt, unicode, start_command, key_seq_list);
4941 m17n_object_unref (key_seq_list);
4946 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4949 MInputMethodInfo *im_info, *config;
4956 if (command == Mnil)
4957 MERROR (MERROR_IM, -1);
4958 MPLIST_DO (plist, keyseqlist)
4959 if (! MPLIST_PLIST_P (plist)
4960 || ! check_command_keyseq (plist))
4961 MERROR (MERROR_IM, -1);
4964 im_info = get_im_info (language, name, Mnil, Mcommand);
4966 MERROR (MERROR_IM, -1);
4969 || ! mplist__assq (im_info->cmds, command)))
4970 MERROR (MERROR_IM, -1);
4972 config = get_config_info (im_info);
4975 if (! im_config_list)
4976 im_config_list = mplist ();
4977 config = new_im_info (NULL, language, name, Mnil, im_config_list);
4978 config->cmds = mplist ();
4979 config->vars = mplist ();
4982 if (command == Mnil)
4984 MInputMethodInfo *custom = get_custom_info (im_info);
4986 mplist_set (config->cmds, Mnil, NULL);
4987 if (custom && custom->cmds)
4989 MPLIST_DO (plist, custom->cmds)
4991 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
4993 mplist_add (plist, Msymbol, command);
4994 mplist_push (config->cmds, Mplist, plist);
4995 M17N_OBJECT_UNREF (plist);
5001 plist = mplist__assq (config->cmds, command);
5004 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
5005 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
5006 if (! MPLIST_TAIL_P (plist))
5007 mplist_set (plist, Mnil, NULL); /* () */
5012 mplist_add (config->cmds, Mplist, plist);
5013 M17N_OBJECT_UNREF (plist);
5014 plist = mplist_add (plist, Msymbol, command);
5015 plist = MPLIST_NEXT (plist);
5021 plist = mplist_add (plist, Msymbol, Mnil);
5022 MPLIST_DO (keyseqlist, keyseqlist)
5024 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5025 plist = mplist_add (plist, Mplist, pl);
5026 M17N_OBJECT_UNREF (pl);
5030 config_all_commands (im_info);
5031 im_info->tick = time (NULL);
5038 @brief Get information about input method variable(s).
5040 The minput_get_variable () function returns information about
5041 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5042 An input method variable controls behavior of an input method.
5044 There are two kinds of variables, global and local. A global
5045 variable has a global definition, and the description and the value
5046 may be inherited by a local variable. Each input method defines a
5047 local variable which has local value. It may also declare a
5048 local variable that inherits definition of a global variable of
5051 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5052 variable is returned. Otherwise information about a local variable
5055 If $VARIABLE is #Mnil, information about all variables is
5058 The return value is a @e well-formed plist (#m17nPlist) of this
5061 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5063 @c NAME is a symbol representing the variable name.
5065 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5066 variable has no description.
5068 @c STATUS is a symbol representing how the value is decided. The
5069 value is #Mnil (the default value), #Mcustomized (the value is
5070 customized by per-user configuration file), or #Mconfigured (the
5071 value is set by the call of minput_config_variable ()). For a
5072 local variable only, it may also be #Minherited (the value is
5073 inherited from the corresponding global variable).
5075 @c VALUE is the initial value of the variable. If the key of this
5076 element is #Mt, the variable has no initial value. Otherwise, the
5077 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5080 @c VALID-VALUEs (if any) specify which values the variable can have.
5081 They have the same type (i.e. having the same key) as @c VALUE except
5082 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5083 may be a plist of two integers specifying the range of possible
5086 If there no @c VALID-VALUE, the variable can have any value as long
5087 as the type is the same as @c VALUE.
5089 If $VARIABLE is not #Mnil, the first element of the returned plist
5090 contains the information about $VARIABLE.
5094 If the requested information was found, a pointer to a non-empty
5095 plist is returned. As the plist is kept in the library, the
5096 caller must not modify nor free it.
5098 Otherwise (the specified input method or the specified variable
5099 does not exist), @c NULL is returned. */
5101 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5103 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5104 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5105 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5107 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5108 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5109 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5110 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5113 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5114 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5116 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5118 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5120 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5123 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5125 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5128 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5129 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5130 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5131 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5132 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5133 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5135 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5136 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5137 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5139 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5140 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5141 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5142 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5144 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5147 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5148 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5152 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5153 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5156 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5160 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5162 MInputMethodInfo *im_info;
5166 im_info = get_im_info (language, name, Mnil, Mvariable);
5167 if (! im_info || ! im_info->configured_vars)
5169 if (variable == Mnil)
5170 return im_info->configured_vars;
5171 return mplist__assq (im_info->configured_vars, variable);
5177 @brief Configure the value of an input method variable.
5179 The minput_config_variable () function assigns $VALUE to the
5180 variable $VARIABLE of the input method specified by $LANGUAGE and
5183 If $VALUE is not NULL, it must be a plist of one element whose key
5184 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5187 If $VALUE is NULL, a configuration for the variable for the input
5188 method is canceled, and the variable is initialized to the default
5189 value. In that case, if $VARIABLE is #Mnil, configurations for
5190 all variables of the input method are canceled.
5192 If $NAME is #Mnil, this function configure the value of global
5193 variable, not that of a specific input method.
5195 The configuration takes effect for input methods opened or
5196 re-opened later in the current session. To make the configuration
5197 take effect for the future session, it must be saved in a per-user
5198 configuration file by the function minput_save_config ().
5202 If the operation was successful, this function returns 0,
5203 otherwise returns -1. The operation fails in these cases:
5205 <li>$VALUE is not in a valid form, the type does not match the
5206 definition, or the value is our of range.
5207 <li>$VARIABLE is not available for the input method.
5208 <li>$LANGUAGE and $NAME do not specify an existing input method.
5212 minput_get_variable (), minput_save_config (). */
5214 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5216 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5217 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5219 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5220 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5222 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5223 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5224 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5226 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5227 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5229 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5230 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5231 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5232 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5236 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5238 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5239 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5240 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5244 minput_get_commands (), minput_save_config ().
5247 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5250 MInputMethodInfo *im_info, *config;
5255 im_info = get_im_info (language, name, Mnil, Mvariable);
5257 MERROR (MERROR_IM, -1);
5258 if (variable == Mnil)
5261 MERROR (MERROR_IM, -1);
5263 else if (! im_info->vars
5264 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5265 MERROR (MERROR_IM, -1);
5267 if (variable != Mnil && value)
5269 plist = MPLIST_PLIST (plist);
5270 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5271 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5272 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5273 if (MPLIST_KEY (plist) != Mt
5274 && ! check_variable_value (value, plist))
5275 MERROR (MERROR_IM, -1);
5278 config = get_config_info (im_info);
5281 if (! im_config_list)
5282 im_config_list = mplist ();
5283 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5284 config->cmds = mplist ();
5285 config->vars = mplist ();
5288 if (variable == Mnil)
5290 MInputMethodInfo *custom = get_custom_info (im_info);
5292 mplist_set (config->vars, Mnil, NULL);
5293 if (custom && custom->cmds)
5295 MPLIST_DO (plist, custom->vars)
5297 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5299 mplist_add (plist, Msymbol, variable);
5300 mplist_push (config->vars, Mplist, plist);
5301 M17N_OBJECT_UNREF (plist);
5307 plist = mplist__assq (config->vars, variable);
5310 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5311 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5312 if (! MPLIST_TAIL_P (plist))
5313 mplist_set (plist, Mnil ,NULL); /* () */
5318 mplist_add (config->vars, Mplist, plist);
5319 M17N_OBJECT_UNREF (plist);
5320 plist = mplist_add (plist, Msymbol, variable);
5321 plist = MPLIST_NEXT (plist);
5325 plist = mplist_add (plist, Msymbol, Mnil);
5326 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5329 config_all_variables (im_info);
5330 im_info->tick = time (NULL);
5337 @brief Get the name of per-user configuration file.
5339 The minput_config_file () function returns the absolute path name
5340 of per-user configuration file into which minput_save_config ()
5341 save configurations. It is usually @c "config.mic" under the
5342 directory @c ".m17n.d" of user's home directory. It is not assured
5343 that the file of the returned name exists nor is
5344 readable/writable. If minput_save_config () fails and returns -1,
5345 an application program might check the file, make it
5346 writable (if possible), and try minput_save_config () again.
5350 This function returns a string. As the string is kept in the
5351 library, the caller must not modify nor free it.
5354 minput_save_config ()
5357 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5359 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5360 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5361 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5362 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5363 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5364 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5365 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5370 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5371 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5374 minput_save_config ()
5378 minput_config_file ()
5382 return mdatabase__file (im_custom_mdb);
5388 @brief Save configurations in per-user configuration file.
5390 The minput_save_config () function saves the configurations done
5391 so far in the current session into the per-user configuration
5396 If the operation was successful, 1 is returned. If the per-user
5397 configuration file is currently locked, 0 is returned. In that
5398 case, the caller may wait for a while and try again. If the
5399 configuration file is not writable, -1 is returned. In that case,
5400 the caller may check the name of the file by calling
5401 minput_config_file (), make it writable if possible, and try
5405 minput_config_file () */
5407 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5409 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5410 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5414 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5415 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5416 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5417 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5421 minput_config_file () */
5424 minput_save_config (void)
5426 MPlist *data, *tail, *plist, *p, *elt;
5430 ret = mdatabase__lock (im_custom_mdb);
5433 if (! im_config_list)
5435 update_custom_info ();
5436 if (! im_custom_list)
5437 im_custom_list = mplist ();
5438 data = tail = mplist ();
5440 MPLIST_DO (plist, im_config_list)
5442 MPlist *pl = MPLIST_PLIST (plist);
5443 MSymbol language, name, extra, command, variable;
5444 MInputMethodInfo *custom, *config;
5446 language = MPLIST_SYMBOL (pl);
5447 pl = MPLIST_NEXT (pl);
5448 name = MPLIST_SYMBOL (pl);
5449 pl = MPLIST_NEXT (pl);
5450 extra = MPLIST_SYMBOL (pl);
5451 pl = MPLIST_NEXT (pl);
5452 config = MPLIST_VAL (pl);
5453 custom = get_custom_info (config);
5455 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5457 MPLIST_DO (pl, config->cmds)
5459 elt = MPLIST_PLIST (pl);
5460 command = MPLIST_SYMBOL (elt);
5462 p = mplist__assq (custom->cmds, command);
5464 custom->cmds = mplist (), p = NULL;
5465 elt = MPLIST_NEXT (elt);
5466 if (MPLIST_TAIL_P (elt))
5469 mplist__pop_unref (p);
5473 elt = MPLIST_NEXT (elt);
5476 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5477 mplist_set (p, Mnil, NULL);
5478 mplist__conc (p, elt);
5482 p = MPLIST_PLIST (pl);
5483 mplist_add (custom->cmds, Mplist, p);
5488 MPLIST_DO (pl, config->vars)
5490 elt = MPLIST_PLIST (pl);
5491 variable = MPLIST_SYMBOL (elt);
5493 p = mplist__assq (custom->vars, variable);
5495 custom->vars = mplist (), p = NULL;
5496 elt = MPLIST_NEXT (elt);
5497 if (MPLIST_TAIL_P (elt))
5500 mplist__pop_unref (p);
5504 elt = MPLIST_NEXT (elt);
5507 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5508 mplist_set (p, Mnil, NULL);
5509 mplist__conc (p, elt);
5513 p = MPLIST_PLIST (pl);
5514 mplist_add (custom->vars, Mplist, p);
5519 M17N_OBJECT_UNREF (im_config_list);
5521 MPLIST_DO (plist, im_custom_list)
5523 MPlist *pl = MPLIST_PLIST (plist);
5524 MSymbol language, name, extra;
5525 MInputMethodInfo *custom, *im_info;
5527 language = MPLIST_SYMBOL (pl);
5528 pl = MPLIST_NEXT (pl);
5529 name = MPLIST_SYMBOL (pl);
5530 pl = MPLIST_NEXT (pl);
5531 extra = MPLIST_SYMBOL (pl);
5532 pl = MPLIST_NEXT (pl);
5533 custom = MPLIST_VAL (pl);
5534 im_info = lookup_im_info (im_info_list, language, name, extra);
5538 config_all_commands (im_info);
5540 config_all_variables (im_info);
5544 tail = mplist_add (tail, Mplist, elt);
5545 M17N_OBJECT_UNREF (elt);
5547 elt = mplist_add (elt, Mplist, pl);
5548 M17N_OBJECT_UNREF (pl);
5549 pl = mplist_add (pl, Msymbol, Minput_method);
5550 pl = mplist_add (pl, Msymbol, language);
5551 pl = mplist_add (pl, Msymbol, name);
5553 pl = mplist_add (pl, Msymbol, extra);
5554 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5557 elt = mplist_add (elt, Mplist, pl);
5558 M17N_OBJECT_UNREF (pl);
5559 pl = mplist_add (pl, Msymbol, Mcommand);
5560 MPLIST_DO (p, custom->cmds)
5561 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5563 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5566 elt = mplist_add (elt, Mplist, pl);
5567 M17N_OBJECT_UNREF (pl);
5568 pl = mplist_add (pl, Msymbol, Mvariable);
5569 MPLIST_DO (p, custom->vars)
5570 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5574 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5575 ret = mdatabase__save (im_custom_mdb, data);
5576 mdatabase__unlock (im_custom_mdb);
5577 M17N_OBJECT_UNREF (data);
5578 return (ret < 0 ? -1 : 1);
5585 @name Obsolete functions
5588 @name Obsolete ¤Ê´Ø¿ô
5594 @brief Get a list of variables of an input method (obsolete).
5596 This function is obsolete. Use minput_get_variable () instead.
5598 The minput_get_variables () function returns a plist (#MPlist) of
5599 variables used to control the behavior of the input method
5600 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5601 (#m17nPlist) of the following format:
5604 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5605 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5609 @c VARNAME is a symbol representing the variable name.
5611 @c DOC-MTEXT is an M-text describing the variable.
5613 @c DEFAULT-VALUE is the default value of the variable. It is a
5614 symbol, integer, or M-text.
5616 @c VALUEs (if any) specifies the possible values of the variable.
5617 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5618 @c TO), where @c FROM and @c TO specifies a range of possible
5621 For instance, suppose an input method has the variables:
5623 @li name:intvar, description:"value is an integer",
5624 initial value:0, value-range:0..3,10,20
5626 @li name:symvar, description:"value is a symbol",
5627 initial value:nil, value-range:a, b, c, nil
5629 @li name:txtvar, description:"value is an M-text",
5630 initial value:empty text, no value-range (i.e. any text)
5632 Then, the returned plist is as follows.
5635 (intvar ("value is an integer" 0 (0 3) 10 20)
5636 symvar ("value is a symbol" nil a b c nil)
5637 txtvar ("value is an M-text" ""))
5641 If the input method uses any variables, a pointer to #MPlist is
5642 returned. As the plist is kept in the library, the caller must not
5643 modify nor free it. If the input method does not use any
5644 variable, @c NULL is returned. */
5646 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5648 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5649 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5650 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5654 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5655 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5659 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5661 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5663 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5666 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5667 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5668 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5670 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5672 @li name:intvar, ÀâÌÀ:"value is an integer",
5673 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5675 @li name:symvar, ÀâÌÀ:"value is a symbol",
5676 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5678 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5679 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5681 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5684 (intvar ("value is an integer" 0 (0 3) 10 20)
5685 symvar ("value is a symbol" nil a b c nil)
5686 txtvar ("value is an M-text" ""))
5690 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5691 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5692 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5695 minput_get_variables (MSymbol language, MSymbol name)
5697 MInputMethodInfo *im_info;
5702 im_info = get_im_info (language, name, Mnil, Mvariable);
5703 if (! im_info || ! im_info->configured_vars)
5706 M17N_OBJECT_UNREF (im_info->bc_vars);
5707 im_info->bc_vars = mplist ();
5708 MPLIST_DO (vars, im_info->configured_vars)
5710 MPlist *plist = MPLIST_PLIST (vars);
5711 MPlist *elt = mplist ();
5713 mplist_push (im_info->bc_vars, Mplist, elt);
5714 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5715 elt = MPLIST_NEXT (elt);
5716 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5717 M17N_OBJECT_UNREF (elt);
5719 return im_info->bc_vars;
5725 @brief Set the initial value of an input method variable.
5727 The minput_set_variable () function sets the initial value of
5728 input method variable $VARIABLE to $VALUE for the input method
5729 specified by $LANGUAGE and $NAME.
5731 By default, the initial value is 0.
5733 This setting gets effective in a newly opened input method.
5736 If the operation was successful, 0 is returned. Otherwise -1 is
5737 returned, and #merror_code is set to #MERROR_IM. */
5739 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5741 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5742 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5743 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5745 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5747 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5750 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5751 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5754 minput_set_variable (MSymbol language, MSymbol name,
5755 MSymbol variable, void *value)
5758 MInputMethodInfo *im_info;
5763 if (variable == Mnil)
5764 MERROR (MERROR_IM, -1);
5765 plist = minput_get_variable (language, name, variable);
5766 plist = MPLIST_PLIST (plist);
5767 plist = MPLIST_NEXT (plist);
5769 mplist_add (pl, MPLIST_KEY (plist), value);
5770 ret = minput_config_variable (language, name, variable, pl);
5771 M17N_OBJECT_UNREF (pl);
5774 im_info = get_im_info (language, name, Mnil, Mvariable);
5783 @brief Get information about input method commands.
5785 The minput_get_commands () function returns information about
5786 input method commands of the input method specified by $LANGUAGE
5787 and $NAME. An input method command is a pseudo key event to which
5788 one or more actual input key sequences are assigned.
5790 There are two kinds of commands, global and local. Global
5791 commands are used by multiple input methods for the same purpose,
5792 and have global key assignments. Local commands are used only by
5793 a specific input method, and have only local key assignments.
5795 Each input method may locally change key assignments for global
5796 commands. The global key assignment for a global command is
5797 effective only when the current input method does not have local
5798 key assignments for that command.
5800 If $NAME is #Mnil, information about global commands is returned.
5801 In this case $LANGUAGE is ignored.
5803 If $NAME is not #Mnil, information about those commands that have
5804 local key assignments in the input method specified by $LANGUAGE
5805 and $NAME is returned.
5808 If no input method commands are found, this function returns @c NULL.
5810 Otherwise, a pointer to a plist is returned. The key of each
5811 element in the plist is a symbol representing a command, and the
5812 value is a plist of the form COMMAND-INFO described below.
5814 The first element of COMMAND-INFO has the key #Mtext, and the
5815 value is an M-text describing the command.
5817 If there are no more elements, that means no key sequences are
5818 assigned to the command. Otherwise, each of the remaining
5819 elements has the key #Mplist, and the value is a plist whose keys are
5820 #Msymbol and values are symbols representing input keys, which are
5821 currently assigned to the command.
5823 As the returned plist is kept in the library, the caller must not
5824 modify nor free it. */
5826 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5828 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5829 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5830 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5831 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5833 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5834 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5835 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5836 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5838 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5839 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5840 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5843 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5844 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5846 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5847 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5851 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5853 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5854 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5855 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5857 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5858 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5859 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5862 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5863 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5864 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5865 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5866 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5868 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5869 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5872 minput_get_commands (MSymbol language, MSymbol name)
5874 MInputMethodInfo *im_info;
5879 im_info = get_im_info (language, name, Mnil, Mcommand);
5880 if (! im_info || ! im_info->configured_vars)
5882 M17N_OBJECT_UNREF (im_info->bc_cmds);
5883 im_info->bc_cmds = mplist ();
5884 MPLIST_DO (cmds, im_info->configured_cmds)
5886 MPlist *plist = MPLIST_PLIST (cmds);
5887 MPlist *elt = mplist ();
5889 mplist_push (im_info->bc_cmds, Mplist, elt);
5890 mplist_add (elt, MPLIST_SYMBOL (plist),
5891 mplist_copy (MPLIST_NEXT (plist)));
5892 M17N_OBJECT_UNREF (elt);
5894 return im_info->bc_cmds;
5900 @brief Assign a key sequence to an input method command (obsolete).
5902 This function is obsolete. Use minput_config_command () instead.
5904 The minput_assign_command_keys () function assigns input key
5905 sequence $KEYSEQ to input method command $COMMAND for the input
5906 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5907 key sequence is assigned globally no matter what $LANGUAGE is.
5908 Otherwise the key sequence is assigned locally.
5910 Each element of $KEYSEQ must have the key $Msymbol and the value
5911 must be a symbol representing an input key.
5913 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5914 globally or locally.
5916 This assignment gets effective in a newly opened input method.
5919 If the operation was successful, 0 is returned. Otherwise -1 is
5920 returned, and #merror_code is set to #MERROR_IM. */
5922 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5924 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5925 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5926 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5927 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5928 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5930 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5931 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5933 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5934 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5936 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5939 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5940 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5943 minput_assign_command_keys (MSymbol language, MSymbol name,
5944 MSymbol command, MPlist *keyseq)
5950 if (command == Mnil)
5951 MERROR (MERROR_IM, -1);
5956 if (! check_command_keyseq (keyseq))
5957 MERROR (MERROR_IM, -1);
5959 mplist_add (plist, Mplist, keyseq);
5964 ret = minput_config_command (language, name, command, keyseq);
5965 M17N_OBJECT_UNREF (keyseq);
5972 /*** @addtogroup m17nDebug */
5978 @brief Dump an input method.
5980 The mdebug_dump_im () function prints the input method $IM in a
5981 human readable way to the stderr. $INDENT specifies how many
5982 columns to indent the lines but the first one.
5985 This function returns $IM. */
5987 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
5989 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
5990 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
5993 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
5996 mdebug_dump_im (MInputMethod *im, int indent)
5998 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6001 prefix = (char *) alloca (indent + 1);
6002 memset (prefix, 32, indent);
6003 prefix[indent] = '\0';
6005 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6006 msymbol_name (im->name));
6007 mdebug_dump_mtext (im_info->title, 0, 0);
6008 if (im->name != Mnil)
6012 MPLIST_DO (state, im_info->states)
6014 fprintf (stderr, "\n%s ", prefix);
6015 dump_im_state (MPLIST_VAL (state), indent + 2);
6018 fprintf (stderr, ")");