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., 51 Franklin Street, Fifth Floor,
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;
658 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
659 return mtext_ref_char (ic->produced,
660 mtext_len (ic->produced) + pos);
661 return get_preceding_char (ic, - pos);
664 return get_following_char (ic, pos - len + 1);
667 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
669 else if (code >= '0' && code <= '9')
671 else if (code == '=')
672 pos = ic->cursor_pos;
673 else if (code == '[')
674 pos = ic->cursor_pos - 1;
675 else if (code == ']')
676 pos = ic->cursor_pos + 1;
677 else if (code == '<')
679 else if (code == '>')
681 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
685 parse_expression (MPlist *plist)
689 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
691 if (! MPLIST_PLIST_P (plist))
693 plist = MPLIST_PLIST (plist);
694 op = MPLIST_SYMBOL (plist);
695 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
696 && op != Mand && op != Mor && op != Mnot
697 && op != Mless && op != Mgreater && op != Mequal
698 && op != Mless_equal && op != Mgreater_equal)
699 MERROR (MERROR_IM, -1);
700 MPLIST_DO (plist, MPLIST_NEXT (plist))
701 if (parse_expression (plist) < 0)
707 resolve_expression (MInputContext *ic, MPlist *plist)
712 if (MPLIST_INTEGER_P (plist))
713 return MPLIST_INTEGER (plist);
714 if (MPLIST_SYMBOL_P (plist))
715 return integer_value (ic, plist, NULL, 1);
716 if (! MPLIST_PLIST_P (plist))
718 plist = MPLIST_PLIST (plist);
719 if (! MPLIST_SYMBOL_P (plist))
721 op = MPLIST_SYMBOL (plist);
722 plist = MPLIST_NEXT (plist);
723 val = resolve_expression (ic, plist);
725 MPLIST_DO (plist, MPLIST_NEXT (plist))
726 val += resolve_expression (ic, plist);
727 else if (op == Mminus)
728 MPLIST_DO (plist, MPLIST_NEXT (plist))
729 val -= resolve_expression (ic, plist);
730 else if (op == Mstar)
731 MPLIST_DO (plist, MPLIST_NEXT (plist))
732 val *= resolve_expression (ic, plist);
733 else if (op == Mslash)
734 MPLIST_DO (plist, MPLIST_NEXT (plist))
735 val /= resolve_expression (ic, plist);
737 MPLIST_DO (plist, MPLIST_NEXT (plist))
738 val &= resolve_expression (ic, plist);
740 MPLIST_DO (plist, MPLIST_NEXT (plist))
741 val |= resolve_expression (ic, plist);
744 else if (op == Mless)
745 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
746 else if (op == Mequal)
747 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
748 else if (op == Mgreater)
749 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
750 else if (op == Mless_equal)
751 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
752 else if (op == Mgreater_equal)
753 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
757 /* Parse PLIST as an action list. PLIST should have this form:
758 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
759 Return 0 if successfully parsed, otherwise return -1. */
762 parse_action_list (MPlist *plist, MPlist *macros)
764 MPLIST_DO (plist, plist)
766 if (MPLIST_MTEXT_P (plist))
768 /* This is a short form of (insert MTEXT). */
769 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
770 MERROR (MERROR_IM, -1); */
772 else if (MPLIST_PLIST_P (plist)
773 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
774 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
778 /* This is a short form of (insert (GROUPS *)). */
779 MPLIST_DO (pl, MPLIST_PLIST (plist))
781 if (MPLIST_PLIST_P (pl))
785 MPLIST_DO (elt, MPLIST_PLIST (pl))
786 if (! MPLIST_MTEXT_P (elt)
787 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
788 MERROR (MERROR_IM, -1);
792 if (! MPLIST_MTEXT_P (pl)
793 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
794 MERROR (MERROR_IM, -1);
798 else if (MPLIST_INTEGER_P (plist))
800 int c = MPLIST_INTEGER (plist);
802 if (c < 0 || c > MCHAR_MAX)
803 MERROR (MERROR_IM, -1);
805 else if (MPLIST_PLIST_P (plist)
806 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
808 MPlist *pl = MPLIST_PLIST (plist);
809 MSymbol action_name = MPLIST_SYMBOL (pl);
811 pl = MPLIST_NEXT (pl);
813 if (action_name == Minsert)
815 if (MPLIST_MTEXT_P (pl))
817 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
818 MERROR (MERROR_IM, -1);
820 else if (MPLIST_PLIST_P (pl))
824 if (MPLIST_PLIST_P (pl))
828 MPLIST_DO (elt, MPLIST_PLIST (pl))
829 if (! MPLIST_MTEXT_P (elt)
830 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
831 MERROR (MERROR_IM, -1);
835 if (! MPLIST_MTEXT_P (pl)
836 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
837 MERROR (MERROR_IM, -1);
841 else if (! MPLIST_SYMBOL_P (pl))
842 MERROR (MERROR_IM, -1);
844 else if (action_name == Mselect
845 || action_name == Mdelete
846 || action_name == Mmove)
848 if (parse_expression (pl) < 0)
851 else if (action_name == Mmark
852 || action_name == Mcall
853 || action_name == Mshift)
855 if (! MPLIST_SYMBOL_P (pl))
856 MERROR (MERROR_IM, -1);
858 else if (action_name == Mundo)
860 if (! MPLIST_TAIL_P (pl))
862 if (! MPLIST_SYMBOL_P (pl)
863 && ! MPLIST_INTEGER_P (pl))
864 MERROR (MERROR_IM, -1);
867 else if (action_name == Mpushback)
869 if (MPLIST_MTEXT_P (pl))
871 MText *mt = MPLIST_MTEXT (pl);
873 if (mtext_nchars (mt) != mtext_nbytes (mt))
874 MERROR (MERROR_IM, -1);
876 else if (MPLIST_PLIST_P (pl))
880 MPLIST_DO (p, MPLIST_PLIST (pl))
881 if (! MPLIST_SYMBOL_P (p))
882 MERROR (MERROR_IM, -1);
884 else if (! MPLIST_INTEGER_P (pl))
885 MERROR (MERROR_IM, -1);
887 else if (action_name == Mset || action_name == Madd
888 || action_name == Msub || action_name == Mmul
889 || action_name == Mdiv)
891 if (! MPLIST_SYMBOL_P (pl))
892 MERROR (MERROR_IM, -1);
893 if (parse_expression (MPLIST_NEXT (pl)) < 0)
896 else if (action_name == Mequal || action_name == Mless
897 || action_name == Mgreater || action_name == Mless_equal
898 || action_name == Mgreater_equal)
900 if (parse_expression (pl) < 0
901 || parse_expression (MPLIST_NEXT (pl)) < 0)
903 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
904 if (! MPLIST_PLIST_P (pl))
905 MERROR (MERROR_IM, -1);
906 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
907 MERROR (MERROR_IM, -1);
908 pl = MPLIST_NEXT (pl);
909 if (MPLIST_PLIST_P (pl)
910 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
911 MERROR (MERROR_IM, -1);
913 else if (action_name == Mshow || action_name == Mhide
914 || action_name == Mcommit || action_name == Munhandle)
916 else if (action_name == Mcond)
919 if (! MPLIST_PLIST_P (pl))
920 MERROR (MERROR_IM, -1);
922 else if (! macros || ! mplist_get (macros, action_name))
923 MERROR (MERROR_IM, -1);
925 else if (! MPLIST_SYMBOL_P (plist))
926 MERROR (MERROR_IM, -1);
933 resolve_command (MPlist *cmds, MSymbol command)
937 if (! cmds || ! (plist = mplist__assq (cmds, command)))
939 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
940 plist = MPLIST_NEXT (plist);
941 plist = MPLIST_NEXT (plist);
942 plist = MPLIST_NEXT (plist);
946 /* Load a translation into MAP from PLIST.
948 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
951 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
952 MPlist *branch_actions, MPlist *macros)
957 if (MPLIST_MTEXT_P (keylist))
959 MText *mt = MPLIST_MTEXT (keylist);
961 len = mtext_nchars (mt);
962 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
964 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
965 for (i = 0; i < len; i++)
966 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
972 if (MFAILP (MPLIST_PLIST_P (keylist)))
974 elt = MPLIST_PLIST (keylist);
975 len = MPLIST_LENGTH (elt);
976 if (MFAILP (len > 0))
978 keyseq = (MSymbol *) alloca (sizeof (int) * len);
979 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
981 if (MPLIST_INTEGER_P (elt))
983 int c = MPLIST_INTEGER (elt);
985 if (MFAILP (c >= 0 && c < 0x100))
987 keyseq[i] = one_char_symbol[c];
991 if (MFAILP (MPLIST_SYMBOL_P (elt)))
993 keyseq[i] = MPLIST_SYMBOL (elt);
998 for (i = 0; i < len; i++)
1000 MIMMap *deeper = NULL;
1003 deeper = mplist_get (map->submaps, keyseq[i]);
1005 map->submaps = mplist ();
1008 /* Fixme: It is better to make all deeper maps at once. */
1009 MSTRUCT_CALLOC (deeper, MERROR_IM);
1010 mplist_put (map->submaps, keyseq[i], deeper);
1015 /* We reach a terminal map. */
1016 if (map->map_actions
1017 || map->branch_actions)
1018 /* This map is already defined. We avoid overriding it. */
1021 if (! MPLIST_TAIL_P (map_actions))
1023 if (parse_action_list (map_actions, macros) < 0)
1024 MERROR (MERROR_IM, -1);
1025 map->map_actions = map_actions;
1029 map->branch_actions = branch_actions;
1030 M17N_OBJECT_REF (branch_actions);
1036 /* Load a branch from PLIST into MAP. PLIST has this form:
1037 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1040 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1043 MPlist *branch_actions;
1045 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1047 map_name = MPLIST_SYMBOL (plist);
1048 plist = MPLIST_NEXT (plist);
1049 if (MPLIST_TAIL_P (plist))
1050 branch_actions = NULL;
1051 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1054 branch_actions = plist;
1055 if (map_name == Mnil)
1057 map->branch_actions = branch_actions;
1059 M17N_OBJECT_REF (branch_actions);
1061 else if (map_name == Mt)
1063 map->map_actions = branch_actions;
1065 M17N_OBJECT_REF (branch_actions);
1067 else if (im_info->maps
1068 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1070 MPLIST_DO (plist, plist)
1072 MPlist *keylist, *map_actions;
1074 if (! MPLIST_PLIST_P (plist))
1075 MERROR (MERROR_IM, -1);
1076 keylist = MPLIST_PLIST (plist);
1077 map_actions = MPLIST_NEXT (keylist);
1078 if (MPLIST_SYMBOL_P (keylist))
1080 MSymbol command = MPLIST_SYMBOL (keylist);
1083 if (MFAILP (command != Mat_reload))
1085 pl = resolve_command (im_info->configured_cmds, command);
1089 load_translation (map, pl, map_actions, branch_actions,
1093 load_translation (map, keylist, map_actions, branch_actions,
1101 /* Load a macro from PLIST into IM_INFO->macros.
1102 PLIST has this from:
1103 PLIST ::= ( MACRO-NAME ACTION * )
1104 IM_INFO->macros is a plist of macro names vs action list. */
1107 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1112 if (! MPLIST_SYMBOL_P (plist))
1113 MERROR (MERROR_IM, -1);
1114 name = MPLIST_SYMBOL (plist);
1115 plist = MPLIST_NEXT (plist);
1116 if (MPLIST_TAIL_P (plist)
1117 || parse_action_list (plist, im_info->macros) < 0)
1118 MERROR (MERROR_IM, -1);
1119 pl = mplist_get (im_info->macros, name);
1120 M17N_OBJECT_UNREF (pl);
1121 mplist_put (im_info->macros, name, plist);
1122 M17N_OBJECT_REF (plist);
1126 /* Load an external module from PLIST into IM_INFO->externals.
1127 PLIST has this form:
1128 PLIST ::= ( MODULE-NAME FUNCTION * )
1129 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1132 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1137 MIMExternalModule *external;
1141 if (MPLIST_MTEXT_P (plist))
1142 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1143 else if (MPLIST_SYMBOL_P (plist))
1144 module = MPLIST_SYMBOL (plist);
1145 module_file = alloca (strlen (MSYMBOL_NAME (module))
1146 + strlen (DLOPEN_SHLIB_EXT) + 1);
1147 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1149 handle = dlopen (module_file, RTLD_NOW);
1150 if (MFAILP (handle))
1152 fprintf (stderr, "%s\n", dlerror ());
1155 func_list = mplist ();
1156 MPLIST_DO (plist, MPLIST_NEXT (plist))
1158 if (! MPLIST_SYMBOL_P (plist))
1159 MERROR_GOTO (MERROR_IM, err_label);
1160 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1163 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1166 MSTRUCT_MALLOC (external, MERROR_IM);
1167 external->handle = handle;
1168 external->func_list = func_list;
1169 mplist_add (im_info->externals, module, external);
1174 M17N_OBJECT_UNREF (func_list);
1179 free_map (MIMMap *map, int top)
1184 M17N_OBJECT_UNREF (map->map_actions);
1187 MPLIST_DO (plist, map->submaps)
1188 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1189 M17N_OBJECT_UNREF (map->submaps);
1191 M17N_OBJECT_UNREF (map->branch_actions);
1196 free_state (void *object)
1198 MIMState *state = object;
1200 M17N_OBJECT_UNREF (state->title);
1202 free_map (state->map, 1);
1206 /** Load a state from PLIST into a newly allocated state object.
1207 PLIST has this form:
1208 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1209 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1210 Return the state object. */
1213 load_state (MInputMethodInfo *im_info, MPlist *plist)
1217 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1219 M17N_OBJECT (state, free_state, MERROR_IM);
1220 state->name = MPLIST_SYMBOL (plist);
1221 plist = MPLIST_NEXT (plist);
1222 if (MPLIST_MTEXT_P (plist))
1224 state->title = MPLIST_MTEXT (plist);
1225 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1226 Mlanguage, im_info->language);
1227 M17N_OBJECT_REF (state->title);
1228 plist = MPLIST_NEXT (plist);
1230 MSTRUCT_CALLOC (state->map, MERROR_IM);
1231 MPLIST_DO (plist, plist)
1233 if (MFAILP (MPLIST_PLIST_P (plist)))
1235 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1240 /* Return a newly created IM_INFO for an input method specified by
1241 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1243 static MInputMethodInfo *
1244 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1247 MInputMethodInfo *im_info;
1250 if (name == Mnil && extra == Mnil)
1251 language = Mt, extra = Mglobal;
1252 MSTRUCT_CALLOC (im_info, MERROR_IM);
1254 im_info->language = language;
1255 im_info->name = name;
1256 im_info->extra = extra;
1259 mplist_add (plist, Mplist, elt);
1260 M17N_OBJECT_UNREF (elt);
1261 elt = mplist_add (elt, Msymbol, language);
1262 elt = mplist_add (elt, Msymbol, name);
1263 elt = mplist_add (elt, Msymbol, extra);
1264 mplist_add (elt, Mt, im_info);
1270 fini_im_info (MInputMethodInfo *im_info)
1274 M17N_OBJECT_UNREF (im_info->cmds);
1275 M17N_OBJECT_UNREF (im_info->configured_cmds);
1276 M17N_OBJECT_UNREF (im_info->bc_cmds);
1277 M17N_OBJECT_UNREF (im_info->vars);
1278 M17N_OBJECT_UNREF (im_info->configured_vars);
1279 M17N_OBJECT_UNREF (im_info->bc_vars);
1280 M17N_OBJECT_UNREF (im_info->description);
1281 M17N_OBJECT_UNREF (im_info->title);
1282 if (im_info->states)
1284 MPLIST_DO (plist, im_info->states)
1286 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1288 M17N_OBJECT_UNREF (state);
1290 M17N_OBJECT_UNREF (im_info->states);
1293 if (im_info->macros)
1295 MPLIST_DO (plist, im_info->macros)
1296 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1297 M17N_OBJECT_UNREF (im_info->macros);
1300 if (im_info->externals)
1302 MPLIST_DO (plist, im_info->externals)
1304 MIMExternalModule *external = MPLIST_VAL (plist);
1306 dlclose (external->handle);
1307 M17N_OBJECT_UNREF (external->func_list);
1309 MPLIST_KEY (plist) = Mt;
1311 M17N_OBJECT_UNREF (im_info->externals);
1315 MPLIST_DO (plist, im_info->maps)
1317 MPlist *p = MPLIST_PLIST (plist);
1319 M17N_OBJECT_UNREF (p);
1321 M17N_OBJECT_UNREF (im_info->maps);
1328 free_im_info (MInputMethodInfo *im_info)
1330 fini_im_info (im_info);
1335 free_im_list (MPlist *plist)
1339 MPLIST_DO (pl, plist)
1341 MInputMethodInfo *im_info;
1343 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1344 im_info = MPLIST_VAL (elt);
1345 free_im_info (im_info);
1347 M17N_OBJECT_UNREF (plist);
1350 static MInputMethodInfo *
1351 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1353 if (name == Mnil && extra == Mnil)
1354 language = Mt, extra = Mglobal;
1355 while ((plist = mplist__assq (plist, language)))
1357 MPlist *elt = MPLIST_PLIST (plist);
1359 plist = MPLIST_NEXT (plist);
1360 elt = MPLIST_NEXT (elt);
1361 if (MPLIST_SYMBOL (elt) != name)
1363 elt = MPLIST_NEXT (elt);
1364 if (MPLIST_SYMBOL (elt) != extra)
1366 elt = MPLIST_NEXT (elt);
1367 return MPLIST_VAL (elt);
1372 static void load_im_info (MPlist *, MInputMethodInfo *);
1374 #define get_custom_info(im_info) \
1376 ? lookup_im_info (im_custom_list, (im_info)->language, \
1377 (im_info)->name, (im_info)->extra) \
1380 #define get_config_info(im_info) \
1382 ? lookup_im_info (im_config_list, (im_info)->language, \
1383 (im_info)->name, (im_info)->extra) \
1387 update_custom_info (void)
1393 if (mdatabase__check (im_custom_mdb) > 0)
1398 MDatabaseInfo *custom_dir_info;
1399 char custom_path[PATH_MAX + 1];
1401 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1402 if (! custom_dir_info->filename
1403 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1405 strcpy (custom_path, custom_dir_info->filename);
1406 strcat (custom_path, CUSTOM_FILE);
1407 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1413 free_im_list (im_custom_list);
1414 im_custom_list = NULL;
1416 plist = mdatabase_load (im_custom_mdb);
1419 im_custom_list = mplist ();
1421 MPLIST_DO (pl, plist)
1423 MSymbol language, name, extra;
1424 MInputMethodInfo *im_info;
1425 MPlist *im_data, *p;
1427 if (! MPLIST_PLIST_P (pl))
1429 p = MPLIST_PLIST (pl);
1430 im_data = MPLIST_NEXT (p);
1431 if (! MPLIST_PLIST_P (p))
1433 p = MPLIST_PLIST (p);
1434 if (! MPLIST_SYMBOL_P (p)
1435 || MPLIST_SYMBOL (p) != Minput_method)
1437 p = MPLIST_NEXT (p);
1438 if (! MPLIST_SYMBOL_P (p))
1440 language = MPLIST_SYMBOL (p);
1441 p = MPLIST_NEXT (p);
1442 if (! MPLIST_SYMBOL_P (p))
1444 name = MPLIST_SYMBOL (p);
1445 if (language == Mnil || name == Mnil)
1447 p = MPLIST_NEXT (p);
1448 if (MPLIST_TAIL_P (p))
1450 else if (MPLIST_SYMBOL_P (p))
1451 extra = MPLIST_SYMBOL (p);
1454 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1455 load_im_info (im_data, im_info);
1457 M17N_OBJECT_UNREF (plist);
1462 update_global_info (void)
1468 int ret = mdatabase__check (global_info->mdb);
1472 fini_im_info (global_info);
1476 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1478 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1480 if (! global_info->mdb
1481 || ! (plist = mdatabase_load (global_info->mdb)))
1484 load_im_info (plist, global_info);
1485 M17N_OBJECT_UNREF (plist);
1490 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1491 and EXTRA. KEY, if not Mnil, tells which kind of information about
1492 the input method is necessary, and the returned IM_INFO may contain
1493 only that information. */
1495 static MInputMethodInfo *
1496 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1499 MInputMethodInfo *im_info;
1502 if (name == Mnil && extra == Mnil)
1503 language = Mt, extra = Mglobal;
1504 im_info = lookup_im_info (im_info_list, language, name, extra);
1507 if (key == Mnil ? im_info->states != NULL
1508 : key == Mcommand ? im_info->cmds != NULL
1509 : key == Mvariable ? im_info->vars != NULL
1510 : key == Mtitle ? im_info->title != NULL
1511 : key == Mdescription ? im_info->description != NULL
1513 /* IM_INFO already contains required information. */
1515 /* We have not yet loaded required information. */
1519 mdb = mdatabase_find (Minput_method, language, name, extra);
1522 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1527 plist = mdatabase_load (im_info->mdb);
1531 mplist_push (load_im_info_keys, key, Mt);
1532 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1533 mplist_pop (load_im_info_keys);
1537 MERROR (MERROR_IM, im_info);
1538 update_global_info ();
1539 load_im_info (plist, im_info);
1540 M17N_OBJECT_UNREF (plist);
1543 if (! im_info->cmds)
1544 im_info->cmds = mplist ();
1545 if (! im_info->vars)
1546 im_info->vars = mplist ();
1548 if (! im_info->title
1549 && (key == Mnil || key == Mtitle))
1550 im_info->title = (name == Mnil ? mtext ()
1551 : mtext_from_data (MSYMBOL_NAME (name),
1552 MSYMBOL_NAMELEN (name),
1553 MTEXT_FORMAT_US_ASCII));
1557 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1558 If updated, but got unloadable, return -1. Otherwise, update
1559 contents of IM_INFO from the new database, and return 1. */
1562 reload_im_info (MInputMethodInfo *im_info)
1567 update_custom_info ();
1568 update_global_info ();
1569 check = mdatabase__check (im_info->mdb);
1572 plist = mdatabase_load (im_info->mdb);
1575 fini_im_info (im_info);
1576 load_im_info (plist, im_info);
1577 M17N_OBJECT_UNREF (plist);
1581 static MInputMethodInfo *
1582 get_im_info_by_tags (MPlist *plist)
1587 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1588 i++, plist = MPLIST_NEXT (plist))
1589 tag[i] = MPLIST_SYMBOL (plist);
1594 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1599 check_description (MPlist *plist)
1603 if (MPLIST_MTEXT_P (plist))
1605 if (MPLIST_PLIST_P (plist))
1607 MPlist *pl = MPLIST_PLIST (plist);
1609 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1611 pl =MPLIST_NEXT (pl);
1612 if (MFAILP (MPLIST_MTEXT_P (pl)))
1614 mt = MPLIST_MTEXT (pl);
1615 M17N_OBJECT_REF (mt);
1618 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1620 if (translated == (char *) MTEXT_DATA (mt))
1621 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1622 if (translated != (char *) MTEXT_DATA (mt))
1624 M17N_OBJECT_UNREF (mt);
1625 mt = mtext__from_data (translated, strlen (translated),
1626 MTEXT_FORMAT_UTF_8, 0);
1630 mplist_set (plist, Mtext, mt);
1631 M17N_OBJECT_UNREF (mt);
1634 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1640 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1644 check_command_keyseq (MPlist *keyseq)
1646 if (MPLIST_PLIST_P (keyseq))
1648 MPlist *p = MPLIST_PLIST (keyseq);
1651 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1655 if (MPLIST_MTEXT_P (keyseq))
1657 MText *mt = MPLIST_MTEXT (keyseq);
1660 for (i = 0; i < mtext_nchars (mt); i++)
1661 if (mtext_ref_char (mt, i) >= 256)
1668 /* Load command defitions from PLIST into IM_INFO->cmds.
1670 PLIST is well-formed and has this form;
1671 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1672 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1673 M-text or a plist of symbols.
1675 The returned list has the same form, but for each element...
1677 (1) If DESCRIPTION and the rest are omitted, the element is not
1678 stored in the returned list.
1680 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1681 description in global_info->cmds (if any). */
1684 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1688 im_info->cmds = tail = mplist ();
1690 MPLIST_DO (plist, MPLIST_NEXT (plist))
1692 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1695 if (MFAILP (MPLIST_PLIST_P (plist)))
1697 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1698 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1700 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1701 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1703 if (MFAILP (im_info != global_info))
1704 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1708 if (! check_description (p))
1709 mplist_set (p, Msymbol, Mnil);
1710 p = MPLIST_NEXT (p);
1711 while (! MPLIST_TAIL_P (p))
1713 if (MFAILP (check_command_keyseq (p)))
1714 mplist__pop_unref (p);
1716 p = MPLIST_NEXT (p);
1719 tail = mplist_add (tail, Mplist, pl);
1724 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1725 MPlist *config_cmds)
1727 MPlist *global = NULL, *custom = NULL, *config = NULL;
1730 MPlist *description = NULL, *keyseq;
1732 name = MPLIST_SYMBOL (plist);
1733 plist = MPLIST_NEXT (plist);
1734 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1735 description = plist;
1736 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1737 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1738 if (MPLIST_TAIL_P (plist))
1741 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1742 global = MPLIST_NEXT (MPLIST_PLIST (global));
1745 keyseq = MPLIST_NEXT (global);
1746 status = Minherited;
1756 keyseq = MPLIST_NEXT (plist);
1760 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1762 config = MPLIST_NEXT (MPLIST_PLIST (config));
1763 if (! MPLIST_TAIL_P (config))
1765 keyseq = MPLIST_NEXT (config);
1766 status = Mconfigured;
1769 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1771 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1772 if (! MPLIST_TAIL_P (custom))
1774 keyseq = MPLIST_NEXT (custom);
1775 status = Mcustomized;
1780 mplist_add (plist, Msymbol, name);
1782 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1784 mplist_add (plist, Msymbol, Mnil);
1785 mplist_add (plist, Msymbol, status);
1786 mplist__conc (plist, keyseq);
1791 config_all_commands (MInputMethodInfo *im_info)
1793 MPlist *global_cmds, *custom_cmds, *config_cmds;
1794 MInputMethodInfo *temp;
1795 MPlist *tail, *plist;
1797 M17N_OBJECT_UNREF (im_info->configured_cmds);
1799 if (MPLIST_TAIL_P (im_info->cmds)
1803 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1804 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1805 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1807 im_info->configured_cmds = tail = mplist ();
1808 MPLIST_DO (plist, im_info->cmds)
1810 MPlist *pl = config_command (MPLIST_PLIST (plist),
1811 global_cmds, custom_cmds, config_cmds);
1814 tail = mplist_add (tail, Mplist, pl);
1815 M17N_OBJECT_UNREF (pl);
1820 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1821 valid, return 0 if not. */
1824 check_variable_value (MPlist *val, MPlist *global)
1826 MSymbol type = MPLIST_KEY (val);
1827 MPlist *valids = MPLIST_NEXT (val);
1829 if (type != Minteger && type != Mtext && type != Msymbol)
1833 if (MPLIST_KEY (global) != Mt
1834 && MPLIST_KEY (global) != MPLIST_KEY (val))
1836 if (MPLIST_TAIL_P (valids))
1837 valids = MPLIST_NEXT (global);
1839 if (MPLIST_TAIL_P (valids))
1842 if (type == Minteger)
1844 int n = MPLIST_INTEGER (val);
1846 MPLIST_DO (valids, valids)
1848 if (MPLIST_INTEGER_P (valids))
1850 if (n == MPLIST_INTEGER (valids))
1853 else if (MPLIST_PLIST_P (valids))
1855 MPlist *p = MPLIST_PLIST (valids);
1856 int min_bound, max_bound;
1858 if (! MPLIST_INTEGER_P (p))
1859 MERROR (MERROR_IM, 0);
1860 min_bound = MPLIST_INTEGER (p);
1861 p = MPLIST_NEXT (p);
1862 if (! MPLIST_INTEGER_P (p))
1863 MERROR (MERROR_IM, 0);
1864 max_bound = MPLIST_INTEGER (p);
1865 if (n >= min_bound && n <= max_bound)
1870 else if (type == Msymbol)
1872 MSymbol sym = MPLIST_SYMBOL (val);
1874 MPLIST_DO (valids, valids)
1876 if (! MPLIST_SYMBOL_P (valids))
1877 MERROR (MERROR_IM, 0);
1878 if (sym == MPLIST_SYMBOL (valids))
1884 MText *mt = MPLIST_MTEXT (val);
1886 MPLIST_DO (valids, valids)
1888 if (! MPLIST_MTEXT_P (valids))
1889 MERROR (MERROR_IM, 0);
1890 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1895 return (MPLIST_TAIL_P (valids));
1898 /* Load variable defitions from PLIST into IM_INFO->vars.
1900 PLIST is well-formed and has this form;
1901 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1903 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1905 The returned list has the same form, but for each element...
1907 (1) If DESCRIPTION and the rest are omitted, the element is not
1908 stored in the returned list.
1910 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1911 description in global_info->vars (if any). */
1914 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1916 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1917 ? global_info->vars : NULL);
1920 im_info->vars = tail = mplist ();
1921 MPLIST_DO (plist, MPLIST_NEXT (plist))
1925 if (MFAILP (MPLIST_PLIST_P (plist)))
1927 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1928 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1930 if (im_info == global_info)
1932 /* Loading a global variable. */
1933 p = MPLIST_NEXT (pl);
1934 if (MPLIST_TAIL_P (p))
1935 mplist_add (p, Msymbol, Mnil);
1938 if (! check_description (p))
1939 mplist_set (p, Msymbol, Mnil);
1940 p = MPLIST_NEXT (p);
1941 if (MFAILP (! MPLIST_TAIL_P (p)
1942 && check_variable_value (p, NULL)))
1943 mplist_set (p, Mt, NULL);
1946 else if (im_info->mdb)
1948 /* Loading a local variable. */
1949 MSymbol name = MPLIST_SYMBOL (pl);
1950 MPlist *global = NULL;
1953 && (p = mplist__assq (global_vars, name)))
1955 /* P ::= ((NAME DESC ...) ...) */
1956 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1957 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1958 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1961 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1962 if (! MPLIST_TAIL_P (p))
1964 if (! check_description (p))
1965 mplist_set (p, Msymbol, Mnil);
1966 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1967 if (MFAILP (! MPLIST_TAIL_P (p)))
1968 mplist_set (p, Mt, NULL);
1971 MPlist *valid_values = MPLIST_NEXT (p);
1973 if (! MPLIST_TAIL_P (valid_values)
1974 ? MFAILP (check_variable_value (p, NULL))
1975 : global && MFAILP (check_variable_value (p, global)))
1976 mplist_set (p, Mt, NULL);
1982 /* Loading a variable customization. */
1983 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1984 if (MFAILP (! MPLIST_TAIL_P (p)))
1986 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1987 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1988 || MPLIST_MTEXT_P (p)))
1991 tail = mplist_add (tail, Mplist, pl);
1996 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
1997 MPlist *config_vars)
1999 MPlist *global = NULL, *custom = NULL, *config = NULL;
2000 MSymbol name = MPLIST_SYMBOL (plist);
2002 MPlist *description = NULL, *value, *valids;
2006 global = mplist__assq (global_vars, name);
2008 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2011 plist = MPLIST_NEXT (plist);
2012 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2013 description = plist;
2015 description = global;
2017 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2019 if (MPLIST_TAIL_P (plist))
2021 /* Inherit from global (if any). */
2025 if (MPLIST_KEY (value) == Mt)
2027 valids = MPLIST_NEXT (global);
2028 status = Minherited;
2040 value = plist = MPLIST_NEXT (plist);
2041 valids = MPLIST_NEXT (value);
2042 if (MPLIST_KEY (value) == Mt)
2044 if (! MPLIST_TAIL_P (valids))
2047 valids = MPLIST_NEXT (global);
2051 if (config_vars && (config = mplist__assq (config_vars, name)))
2053 config = MPLIST_NEXT (MPLIST_PLIST (config));
2054 if (! MPLIST_TAIL_P (config))
2056 value = MPLIST_NEXT (config);
2057 if (MFAILP (check_variable_value (value, global ? global : plist)))
2059 status = Mconfigured;
2062 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2064 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2065 if (! MPLIST_TAIL_P (custom))
2067 value = MPLIST_NEXT (custom);
2068 if (MFAILP (check_variable_value (value, global ? global : plist)))
2070 status = Mcustomized;
2075 mplist_add (plist, Msymbol, name);
2077 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2079 mplist_add (plist, Msymbol, Mnil);
2080 mplist_add (plist, Msymbol, status);
2082 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2084 mplist_add (plist, Mt, NULL);
2085 if (valids && ! MPLIST_TAIL_P (valids))
2086 mplist__conc (plist, valids);
2090 /* Return a configured variable definition list based on
2091 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2092 get it from global_info->vars. */
2095 config_all_variables (MInputMethodInfo *im_info)
2097 MPlist *global_vars, *custom_vars, *config_vars;
2098 MInputMethodInfo *temp;
2099 MPlist *tail, *plist;
2101 M17N_OBJECT_UNREF (im_info->configured_vars);
2103 if (MPLIST_TAIL_P (im_info->vars)
2107 global_vars = im_info != global_info ? global_info->vars : NULL;
2108 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2109 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2111 im_info->configured_vars = tail = mplist ();
2112 MPLIST_DO (plist, im_info->vars)
2114 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2115 global_vars, custom_vars, config_vars);
2118 tail = mplist_add (tail, Mplist, pl);
2119 M17N_OBJECT_UNREF (pl);
2124 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2125 CONFIG contains configuration information of the input method. */
2128 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2132 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2134 load_commands (im_info, MPLIST_PLIST (pl));
2135 config_all_commands (im_info);
2136 pl = mplist_pop (pl);
2137 M17N_OBJECT_UNREF (pl);
2140 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2142 load_variables (im_info, MPLIST_PLIST (pl));
2143 config_all_variables (im_info);
2144 pl = mplist_pop (pl);
2145 M17N_OBJECT_UNREF (pl);
2148 MPLIST_DO (plist, plist)
2149 if (MPLIST_PLIST_P (plist))
2151 MPlist *elt = MPLIST_PLIST (plist);
2154 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2156 key = MPLIST_SYMBOL (elt);
2161 elt = MPLIST_NEXT (elt);
2162 if (MFAILP (MPLIST_MTEXT_P (elt)))
2164 im_info->title = MPLIST_MTEXT (elt);
2165 M17N_OBJECT_REF (im_info->title);
2167 else if (key == Mmap)
2169 pl = mplist__from_alist (MPLIST_NEXT (elt));
2172 if (! im_info->maps)
2176 mplist__conc (im_info->maps, pl);
2177 M17N_OBJECT_UNREF (pl);
2180 else if (key == Mmacro)
2182 if (! im_info->macros)
2183 im_info->macros = mplist ();
2184 MPLIST_DO (elt, MPLIST_NEXT (elt))
2186 if (MFAILP (MPLIST_PLIST_P (elt)))
2188 load_macros (im_info, MPLIST_PLIST (elt));
2191 else if (key == Mmodule)
2193 if (! im_info->externals)
2194 im_info->externals = mplist ();
2195 MPLIST_DO (elt, MPLIST_NEXT (elt))
2197 if (MFAILP (MPLIST_PLIST_P (elt)))
2199 load_external_module (im_info, MPLIST_PLIST (elt));
2202 else if (key == Mstate)
2204 MPLIST_DO (elt, MPLIST_NEXT (elt))
2208 if (MFAILP (MPLIST_PLIST_P (elt)))
2210 pl = MPLIST_PLIST (elt);
2211 if (! im_info->states)
2212 im_info->states = mplist ();
2213 state = load_state (im_info, MPLIST_PLIST (elt));
2216 mplist_put (im_info->states, state->name, state);
2219 else if (key == Minclude)
2221 /* elt ::= include (tag1 tag2 ...) key item ... */
2223 MInputMethodInfo *temp;
2225 elt = MPLIST_NEXT (elt);
2226 if (MFAILP (MPLIST_PLIST_P (elt)))
2228 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2231 elt = MPLIST_NEXT (elt);
2232 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2234 key = MPLIST_SYMBOL (elt);
2235 elt = MPLIST_NEXT (elt);
2238 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2240 if (! im_info->maps)
2241 im_info->maps = mplist ();
2242 MPLIST_DO (pl, temp->maps)
2244 p = MPLIST_VAL (pl);
2245 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2246 M17N_OBJECT_REF (p);
2249 else if (key == Mmacro)
2251 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2253 if (! im_info->macros)
2254 im_info->macros = mplist ();
2255 MPLIST_DO (pl, temp->macros)
2257 p = MPLIST_VAL (pl);
2258 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2259 M17N_OBJECT_REF (p);
2262 else if (key == Mstate)
2264 if (! temp->states || MPLIST_TAIL_P (temp->states))
2266 if (! im_info->states)
2267 im_info->states = mplist ();
2268 MPLIST_DO (pl, temp->states)
2270 MIMState *state = MPLIST_VAL (pl);
2272 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2273 M17N_OBJECT_REF (state);
2277 else if (key == Mdescription)
2279 if (im_info->description)
2281 elt = MPLIST_NEXT (elt);
2282 if (! check_description (elt))
2284 im_info->description = MPLIST_MTEXT (elt);
2285 M17N_OBJECT_REF (im_info->description);
2288 im_info->tick = time (NULL);
2293 static int take_action_list (MInputContext *ic, MPlist *action_list);
2294 static void preedit_commit (MInputContext *ic);
2297 shift_state (MInputContext *ic, MSymbol state_name)
2299 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2300 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2301 MIMState *orig_state = ic_info->state, *state;
2303 /* Find a state to shift to. If not found, shift to the initial
2305 if (state_name == Mt)
2307 if (! ic_info->prev_state)
2309 state = ic_info->prev_state;
2311 else if (state_name == Mnil)
2313 state = (MIMState *) MPLIST_VAL (im_info->states);
2317 state = (MIMState *) mplist_get (im_info->states, state_name);
2319 state = (MIMState *) MPLIST_VAL (im_info->states);
2322 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2324 /* Enter the new state. */
2325 ic_info->state = state;
2326 ic_info->map = state->map;
2327 ic_info->state_key_head = ic_info->key_head;
2328 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2330 /* We have shifted to the initial state. */
2331 preedit_commit (ic);
2332 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2333 ic_info->state_pos = ic->cursor_pos;
2334 if (state != orig_state)
2336 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2338 /* Shifted to the initial state. */
2339 ic_info->prev_state = NULL;
2340 M17N_OBJECT_UNREF (ic_info->vars_saved);
2341 ic_info->vars_saved = mplist_copy (ic_info->vars);
2344 ic_info->prev_state = orig_state;
2347 ic->status = state->title;
2349 ic->status = im_info->title;
2350 ic->status_changed = 1;
2351 if (ic_info->map == ic_info->state->map
2352 && ic_info->map->map_actions)
2354 MDEBUG_PRINT (" init-actions:");
2355 take_action_list (ic, ic_info->map->map_actions);
2360 /* Find a candidate group that contains a candidate number INDEX from
2361 PLIST. Set START_INDEX to the first candidate number of the group,
2362 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2363 candidate group number if they are non-NULL. If INDEX is -1, find
2364 the last candidate group. */
2367 find_candidates_group (MPlist *plist, int index,
2368 int *start_index, int *end_index, int *group_index)
2370 int i = 0, gidx = 0, len;
2372 MPLIST_DO (plist, plist)
2374 if (MPLIST_MTEXT_P (plist))
2375 len = mtext_nchars (MPLIST_MTEXT (plist));
2377 len = mplist_length (MPLIST_PLIST (plist));
2378 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2384 *end_index = i + len;
2386 *group_index = gidx;
2395 /* Adjust markers for the change of preedit text.
2396 If FROM == TO, the change is insertion of INS chars.
2397 If FROM < TO and INS == 0, the change is deletion of the range.
2398 If FROM < TO and INS > 0, the change is replacement. */
2401 adjust_markers (MInputContext *ic, int from, int to, int ins)
2403 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2408 MPLIST_DO (markers, ic_info->markers)
2409 if (MPLIST_INTEGER (markers) > from)
2410 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2411 if (ic->cursor_pos >= from)
2412 ic->cursor_pos += ins;
2416 MPLIST_DO (markers, ic_info->markers)
2418 if (MPLIST_INTEGER (markers) >= to)
2419 MPLIST_VAL (markers)
2420 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2421 else if (MPLIST_INTEGER (markers) > from)
2422 MPLIST_VAL (markers) = (void *) from;
2424 if (ic->cursor_pos >= to)
2425 ic->cursor_pos += ins - (to - from);
2426 else if (ic->cursor_pos > from)
2427 ic->cursor_pos = from;
2433 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2435 int nchars = mt ? mtext_nchars (mt) : 1;
2438 mtext_ins (ic->preedit, pos, mt);
2440 mtext_ins_char (ic->preedit, pos, c, 1);
2441 adjust_markers (ic, pos, pos, nchars);
2442 ic->preedit_changed = 1;
2447 preedit_delete (MInputContext *ic, int from, int to)
2449 mtext_del (ic->preedit, from, to);
2450 adjust_markers (ic, from, to, 0);
2451 ic->preedit_changed = 1;
2455 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2459 mtext_del (ic->preedit, from, to);
2462 mtext_ins (ic->preedit, from, mt);
2463 ins = mtext_nchars (mt);
2467 mtext_ins_char (ic->preedit, from, c, 1);
2470 adjust_markers (ic, from, to, ins);
2471 ic->preedit_changed = 1;
2476 preedit_commit (MInputContext *ic)
2478 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2479 int preedit_len = mtext_nchars (ic->preedit);
2481 if (preedit_len > 0)
2485 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2486 Mcandidate_list, NULL, 0);
2487 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2488 Mcandidate_index, NULL, 0);
2489 mtext_cat (ic->produced, ic->preedit);
2490 if (mdebug__flag & mdebug_mask)
2494 MDEBUG_PRINT (" (commit");
2495 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2496 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2500 mtext_reset (ic->preedit);
2501 mtext_reset (ic_info->preedit_saved);
2502 MPLIST_DO (p, ic_info->markers)
2504 ic->cursor_pos = ic_info->state_pos = 0;
2505 ic->preedit_changed = 1;
2506 ic_info->commit_key_head = ic_info->key_head;
2508 if (ic->candidate_list)
2510 M17N_OBJECT_UNREF (ic->candidate_list);
2511 ic->candidate_list = NULL;
2512 ic->candidate_index = 0;
2513 ic->candidate_from = ic->candidate_to = 0;
2514 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2515 if (ic->candidate_show)
2517 ic->candidate_show = 0;
2518 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2524 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2526 int code = marker_code (sym, 0);
2528 if (mt && (code == '[' || code == ']'))
2532 if (code == '[' && current > 0)
2534 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2538 else if (code == ']' && current < mtext_nchars (mt))
2540 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2546 return (code == '<' ? 0
2547 : code == '>' ? limit
2548 : code == '-' ? current - 1
2549 : code == '+' ? current + 1
2550 : code == '=' ? current
2551 : code - '0' > limit ? limit
2555 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2559 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2561 int from = mtext_property_start (prop);
2562 int to = mtext_property_end (prop);
2564 MPlist *candidate_list = mtext_property_value (prop);
2565 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2567 int ingroup_index = idx - start;
2570 if (MPLIST_MTEXT_P (group))
2572 mt = MPLIST_MTEXT (group);
2573 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2581 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2582 i++, plist = MPLIST_NEXT (plist));
2583 mt = MPLIST_MTEXT (plist);
2584 preedit_replace (ic, from, to, mt, 0);
2585 to = from + mtext_nchars (mt);
2587 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2588 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2589 ic->cursor_pos = to;
2593 get_select_charset (MInputContextInfo * ic_info)
2595 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2598 if (! MPLIST_VAL (plist))
2600 sym = MPLIST_SYMBOL (plist);
2603 return MCHARSET (sym);
2607 adjust_candidates (MPlist *plist, MCharset *charset)
2611 /* plist ::= MTEXT ... | PLIST ... */
2612 plist = mplist_copy (plist);
2613 if (MPLIST_MTEXT_P (plist))
2616 while (! MPLIST_TAIL_P (pl))
2618 /* pl ::= MTEXT ... */
2619 MText *mt = MPLIST_MTEXT (pl);
2623 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2625 c = mtext_ref_char (mt, i);
2626 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2630 mt = mtext_dup (mt);
2631 mplist_set (pl, Mtext, mt);
2632 M17N_OBJECT_UNREF (mt);
2635 mtext_del (mt, i, i + 1);
2638 if (mtext_len (mt) > 0)
2639 pl = MPLIST_NEXT (pl);
2643 M17N_OBJECT_UNREF (mt);
2647 else /* MPLIST_PLIST_P (plist) */
2650 while (! MPLIST_TAIL_P (pl))
2652 /* pl ::= (MTEXT ...) ... */
2653 MPlist *p = MPLIST_PLIST (pl);
2655 /* p ::= MTEXT ... */
2659 while (! MPLIST_TAIL_P (p0))
2661 MText *mt = MPLIST_MTEXT (p0);
2664 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2666 c = mtext_ref_char (mt, i);
2667 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2672 p0 = MPLIST_NEXT (p0);
2679 p = mplist_copy (p);
2680 mplist_set (pl, Mplist, p);
2681 M17N_OBJECT_UNREF (p);
2685 p0 = MPLIST_NEXT (p0);
2688 M17N_OBJECT_UNREF (mt);
2691 if (! MPLIST_TAIL_P (p))
2692 pl = MPLIST_NEXT (pl);
2696 M17N_OBJECT_UNREF (p);
2700 if (MPLIST_TAIL_P (plist))
2702 M17N_OBJECT_UNREF (plist);
2709 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2711 MCharset *charset = get_select_charset (ic_info);
2716 plist = resolve_variable (ic_info, Mcandidates_group_size);
2717 column = MPLIST_INTEGER (plist);
2719 plist = MPLIST_PLIST (args);
2721 plist = adjust_candidates (plist, charset);
2723 if (plist && column > 0)
2725 if (MPLIST_MTEXT_P (plist))
2727 MText *mt = MPLIST_MTEXT (plist);
2728 MPlist *next = MPLIST_NEXT (plist);
2730 if (MPLIST_TAIL_P (next))
2731 M17N_OBJECT_REF (mt);
2734 mt = mtext_dup (mt);
2735 while (! MPLIST_TAIL_P (next))
2737 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2738 next = MPLIST_NEXT (next);
2741 M17N_OBJECT_UNREF (plist);
2743 len = mtext_nchars (mt);
2745 mplist_add (plist, Mtext, mt);
2748 for (i = 0; i < len; i += column)
2750 int to = (i + column < len ? i + column : len);
2751 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2753 mplist_add (plist, Mtext, sub);
2754 M17N_OBJECT_UNREF (sub);
2757 M17N_OBJECT_UNREF (mt);
2759 else /* MPLIST_PLIST_P (plist) */
2761 MPlist *pl = MPLIST_PLIST (plist), *p;
2762 MPlist *next = MPLIST_NEXT (plist);
2765 if (MPLIST_TAIL_P (next))
2766 M17N_OBJECT_REF (pl);
2769 pl = mplist_copy (pl);
2770 while (! MPLIST_TAIL_P (next))
2772 p = mplist_copy (MPLIST_PLIST (next));
2773 pl = mplist__conc (pl, p);
2774 M17N_OBJECT_UNREF (p);
2775 next = MPLIST_NEXT (next);
2778 M17N_OBJECT_UNREF (plist);
2780 len = mplist_length (pl);
2782 mplist_add (plist, Mplist, pl);
2787 for (i = 0; i < len; i += column)
2790 mplist_add (plist, Mplist, p);
2791 M17N_OBJECT_UNREF (p);
2792 for (j = 0; j < column && i + j < len; j++)
2794 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
2795 p0 = MPLIST_NEXT (p0);
2799 M17N_OBJECT_UNREF (pl);
2808 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2810 MPlist *action = NULL;
2814 if (MPLIST_SYMBOL_P (action_list))
2816 MSymbol var = MPLIST_SYMBOL (action_list);
2819 MPLIST_DO (p, ic_info->vars)
2820 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2822 if (MPLIST_TAIL_P (p))
2824 action = MPLIST_NEXT (MPLIST_PLIST (p));
2825 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2828 if (MPLIST_PLIST_P (action_list))
2830 action = MPLIST_PLIST (action_list);
2831 if (MPLIST_SYMBOL_P (action))
2833 name = MPLIST_SYMBOL (action);
2834 args = MPLIST_NEXT (action);
2836 && MPLIST_PLIST_P (args))
2837 mplist_set (action, Msymbol, M_candidates);
2839 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2842 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2843 mplist_push (action, Msymbol, M_candidates);
2844 mplist_set (action_list, Mplist, action);
2845 M17N_OBJECT_UNREF (action);
2848 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2851 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2852 mplist_push (action, Msymbol, Minsert);
2853 mplist_set (action_list, Mplist, action);
2854 M17N_OBJECT_UNREF (action);
2859 /* Perform list of actions in ACTION_LIST for the current input
2860 context IC. If unhandle action was not performed, return 0.
2861 Otherwise, return -1. */
2864 take_action_list (MInputContext *ic, MPlist *action_list)
2866 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2867 MPlist *candidate_list = ic->candidate_list;
2868 int candidate_index = ic->candidate_index;
2869 int candidate_show = ic->candidate_show;
2870 MTextProperty *prop;
2872 MPLIST_DO (action_list, action_list)
2874 MPlist *action = regularize_action (action_list, ic_info);
2880 name = MPLIST_SYMBOL (action);
2881 args = MPLIST_NEXT (action);
2883 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2884 if (name == Minsert)
2886 if (MPLIST_SYMBOL_P (args))
2888 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2889 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2892 if (MPLIST_MTEXT_P (args))
2893 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2894 else /* MPLIST_INTEGER_P (args)) */
2895 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2897 else if (name == M_candidates)
2899 MPlist *plist = get_candidate_list (ic_info, args);
2904 if (MPLIST_MTEXT_P (plist))
2906 preedit_insert (ic, ic->cursor_pos, NULL,
2907 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2912 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2914 preedit_insert (ic, ic->cursor_pos, mt, 0);
2915 len = mtext_nchars (mt);
2917 mtext_put_prop (ic->preedit,
2918 ic->cursor_pos - len, ic->cursor_pos,
2919 Mcandidate_list, plist);
2920 mtext_put_prop (ic->preedit,
2921 ic->cursor_pos - len, ic->cursor_pos,
2922 Mcandidate_index, (void *) 0);
2924 else if (name == Mselect)
2927 int code, idx, gindex;
2928 int pos = ic->cursor_pos;
2930 int idx_decided = 0;
2933 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2936 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2937 group = find_candidates_group (mtext_property_value (prop), idx,
2938 &start, &end, &gindex);
2939 if (MPLIST_SYMBOL_P (args))
2941 code = marker_code (MPLIST_SYMBOL (args), 0);
2944 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2945 if (! MPLIST_INTEGER_P (args))
2947 idx = start + MPLIST_INTEGER (args);
2948 if (idx < start || idx >= end)
2956 if (code != '[' && code != ']')
2961 ? new_index (NULL, ic->candidate_index - start,
2962 end - start - 1, MPLIST_SYMBOL (args),
2964 : MPLIST_INTEGER (args)));
2967 find_candidates_group (mtext_property_value (prop), -1,
2972 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2977 int ingroup_index = idx - start;
2980 group = mtext_property_value (prop);
2981 len = mplist_length (group);
2994 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2995 idx += (MPLIST_MTEXT_P (group)
2996 ? mtext_nchars (MPLIST_MTEXT (group))
2997 : mplist_length (MPLIST_PLIST (group)));
2998 len = (MPLIST_MTEXT_P (group)
2999 ? mtext_nchars (MPLIST_MTEXT (group))
3000 : mplist_length (MPLIST_PLIST (group)));
3001 if (ingroup_index >= len)
3002 ingroup_index = len - 1;
3003 idx += ingroup_index;
3005 update_candidate (ic, prop, idx);
3006 MDEBUG_PRINT1 ("(%d)", idx);
3008 else if (name == Mshow)
3009 ic->candidate_show = 1;
3010 else if (name == Mhide)
3011 ic->candidate_show = 0;
3012 else if (name == Mdelete)
3014 int len = mtext_nchars (ic->preedit);
3018 if (MPLIST_SYMBOL_P (args)
3019 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3021 to = ic->cursor_pos + pos;
3024 delete_surrounding_text (ic, to);
3029 delete_surrounding_text (ic, to - len);
3035 to = (MPLIST_SYMBOL_P (args)
3036 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3038 : MPLIST_INTEGER (args));
3044 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3045 if (to < ic->cursor_pos)
3046 preedit_delete (ic, to, ic->cursor_pos);
3047 else if (to > ic->cursor_pos)
3048 preedit_delete (ic, ic->cursor_pos, to);
3050 else if (name == Mmove)
3052 int len = mtext_nchars (ic->preedit);
3054 = (MPLIST_SYMBOL_P (args)
3055 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3057 : MPLIST_INTEGER (args));
3063 if (pos != ic->cursor_pos)
3065 ic->cursor_pos = pos;
3066 ic->preedit_changed = 1;
3068 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3070 else if (name == Mmark)
3072 int code = marker_code (MPLIST_SYMBOL (args), 0);
3076 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3077 (void *) ic->cursor_pos);
3078 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3081 else if (name == Mpushback)
3083 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3087 if (MPLIST_SYMBOL_P (args))
3089 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3090 if (MPLIST_INTEGER_P (args))
3091 num = MPLIST_INTEGER (args);
3096 num = MPLIST_INTEGER (args);
3099 ic_info->key_head -= num;
3101 ic_info->key_head = 0;
3103 ic_info->key_head = - num;
3104 if (ic_info->key_head > ic_info->used)
3105 ic_info->key_head = ic_info->used;
3107 else if (MPLIST_MTEXT_P (args))
3109 MText *mt = MPLIST_MTEXT (args);
3110 int i, len = mtext_nchars (mt);
3113 ic_info->key_head--;
3114 for (i = 0; i < len; i++)
3116 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3117 if (ic_info->key_head + i < ic_info->used)
3118 ic_info->keys[ic_info->key_head + i] = key;
3120 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3125 MPlist *plist = MPLIST_PLIST (args), *pl;
3129 ic_info->key_head--;
3131 MPLIST_DO (pl, plist)
3133 key = MPLIST_SYMBOL (pl);
3134 if (ic_info->key_head < ic_info->used)
3135 ic_info->keys[ic_info->key_head + i] = key;
3137 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3142 else if (name == Mcall)
3144 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3145 MIMExternalFunc func = NULL;
3146 MSymbol module, func_name;
3147 MPlist *func_args, *val;
3150 module = MPLIST_SYMBOL (args);
3151 args = MPLIST_NEXT (args);
3152 func_name = MPLIST_SYMBOL (args);
3154 if (im_info->externals)
3156 MIMExternalModule *external
3157 = (MIMExternalModule *) mplist_get (im_info->externals,
3160 func = (MIMExternalFunc) mplist_get (external->func_list,
3165 func_args = mplist ();
3166 mplist_add (func_args, Mt, ic);
3167 MPLIST_DO (args, MPLIST_NEXT (args))
3171 if (MPLIST_KEY (args) == Msymbol
3172 && MPLIST_KEY (args) != Mnil
3173 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3175 code = new_index (ic, ic->cursor_pos,
3176 mtext_nchars (ic->preedit),
3177 MPLIST_SYMBOL (args), ic->preedit);
3178 mplist_add (func_args, Minteger, (void *) code);
3181 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3183 val = (func) (func_args);
3184 M17N_OBJECT_UNREF (func_args);
3185 if (val && ! MPLIST_TAIL_P (val))
3186 ret = take_action_list (ic, val);
3187 M17N_OBJECT_UNREF (val);
3191 else if (name == Mshift)
3193 shift_state (ic, MPLIST_SYMBOL (args));
3195 else if (name == Mundo)
3197 int intarg = (MPLIST_TAIL_P (args)
3199 : integer_value (ic, args, NULL, 0));
3201 mtext_reset (ic->preedit);
3202 mtext_reset (ic_info->preedit_saved);
3203 mtext_reset (ic->produced);
3204 M17N_OBJECT_UNREF (ic_info->vars);
3205 ic_info->vars = mplist_copy (ic_info->vars_saved);
3206 ic->cursor_pos = ic_info->state_pos = 0;
3207 ic_info->state_key_head = ic_info->key_head
3208 = ic_info->commit_key_head = 0;
3210 shift_state (ic, Mnil);
3213 if (MPLIST_TAIL_P (args))
3218 ic_info->used += intarg;
3221 ic_info->used = intarg;
3224 else if (name == Mset || name == Madd || name == Msub
3225 || name == Mmul || name == Mdiv)
3227 MSymbol sym = MPLIST_SYMBOL (args);
3232 val1 = integer_value (ic, args, &value, 0);
3233 args = MPLIST_NEXT (args);
3234 val2 = resolve_expression (ic, args);
3236 val1 = val2, op = "=";
3237 else if (name == Madd)
3238 val1 += val2, op = "+=";
3239 else if (name == Msub)
3240 val1 -= val2, op = "-=";
3241 else if (name == Mmul)
3242 val1 *= val2, op = "*=";
3244 val1 /= val2, op = "/=";
3245 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3246 MSYMBOL_NAME (sym), op, val1, val1);
3248 mplist_set (value, Minteger, (void *) val1);
3250 else if (name == Mequal || name == Mless || name == Mgreater
3251 || name == Mless_equal || name == Mgreater_equal)
3254 MPlist *actions1, *actions2;
3257 val1 = resolve_expression (ic, args);
3258 args = MPLIST_NEXT (args);
3259 val2 = resolve_expression (ic, args);
3260 args = MPLIST_NEXT (args);
3261 actions1 = MPLIST_PLIST (args);
3262 args = MPLIST_NEXT (args);
3263 if (MPLIST_TAIL_P (args))
3266 actions2 = MPLIST_PLIST (args);
3267 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3268 if (name == Mequal ? val1 == val2
3269 : name == Mless ? val1 < val2
3270 : name == Mgreater ? val1 > val2
3271 : name == Mless_equal ? val1 <= val2
3274 MDEBUG_PRINT ("ok");
3275 ret = take_action_list (ic, actions1);
3279 MDEBUG_PRINT ("no");
3281 ret = take_action_list (ic, actions2);
3286 else if (name == Mcond)
3290 MPLIST_DO (args, args)
3295 if (! MPLIST_PLIST (args))
3297 cond = MPLIST_PLIST (args);
3298 if (resolve_expression (ic, cond) != 0)
3300 MDEBUG_PRINT1 ("(%dth)", idx);
3301 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3307 else if (name == Mcommit)
3309 preedit_commit (ic);
3311 else if (name == Munhandle)
3313 preedit_commit (ic);
3318 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3322 && (actions = mplist_get (im_info->macros, name)))
3324 if (take_action_list (ic, actions) < 0)
3330 if (ic->candidate_list)
3332 M17N_OBJECT_UNREF (ic->candidate_list);
3333 ic->candidate_list = NULL;
3335 if (ic->cursor_pos > 0
3336 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3339 ic->candidate_list = mtext_property_value (prop);
3340 M17N_OBJECT_REF (ic->candidate_list);
3342 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3344 ic->candidate_from = mtext_property_start (prop);
3345 ic->candidate_to = mtext_property_end (prop);
3348 if (candidate_list != ic->candidate_list)
3349 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3350 if (candidate_index != ic->candidate_index)
3351 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3352 if (candidate_show != ic->candidate_show)
3353 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3358 /* Handle the input key KEY in the current state and map specified in
3359 the input context IC. If KEY is handled correctly, return 0.
3360 Otherwise, return -1. */
3363 handle_key (MInputContext *ic)
3365 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3366 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3367 MIMMap *map = ic_info->map;
3368 MIMMap *submap = NULL;
3369 MSymbol key = ic_info->keys[ic_info->key_head];
3370 MSymbol alias = Mnil;
3373 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3374 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3378 submap = mplist_get (map->submaps, key);
3381 && (alias = msymbol_get (alias, M_key_alias))
3383 submap = mplist_get (map->submaps, alias);
3388 if (! alias || alias == key)
3389 MDEBUG_PRINT (" submap-found");
3391 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3392 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3393 ic->preedit_changed = 1;
3394 ic->cursor_pos = ic_info->state_pos;
3395 ic_info->key_head++;
3396 ic_info->map = map = submap;
3397 if (map->map_actions)
3399 MDEBUG_PRINT (" map-actions:");
3400 if (take_action_list (ic, map->map_actions) < 0)
3402 MDEBUG_PRINT ("\n");
3406 else if (map->submaps)
3408 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3410 MSymbol key = ic_info->keys[i];
3411 char *name = msymbol_name (key);
3413 if (! name[0] || ! name[1])
3414 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3418 /* If this is the terminal map or we have shifted to another
3419 state, perform branch actions (if any). */
3420 if (! map->submaps || map != ic_info->map)
3422 if (map->branch_actions)
3424 MDEBUG_PRINT (" branch-actions:");
3425 if (take_action_list (ic, map->branch_actions) < 0)
3427 MDEBUG_PRINT ("\n");
3431 /* If MAP is still not the root map, shift to the current
3433 if (ic_info->map != ic_info->state->map)
3434 shift_state (ic, ic_info->state->name);
3439 /* MAP can not handle KEY. */
3441 /* Perform branch actions if any. */
3442 if (map->branch_actions)
3444 MDEBUG_PRINT (" branch-actions:");
3445 if (take_action_list (ic, map->branch_actions) < 0)
3447 MDEBUG_PRINT ("\n");
3452 if (map == ic_info->map)
3454 /* The above branch actions didn't change the state. */
3456 /* If MAP is the root map of the initial state, it means
3457 that the current input method can not handle KEY. */
3458 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3460 MDEBUG_PRINT (" unhandled\n");
3464 if (map != ic_info->state->map)
3466 /* MAP is not the root map. Shift to the root map of the
3468 shift_state (ic, ic_info->state->name);
3472 /* MAP is the root map. Shift to the initial state. */
3473 shift_state (ic, Mnil);
3477 MDEBUG_PRINT ("\n");
3481 /* Initialize IC->ic_info. */
3484 init_ic_info (MInputContext *ic)
3486 MInputMethodInfo *im_info = ic->im->info;
3487 MInputContextInfo *ic_info = ic->info;
3490 MLIST_INIT1 (ic_info, keys, 8);;
3492 ic_info->markers = mplist ();
3494 ic_info->vars = mplist ();
3495 if (im_info->configured_vars)
3496 MPLIST_DO (plist, im_info->configured_vars)
3498 MPlist *pl = MPLIST_PLIST (plist);
3499 MSymbol name = MPLIST_SYMBOL (pl);
3501 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3502 if (MPLIST_KEY (pl) != Mt)
3504 MPlist *p = mplist ();
3506 mplist_push (ic_info->vars, Mplist, p);
3507 M17N_OBJECT_UNREF (p);
3508 mplist_add (p, Msymbol, name);
3509 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3512 ic_info->vars_saved = mplist_copy (ic_info->vars);
3514 if (im_info->externals)
3516 MPlist *func_args = mplist (), *plist;
3518 mplist_add (func_args, Mt, ic);
3519 MPLIST_DO (plist, im_info->externals)
3521 MIMExternalModule *external = MPLIST_VAL (plist);
3522 MIMExternalFunc func
3523 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3528 M17N_OBJECT_UNREF (func_args);
3531 ic_info->preedit_saved = mtext ();
3532 ic_info->tick = im_info->tick;
3535 /* Finalize IC->ic_info. */
3538 fini_ic_info (MInputContext *ic)
3540 MInputMethodInfo *im_info = ic->im->info;
3541 MInputContextInfo *ic_info = ic->info;
3543 if (im_info->externals)
3545 MPlist *func_args = mplist (), *plist;
3547 mplist_add (func_args, Mt, ic);
3548 MPLIST_DO (plist, im_info->externals)
3550 MIMExternalModule *external = MPLIST_VAL (plist);
3551 MIMExternalFunc func
3552 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3557 M17N_OBJECT_UNREF (func_args);
3560 MLIST_FREE1 (ic_info, keys);
3561 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3562 M17N_OBJECT_UNREF (ic_info->markers);
3563 M17N_OBJECT_UNREF (ic_info->vars);
3564 M17N_OBJECT_UNREF (ic_info->vars_saved);
3565 M17N_OBJECT_UNREF (ic_info->preceding_text);
3566 M17N_OBJECT_UNREF (ic_info->following_text);
3568 memset (ic_info, 0, sizeof (MInputContextInfo));
3572 re_init_ic (MInputContext *ic, int reload)
3574 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3575 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3576 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3578 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3579 preedit_changed = mtext_nchars (ic->preedit) > 0;
3580 cursor_pos_changed = ic->cursor_pos > 0;
3581 candidates_changed = 0;
3582 if (ic->candidate_list)
3584 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3585 M17N_OBJECT_UNREF (ic->candidate_list);
3586 ic->candidate_list = NULL;
3588 if (ic->candidate_show)
3590 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3591 ic->candidate_show = 0;
3593 if (ic->candidate_index > 0)
3595 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3596 ic->candidate_index = 0;
3597 ic->candidate_from = ic->candidate_to = 0;
3599 if (mtext_nchars (ic->produced) > 0)
3600 mtext_reset (ic->produced);
3601 if (mtext_nchars (ic->preedit) > 0)
3602 mtext_reset (ic->preedit);
3604 M17N_OBJECT_UNREF (ic->plist);
3605 ic->plist = mplist ();
3609 reload_im_info (im_info);
3611 shift_state (ic, Mnil);
3612 ic->status_changed = status_changed;
3613 ic->preedit_changed = preedit_changed;
3614 ic->cursor_pos_changed = cursor_pos_changed;
3615 ic->candidates_changed = candidates_changed;
3619 reset_ic (MInputContext *ic, MSymbol ignore)
3621 MDEBUG_PRINT ("\n [IM] reset\n");
3626 open_im (MInputMethod *im)
3628 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3631 MERROR (MERROR_IM, -1);
3638 close_im (MInputMethod *im)
3644 create_ic (MInputContext *ic)
3646 MInputContextInfo *ic_info;
3648 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3651 shift_state (ic, Mnil);
3656 destroy_ic (MInputContext *ic)
3663 check_reload (MInputContext *ic, MSymbol key)
3665 MInputMethodInfo *im_info = ic->im->info;
3666 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3670 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3674 MPLIST_DO (plist, plist)
3676 MSymbol this_key, alias;
3678 if (MPLIST_MTEXT_P (plist))
3680 MText *mt = MPLIST_MTEXT (plist);
3681 int c = mtext_ref_char (mt, 0);
3685 this_key = one_char_symbol[c];
3689 MPlist *pl = MPLIST_PLIST (plist);
3691 this_key = MPLIST_SYMBOL (pl);
3695 && (alias = msymbol_get (alias, M_key_alias))
3696 && alias != this_key);
3700 if (MPLIST_TAIL_P (plist))
3703 MDEBUG_PRINT ("\n [IM] reload");
3709 /** Handle the input key KEY in the current state and map of IC->info.
3710 If KEY is handled but no text is produced, return 0, otherwise
3716 filter (MInputContext *ic, MSymbol key, void *arg)
3718 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3719 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3722 if (check_reload (ic, key))
3725 if (! ic_info->state)
3727 ic_info->key_unhandled = 1;
3730 mtext_reset (ic->produced);
3731 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3732 M17N_OBJECT_UNREF (ic_info->preceding_text);
3733 M17N_OBJECT_UNREF (ic_info->following_text);
3734 ic_info->preceding_text = ic_info->following_text = NULL;
3735 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3736 ic_info->key_unhandled = 0;
3739 if (handle_key (ic) < 0)
3741 /* KEY was not handled. Delete it from the current key sequence. */
3742 if (ic_info->used > 0)
3744 memmove (ic_info->keys, ic_info->keys + 1,
3745 sizeof (int) * (ic_info->used - 1));
3747 if (ic_info->state_key_head > 0)
3748 ic_info->state_key_head--;
3749 if (ic_info->commit_key_head > 0)
3750 ic_info->commit_key_head--;
3752 /* This forces returning 1. */
3753 ic_info->key_unhandled = 1;
3759 reset_ic (ic, Mnil);
3760 ic_info->key_unhandled = 1;
3763 /* Break the loop if all keys were handled. */
3764 } while (ic_info->key_head < ic_info->used);
3766 /* If the current map is the root of the initial state, we should
3767 produce any preedit text in ic->produced. */
3768 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3769 preedit_commit (ic);
3771 if (mtext_nchars (ic->produced) > 0)
3773 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3775 if (mdebug__flag & mdebug_mask)
3777 MDEBUG_PRINT (" (produced");
3778 for (i = 0; i < mtext_nchars (ic->produced); i++)
3779 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3784 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3785 Mlanguage, ic->im->language);
3787 if (ic_info->commit_key_head > 0)
3789 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3790 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3791 ic_info->used -= ic_info->commit_key_head;
3792 ic_info->key_head -= ic_info->commit_key_head;
3793 ic_info->state_key_head -= ic_info->commit_key_head;
3794 ic_info->commit_key_head = 0;
3796 if (ic_info->key_unhandled)
3799 ic_info->key_head = ic_info->state_key_head
3800 = ic_info->commit_key_head = 0;
3803 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3807 /** Return 1 if the last event or key was not handled, otherwise
3810 There is no need of looking up because ic->produced should already
3811 contain the produced text (if any).
3816 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3818 mtext_cat (mt, ic->produced);
3819 mtext_reset (ic->produced);
3820 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3824 /* Input method command handler. */
3826 /* List of all (global and local) commands.
3827 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3828 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3829 Global commands are stored as (t (t COMMAND ...)) */
3832 /* Input method variable handler. */
3835 /* Support functions for mdebug_dump_im. */
3838 dump_im_map (MPlist *map_list, int indent)
3841 MSymbol key = MPLIST_KEY (map_list);
3842 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3844 prefix = (char *) alloca (indent + 1);
3845 memset (prefix, 32, indent);
3846 prefix[indent] = '\0';
3848 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3849 if (map->map_actions)
3850 mdebug_dump_plist (map->map_actions, indent + 2);
3853 MPLIST_DO (map_list, map->submaps)
3855 fprintf (stderr, "\n%s ", prefix);
3856 dump_im_map (map_list, indent + 2);
3859 if (map->branch_actions)
3861 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3862 mdebug_dump_plist (map->branch_actions, indent + 4);
3863 fprintf (stderr, ")");
3865 fprintf (stderr, ")");
3870 dump_im_state (MIMState *state, int indent)
3875 prefix = (char *) alloca (indent + 1);
3876 memset (prefix, 32, indent);
3877 prefix[indent] = '\0';
3879 fprintf (stderr, "(%s", msymbol_name (state->name));
3880 if (state->map->submaps)
3882 MPLIST_DO (map_list, state->map->submaps)
3884 fprintf (stderr, "\n%s ", prefix);
3885 dump_im_map (map_list, indent + 2);
3888 fprintf (stderr, ")");
3896 Minput_driver = msymbol ("input-driver");
3898 Minput_preedit_start = msymbol ("input-preedit-start");
3899 Minput_preedit_done = msymbol ("input-preedit-done");
3900 Minput_preedit_draw = msymbol ("input-preedit-draw");
3901 Minput_status_start = msymbol ("input-status-start");
3902 Minput_status_done = msymbol ("input-status-done");
3903 Minput_status_draw = msymbol ("input-status-draw");
3904 Minput_candidates_start = msymbol ("input-candidates-start");
3905 Minput_candidates_done = msymbol ("input-candidates-done");
3906 Minput_candidates_draw = msymbol ("input-candidates-draw");
3907 Minput_set_spot = msymbol ("input-set-spot");
3908 Minput_focus_move = msymbol ("input-focus-move");
3909 Minput_focus_in = msymbol ("input-focus-in");
3910 Minput_focus_out = msymbol ("input-focus-out");
3911 Minput_toggle = msymbol ("input-toggle");
3912 Minput_reset = msymbol ("input-reset");
3913 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3914 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3915 Mcustomized = msymbol ("customized");
3916 Mconfigured = msymbol ("configured");
3917 Minherited = msymbol ("inherited");
3919 minput_default_driver.open_im = open_im;
3920 minput_default_driver.close_im = close_im;
3921 minput_default_driver.create_ic = create_ic;
3922 minput_default_driver.destroy_ic = destroy_ic;
3923 minput_default_driver.filter = filter;
3924 minput_default_driver.lookup = lookup;
3925 minput_default_driver.callback_list = mplist ();
3926 mplist_put (minput_default_driver.callback_list, Minput_reset,
3928 minput_driver = &minput_default_driver;
3930 fully_initialized = 0;
3937 if (fully_initialized)
3939 free_im_list (im_info_list);
3941 free_im_list (im_custom_list);
3943 free_im_list (im_config_list);
3944 M17N_OBJECT_UNREF (load_im_info_keys);
3947 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3948 M17N_OBJECT_UNREF (minput_driver->callback_list);
3953 minput__char_to_key (int c)
3955 if (c < 0 || c >= 0x100)
3958 return one_char_symbol[c];
3962 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3967 /*** @addtogroup m17nInputMethod */
3972 @name Variables: Predefined symbols for callback commands.
3974 These are the predefined symbols that are used as the @c COMMAND
3975 argument of callback functions of an input method driver (see
3976 #MInputDriver::callback_list).
3978 Most of them do not require extra argument nor return any value;
3979 exceptions are these:
3981 Minput_get_surrounding_text: When a callback function assigned for
3982 this command is called, the first element of #MInputContext::plist
3983 has key #Minteger and the value specifies which portion of the
3984 surrounding text should be retrieved. If the value is positive,
3985 it specifies the number of characters following the current cursor
3986 position. If the value is negative, the absolute value specifies
3987 the number of characters preceding the current cursor position.
3988 If the value is zero, it means that the caller just wants to know
3989 if the surrounding text is currently supported or not.
3991 If the surrounding text is currently supported, the callback
3992 function must set the key of this element to #Mtext and the value
3993 to the retrieved M-text. The length of the M-text may be shorter
3994 than the requested number of characters, if the available text is
3995 not that long. The length can be zero in the worst case. Or, the
3996 length may be longer if an application thinks it is more efficient
3997 to return that length.
3999 If the surrounding text is not currently supported, the callback
4000 function should return without changing the first element of
4001 #MInputContext::plist.
4003 Minput_delete_surrounding_text: When a callback function assigned
4004 for this command is called, the first element of
4005 #MInputContext::plist has key #Minteger and the value specifies
4006 which portion of the surrounding text should be deleted in the
4007 same way as the case of Minput_get_surrounding_text. The callback
4008 function must delete the specified text. It should not alter
4009 #MInputContext::plist. */
4011 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4013 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4014 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4016 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4018 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4019 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4020 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4021 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4022 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4023 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4024 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4026 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4027 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4028 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4029 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4030 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4032 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4033 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4035 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4036 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4037 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4038 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4039 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4040 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4044 MSymbol Minput_preedit_start;
4045 MSymbol Minput_preedit_done;
4046 MSymbol Minput_preedit_draw;
4047 MSymbol Minput_status_start;
4048 MSymbol Minput_status_done;
4049 MSymbol Minput_status_draw;
4050 MSymbol Minput_candidates_start;
4051 MSymbol Minput_candidates_done;
4052 MSymbol Minput_candidates_draw;
4053 MSymbol Minput_set_spot;
4054 MSymbol Minput_toggle;
4055 MSymbol Minput_reset;
4056 MSymbol Minput_get_surrounding_text;
4057 MSymbol Minput_delete_surrounding_text;
4063 @name Variables: Predefined symbols for special input events.
4065 These are the predefined symbols that are used as the @c KEY
4066 argument of minput_filter (). */
4068 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4070 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4075 MSymbol Minput_focus_out;
4076 MSymbol Minput_focus_in;
4077 MSymbol Minput_focus_move;
4083 @name Variables: Predefined symbols used in input method information.
4085 These are the predefined symbols describing status of input method
4086 command and variable, and are used in a return value of
4087 minput_get_command () and minput_get_variable (). */
4089 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4091 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4092 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4096 MSymbol Mcustomized;
4097 MSymbol Mconfigured;
4103 @brief The default driver for internal input methods.
4105 The variable #minput_default_driver is the default driver for
4106 internal input methods.
4108 The member MInputDriver::open_im () searches the m17n database for
4109 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4110 $NAME\> and loads it.
4112 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4113 programmers responsibility to set it to a plist of proper callback
4114 functions. Otherwise, no feedback information (e.g. preedit text)
4115 can be shown to users.
4117 The macro M17N_INIT () sets the variable #minput_driver to the
4118 pointer to this driver so that all internal input methods use it.
4120 Therefore, unless @c minput_driver is set differently, the driver
4121 dependent arguments $ARG of the functions whose name begins with
4122 "minput_" are all ignored. */
4124 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4126 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4128 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4129 \< #Minput_method, $LANGUAGE, $NAME\>
4130 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4132 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4133 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4134 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4135 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4137 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4138 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4140 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4141 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4143 MInputDriver minput_default_driver;
4147 @brief The driver for internal input methods.
4149 The variable #minput_driver is a pointer to the input method
4150 driver that is used by internal input methods. The macro
4151 M17N_INIT () initializes it to a pointer to #minput_default_driver
4152 if <m17n<EM></EM>.h> is included. */
4154 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4156 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4157 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4158 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4159 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4161 MInputDriver *minput_driver;
4163 MSymbol Minput_driver;
4178 @brief Open an input method.
4180 The minput_open_im () function opens an input method whose
4181 language and name match $LANGUAGE and $NAME, and returns a pointer
4182 to the input method object newly allocated.
4184 This function at first decides a driver for the input method as
4187 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4188 #minput_driver is used.
4190 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4191 driver pointed to by the property value is used to open the input
4192 method. If $NAME has no such a property, @c NULL is returned.
4194 Then, the member MInputDriver::open_im () of the driver is
4197 $ARG is set in the member @c arg of the structure MInputMethod so
4198 that the driver can refer to it. */
4200 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4202 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4203 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4205 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4207 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4208 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4210 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4211 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4212 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4214 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4216 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4218 @latexonly \IPAlabel{minput_open} @endlatexonly
4223 minput_open_im (MSymbol language, MSymbol name, void *arg)
4226 MInputDriver *driver;
4230 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4231 msymbol_name (language), msymbol_name (name));
4233 driver = minput_driver;
4236 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4238 MERROR (MERROR_IM, NULL);
4241 MSTRUCT_CALLOC (im, MERROR_IM);
4242 im->language = language;
4245 im->driver = *driver;
4246 if ((*im->driver.open_im) (im) < 0)
4248 MDEBUG_PRINT (" failed\n");
4252 MDEBUG_PRINT (" ok\n");
4259 @brief Close an input method.
4261 The minput_close_im () function closes the input method $IM, which
4262 must have been created by minput_open_im (). */
4265 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4267 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4268 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4271 minput_close_im (MInputMethod *im)
4273 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4274 msymbol_name (im->name), msymbol_name (im->language));
4275 (*im->driver.close_im) (im);
4277 MDEBUG_PRINT (" done\n");
4283 @brief Create an input context.
4285 The minput_create_ic () function creates an input context object
4286 associated with input method $IM, and calls callback functions
4287 corresponding to #Minput_preedit_start, #Minput_status_start, and
4288 #Minput_status_draw in this order.
4291 If an input context is successfully created, minput_create_ic ()
4292 returns a pointer to it. Otherwise it returns @c NULL. */
4295 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4297 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4298 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4299 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4300 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4303 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4304 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4308 minput_create_ic (MInputMethod *im, void *arg)
4312 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4313 msymbol_name (im->name), msymbol_name (im->language));
4314 MSTRUCT_CALLOC (ic, MERROR_IM);
4317 ic->preedit = mtext ();
4318 ic->candidate_list = NULL;
4319 ic->produced = mtext ();
4320 ic->spot.x = ic->spot.y = 0;
4322 ic->plist = mplist ();
4323 if ((*im->driver.create_ic) (ic) < 0)
4325 MDEBUG_PRINT (" failed\n");
4326 M17N_OBJECT_UNREF (ic->preedit);
4327 M17N_OBJECT_UNREF (ic->produced);
4328 M17N_OBJECT_UNREF (ic->plist);
4333 if (im->driver.callback_list)
4335 minput_callback (ic, Minput_preedit_start);
4336 minput_callback (ic, Minput_status_start);
4337 minput_callback (ic, Minput_status_draw);
4340 MDEBUG_PRINT (" ok\n");
4347 @brief Destroy an input context.
4349 The minput_destroy_ic () function destroys the input context $IC,
4350 which must have been created by minput_create_ic (). It calls
4351 callback functions corresponding to #Minput_preedit_done,
4352 #Minput_status_done, and #Minput_candidates_done in this order. */
4355 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4357 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4358 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4359 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4360 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4361 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4365 minput_destroy_ic (MInputContext *ic)
4367 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4368 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4369 if (ic->im->driver.callback_list)
4371 minput_callback (ic, Minput_preedit_done);
4372 minput_callback (ic, Minput_status_done);
4373 minput_callback (ic, Minput_candidates_done);
4375 (*ic->im->driver.destroy_ic) (ic);
4376 M17N_OBJECT_UNREF (ic->preedit);
4377 M17N_OBJECT_UNREF (ic->produced);
4378 M17N_OBJECT_UNREF (ic->plist);
4379 MDEBUG_PRINT (" done\n");
4386 @brief Filter an input key.
4388 The minput_filter () function filters input key $KEY according to
4389 input context $IC, and calls callback functions corresponding to
4390 #Minput_preedit_draw, #Minput_status_draw, and
4391 #Minput_candidates_draw if the preedit text, the status, and the
4392 current candidate are changed respectively.
4394 To make the input method commit the current preedit text (if any)
4395 and shift to the initial state, call this function with #Mnil as
4398 To inform the input method about the focus-out event, call this
4399 function with #Minput_focus_out as $KEY.
4401 To inform the input method about the focus-in event, call this
4402 function with #Minput_focus_in as $KEY.
4404 To inform the input method about the focus-move event (i.e. input
4405 spot change within the same input context), call this function
4406 with #Minput_focus_move as $KEY.
4409 If $KEY is filtered out, this function returns 1. In that case,
4410 the caller should discard the key. Otherwise, it returns 0, and
4411 the caller should handle the key, for instance, by calling the
4412 function minput_lookup () with the same key. */
4415 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4417 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4418 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4419 #Minput_preedit_draw, #Minput_status_draw,
4420 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4423 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4424 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4425 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4426 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4428 @latexonly \IPAlabel{minput_filter} @endlatexonly
4432 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4439 if (ic->im->driver.callback_list
4440 && mtext_nchars (ic->preedit) > 0)
4441 minput_callback (ic, Minput_preedit_draw);
4443 ret = (*ic->im->driver.filter) (ic, key, arg);
4445 if (ic->im->driver.callback_list)
4447 if (ic->preedit_changed)
4448 minput_callback (ic, Minput_preedit_draw);
4449 if (ic->status_changed)
4450 minput_callback (ic, Minput_status_draw);
4451 if (ic->candidates_changed)
4452 minput_callback (ic, Minput_candidates_draw);
4461 @brief Look up a text produced in the input context.
4463 The minput_lookup () function looks up a text in the input context
4464 $IC. $KEY must be identical to the one that was used in the previous call of
4467 If a text was produced by the input method, it is concatenated
4470 This function calls #MInputDriver::lookup .
4473 If $KEY was correctly handled by the input method, this function
4474 returns 0. Otherwise, it returns -1, even though some text
4475 might be produced in $MT. */
4478 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4480 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4481 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4483 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4486 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4489 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4490 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4491 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4493 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4496 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4498 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4503 @brief Set the spot of the input context.
4505 The minput_set_spot () function sets the spot of input context $IC
4506 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4507 The semantics of these values depends on the input method driver.
4509 For instance, a driver designed to work in a CUI environment may
4510 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4511 $DESCENT . A driver designed to work in a window system may
4512 interpret $X and $Y as the pixel offsets relative to the origin of the
4513 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4514 descent pixels of the line at ($X . $Y ).
4516 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4518 $MT and $POS are the M-text and the character position at the spot.
4519 $MT may be @c NULL, in which case, the input method cannot get
4520 information about the text around the spot. */
4523 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4525 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4526 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4527 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4529 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4530 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4531 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4532 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4533 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4534 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4536 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4538 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4539 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4543 minput_set_spot (MInputContext *ic, int x, int y,
4544 int ascent, int descent, int fontsize,
4549 ic->spot.ascent = ascent;
4550 ic->spot.descent = descent;
4551 ic->spot.fontsize = fontsize;
4554 if (ic->im->driver.callback_list)
4555 minput_callback (ic, Minput_set_spot);
4560 @brief Toggle input method.
4562 The minput_toggle () function toggles the input method associated
4563 with input context $IC. */
4565 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4567 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4568 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4572 minput_toggle (MInputContext *ic)
4574 if (ic->im->driver.callback_list)
4575 minput_callback (ic, Minput_toggle);
4576 ic->active = ! ic->active;
4582 @brief Reset an input context.
4584 The minput_reset_ic () function resets input context $IC by
4585 calling a callback function corresponding to #Minput_reset. It
4586 resets the status of $IC to its initial one. As the
4587 current preedit text is deleted without commitment, if necessary,
4588 call minput_filter () with the arg @r key #Mnil to force the input
4589 method to commit the preedit in advance. */
4592 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4594 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4595 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4596 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4597 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4598 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4599 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4602 minput_reset_ic (MInputContext *ic)
4604 if (ic->im->driver.callback_list)
4605 minput_callback (ic, Minput_reset);
4611 @brief Get title and icon filename of an input method.
4613 The minput_get_title_icon () function returns a plist containing a
4614 title and icon filename (if any) of an input method specified by
4615 $LANGUAGE and $NAME.
4617 The first element of the plist has key #Mtext and the value is an
4618 M-text of the title for identifying the input method. The second
4619 element (if any) has key #Mtext and the value is an M-text of the
4620 icon image (absolute) filename for the same purpose.
4623 If there exists a specified input method and it defines an title,
4624 a plist is returned. Otherwise, NULL is returned. The caller
4625 must free the plist by m17n_object_unref (). */
4627 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4629 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4630 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4633 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4634 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4635 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4638 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4639 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4640 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4643 minput_get_title_icon (MSymbol language, MSymbol name)
4645 MInputMethodInfo *im_info;
4652 im_info = get_im_info (language, name, Mnil, Mtitle);
4653 if (! im_info || !im_info->title)
4655 mt = mtext_get_prop (im_info->title, 0, Mtext);
4657 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4660 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4663 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4664 (char *) MSYMBOL_NAME (name));
4665 file = mdatabase__find_file (buf);
4666 if (! file && language == Mt)
4668 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4669 file = mdatabase__find_file (buf);
4674 mplist_add (plist, Mtext, im_info->title);
4677 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4679 mplist_add (plist, Mtext, mt);
4680 M17N_OBJECT_UNREF (mt);
4688 @brief Get description text of an input method.
4690 The minput_get_description () function returns an M-text that
4691 describes the input method specified by $LANGUAGE and $NAME.
4694 If the specified input method has a description text, a pointer to
4695 #MText is returned. The caller has to free it by m17n_object_unref ().
4696 If the input method does not have a description text, @c NULL is
4699 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4701 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4702 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4704 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4705 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4706 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4707 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4710 minput_get_description (MSymbol language, MSymbol name)
4712 MInputMethodInfo *im_info;
4720 extra = language, language = Mt;
4722 im_info = get_im_info (language, name, extra, Mdescription);
4723 if (! im_info || ! im_info->description)
4725 M17N_OBJECT_REF (im_info->description);
4726 return im_info->description;
4732 @brief Get information about input method command(s).
4734 The minput_get_command () function returns information about
4735 the command $COMMAND of the input method specified by $LANGUAGE and
4736 $NAME. An input method command is a pseudo key event to which one
4737 or more actual input key sequences are assigned.
4739 There are two kinds of commands, global and local. A global
4740 command has a global definition, and the description and the key
4741 assignment may be inherited by a local command. Each input method
4742 defines a local command which has a local key assignment. It may
4743 also declare a local command that inherits the definition of a
4744 global command of the same name.
4746 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4747 information about a global command. Otherwise information about a
4748 local command is returned.
4750 If $COMMAND is #Mnil, information about all commands is returned.
4752 The return value is a @e well-formed plist (#m17nPlist) of this
4755 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4757 @c NAME is a symbol representing the command name.
4759 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4760 command has no description.
4762 @c STATUS is a symbol representing how the key assignment is decided.
4763 The value is #Mnil (the default key assignment), #Mcustomized (the
4764 key assignment is customized by per-user configuration file), or
4765 #Mconfigured (the key assignment is set by the call of
4766 minput_config_command ()). For a local command only, it may also
4767 be #Minherited (the key assignment is inherited from the
4768 corresponding global command).
4770 @c KEYSEQ is a plist of one or more symbols representing a key
4771 sequence assigned to the command. If there's no KEYSEQ, the
4772 command is currently disabled (i.e. no key sequence can trigger
4773 actions of the command).
4775 If $COMMAND is not #Mnil, the first element of the returned plist
4776 contains the information about $COMMAND.
4780 If the requested information was found, a pointer to a non-empty
4781 plist is returned. As the plist is kept in the library, the
4782 caller must not modify nor free it.
4784 Otherwise (the specified input method or the specified command
4785 does not exist), @c NULL is returned. */
4787 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4789 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4790 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4791 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4792 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4794 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4795 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4796 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4797 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4798 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4800 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4801 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4804 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4806 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4809 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4811 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4813 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4816 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4817 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4818 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4819 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4820 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4821 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4823 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4824 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4825 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4826 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4828 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4829 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4833 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4834 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4837 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4842 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4844 /* Return a description of the command COMMAND of the input method
4845 specified by LANGUAGE and NAME. */
4846 MPlist *cmd = minput_get_command (langauge, name, command);
4851 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4852 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4853 return (mplist_key (plist) == Mtext
4854 ? (MText *) mplist_value (plist)
4860 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4862 MInputMethodInfo *im_info;
4866 im_info = get_im_info (language, name, Mnil, Mcommand);
4868 || ! im_info->configured_cmds
4869 || MPLIST_TAIL_P (im_info->configured_cmds))
4871 if (command == Mnil)
4872 return im_info->configured_cmds;
4873 return mplist__assq (im_info->configured_cmds, command);
4879 @brief Configure the key sequence of an input method command.
4881 The minput_config_command () function assigns a list of key
4882 sequences $KEYSEQLIST to the command $COMMAND of the input method
4883 specified by $LANGUAGE and $NAME.
4885 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4886 sequences, and each key sequence must be a plist of symbols.
4888 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4890 If $KEYSEQLIST is NULL, the configuration of the command for the
4891 input method is canceled, and the default key sequences become
4892 effective. In such case, if $COMMAND is #Mnil, configurations for
4893 all commands of the input method are canceled.
4895 If $NAME is #Mnil, this function configures the key assignment of a
4896 global command, not that of a specific input method.
4898 The configuration takes effect for input methods opened or
4899 re-opened later in the current session. In order to make the
4900 configuration take effect for the future session, it must be saved
4901 in a per-user configuration file by the function
4902 minput_save_config ().
4906 If the operation was successful, this function returns 0,
4907 otherwise returns -1. The operation fails in these cases:
4909 <li>$KEYSEQLIST is not in a valid form.
4910 <li>$COMMAND is not available for the input method.
4911 <li>$LANGUAGE and $NAME do not specify an existing input method.
4915 minput_get_commands (), minput_save_config ().
4918 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4920 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4921 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4922 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4924 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4925 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4927 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4929 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4930 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4931 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4934 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4935 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4937 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4938 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4939 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4940 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4944 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4946 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4947 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4948 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4952 minput_get_commands (), minput_save_config ().
4956 /* Add "C-x u" to the "start" command of Unicode input method. */
4958 MSymbol start_command = msymbol ("start");
4959 MSymbol unicode = msymbol ("unicode");
4960 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4962 /* At first get the current key-sequence assignment. */
4963 cmd = mplist_get_command (Mt, unicode, start_command);
4966 /* The input method does not have the command "start". Here
4967 should come some error handling code. */
4969 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4970 the part (KEY-SEQUENCE ...). */
4971 plist = mplist_next (mplist_next (mplist_value (cmd)));
4972 /* Copy it because we should not modify it directly. */
4973 key_seq_list = mplist_copy (plist);
4974 m17n_object_unref (cmds);
4976 key_seq = mplist ();
4977 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4978 mplist_add (key_seq, Msymbol, msymbol ("u"));
4979 mplist_add (key_seq_list, Mplist, key_seq);
4980 m17n_object_unref (key_seq);
4982 minput_config_command (Mt, unicode, start_command, key_seq_list);
4983 m17n_object_unref (key_seq_list);
4988 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4991 MInputMethodInfo *im_info, *config;
4998 if (command == Mnil)
4999 MERROR (MERROR_IM, -1);
5000 MPLIST_DO (plist, keyseqlist)
5001 if (! MPLIST_PLIST_P (plist)
5002 || ! check_command_keyseq (plist))
5003 MERROR (MERROR_IM, -1);
5006 im_info = get_im_info (language, name, Mnil, Mcommand);
5008 MERROR (MERROR_IM, -1);
5011 || ! mplist__assq (im_info->cmds, command)))
5012 MERROR (MERROR_IM, -1);
5014 config = get_config_info (im_info);
5017 if (! im_config_list)
5018 im_config_list = mplist ();
5019 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5020 config->cmds = mplist ();
5021 config->vars = mplist ();
5024 if (command == Mnil)
5026 MInputMethodInfo *custom = get_custom_info (im_info);
5028 mplist_set (config->cmds, Mnil, NULL);
5029 if (custom && custom->cmds)
5031 MPLIST_DO (plist, custom->cmds)
5033 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5035 mplist_add (plist, Msymbol, command);
5036 mplist_push (config->cmds, Mplist, plist);
5037 M17N_OBJECT_UNREF (plist);
5043 plist = mplist__assq (config->cmds, command);
5046 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
5047 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
5048 if (! MPLIST_TAIL_P (plist))
5049 mplist_set (plist, Mnil, NULL); /* () */
5054 mplist_add (config->cmds, Mplist, plist);
5055 M17N_OBJECT_UNREF (plist);
5056 plist = mplist_add (plist, Msymbol, command);
5057 plist = MPLIST_NEXT (plist);
5063 plist = mplist_add (plist, Msymbol, Mnil);
5064 MPLIST_DO (keyseqlist, keyseqlist)
5066 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5067 plist = mplist_add (plist, Mplist, pl);
5068 M17N_OBJECT_UNREF (pl);
5072 config_all_commands (im_info);
5073 im_info->tick = time (NULL);
5080 @brief Get information about input method variable(s).
5082 The minput_get_variable () function returns information about
5083 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5084 An input method variable controls behavior of an input method.
5086 There are two kinds of variables, global and local. A global
5087 variable has a global definition, and the description and the value
5088 may be inherited by a local variable. Each input method defines a
5089 local variable which has local value. It may also declare a
5090 local variable that inherits definition of a global variable of
5093 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5094 variable is returned. Otherwise information about a local variable
5097 If $VARIABLE is #Mnil, information about all variables is
5100 The return value is a @e well-formed plist (#m17nPlist) of this
5103 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5105 @c NAME is a symbol representing the variable name.
5107 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5108 variable has no description.
5110 @c STATUS is a symbol representing how the value is decided. The
5111 value is #Mnil (the default value), #Mcustomized (the value is
5112 customized by per-user configuration file), or #Mconfigured (the
5113 value is set by the call of minput_config_variable ()). For a
5114 local variable only, it may also be #Minherited (the value is
5115 inherited from the corresponding global variable).
5117 @c VALUE is the initial value of the variable. If the key of this
5118 element is #Mt, the variable has no initial value. Otherwise, the
5119 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5122 @c VALID-VALUEs (if any) specify which values the variable can have.
5123 They have the same type (i.e. having the same key) as @c VALUE except
5124 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5125 may be a plist of two integers specifying the range of possible
5128 If there no @c VALID-VALUE, the variable can have any value as long
5129 as the type is the same as @c VALUE.
5131 If $VARIABLE is not #Mnil, the first element of the returned plist
5132 contains the information about $VARIABLE.
5136 If the requested information was found, a pointer to a non-empty
5137 plist is returned. As the plist is kept in the library, the
5138 caller must not modify nor free it.
5140 Otherwise (the specified input method or the specified variable
5141 does not exist), @c NULL is returned. */
5143 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5145 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5146 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5147 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5149 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5150 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5151 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5152 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5155 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5156 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5158 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5160 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5162 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5165 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5167 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5170 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5171 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5172 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5173 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5174 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5175 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5177 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5178 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5179 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5181 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5182 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5183 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5184 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5186 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5189 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5190 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5194 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5195 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5198 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5202 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5204 MInputMethodInfo *im_info;
5208 im_info = get_im_info (language, name, Mnil, Mvariable);
5209 if (! im_info || ! im_info->configured_vars)
5211 if (variable == Mnil)
5212 return im_info->configured_vars;
5213 return mplist__assq (im_info->configured_vars, variable);
5219 @brief Configure the value of an input method variable.
5221 The minput_config_variable () function assigns $VALUE to the
5222 variable $VARIABLE of the input method specified by $LANGUAGE and
5225 If $VALUE is not NULL, it must be a plist of one element whose key
5226 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5229 If $VALUE is NULL, a configuration for the variable for the input
5230 method is canceled, and the variable is initialized to the default
5231 value. In that case, if $VARIABLE is #Mnil, configurations for
5232 all variables of the input method are canceled.
5234 If $NAME is #Mnil, this function configure the value of global
5235 variable, not that of a specific input method.
5237 The configuration takes effect for input methods opened or
5238 re-opened later in the current session. To make the configuration
5239 take effect for the future session, it must be saved in a per-user
5240 configuration file by the function minput_save_config ().
5244 If the operation was successful, this function returns 0,
5245 otherwise returns -1. The operation fails in these cases:
5247 <li>$VALUE is not in a valid form, the type does not match the
5248 definition, or the value is our of range.
5249 <li>$VARIABLE is not available for the input method.
5250 <li>$LANGUAGE and $NAME do not specify an existing input method.
5254 minput_get_variable (), minput_save_config (). */
5256 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5258 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5259 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5261 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5262 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5264 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5265 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5266 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5268 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5269 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5271 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5272 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5273 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5274 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5278 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5280 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5281 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5282 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5286 minput_get_commands (), minput_save_config ().
5289 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5292 MInputMethodInfo *im_info, *config;
5297 im_info = get_im_info (language, name, Mnil, Mvariable);
5299 MERROR (MERROR_IM, -1);
5300 if (variable == Mnil)
5303 MERROR (MERROR_IM, -1);
5305 else if (! im_info->vars
5306 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5307 MERROR (MERROR_IM, -1);
5309 if (variable != Mnil && value)
5311 plist = MPLIST_PLIST (plist);
5312 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5313 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5314 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5315 if (MPLIST_KEY (plist) != Mt
5316 && ! check_variable_value (value, plist))
5317 MERROR (MERROR_IM, -1);
5320 config = get_config_info (im_info);
5323 if (! im_config_list)
5324 im_config_list = mplist ();
5325 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5326 config->cmds = mplist ();
5327 config->vars = mplist ();
5330 if (variable == Mnil)
5332 MInputMethodInfo *custom = get_custom_info (im_info);
5334 mplist_set (config->vars, Mnil, NULL);
5335 if (custom && custom->cmds)
5337 MPLIST_DO (plist, custom->vars)
5339 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5341 mplist_add (plist, Msymbol, variable);
5342 mplist_push (config->vars, Mplist, plist);
5343 M17N_OBJECT_UNREF (plist);
5349 plist = mplist__assq (config->vars, variable);
5352 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5353 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5354 if (! MPLIST_TAIL_P (plist))
5355 mplist_set (plist, Mnil ,NULL); /* () */
5360 mplist_add (config->vars, Mplist, plist);
5361 M17N_OBJECT_UNREF (plist);
5362 plist = mplist_add (plist, Msymbol, variable);
5363 plist = MPLIST_NEXT (plist);
5367 plist = mplist_add (plist, Msymbol, Mnil);
5368 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5371 config_all_variables (im_info);
5372 im_info->tick = time (NULL);
5379 @brief Get the name of per-user configuration file.
5381 The minput_config_file () function returns the absolute path name
5382 of per-user configuration file into which minput_save_config ()
5383 save configurations. It is usually @c "config.mic" under the
5384 directory @c ".m17n.d" of user's home directory. It is not assured
5385 that the file of the returned name exists nor is
5386 readable/writable. If minput_save_config () fails and returns -1,
5387 an application program might check the file, make it
5388 writable (if possible), and try minput_save_config () again.
5392 This function returns a string. As the string is kept in the
5393 library, the caller must not modify nor free it.
5396 minput_save_config ()
5399 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5401 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5402 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5403 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5404 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5405 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5406 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5407 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5412 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5413 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5416 minput_save_config ()
5420 minput_config_file ()
5424 return mdatabase__file (im_custom_mdb);
5430 @brief Save configurations in per-user configuration file.
5432 The minput_save_config () function saves the configurations done
5433 so far in the current session into the per-user configuration
5438 If the operation was successful, 1 is returned. If the per-user
5439 configuration file is currently locked, 0 is returned. In that
5440 case, the caller may wait for a while and try again. If the
5441 configuration file is not writable, -1 is returned. In that case,
5442 the caller may check the name of the file by calling
5443 minput_config_file (), make it writable if possible, and try
5447 minput_config_file () */
5449 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5451 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5452 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5456 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5457 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5458 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5459 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5463 minput_config_file () */
5466 minput_save_config (void)
5468 MPlist *data, *tail, *plist, *p, *elt;
5472 ret = mdatabase__lock (im_custom_mdb);
5475 if (! im_config_list)
5477 update_custom_info ();
5478 if (! im_custom_list)
5479 im_custom_list = mplist ();
5480 data = tail = mplist ();
5482 MPLIST_DO (plist, im_config_list)
5484 MPlist *pl = MPLIST_PLIST (plist);
5485 MSymbol language, name, extra, command, variable;
5486 MInputMethodInfo *custom, *config;
5488 language = MPLIST_SYMBOL (pl);
5489 pl = MPLIST_NEXT (pl);
5490 name = MPLIST_SYMBOL (pl);
5491 pl = MPLIST_NEXT (pl);
5492 extra = MPLIST_SYMBOL (pl);
5493 pl = MPLIST_NEXT (pl);
5494 config = MPLIST_VAL (pl);
5495 custom = get_custom_info (config);
5497 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5499 MPLIST_DO (pl, config->cmds)
5501 elt = MPLIST_PLIST (pl);
5502 command = MPLIST_SYMBOL (elt);
5504 p = mplist__assq (custom->cmds, command);
5506 custom->cmds = mplist (), p = NULL;
5507 elt = MPLIST_NEXT (elt);
5508 if (MPLIST_TAIL_P (elt))
5511 mplist__pop_unref (p);
5515 elt = MPLIST_NEXT (elt);
5518 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5519 mplist_set (p, Mnil, NULL);
5520 mplist__conc (p, elt);
5524 p = MPLIST_PLIST (pl);
5525 mplist_add (custom->cmds, Mplist, p);
5530 MPLIST_DO (pl, config->vars)
5532 elt = MPLIST_PLIST (pl);
5533 variable = MPLIST_SYMBOL (elt);
5535 p = mplist__assq (custom->vars, variable);
5537 custom->vars = mplist (), p = NULL;
5538 elt = MPLIST_NEXT (elt);
5539 if (MPLIST_TAIL_P (elt))
5542 mplist__pop_unref (p);
5546 elt = MPLIST_NEXT (elt);
5549 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5550 mplist_set (p, Mnil, NULL);
5551 mplist__conc (p, elt);
5555 p = MPLIST_PLIST (pl);
5556 mplist_add (custom->vars, Mplist, p);
5561 M17N_OBJECT_UNREF (im_config_list);
5563 MPLIST_DO (plist, im_custom_list)
5565 MPlist *pl = MPLIST_PLIST (plist);
5566 MSymbol language, name, extra;
5567 MInputMethodInfo *custom, *im_info;
5569 language = MPLIST_SYMBOL (pl);
5570 pl = MPLIST_NEXT (pl);
5571 name = MPLIST_SYMBOL (pl);
5572 pl = MPLIST_NEXT (pl);
5573 extra = MPLIST_SYMBOL (pl);
5574 pl = MPLIST_NEXT (pl);
5575 custom = MPLIST_VAL (pl);
5576 im_info = lookup_im_info (im_info_list, language, name, extra);
5580 config_all_commands (im_info);
5582 config_all_variables (im_info);
5586 tail = mplist_add (tail, Mplist, elt);
5587 M17N_OBJECT_UNREF (elt);
5589 elt = mplist_add (elt, Mplist, pl);
5590 M17N_OBJECT_UNREF (pl);
5591 pl = mplist_add (pl, Msymbol, Minput_method);
5592 pl = mplist_add (pl, Msymbol, language);
5593 pl = mplist_add (pl, Msymbol, name);
5595 pl = mplist_add (pl, Msymbol, extra);
5596 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5599 elt = mplist_add (elt, Mplist, pl);
5600 M17N_OBJECT_UNREF (pl);
5601 pl = mplist_add (pl, Msymbol, Mcommand);
5602 MPLIST_DO (p, custom->cmds)
5603 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5605 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5608 elt = mplist_add (elt, Mplist, pl);
5609 M17N_OBJECT_UNREF (pl);
5610 pl = mplist_add (pl, Msymbol, Mvariable);
5611 MPLIST_DO (p, custom->vars)
5612 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5616 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5617 ret = mdatabase__save (im_custom_mdb, data);
5618 mdatabase__unlock (im_custom_mdb);
5619 M17N_OBJECT_UNREF (data);
5620 return (ret < 0 ? -1 : 1);
5627 @name Obsolete functions
5630 @name Obsolete ¤Ê´Ø¿ô
5636 @brief Get a list of variables of an input method (obsolete).
5638 This function is obsolete. Use minput_get_variable () instead.
5640 The minput_get_variables () function returns a plist (#MPlist) of
5641 variables used to control the behavior of the input method
5642 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5643 (#m17nPlist) of the following format:
5646 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5647 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5651 @c VARNAME is a symbol representing the variable name.
5653 @c DOC-MTEXT is an M-text describing the variable.
5655 @c DEFAULT-VALUE is the default value of the variable. It is a
5656 symbol, integer, or M-text.
5658 @c VALUEs (if any) specifies the possible values of the variable.
5659 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5660 @c TO), where @c FROM and @c TO specifies a range of possible
5663 For instance, suppose an input method has the variables:
5665 @li name:intvar, description:"value is an integer",
5666 initial value:0, value-range:0..3,10,20
5668 @li name:symvar, description:"value is a symbol",
5669 initial value:nil, value-range:a, b, c, nil
5671 @li name:txtvar, description:"value is an M-text",
5672 initial value:empty text, no value-range (i.e. any text)
5674 Then, the returned plist is as follows.
5677 (intvar ("value is an integer" 0 (0 3) 10 20)
5678 symvar ("value is a symbol" nil a b c nil)
5679 txtvar ("value is an M-text" ""))
5683 If the input method uses any variables, a pointer to #MPlist is
5684 returned. As the plist is kept in the library, the caller must not
5685 modify nor free it. If the input method does not use any
5686 variable, @c NULL is returned. */
5688 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5690 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5691 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5692 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5696 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5697 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5701 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5703 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5705 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5708 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5709 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5710 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5712 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5714 @li name:intvar, ÀâÌÀ:"value is an integer",
5715 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5717 @li name:symvar, ÀâÌÀ:"value is a symbol",
5718 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5720 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5721 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5723 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5726 (intvar ("value is an integer" 0 (0 3) 10 20)
5727 symvar ("value is a symbol" nil a b c nil)
5728 txtvar ("value is an M-text" ""))
5732 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5733 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5734 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5737 minput_get_variables (MSymbol language, MSymbol name)
5739 MInputMethodInfo *im_info;
5744 im_info = get_im_info (language, name, Mnil, Mvariable);
5745 if (! im_info || ! im_info->configured_vars)
5748 M17N_OBJECT_UNREF (im_info->bc_vars);
5749 im_info->bc_vars = mplist ();
5750 MPLIST_DO (vars, im_info->configured_vars)
5752 MPlist *plist = MPLIST_PLIST (vars);
5753 MPlist *elt = mplist ();
5755 mplist_push (im_info->bc_vars, Mplist, elt);
5756 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5757 elt = MPLIST_NEXT (elt);
5758 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5759 M17N_OBJECT_UNREF (elt);
5761 return im_info->bc_vars;
5767 @brief Set the initial value of an input method variable.
5769 The minput_set_variable () function sets the initial value of
5770 input method variable $VARIABLE to $VALUE for the input method
5771 specified by $LANGUAGE and $NAME.
5773 By default, the initial value is 0.
5775 This setting gets effective in a newly opened input method.
5778 If the operation was successful, 0 is returned. Otherwise -1 is
5779 returned, and #merror_code is set to #MERROR_IM. */
5781 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5783 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5784 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5785 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5787 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5789 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5792 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5793 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5796 minput_set_variable (MSymbol language, MSymbol name,
5797 MSymbol variable, void *value)
5800 MInputMethodInfo *im_info;
5805 if (variable == Mnil)
5806 MERROR (MERROR_IM, -1);
5807 plist = minput_get_variable (language, name, variable);
5808 plist = MPLIST_PLIST (plist);
5809 plist = MPLIST_NEXT (plist);
5811 mplist_add (pl, MPLIST_KEY (plist), value);
5812 ret = minput_config_variable (language, name, variable, pl);
5813 M17N_OBJECT_UNREF (pl);
5816 im_info = get_im_info (language, name, Mnil, Mvariable);
5825 @brief Get information about input method commands.
5827 The minput_get_commands () function returns information about
5828 input method commands of the input method specified by $LANGUAGE
5829 and $NAME. An input method command is a pseudo key event to which
5830 one or more actual input key sequences are assigned.
5832 There are two kinds of commands, global and local. Global
5833 commands are used by multiple input methods for the same purpose,
5834 and have global key assignments. Local commands are used only by
5835 a specific input method, and have only local key assignments.
5837 Each input method may locally change key assignments for global
5838 commands. The global key assignment for a global command is
5839 effective only when the current input method does not have local
5840 key assignments for that command.
5842 If $NAME is #Mnil, information about global commands is returned.
5843 In this case $LANGUAGE is ignored.
5845 If $NAME is not #Mnil, information about those commands that have
5846 local key assignments in the input method specified by $LANGUAGE
5847 and $NAME is returned.
5850 If no input method commands are found, this function returns @c NULL.
5852 Otherwise, a pointer to a plist is returned. The key of each
5853 element in the plist is a symbol representing a command, and the
5854 value is a plist of the form COMMAND-INFO described below.
5856 The first element of COMMAND-INFO has the key #Mtext, and the
5857 value is an M-text describing the command.
5859 If there are no more elements, that means no key sequences are
5860 assigned to the command. Otherwise, each of the remaining
5861 elements has the key #Mplist, and the value is a plist whose keys are
5862 #Msymbol and values are symbols representing input keys, which are
5863 currently assigned to the command.
5865 As the returned plist is kept in the library, the caller must not
5866 modify nor free it. */
5868 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5870 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5871 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5872 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5873 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5875 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5876 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5877 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5878 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5880 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5881 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5882 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5885 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5886 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5888 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5889 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5893 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5895 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5896 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5897 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5899 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5900 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5901 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5904 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5905 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5906 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5907 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5908 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5910 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5911 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5914 minput_get_commands (MSymbol language, MSymbol name)
5916 MInputMethodInfo *im_info;
5921 im_info = get_im_info (language, name, Mnil, Mcommand);
5922 if (! im_info || ! im_info->configured_vars)
5924 M17N_OBJECT_UNREF (im_info->bc_cmds);
5925 im_info->bc_cmds = mplist ();
5926 MPLIST_DO (cmds, im_info->configured_cmds)
5928 MPlist *plist = MPLIST_PLIST (cmds);
5929 MPlist *elt = mplist ();
5931 mplist_push (im_info->bc_cmds, Mplist, elt);
5932 mplist_add (elt, MPLIST_SYMBOL (plist),
5933 mplist_copy (MPLIST_NEXT (plist)));
5934 M17N_OBJECT_UNREF (elt);
5936 return im_info->bc_cmds;
5942 @brief Assign a key sequence to an input method command (obsolete).
5944 This function is obsolete. Use minput_config_command () instead.
5946 The minput_assign_command_keys () function assigns input key
5947 sequence $KEYSEQ to input method command $COMMAND for the input
5948 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5949 key sequence is assigned globally no matter what $LANGUAGE is.
5950 Otherwise the key sequence is assigned locally.
5952 Each element of $KEYSEQ must have the key $Msymbol and the value
5953 must be a symbol representing an input key.
5955 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5956 globally or locally.
5958 This assignment gets effective in a newly opened input method.
5961 If the operation was successful, 0 is returned. Otherwise -1 is
5962 returned, and #merror_code is set to #MERROR_IM. */
5964 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5966 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5967 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5968 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5969 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5970 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5972 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5973 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5975 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5976 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5978 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5981 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5982 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5985 minput_assign_command_keys (MSymbol language, MSymbol name,
5986 MSymbol command, MPlist *keyseq)
5992 if (command == Mnil)
5993 MERROR (MERROR_IM, -1);
5998 if (! check_command_keyseq (keyseq))
5999 MERROR (MERROR_IM, -1);
6001 mplist_add (plist, Mplist, keyseq);
6006 ret = minput_config_command (language, name, command, keyseq);
6007 M17N_OBJECT_UNREF (keyseq);
6014 @brief Call a callback function
6016 The minput_callback () functions calls a callback function
6017 $COMMAND assigned for the input context $IC. The caller must set
6018 specific elements in $IC->plist if the callback function requires.
6021 If there exists a specified callback function, 0 is returned.
6022 Otherwise -1 is returned. By side effects, $IC->plist may be
6026 minput_callback (MInputContext *ic, MSymbol command)
6028 MInputCallbackFunc func;
6030 if (! ic->im->driver.callback_list)
6032 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
6036 (func) (ic, command);
6043 /*** @addtogroup m17nDebug */
6049 @brief Dump an input method.
6051 The mdebug_dump_im () function prints the input method $IM in a
6052 human readable way to the stderr. $INDENT specifies how many
6053 columns to indent the lines but the first one.
6056 This function returns $IM. */
6058 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6060 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6061 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6064 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6067 mdebug_dump_im (MInputMethod *im, int indent)
6069 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6072 prefix = (char *) alloca (indent + 1);
6073 memset (prefix, 32, indent);
6074 prefix[indent] = '\0';
6076 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6077 msymbol_name (im->name));
6078 mdebug_dump_mtext (im_info->title, 0, 0);
6079 if (im->name != Mnil)
6083 MPLIST_DO (state, im_info->states)
6085 fprintf (stderr, "\n%s ", prefix);
6086 dump_im_state (MPLIST_VAL (state), indent + 2);
6089 fprintf (stderr, ")");