1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
156 #include "m17n-gui.h"
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_mask = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mundo = msymbol ("undo");
406 Mcall = msymbol ("call");
407 Mshift = msymbol ("shift");
408 Mselect = msymbol ("select");
409 Mshow = msymbol ("show");
410 Mhide = msymbol ("hide");
411 Mcommit = msymbol ("commit");
412 Munhandle = msymbol ("unhandle");
413 Mset = msymbol ("set");
414 Madd = msymbol ("add");
415 Msub = msymbol ("sub");
416 Mmul = msymbol ("mul");
417 Mdiv = msymbol ("div");
418 Mequal = msymbol ("=");
419 Mless = msymbol ("<");
420 Mgreater = msymbol (">");
421 Mless_equal = msymbol ("<=");
422 Mgreater_equal = msymbol (">=");
423 Mcond = msymbol ("cond");
424 Mplus = msymbol ("+");
425 Mminus = msymbol ("-");
426 Mstar = msymbol ("*");
427 Mslash = msymbol ("/");
428 Mand = msymbol ("&");
430 Mnot = msymbol ("!");
432 Mat_reload = msymbol ("@reload");
434 Mcandidates_group_size = msymbol ("candidates-group-size");
435 Mcandidates_charset = msymbol ("candidates-charset");
437 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
438 Mcandidate_index = msymbol (" candidate-index");
440 Minit = msymbol ("init");
441 Mfini = msymbol ("fini");
443 Mdescription = msymbol ("description");
444 Mcommand = msymbol ("command");
445 Mvariable = msymbol ("variable");
446 Mglobal = msymbol ("global");
447 Mconfig = msymbol ("config");
448 M_gettext = msymbol ("_");
450 load_im_info_keys = mplist ();
451 mplist_add (load_im_info_keys, Mstate, Mnil);
452 mplist_push (load_im_info_keys, Mmap, Mnil);
454 im_info_list = mplist ();
455 im_config_list = im_custom_list = NULL;
456 im_custom_mdb = NULL;
457 update_custom_info ();
459 update_global_info ();
461 fully_initialized = 1;
464 #define MINPUT__INIT() \
466 if (! fully_initialized) \
467 fully_initialize (); \
472 marker_code (MSymbol sym, int surrounding)
478 name = MSYMBOL_NAME (sym);
479 return (name[0] != '@' ? -1
480 : (((name[1] >= '0' && name[1] <= '9')
481 || name[1] == '<' || name[1] == '>' || name[1] == '='
482 || name[1] == '[' || name[1] == ']'
484 && name[2] == '\0') ? name[1]
485 : (name[1] != '+' && name[1] != '-') ? -1
486 : (name[2] == '\0' || surrounding) ? name[1]
492 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
494 MPlist *plist = mplist__assq (ic_info->vars, var);
498 plist = MPLIST_PLIST (plist);
499 return MPLIST_NEXT (plist);
503 mplist_push (ic_info->vars, Mplist, plist);
504 M17N_OBJECT_UNREF (plist);
505 plist = mplist_add (plist, Msymbol, var);
506 plist = mplist_add (plist, Minteger, (void *) 0);
511 get_surrounding_text (MInputContext *ic, int len)
515 mplist_push (ic->plist, Minteger, (void *) len);
516 if (minput__callback (ic, Minput_get_surrounding_text) >= 0
517 && MPLIST_MTEXT_P (ic->plist))
518 mt = MPLIST_MTEXT (ic->plist);
519 mplist_pop (ic->plist);
524 delete_surrounding_text (MInputContext *ic, int pos)
526 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
528 mplist_push (ic->plist, Minteger, (void *) pos);
529 minput__callback (ic, Minput_delete_surrounding_text);
530 mplist_pop (ic->plist);
533 M17N_OBJECT_UNREF (ic_info->preceding_text);
534 ic_info->preceding_text = NULL;
538 M17N_OBJECT_UNREF (ic_info->following_text);
539 ic_info->following_text = NULL;
544 get_preceding_char (MInputContext *ic, int pos)
546 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
550 if (ic_info->preceding_text)
552 len = mtext_nchars (ic_info->preceding_text);
554 return mtext_ref_char (ic_info->preceding_text, len - pos);
556 mt = get_surrounding_text (ic, - pos);
559 len = mtext_nchars (mt);
560 if (ic_info->preceding_text)
562 if (mtext_nchars (ic_info->preceding_text) < len)
564 M17N_OBJECT_UNREF (ic_info->preceding_text);
565 ic_info->preceding_text = mt;
569 ic_info->preceding_text = mt;
572 return mtext_ref_char (ic_info->preceding_text, len - pos);
576 get_following_char (MInputContext *ic, int pos)
578 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
582 if (ic_info->following_text)
584 len = mtext_nchars (ic_info->following_text);
586 return mtext_ref_char (ic_info->following_text, pos - 1);
588 mt = get_surrounding_text (ic, pos);
591 len = mtext_nchars (mt);
592 if (ic_info->following_text)
594 if (mtext_nchars (ic_info->following_text) < len)
596 M17N_OBJECT_UNREF (ic_info->following_text);
597 ic_info->following_text = mt;
601 ic_info->following_text = mt;
604 return mtext_ref_char (ic_info->following_text, pos - 1);
608 surrounding_pos (MSymbol sym)
614 name = MSYMBOL_NAME (sym);
616 && (name[1] == '-' || name[1] == '+')
617 && name[2] >= '1' && name[2] <= '9')
618 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
623 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
625 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
627 MText *preedit = ic->preedit;
628 int len = mtext_nchars (preedit);
632 if (MPLIST_INTEGER_P (arg))
633 return MPLIST_INTEGER (arg);
635 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
638 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
642 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
645 return ic_info->key_head;
646 if ((code == '-' || code == '+'))
648 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
652 pos = atoi (name + 1);
654 return get_preceding_char (ic, 0);
655 pos = ic->cursor_pos + pos;
657 return get_preceding_char (ic, - pos);
659 return get_following_char (ic, pos - len + 1);
662 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
664 else if (code >= '0' && code <= '9')
666 else if (code == '=')
667 pos = ic->cursor_pos;
668 else if (code == '[')
669 pos = ic->cursor_pos - 1;
670 else if (code == ']')
671 pos = ic->cursor_pos + 1;
672 else if (code == '<')
674 else if (code == '>')
676 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
680 parse_expression (MPlist *plist)
684 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
686 if (! MPLIST_PLIST_P (plist))
688 plist = MPLIST_PLIST (plist);
689 op = MPLIST_SYMBOL (plist);
690 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
691 && op != Mand && op != Mor && op != Mnot
692 && op != Mless && op != Mgreater && op != Mequal
693 && op != Mless_equal && op != Mgreater_equal)
694 MERROR (MERROR_IM, -1);
695 MPLIST_DO (plist, MPLIST_NEXT (plist))
696 if (parse_expression (plist) < 0)
702 resolve_expression (MInputContext *ic, MPlist *plist)
707 if (MPLIST_INTEGER_P (plist))
708 return MPLIST_INTEGER (plist);
709 if (MPLIST_SYMBOL_P (plist))
710 return integer_value (ic, plist, NULL, 1);
711 if (! MPLIST_PLIST_P (plist))
713 plist = MPLIST_PLIST (plist);
714 if (! MPLIST_SYMBOL_P (plist))
716 op = MPLIST_SYMBOL (plist);
717 plist = MPLIST_NEXT (plist);
718 val = resolve_expression (ic, plist);
720 MPLIST_DO (plist, MPLIST_NEXT (plist))
721 val += resolve_expression (ic, plist);
722 else if (op == Mminus)
723 MPLIST_DO (plist, MPLIST_NEXT (plist))
724 val -= resolve_expression (ic, plist);
725 else if (op == Mstar)
726 MPLIST_DO (plist, MPLIST_NEXT (plist))
727 val *= resolve_expression (ic, plist);
728 else if (op == Mslash)
729 MPLIST_DO (plist, MPLIST_NEXT (plist))
730 val /= resolve_expression (ic, plist);
732 MPLIST_DO (plist, MPLIST_NEXT (plist))
733 val &= resolve_expression (ic, plist);
735 MPLIST_DO (plist, MPLIST_NEXT (plist))
736 val |= resolve_expression (ic, plist);
739 else if (op == Mless)
740 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
741 else if (op == Mequal)
742 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
743 else if (op == Mgreater)
744 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
745 else if (op == Mless_equal)
746 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
747 else if (op == Mgreater_equal)
748 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
752 /* Parse PLIST as an action list. PLIST should have this form:
753 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
754 Return 0 if successfully parsed, otherwise return -1. */
757 parse_action_list (MPlist *plist, MPlist *macros)
759 MPLIST_DO (plist, plist)
761 if (MPLIST_MTEXT_P (plist))
763 /* This is a short form of (insert MTEXT). */
764 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
765 MERROR (MERROR_IM, -1); */
767 else if (MPLIST_PLIST_P (plist)
768 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
769 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
773 /* This is a short form of (insert (GROUPS *)). */
774 MPLIST_DO (pl, MPLIST_PLIST (plist))
776 if (MPLIST_PLIST_P (pl))
780 MPLIST_DO (elt, MPLIST_PLIST (pl))
781 if (! MPLIST_MTEXT_P (elt)
782 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
783 MERROR (MERROR_IM, -1);
787 if (! MPLIST_MTEXT_P (pl)
788 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
789 MERROR (MERROR_IM, -1);
793 else if (MPLIST_INTEGER_P (plist))
795 int c = MPLIST_INTEGER (plist);
797 if (c < 0 || c > MCHAR_MAX)
798 MERROR (MERROR_IM, -1);
800 else if (MPLIST_PLIST_P (plist)
801 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
803 MPlist *pl = MPLIST_PLIST (plist);
804 MSymbol action_name = MPLIST_SYMBOL (pl);
806 pl = MPLIST_NEXT (pl);
808 if (action_name == Minsert)
810 if (MPLIST_MTEXT_P (pl))
812 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
813 MERROR (MERROR_IM, -1);
815 else if (MPLIST_PLIST_P (pl))
819 if (MPLIST_PLIST_P (pl))
823 MPLIST_DO (elt, MPLIST_PLIST (pl))
824 if (! MPLIST_MTEXT_P (elt)
825 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
826 MERROR (MERROR_IM, -1);
830 if (! MPLIST_MTEXT_P (pl)
831 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
832 MERROR (MERROR_IM, -1);
836 else if (! MPLIST_SYMBOL_P (pl))
837 MERROR (MERROR_IM, -1);
839 else if (action_name == Mselect
840 || action_name == Mdelete
841 || action_name == Mmove)
843 if (parse_expression (pl) < 0)
846 else if (action_name == Mmark
847 || action_name == Mcall
848 || action_name == Mshift)
850 if (! MPLIST_SYMBOL_P (pl))
851 MERROR (MERROR_IM, -1);
853 else if (action_name == Mundo)
855 if (! MPLIST_TAIL_P (pl))
857 if (! MPLIST_SYMBOL_P (pl)
858 && (! MPLIST_INTEGER_P (pl)
859 || MPLIST_INTEGER (pl) == 0))
860 MERROR (MERROR_IM, -1);
863 else if (action_name == Mpushback)
865 if (MPLIST_MTEXT_P (pl))
867 MText *mt = MPLIST_MTEXT (pl);
869 if (mtext_nchars (mt) != mtext_nbytes (mt))
870 MERROR (MERROR_IM, -1);
872 else if (MPLIST_PLIST_P (pl))
876 MPLIST_DO (p, MPLIST_PLIST (pl))
877 if (! MPLIST_SYMBOL_P (p))
878 MERROR (MERROR_IM, -1);
880 else if (! MPLIST_INTEGER_P (pl))
881 MERROR (MERROR_IM, -1);
883 else if (action_name == Mset || action_name == Madd
884 || action_name == Msub || action_name == Mmul
885 || action_name == Mdiv)
887 if (! MPLIST_SYMBOL_P (pl))
888 MERROR (MERROR_IM, -1);
889 if (parse_expression (MPLIST_NEXT (pl)) < 0)
892 else if (action_name == Mequal || action_name == Mless
893 || action_name == Mgreater || action_name == Mless_equal
894 || action_name == Mgreater_equal)
896 if (parse_expression (pl) < 0
897 || parse_expression (MPLIST_NEXT (pl)) < 0)
899 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
900 if (! MPLIST_PLIST_P (pl))
901 MERROR (MERROR_IM, -1);
902 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
903 MERROR (MERROR_IM, -1);
904 pl = MPLIST_NEXT (pl);
905 if (MPLIST_PLIST_P (pl)
906 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
907 MERROR (MERROR_IM, -1);
909 else if (action_name == Mshow || action_name == Mhide
910 || action_name == Mcommit || action_name == Munhandle)
912 else if (action_name == Mcond)
915 if (! MPLIST_PLIST_P (pl))
916 MERROR (MERROR_IM, -1);
918 else if (! macros || ! mplist_get (macros, action_name))
919 MERROR (MERROR_IM, -1);
921 else if (! MPLIST_SYMBOL_P (plist))
922 MERROR (MERROR_IM, -1);
929 resolve_command (MPlist *cmds, MSymbol command)
933 if (! cmds || ! (plist = mplist__assq (cmds, command)))
935 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
936 plist = MPLIST_NEXT (plist);
937 plist = MPLIST_NEXT (plist);
938 plist = MPLIST_NEXT (plist);
942 /* Load a translation into MAP from PLIST.
944 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
947 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
948 MPlist *branch_actions, MPlist *macros)
953 if (MPLIST_MTEXT_P (keylist))
955 MText *mt = MPLIST_MTEXT (keylist);
957 len = mtext_nchars (mt);
958 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
960 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
961 for (i = 0; i < len; i++)
962 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
968 if (MFAILP (MPLIST_PLIST_P (keylist)))
970 elt = MPLIST_PLIST (keylist);
971 len = MPLIST_LENGTH (elt);
972 if (MFAILP (len > 0))
974 keyseq = (MSymbol *) alloca (sizeof (int) * len);
975 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
977 if (MPLIST_INTEGER_P (elt))
979 int c = MPLIST_INTEGER (elt);
981 if (MFAILP (c >= 0 && c < 0x100))
983 keyseq[i] = one_char_symbol[c];
987 if (MFAILP (MPLIST_SYMBOL_P (elt)))
989 keyseq[i] = MPLIST_SYMBOL (elt);
994 for (i = 0; i < len; i++)
996 MIMMap *deeper = NULL;
999 deeper = mplist_get (map->submaps, keyseq[i]);
1001 map->submaps = mplist ();
1004 /* Fixme: It is better to make all deeper maps at once. */
1005 MSTRUCT_CALLOC (deeper, MERROR_IM);
1006 mplist_put (map->submaps, keyseq[i], deeper);
1011 /* We reach a terminal map. */
1012 if (map->map_actions
1013 || map->branch_actions)
1014 /* This map is already defined. We avoid overriding it. */
1017 if (! MPLIST_TAIL_P (map_actions))
1019 if (parse_action_list (map_actions, macros) < 0)
1020 MERROR (MERROR_IM, -1);
1021 map->map_actions = map_actions;
1025 map->branch_actions = branch_actions;
1026 M17N_OBJECT_REF (branch_actions);
1032 /* Load a branch from PLIST into MAP. PLIST has this form:
1033 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1036 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1039 MPlist *branch_actions;
1041 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1043 map_name = MPLIST_SYMBOL (plist);
1044 plist = MPLIST_NEXT (plist);
1045 if (MPLIST_TAIL_P (plist))
1046 branch_actions = NULL;
1047 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1050 branch_actions = plist;
1051 if (map_name == Mnil)
1053 map->branch_actions = branch_actions;
1055 M17N_OBJECT_REF (branch_actions);
1057 else if (map_name == Mt)
1059 map->map_actions = branch_actions;
1061 M17N_OBJECT_REF (branch_actions);
1063 else if (im_info->maps
1064 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1066 MPLIST_DO (plist, plist)
1068 MPlist *keylist, *map_actions;
1070 if (! MPLIST_PLIST_P (plist))
1071 MERROR (MERROR_IM, -1);
1072 keylist = MPLIST_PLIST (plist);
1073 map_actions = MPLIST_NEXT (keylist);
1074 if (MPLIST_SYMBOL_P (keylist))
1076 MSymbol command = MPLIST_SYMBOL (keylist);
1079 if (MFAILP (command != Mat_reload))
1081 pl = resolve_command (im_info->configured_cmds, command);
1085 load_translation (map, pl, map_actions, branch_actions,
1089 load_translation (map, keylist, map_actions, branch_actions,
1097 /* Load a macro from PLIST into IM_INFO->macros.
1098 PLIST has this from:
1099 PLIST ::= ( MACRO-NAME ACTION * )
1100 IM_INFO->macros is a plist of macro names vs action list. */
1103 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1108 if (! MPLIST_SYMBOL_P (plist))
1109 MERROR (MERROR_IM, -1);
1110 name = MPLIST_SYMBOL (plist);
1111 plist = MPLIST_NEXT (plist);
1112 if (MPLIST_TAIL_P (plist)
1113 || parse_action_list (plist, im_info->macros) < 0)
1114 MERROR (MERROR_IM, -1);
1115 pl = mplist_get (im_info->macros, name);
1116 M17N_OBJECT_UNREF (pl);
1117 mplist_put (im_info->macros, name, plist);
1118 M17N_OBJECT_REF (plist);
1122 /* Load an external module from PLIST into IM_INFO->externals.
1123 PLIST has this form:
1124 PLIST ::= ( MODULE-NAME FUNCTION * )
1125 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1128 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1133 MIMExternalModule *external;
1137 if (MPLIST_MTEXT_P (plist))
1138 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1139 else if (MPLIST_SYMBOL_P (plist))
1140 module = MPLIST_SYMBOL (plist);
1141 module_file = alloca (strlen (MSYMBOL_NAME (module))
1142 + strlen (DLOPEN_SHLIB_EXT) + 1);
1143 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1145 handle = dlopen (module_file, RTLD_NOW);
1146 if (MFAILP (handle))
1148 fprintf (stderr, "%s\n", dlerror ());
1151 func_list = mplist ();
1152 MPLIST_DO (plist, MPLIST_NEXT (plist))
1154 if (! MPLIST_SYMBOL_P (plist))
1155 MERROR_GOTO (MERROR_IM, err_label);
1156 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1159 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1162 MSTRUCT_MALLOC (external, MERROR_IM);
1163 external->handle = handle;
1164 external->func_list = func_list;
1165 mplist_add (im_info->externals, module, external);
1170 M17N_OBJECT_UNREF (func_list);
1175 free_map (MIMMap *map, int top)
1180 M17N_OBJECT_UNREF (map->map_actions);
1183 MPLIST_DO (plist, map->submaps)
1184 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1185 M17N_OBJECT_UNREF (map->submaps);
1187 M17N_OBJECT_UNREF (map->branch_actions);
1192 free_state (void *object)
1194 MIMState *state = object;
1196 M17N_OBJECT_UNREF (state->title);
1198 free_map (state->map, 1);
1202 /** Load a state from PLIST into a newly allocated state object.
1203 PLIST has this form:
1204 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1205 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1206 Return the state object. */
1209 load_state (MInputMethodInfo *im_info, MPlist *plist)
1213 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1215 M17N_OBJECT (state, free_state, MERROR_IM);
1216 state->name = MPLIST_SYMBOL (plist);
1217 plist = MPLIST_NEXT (plist);
1218 if (MPLIST_MTEXT_P (plist))
1220 state->title = MPLIST_MTEXT (plist);
1221 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1222 Mlanguage, im_info->language);
1223 M17N_OBJECT_REF (state->title);
1224 plist = MPLIST_NEXT (plist);
1226 MSTRUCT_CALLOC (state->map, MERROR_IM);
1227 MPLIST_DO (plist, plist)
1229 if (MFAILP (MPLIST_PLIST_P (plist)))
1231 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1236 /* Return a newly created IM_INFO for an input method specified by
1237 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1239 static MInputMethodInfo *
1240 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1243 MInputMethodInfo *im_info;
1246 if (name == Mnil && extra == Mnil)
1247 language = Mt, extra = Mglobal;
1248 MSTRUCT_CALLOC (im_info, MERROR_IM);
1250 im_info->language = language;
1251 im_info->name = name;
1252 im_info->extra = extra;
1255 mplist_add (plist, Mplist, elt);
1256 M17N_OBJECT_UNREF (elt);
1257 elt = mplist_add (elt, Msymbol, language);
1258 elt = mplist_add (elt, Msymbol, name);
1259 elt = mplist_add (elt, Msymbol, extra);
1260 mplist_add (elt, Mt, im_info);
1266 fini_im_info (MInputMethodInfo *im_info)
1270 M17N_OBJECT_UNREF (im_info->cmds);
1271 M17N_OBJECT_UNREF (im_info->configured_cmds);
1272 M17N_OBJECT_UNREF (im_info->bc_cmds);
1273 M17N_OBJECT_UNREF (im_info->vars);
1274 M17N_OBJECT_UNREF (im_info->configured_vars);
1275 M17N_OBJECT_UNREF (im_info->bc_vars);
1276 M17N_OBJECT_UNREF (im_info->description);
1277 M17N_OBJECT_UNREF (im_info->title);
1278 if (im_info->states)
1280 MPLIST_DO (plist, im_info->states)
1282 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1284 M17N_OBJECT_UNREF (state);
1286 M17N_OBJECT_UNREF (im_info->states);
1289 if (im_info->macros)
1291 MPLIST_DO (plist, im_info->macros)
1292 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1293 M17N_OBJECT_UNREF (im_info->macros);
1296 if (im_info->externals)
1298 MPLIST_DO (plist, im_info->externals)
1300 MIMExternalModule *external = MPLIST_VAL (plist);
1302 dlclose (external->handle);
1303 M17N_OBJECT_UNREF (external->func_list);
1305 MPLIST_KEY (plist) = Mt;
1307 M17N_OBJECT_UNREF (im_info->externals);
1311 MPLIST_DO (plist, im_info->maps)
1313 MPlist *p = MPLIST_PLIST (plist);
1315 M17N_OBJECT_UNREF (p);
1317 M17N_OBJECT_UNREF (im_info->maps);
1324 free_im_info (MInputMethodInfo *im_info)
1326 fini_im_info (im_info);
1331 free_im_list (MPlist *plist)
1335 MPLIST_DO (pl, plist)
1337 MInputMethodInfo *im_info;
1339 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1340 im_info = MPLIST_VAL (elt);
1341 free_im_info (im_info);
1343 M17N_OBJECT_UNREF (plist);
1346 static MInputMethodInfo *
1347 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1349 if (name == Mnil && extra == Mnil)
1350 language = Mt, extra = Mglobal;
1351 while ((plist = mplist__assq (plist, language)))
1353 MPlist *elt = MPLIST_PLIST (plist);
1355 plist = MPLIST_NEXT (plist);
1356 elt = MPLIST_NEXT (elt);
1357 if (MPLIST_SYMBOL (elt) != name)
1359 elt = MPLIST_NEXT (elt);
1360 if (MPLIST_SYMBOL (elt) != extra)
1362 elt = MPLIST_NEXT (elt);
1363 return MPLIST_VAL (elt);
1368 static void load_im_info (MPlist *, MInputMethodInfo *);
1370 #define get_custom_info(im_info) \
1372 ? lookup_im_info (im_custom_list, (im_info)->language, \
1373 (im_info)->name, (im_info)->extra) \
1376 #define get_config_info(im_info) \
1378 ? lookup_im_info (im_config_list, (im_info)->language, \
1379 (im_info)->name, (im_info)->extra) \
1383 update_custom_info (void)
1389 if (mdatabase__check (im_custom_mdb) > 0)
1394 MDatabaseInfo *custom_dir_info;
1395 char custom_path[PATH_MAX + 1];
1397 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1398 if (! custom_dir_info->filename
1399 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1401 strcpy (custom_path, custom_dir_info->filename);
1402 strcat (custom_path, CUSTOM_FILE);
1403 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1409 free_im_list (im_custom_list);
1410 im_custom_list = NULL;
1412 plist = mdatabase_load (im_custom_mdb);
1415 im_custom_list = mplist ();
1417 MPLIST_DO (pl, plist)
1419 MSymbol language, name, extra;
1420 MInputMethodInfo *im_info;
1421 MPlist *im_data, *p;
1423 if (! MPLIST_PLIST_P (pl))
1425 p = MPLIST_PLIST (pl);
1426 im_data = MPLIST_NEXT (p);
1427 if (! MPLIST_PLIST_P (p))
1429 p = MPLIST_PLIST (p);
1430 if (! MPLIST_SYMBOL_P (p)
1431 || MPLIST_SYMBOL (p) != Minput_method)
1433 p = MPLIST_NEXT (p);
1434 if (! MPLIST_SYMBOL_P (p))
1436 language = MPLIST_SYMBOL (p);
1437 p = MPLIST_NEXT (p);
1438 if (! MPLIST_SYMBOL_P (p))
1440 name = MPLIST_SYMBOL (p);
1441 if (language == Mnil || name == Mnil)
1443 p = MPLIST_NEXT (p);
1444 if (MPLIST_TAIL_P (p))
1446 else if (MPLIST_SYMBOL_P (p))
1447 extra = MPLIST_SYMBOL (p);
1450 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1451 load_im_info (im_data, im_info);
1453 M17N_OBJECT_UNREF (plist);
1458 update_global_info (void)
1464 int ret = mdatabase__check (global_info->mdb);
1468 fini_im_info (global_info);
1472 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1474 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1476 if (! global_info->mdb
1477 || ! (plist = mdatabase_load (global_info->mdb)))
1480 load_im_info (plist, global_info);
1481 M17N_OBJECT_UNREF (plist);
1486 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1487 and EXTRA. KEY, if not Mnil, tells which kind of information about
1488 the input method is necessary, and the returned IM_INFO may contain
1489 only that information. */
1491 static MInputMethodInfo *
1492 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1495 MInputMethodInfo *im_info;
1498 if (name == Mnil && extra == Mnil)
1499 language = Mt, extra = Mglobal;
1500 im_info = lookup_im_info (im_info_list, language, name, extra);
1503 if (key == Mnil ? im_info->states != NULL
1504 : key == Mcommand ? im_info->cmds != NULL
1505 : key == Mvariable ? im_info->vars != NULL
1506 : key == Mtitle ? im_info->title != NULL
1507 : key == Mdescription ? im_info->description != NULL
1509 /* IM_INFO already contains required information. */
1511 /* We have not yet loaded required information. */
1515 mdb = mdatabase_find (Minput_method, language, name, extra);
1518 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1523 plist = mdatabase_load (im_info->mdb);
1527 mplist_push (load_im_info_keys, key, Mt);
1528 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1529 mplist_pop (load_im_info_keys);
1533 MERROR (MERROR_IM, im_info);
1534 update_global_info ();
1535 load_im_info (plist, im_info);
1536 M17N_OBJECT_UNREF (plist);
1539 if (! im_info->cmds)
1540 im_info->cmds = mplist ();
1541 if (! im_info->vars)
1542 im_info->vars = mplist ();
1544 if (! im_info->title
1545 && (key == Mnil || key == Mtitle))
1546 im_info->title = (name == Mnil ? mtext ()
1547 : mtext_from_data (MSYMBOL_NAME (name),
1548 MSYMBOL_NAMELEN (name),
1549 MTEXT_FORMAT_US_ASCII));
1553 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1554 If updated, but got unloadable, return -1. Otherwise, update
1555 contents of IM_INFO from the new database, and return 1. */
1558 reload_im_info (MInputMethodInfo *im_info)
1563 update_custom_info ();
1564 update_global_info ();
1565 check = mdatabase__check (im_info->mdb);
1568 plist = mdatabase_load (im_info->mdb);
1571 fini_im_info (im_info);
1572 load_im_info (plist, im_info);
1573 M17N_OBJECT_UNREF (plist);
1577 static MInputMethodInfo *
1578 get_im_info_by_tags (MPlist *plist)
1583 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1584 i++, plist = MPLIST_NEXT (plist))
1585 tag[i] = MPLIST_SYMBOL (plist);
1590 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1595 check_description (MPlist *plist)
1599 if (MPLIST_MTEXT_P (plist))
1601 if (MPLIST_PLIST_P (plist))
1603 MPlist *pl = MPLIST_PLIST (plist);
1605 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1607 pl =MPLIST_NEXT (pl);
1608 if (MFAILP (MPLIST_MTEXT_P (pl)))
1610 mt = MPLIST_MTEXT (pl);
1611 M17N_OBJECT_REF (mt);
1614 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1616 if (translated == (char *) MTEXT_DATA (mt))
1617 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1618 if (translated != (char *) MTEXT_DATA (mt))
1620 M17N_OBJECT_UNREF (mt);
1621 mt = mtext__from_data (translated, strlen (translated),
1622 MTEXT_FORMAT_UTF_8, 0);
1626 mplist_set (plist, Mtext, mt);
1627 M17N_OBJECT_UNREF (mt);
1630 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1636 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1640 check_command_keyseq (MPlist *keyseq)
1642 if (MPLIST_PLIST_P (keyseq))
1644 MPlist *p = MPLIST_PLIST (keyseq);
1647 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1651 if (MPLIST_MTEXT_P (keyseq))
1653 MText *mt = MPLIST_MTEXT (keyseq);
1656 for (i = 0; i < mtext_nchars (mt); i++)
1657 if (mtext_ref_char (mt, i) >= 256)
1664 /* Load command defitions from PLIST into IM_INFO->cmds.
1666 PLIST is well-formed and has this form;
1667 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1668 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1669 M-text or a plist of symbols.
1671 The returned list has the same form, but for each element...
1673 (1) If DESCRIPTION and the rest are omitted, the element is not
1674 stored in the returned list.
1676 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1677 description in global_info->cmds (if any). */
1680 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1684 im_info->cmds = tail = mplist ();
1686 MPLIST_DO (plist, MPLIST_NEXT (plist))
1688 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1691 if (MFAILP (MPLIST_PLIST_P (plist)))
1693 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1694 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1696 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1697 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1699 if (MFAILP (im_info != global_info))
1700 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1704 if (! check_description (p))
1705 mplist_set (p, Msymbol, Mnil);
1706 p = MPLIST_NEXT (p);
1707 while (! MPLIST_TAIL_P (p))
1709 if (MFAILP (check_command_keyseq (p)))
1710 mplist__pop_unref (p);
1712 p = MPLIST_NEXT (p);
1715 tail = mplist_add (tail, Mplist, pl);
1720 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1721 MPlist *config_cmds)
1723 MPlist *global = NULL, *custom = NULL, *config = NULL;
1726 MPlist *description = NULL, *keyseq;
1728 name = MPLIST_SYMBOL (plist);
1729 plist = MPLIST_NEXT (plist);
1730 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1731 description = plist;
1732 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1733 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1734 if (MPLIST_TAIL_P (plist))
1737 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1738 global = MPLIST_NEXT (MPLIST_PLIST (global));
1741 keyseq = MPLIST_NEXT (global);
1742 status = Minherited;
1752 keyseq = MPLIST_NEXT (plist);
1756 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1758 config = MPLIST_NEXT (MPLIST_PLIST (config));
1759 if (! MPLIST_TAIL_P (config))
1761 keyseq = MPLIST_NEXT (config);
1762 status = Mconfigured;
1765 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1767 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1768 if (! MPLIST_TAIL_P (custom))
1770 keyseq = MPLIST_NEXT (custom);
1771 status = Mcustomized;
1776 mplist_add (plist, Msymbol, name);
1778 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1780 mplist_add (plist, Msymbol, Mnil);
1781 mplist_add (plist, Msymbol, status);
1782 mplist__conc (plist, keyseq);
1787 config_all_commands (MInputMethodInfo *im_info)
1789 MPlist *global_cmds, *custom_cmds, *config_cmds;
1790 MInputMethodInfo *temp;
1791 MPlist *tail, *plist;
1793 M17N_OBJECT_UNREF (im_info->configured_cmds);
1795 if (MPLIST_TAIL_P (im_info->cmds)
1799 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1800 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1801 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1803 im_info->configured_cmds = tail = mplist ();
1804 MPLIST_DO (plist, im_info->cmds)
1806 MPlist *pl = config_command (MPLIST_PLIST (plist),
1807 global_cmds, custom_cmds, config_cmds);
1810 tail = mplist_add (tail, Mplist, pl);
1811 M17N_OBJECT_UNREF (pl);
1816 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1817 valid, return 0 if not. */
1820 check_variable_value (MPlist *val, MPlist *global)
1822 MSymbol type = MPLIST_KEY (val);
1823 MPlist *valids = MPLIST_NEXT (val);
1825 if (type != Minteger && type != Mtext && type != Msymbol)
1829 if (MPLIST_KEY (global) != Mt
1830 && MPLIST_KEY (global) != MPLIST_KEY (val))
1832 if (MPLIST_TAIL_P (valids))
1833 valids = MPLIST_NEXT (global);
1835 if (MPLIST_TAIL_P (valids))
1838 if (type == Minteger)
1840 int n = MPLIST_INTEGER (val);
1842 MPLIST_DO (valids, valids)
1844 if (MPLIST_INTEGER_P (valids))
1846 if (n == MPLIST_INTEGER (valids))
1849 else if (MPLIST_PLIST_P (valids))
1851 MPlist *p = MPLIST_PLIST (valids);
1852 int min_bound, max_bound;
1854 if (! MPLIST_INTEGER_P (p))
1855 MERROR (MERROR_IM, 0);
1856 min_bound = MPLIST_INTEGER (p);
1857 p = MPLIST_NEXT (p);
1858 if (! MPLIST_INTEGER_P (p))
1859 MERROR (MERROR_IM, 0);
1860 max_bound = MPLIST_INTEGER (p);
1861 if (n >= min_bound && n <= max_bound)
1866 else if (type == Msymbol)
1868 MSymbol sym = MPLIST_SYMBOL (val);
1870 MPLIST_DO (valids, valids)
1872 if (! MPLIST_SYMBOL_P (valids))
1873 MERROR (MERROR_IM, 0);
1874 if (sym == MPLIST_SYMBOL (valids))
1880 MText *mt = MPLIST_MTEXT (val);
1882 MPLIST_DO (valids, valids)
1884 if (! MPLIST_MTEXT_P (valids))
1885 MERROR (MERROR_IM, 0);
1886 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1891 return (MPLIST_TAIL_P (valids));
1894 /* Load variable defitions from PLIST into IM_INFO->vars.
1896 PLIST is well-formed and has this form;
1897 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1899 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1901 The returned list has the same form, but for each element...
1903 (1) If DESCRIPTION and the rest are omitted, the element is not
1904 stored in the returned list.
1906 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1907 description in global_info->vars (if any). */
1910 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1912 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1913 ? global_info->vars : NULL);
1916 im_info->vars = tail = mplist ();
1917 MPLIST_DO (plist, MPLIST_NEXT (plist))
1921 if (MFAILP (MPLIST_PLIST_P (plist)))
1923 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1924 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1926 if (im_info == global_info)
1928 /* Loading a global variable. */
1929 p = MPLIST_NEXT (pl);
1930 if (MPLIST_TAIL_P (p))
1931 mplist_add (p, Msymbol, Mnil);
1934 if (! check_description (p))
1935 mplist_set (p, Msymbol, Mnil);
1936 p = MPLIST_NEXT (p);
1937 if (MFAILP (! MPLIST_TAIL_P (p)
1938 && check_variable_value (p, NULL)))
1939 mplist_set (p, Mt, NULL);
1942 else if (im_info->mdb)
1944 /* Loading a local variable. */
1945 MSymbol name = MPLIST_SYMBOL (pl);
1946 MPlist *global = NULL;
1949 && (p = mplist__assq (global_vars, name)))
1951 /* P ::= ((NAME DESC ...) ...) */
1952 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1953 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1954 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1957 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1958 if (! MPLIST_TAIL_P (p))
1960 if (! check_description (p))
1961 mplist_set (p, Msymbol, Mnil);
1962 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1963 if (MFAILP (! MPLIST_TAIL_P (p)))
1964 mplist_set (p, Mt, NULL);
1967 MPlist *valid_values = MPLIST_NEXT (p);
1969 if (! MPLIST_TAIL_P (valid_values)
1970 ? MFAILP (check_variable_value (p, NULL))
1971 : global && MFAILP (check_variable_value (p, global)))
1972 mplist_set (p, Mt, NULL);
1978 /* Loading a variable customization. */
1979 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1980 if (MFAILP (! MPLIST_TAIL_P (p)))
1982 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1983 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1984 || MPLIST_MTEXT_P (p)))
1987 tail = mplist_add (tail, Mplist, pl);
1992 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
1993 MPlist *config_vars)
1995 MPlist *global = NULL, *custom = NULL, *config = NULL;
1996 MSymbol name = MPLIST_SYMBOL (plist);
1998 MPlist *description = NULL, *value, *valids;
2002 global = mplist__assq (global_vars, name);
2004 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2007 plist = MPLIST_NEXT (plist);
2008 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2009 description = plist;
2011 description = global;
2013 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2015 if (MPLIST_TAIL_P (plist))
2017 /* Inherit from global (if any). */
2021 if (MPLIST_KEY (value) == Mt)
2023 valids = MPLIST_NEXT (global);
2024 status = Minherited;
2036 value = plist = MPLIST_NEXT (plist);
2037 valids = MPLIST_NEXT (value);
2038 if (MPLIST_KEY (value) == Mt)
2040 if (! MPLIST_TAIL_P (valids))
2043 valids = MPLIST_NEXT (global);
2047 if (config_vars && (config = mplist__assq (config_vars, name)))
2049 config = MPLIST_NEXT (MPLIST_PLIST (config));
2050 if (! MPLIST_TAIL_P (config))
2052 value = MPLIST_NEXT (config);
2053 if (MFAILP (check_variable_value (value, global ? global : plist)))
2055 status = Mconfigured;
2058 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2060 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2061 if (! MPLIST_TAIL_P (custom))
2063 value = MPLIST_NEXT (custom);
2064 if (MFAILP (check_variable_value (value, global ? global : plist)))
2066 status = Mcustomized;
2071 mplist_add (plist, Msymbol, name);
2073 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2075 mplist_add (plist, Msymbol, Mnil);
2076 mplist_add (plist, Msymbol, status);
2078 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2080 mplist_add (plist, Mt, NULL);
2081 if (valids && ! MPLIST_TAIL_P (valids))
2082 mplist__conc (plist, valids);
2086 /* Return a configured variable definition list based on
2087 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2088 get it from global_info->vars. */
2091 config_all_variables (MInputMethodInfo *im_info)
2093 MPlist *global_vars, *custom_vars, *config_vars;
2094 MInputMethodInfo *temp;
2095 MPlist *tail, *plist;
2097 M17N_OBJECT_UNREF (im_info->configured_vars);
2099 if (MPLIST_TAIL_P (im_info->vars)
2103 global_vars = im_info != global_info ? global_info->vars : NULL;
2104 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2105 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2107 im_info->configured_vars = tail = mplist ();
2108 MPLIST_DO (plist, im_info->vars)
2110 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2111 global_vars, custom_vars, config_vars);
2114 tail = mplist_add (tail, Mplist, pl);
2115 M17N_OBJECT_UNREF (pl);
2120 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2121 CONFIG contains configuration information of the input method. */
2124 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2128 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2130 load_commands (im_info, MPLIST_PLIST (pl));
2131 config_all_commands (im_info);
2132 pl = mplist_pop (pl);
2133 M17N_OBJECT_UNREF (pl);
2136 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2138 load_variables (im_info, MPLIST_PLIST (pl));
2139 config_all_variables (im_info);
2140 pl = mplist_pop (pl);
2141 M17N_OBJECT_UNREF (pl);
2144 MPLIST_DO (plist, plist)
2145 if (MPLIST_PLIST_P (plist))
2147 MPlist *elt = MPLIST_PLIST (plist);
2150 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2152 key = MPLIST_SYMBOL (elt);
2157 elt = MPLIST_NEXT (elt);
2158 if (MFAILP (MPLIST_MTEXT_P (elt)))
2160 im_info->title = MPLIST_MTEXT (elt);
2161 M17N_OBJECT_REF (im_info->title);
2163 else if (key == Mmap)
2165 pl = mplist__from_alist (MPLIST_NEXT (elt));
2168 if (! im_info->maps)
2172 mplist__conc (im_info->maps, pl);
2173 M17N_OBJECT_UNREF (pl);
2176 else if (key == Mmacro)
2178 if (! im_info->macros)
2179 im_info->macros = mplist ();
2180 MPLIST_DO (elt, MPLIST_NEXT (elt))
2182 if (MFAILP (MPLIST_PLIST_P (elt)))
2184 load_macros (im_info, MPLIST_PLIST (elt));
2187 else if (key == Mmodule)
2189 if (! im_info->externals)
2190 im_info->externals = mplist ();
2191 MPLIST_DO (elt, MPLIST_NEXT (elt))
2193 if (MFAILP (MPLIST_PLIST_P (elt)))
2195 load_external_module (im_info, MPLIST_PLIST (elt));
2198 else if (key == Mstate)
2200 MPLIST_DO (elt, MPLIST_NEXT (elt))
2204 if (MFAILP (MPLIST_PLIST_P (elt)))
2206 pl = MPLIST_PLIST (elt);
2207 if (! im_info->states)
2208 im_info->states = mplist ();
2209 state = load_state (im_info, MPLIST_PLIST (elt));
2212 mplist_put (im_info->states, state->name, state);
2215 else if (key == Minclude)
2217 /* elt ::= include (tag1 tag2 ...) key item ... */
2219 MInputMethodInfo *temp;
2221 elt = MPLIST_NEXT (elt);
2222 if (MFAILP (MPLIST_PLIST_P (elt)))
2224 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2227 elt = MPLIST_NEXT (elt);
2228 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2230 key = MPLIST_SYMBOL (elt);
2231 elt = MPLIST_NEXT (elt);
2234 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2236 if (! im_info->maps)
2237 im_info->maps = mplist ();
2238 MPLIST_DO (pl, temp->maps)
2240 p = MPLIST_VAL (pl);
2241 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2242 M17N_OBJECT_REF (p);
2245 else if (key == Mmacro)
2247 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2249 if (! im_info->macros)
2250 im_info->macros = mplist ();
2251 MPLIST_DO (pl, temp->macros)
2253 p = MPLIST_VAL (pl);
2254 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2255 M17N_OBJECT_REF (p);
2258 else if (key == Mstate)
2260 if (! temp->states || MPLIST_TAIL_P (temp->states))
2262 if (! im_info->states)
2263 im_info->states = mplist ();
2264 MPLIST_DO (pl, temp->states)
2266 MIMState *state = MPLIST_VAL (pl);
2268 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2269 M17N_OBJECT_REF (state);
2273 else if (key == Mdescription)
2275 if (im_info->description)
2277 elt = MPLIST_NEXT (elt);
2278 if (! check_description (elt))
2280 im_info->description = MPLIST_MTEXT (elt);
2281 M17N_OBJECT_REF (im_info->description);
2284 im_info->tick = time (NULL);
2289 static int take_action_list (MInputContext *ic, MPlist *action_list);
2290 static void preedit_commit (MInputContext *ic);
2293 shift_state (MInputContext *ic, MSymbol state_name)
2295 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2296 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2297 MIMState *orig_state = ic_info->state, *state;
2299 /* Find a state to shift to. If not found, shift to the initial
2301 if (state_name == Mt)
2303 if (! ic_info->prev_state)
2305 state = ic_info->prev_state;
2307 else if (state_name == Mnil)
2309 state = (MIMState *) MPLIST_VAL (im_info->states);
2313 state = (MIMState *) mplist_get (im_info->states, state_name);
2315 state = (MIMState *) MPLIST_VAL (im_info->states);
2318 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2320 /* Enter the new state. */
2321 ic_info->state = state;
2322 ic_info->map = state->map;
2323 ic_info->state_key_head = ic_info->key_head;
2324 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2326 /* We have shifted to the initial state. */
2327 preedit_commit (ic);
2328 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2329 ic_info->state_pos = ic->cursor_pos;
2330 if (state != orig_state)
2332 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2334 /* Shifted to the initial state. */
2335 ic_info->prev_state = NULL;
2336 M17N_OBJECT_UNREF (ic_info->vars_saved);
2337 ic_info->vars_saved = mplist_copy (ic_info->vars);
2340 ic_info->prev_state = orig_state;
2343 ic->status = state->title;
2345 ic->status = im_info->title;
2346 ic->status_changed = 1;
2347 if (ic_info->map == ic_info->state->map
2348 && ic_info->map->map_actions)
2350 MDEBUG_PRINT (" init-actions:");
2351 take_action_list (ic, ic_info->map->map_actions);
2356 /* Find a candidate group that contains a candidate number INDEX from
2357 PLIST. Set START_INDEX to the first candidate number of the group,
2358 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2359 candidate group number if they are non-NULL. If INDEX is -1, find
2360 the last candidate group. */
2363 find_candidates_group (MPlist *plist, int index,
2364 int *start_index, int *end_index, int *group_index)
2366 int i = 0, gidx = 0, len;
2368 MPLIST_DO (plist, plist)
2370 if (MPLIST_MTEXT_P (plist))
2371 len = mtext_nchars (MPLIST_MTEXT (plist));
2373 len = mplist_length (MPLIST_PLIST (plist));
2374 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2380 *end_index = i + len;
2382 *group_index = gidx;
2392 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2394 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2396 int nchars = mt ? mtext_nchars (mt) : 1;
2399 mtext_ins (ic->preedit, pos, mt);
2401 mtext_ins_char (ic->preedit, pos, c, 1);
2402 MPLIST_DO (markers, ic_info->markers)
2403 if (MPLIST_INTEGER (markers) > pos)
2404 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
2405 if (ic->cursor_pos >= pos)
2406 ic->cursor_pos += nchars;
2407 ic->preedit_changed = 1;
2412 preedit_delete (MInputContext *ic, int from, int to)
2414 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2417 mtext_del (ic->preedit, from, to);
2418 MPLIST_DO (markers, ic_info->markers)
2420 if (MPLIST_INTEGER (markers) > to)
2421 MPLIST_VAL (markers)
2422 = (void *) (MPLIST_INTEGER (markers) - (to - from));
2423 else if (MPLIST_INTEGER (markers) > from);
2424 MPLIST_VAL (markers) = (void *) from;
2426 if (ic->cursor_pos >= to)
2427 ic->cursor_pos -= to - from;
2428 else if (ic->cursor_pos > from)
2429 ic->cursor_pos = from;
2430 ic->preedit_changed = 1;
2434 preedit_commit (MInputContext *ic)
2436 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2437 int preedit_len = mtext_nchars (ic->preedit);
2439 if (preedit_len > 0)
2443 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2444 Mcandidate_list, NULL, 0);
2445 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2446 Mcandidate_index, NULL, 0);
2447 mtext_cat (ic->produced, ic->preedit);
2448 mtext_reset (ic->preedit);
2449 mtext_reset (ic_info->preedit_saved);
2450 MPLIST_DO (p, ic_info->markers)
2452 ic->cursor_pos = ic_info->state_pos = 0;
2453 ic->preedit_changed = 1;
2455 if (ic->candidate_list)
2457 M17N_OBJECT_UNREF (ic->candidate_list);
2458 ic->candidate_list = NULL;
2459 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2460 if (ic->candidate_show)
2462 ic->candidate_show = 0;
2463 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2469 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2471 int code = marker_code (sym, 0);
2473 if (mt && (code == '[' || code == ']'))
2477 if (code == '[' && current > 0)
2479 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2483 else if (code == ']' && current < mtext_nchars (mt))
2485 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2491 return (code == '<' ? 0
2492 : code == '>' ? limit
2493 : code == '-' ? current - 1
2494 : code == '+' ? current + 1
2495 : code == '=' ? current
2496 : code - '0' > limit ? limit
2500 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2504 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2506 int from = mtext_property_start (prop);
2507 int to = mtext_property_end (prop);
2509 MPlist *candidate_list = mtext_property_value (prop);
2510 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2512 int ingroup_index = idx - start;
2515 preedit_delete (ic, from, to);
2516 if (MPLIST_MTEXT_P (group))
2518 mt = MPLIST_MTEXT (group);
2519 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
2527 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2528 i++, plist = MPLIST_NEXT (plist));
2529 mt = MPLIST_MTEXT (plist);
2530 preedit_insert (ic, from, mt, 0);
2531 to = from + mtext_nchars (mt);
2533 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2534 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2535 ic->cursor_pos = to;
2539 get_select_charset (MInputContextInfo * ic_info)
2541 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2544 if (! MPLIST_VAL (plist))
2546 sym = MPLIST_SYMBOL (plist);
2549 return MCHARSET (sym);
2553 adjust_candidates (MPlist *plist, MCharset *charset)
2557 /* plist ::= MTEXT ... | PLIST ... */
2558 plist = mplist_copy (plist);
2559 if (MPLIST_MTEXT_P (plist))
2562 while (! MPLIST_TAIL_P (pl))
2564 /* pl ::= MTEXT ... */
2565 MText *mt = MPLIST_MTEXT (pl);
2569 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2571 c = mtext_ref_char (mt, i);
2572 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2576 mt = mtext_dup (mt);
2577 mplist_set (pl, Mtext, mt);
2578 M17N_OBJECT_UNREF (mt);
2581 mtext_del (mt, i, i + 1);
2584 if (mtext_len (mt) > 0)
2585 pl = MPLIST_NEXT (pl);
2589 M17N_OBJECT_UNREF (mt);
2593 else /* MPLIST_PLIST_P (plist) */
2596 while (! MPLIST_TAIL_P (pl))
2598 /* pl ::= (MTEXT ...) ... */
2599 MPlist *p = MPLIST_PLIST (pl);
2601 /* p ::= MTEXT ... */
2605 while (! MPLIST_TAIL_P (p0))
2607 MText *mt = MPLIST_MTEXT (p0);
2610 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2612 c = mtext_ref_char (mt, i);
2613 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2618 p0 = MPLIST_NEXT (p0);
2625 p = mplist_copy (p);
2626 mplist_set (pl, Mplist, p);
2627 M17N_OBJECT_UNREF (p);
2631 p0 = MPLIST_NEXT (p0);
2634 M17N_OBJECT_UNREF (mt);
2637 if (! MPLIST_TAIL_P (p))
2638 pl = MPLIST_NEXT (pl);
2642 M17N_OBJECT_UNREF (p);
2646 if (MPLIST_TAIL_P (plist))
2648 M17N_OBJECT_UNREF (plist);
2655 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2657 MCharset *charset = get_select_charset (ic_info);
2662 plist = resolve_variable (ic_info, Mcandidates_group_size);
2663 column = MPLIST_INTEGER (plist);
2665 plist = MPLIST_PLIST (args);
2667 plist = adjust_candidates (plist, charset);
2669 if (plist && column > 0)
2671 if (MPLIST_MTEXT_P (plist))
2673 MText *mt = MPLIST_MTEXT (plist);
2674 MPlist *next = MPLIST_NEXT (plist);
2676 if (MPLIST_TAIL_P (next))
2677 M17N_OBJECT_REF (mt);
2680 mt = mtext_dup (mt);
2681 while (! MPLIST_TAIL_P (next))
2683 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2684 next = MPLIST_NEXT (next);
2687 M17N_OBJECT_UNREF (plist);
2689 len = mtext_nchars (mt);
2691 mplist_add (plist, Mtext, mt);
2694 for (i = 0; i < len; i += column)
2696 int to = (i + column < len ? i + column : len);
2697 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2699 mplist_add (plist, Mtext, sub);
2700 M17N_OBJECT_UNREF (sub);
2703 M17N_OBJECT_UNREF (mt);
2705 else /* MPLIST_PLIST_P (plist) */
2707 MPlist *pl = MPLIST_PLIST (plist), *p;
2708 MPlist *next = MPLIST_NEXT (plist);
2711 if (MPLIST_TAIL_P (next))
2712 M17N_OBJECT_REF (pl);
2715 pl = mplist_copy (pl);
2716 while (! MPLIST_TAIL_P (next))
2718 p = mplist_copy (MPLIST_PLIST (next));
2719 pl = mplist__conc (pl, p);
2720 M17N_OBJECT_UNREF (p);
2721 next = MPLIST_NEXT (next);
2724 M17N_OBJECT_UNREF (plist);
2726 len = mplist_length (pl);
2728 mplist_add (plist, Mplist, pl);
2733 for (i = 0; i < len; i += column)
2736 mplist_add (plist, Mplist, p);
2737 M17N_OBJECT_UNREF (p);
2738 for (j = 0; j < column && i + j < len; j++)
2740 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
2741 p0 = MPLIST_NEXT (p0);
2745 M17N_OBJECT_UNREF (pl);
2754 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2756 MPlist *action = NULL;
2760 if (MPLIST_SYMBOL_P (action_list))
2762 MSymbol var = MPLIST_SYMBOL (action_list);
2765 MPLIST_DO (p, ic_info->vars)
2766 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2768 if (MPLIST_TAIL_P (p))
2770 action = MPLIST_NEXT (MPLIST_PLIST (p));
2771 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2774 if (MPLIST_PLIST_P (action_list))
2776 action = MPLIST_PLIST (action_list);
2777 if (MPLIST_SYMBOL_P (action))
2779 name = MPLIST_SYMBOL (action);
2780 args = MPLIST_NEXT (action);
2782 && MPLIST_PLIST_P (args))
2783 mplist_set (action, Msymbol, M_candidates);
2785 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2788 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2789 mplist_push (action, Msymbol, M_candidates);
2790 mplist_set (action_list, Mplist, action);
2791 M17N_OBJECT_UNREF (action);
2794 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2797 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2798 mplist_push (action, Msymbol, Minsert);
2799 mplist_set (action_list, Mplist, action);
2800 M17N_OBJECT_UNREF (action);
2805 /* Perform list of actions in ACTION_LIST for the current input
2806 context IC. If all actions are performed without error, return 0.
2807 Otherwise, return -1. */
2810 take_action_list (MInputContext *ic, MPlist *action_list)
2812 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2813 MPlist *candidate_list = ic->candidate_list;
2814 int candidate_index = ic->candidate_index;
2815 int candidate_show = ic->candidate_show;
2816 MTextProperty *prop;
2818 MPLIST_DO (action_list, action_list)
2820 MPlist *action = regularize_action (action_list, ic_info);
2826 name = MPLIST_SYMBOL (action);
2827 args = MPLIST_NEXT (action);
2829 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2830 if (name == Minsert)
2832 if (MPLIST_SYMBOL_P (args))
2834 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2835 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2838 if (MPLIST_MTEXT_P (args))
2839 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2840 else /* MPLIST_INTEGER_P (args)) */
2841 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2843 else if (name == M_candidates)
2845 MPlist *plist = get_candidate_list (ic_info, args);
2850 if (MPLIST_MTEXT_P (plist))
2852 preedit_insert (ic, ic->cursor_pos, NULL,
2853 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2858 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2860 preedit_insert (ic, ic->cursor_pos, mt, 0);
2861 len = mtext_nchars (mt);
2863 mtext_put_prop (ic->preedit,
2864 ic->cursor_pos - len, ic->cursor_pos,
2865 Mcandidate_list, plist);
2866 mtext_put_prop (ic->preedit,
2867 ic->cursor_pos - len, ic->cursor_pos,
2868 Mcandidate_index, (void *) 0);
2870 else if (name == Mselect)
2873 int code, idx, gindex;
2874 int pos = ic->cursor_pos;
2878 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2881 if (MPLIST_SYMBOL_P (args))
2883 code = marker_code (MPLIST_SYMBOL (args), 0);
2889 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2890 group = find_candidates_group (mtext_property_value (prop), idx,
2891 &start, &end, &gindex);
2893 if (code != '[' && code != ']')
2897 ? new_index (NULL, ic->candidate_index - start,
2898 end - start - 1, MPLIST_SYMBOL (args),
2900 : MPLIST_INTEGER (args)));
2903 find_candidates_group (mtext_property_value (prop), -1,
2908 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2913 int ingroup_index = idx - start;
2916 group = mtext_property_value (prop);
2917 len = mplist_length (group);
2930 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2931 idx += (MPLIST_MTEXT_P (group)
2932 ? mtext_nchars (MPLIST_MTEXT (group))
2933 : mplist_length (MPLIST_PLIST (group)));
2934 len = (MPLIST_MTEXT_P (group)
2935 ? mtext_nchars (MPLIST_MTEXT (group))
2936 : mplist_length (MPLIST_PLIST (group)));
2937 if (ingroup_index >= len)
2938 ingroup_index = len - 1;
2939 idx += ingroup_index;
2941 update_candidate (ic, prop, idx);
2943 else if (name == Mshow)
2944 ic->candidate_show = 1;
2945 else if (name == Mhide)
2946 ic->candidate_show = 0;
2947 else if (name == Mdelete)
2949 int len = mtext_nchars (ic->preedit);
2953 if (MPLIST_SYMBOL_P (args)
2954 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
2956 delete_surrounding_text (ic, pos);
2960 to = (MPLIST_SYMBOL_P (args)
2961 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2963 : MPLIST_INTEGER (args));
2968 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
2969 if (to < ic->cursor_pos)
2970 preedit_delete (ic, to, ic->cursor_pos);
2971 else if (to > ic->cursor_pos)
2972 preedit_delete (ic, ic->cursor_pos, to);
2975 else if (name == Mmove)
2977 int len = mtext_nchars (ic->preedit);
2979 = (MPLIST_SYMBOL_P (args)
2980 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2982 : MPLIST_INTEGER (args));
2988 if (pos != ic->cursor_pos)
2990 ic->cursor_pos = pos;
2991 ic->preedit_changed = 1;
2994 else if (name == Mmark)
2996 int code = marker_code (MPLIST_SYMBOL (args), 0);
2999 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3000 (void *) ic->cursor_pos);
3002 else if (name == Mpushback)
3004 if (MPLIST_INTEGER_P (args))
3006 int num = MPLIST_INTEGER (args);
3009 ic_info->key_head -= num;
3011 ic_info->key_head = num;
3012 if (ic_info->key_head > ic_info->used)
3013 ic_info->key_head = ic_info->used;
3015 else if (MPLIST_MTEXT_P (args))
3017 MText *mt = MPLIST_MTEXT (args);
3018 int i, len = mtext_nchars (mt);
3021 ic_info->key_head--;
3022 for (i = 0; i < len; i++)
3024 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3025 if (ic_info->key_head + i < ic_info->used)
3026 ic_info->keys[ic_info->key_head + i] = key;
3028 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3033 MPlist *plist = MPLIST_PLIST (args), *pl;
3037 ic_info->key_head--;
3039 MPLIST_DO (pl, plist)
3041 key = MPLIST_SYMBOL (pl);
3042 if (ic_info->key_head < ic_info->used)
3043 ic_info->keys[ic_info->key_head + i] = key;
3045 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3050 else if (name == Mcall)
3052 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3053 MIMExternalFunc func = NULL;
3054 MSymbol module, func_name;
3055 MPlist *func_args, *val;
3058 module = MPLIST_SYMBOL (args);
3059 args = MPLIST_NEXT (args);
3060 func_name = MPLIST_SYMBOL (args);
3062 if (im_info->externals)
3064 MIMExternalModule *external
3065 = (MIMExternalModule *) mplist_get (im_info->externals,
3068 func = (MIMExternalFunc) mplist_get (external->func_list,
3073 func_args = mplist ();
3074 mplist_add (func_args, Mt, ic);
3075 MPLIST_DO (args, MPLIST_NEXT (args))
3079 if (MPLIST_KEY (args) == Msymbol
3080 && MPLIST_KEY (args) != Mnil
3081 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3083 code = new_index (ic, ic->cursor_pos,
3084 mtext_nchars (ic->preedit),
3085 MPLIST_SYMBOL (args), ic->preedit);
3086 mplist_add (func_args, Minteger, (void *) code);
3089 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3091 val = (func) (func_args);
3092 M17N_OBJECT_UNREF (func_args);
3093 if (val && ! MPLIST_TAIL_P (val))
3094 ret = take_action_list (ic, val);
3095 M17N_OBJECT_UNREF (val);
3099 else if (name == Mshift)
3101 shift_state (ic, MPLIST_SYMBOL (args));
3103 else if (name == Mundo)
3105 int intarg = (MPLIST_TAIL_P (args)
3107 : integer_value (ic, args, NULL, 0));
3109 mtext_reset (ic->preedit);
3110 mtext_reset (ic_info->preedit_saved);
3111 mtext_reset (ic->produced);
3112 M17N_OBJECT_UNREF (ic_info->vars);
3113 ic_info->vars = mplist_copy (ic_info->vars_saved);
3114 ic->cursor_pos = ic_info->state_pos = 0;
3115 ic_info->state_key_head = ic_info->key_head = 0;
3117 shift_state (ic, Mnil);
3120 if (MPLIST_TAIL_P (args))
3125 ic_info->used += intarg;
3128 ic_info->used = intarg;
3131 else if (name == Mset || name == Madd || name == Msub
3132 || name == Mmul || name == Mdiv)
3134 MSymbol sym = MPLIST_SYMBOL (args);
3139 val1 = integer_value (ic, args, &value, 0);
3140 args = MPLIST_NEXT (args);
3141 val2 = resolve_expression (ic, args);
3143 val1 = val2, op = "=";
3144 else if (name == Madd)
3145 val1 += val2, op = "+=";
3146 else if (name == Msub)
3147 val1 -= val2, op = "-=";
3148 else if (name == Mmul)
3149 val1 *= val2, op = "*=";
3151 val1 /= val2, op = "/=";
3152 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3153 MSYMBOL_NAME (sym), op, val1, val1);
3155 mplist_set (value, Minteger, (void *) val1);
3157 else if (name == Mequal || name == Mless || name == Mgreater
3158 || name == Mless_equal || name == Mgreater_equal)
3161 MPlist *actions1, *actions2;
3164 val1 = resolve_expression (ic, args);
3165 args = MPLIST_NEXT (args);
3166 val2 = resolve_expression (ic, args);
3167 args = MPLIST_NEXT (args);
3168 actions1 = MPLIST_PLIST (args);
3169 args = MPLIST_NEXT (args);
3170 if (MPLIST_TAIL_P (args))
3173 actions2 = MPLIST_PLIST (args);
3174 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3175 if (name == Mequal ? val1 == val2
3176 : name == Mless ? val1 < val2
3177 : name == Mgreater ? val1 > val2
3178 : name == Mless_equal ? val1 <= val2
3181 MDEBUG_PRINT ("ok");
3182 ret = take_action_list (ic, actions1);
3186 MDEBUG_PRINT ("no");
3188 ret = take_action_list (ic, actions2);
3193 else if (name == Mcond)
3197 MPLIST_DO (args, args)
3202 if (! MPLIST_PLIST (args))
3204 cond = MPLIST_PLIST (args);
3205 if (resolve_expression (ic, cond) != 0)
3207 MDEBUG_PRINT1 ("(%dth)", idx);
3208 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3214 else if (name == Mcommit)
3216 preedit_commit (ic);
3218 else if (name == Munhandle)
3220 preedit_commit (ic);
3225 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3229 && (actions = mplist_get (im_info->macros, name)))
3231 if (take_action_list (ic, actions) < 0)
3237 if (ic->candidate_list)
3239 M17N_OBJECT_UNREF (ic->candidate_list);
3240 ic->candidate_list = NULL;
3242 if (ic->cursor_pos > 0
3243 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3246 ic->candidate_list = mtext_property_value (prop);
3247 M17N_OBJECT_REF (ic->candidate_list);
3249 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3251 ic->candidate_from = mtext_property_start (prop);
3252 ic->candidate_to = mtext_property_end (prop);
3255 if (candidate_list != ic->candidate_list)
3256 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3257 if (candidate_index != ic->candidate_index)
3258 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3259 if (candidate_show != ic->candidate_show)
3260 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3265 /* Handle the input key KEY in the current state and map specified in
3266 the input context IC. If KEY is handled correctly, return 0.
3267 Otherwise, return -1. */
3270 handle_key (MInputContext *ic)
3272 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3273 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3274 MIMMap *map = ic_info->map;
3275 MIMMap *submap = NULL;
3276 MSymbol key = ic_info->keys[ic_info->key_head];
3277 MSymbol alias = Mnil;
3280 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3281 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3285 submap = mplist_get (map->submaps, key);
3288 && (alias = msymbol_get (alias, M_key_alias))
3290 submap = mplist_get (map->submaps, alias);
3295 if (! alias || alias == key)
3296 MDEBUG_PRINT (" submap-found");
3298 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3299 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3300 ic->preedit_changed = 1;
3301 ic->cursor_pos = ic_info->state_pos;
3302 ic_info->key_head++;
3303 ic_info->map = map = submap;
3304 if (map->map_actions)
3306 MDEBUG_PRINT (" map-actions:");
3307 if (take_action_list (ic, map->map_actions) < 0)
3309 MDEBUG_PRINT ("\n");
3313 else if (map->submaps)
3315 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3317 MSymbol key = ic_info->keys[i];
3318 char *name = msymbol_name (key);
3320 if (! name[0] || ! name[1])
3321 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3325 /* If this is the terminal map or we have shifted to another
3326 state, perform branch actions (if any). */
3327 if (! map->submaps || map != ic_info->map)
3329 if (map->branch_actions)
3331 MDEBUG_PRINT (" branch-actions:");
3332 if (take_action_list (ic, map->branch_actions) < 0)
3334 MDEBUG_PRINT ("\n");
3338 /* If MAP is still not the root map, shift to the current
3340 if (ic_info->map != ic_info->state->map)
3341 shift_state (ic, ic_info->state->name);
3346 /* MAP can not handle KEY. */
3348 /* If MAP is the root map of the initial state, it means that
3349 the current input method can not handle KEY. */
3350 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3352 MDEBUG_PRINT (" unhandled\n");
3356 if (map != ic_info->state->map)
3358 /* If MAP is not the root map... */
3359 /* If MAP has branch actions, perform them. */
3360 if (map->branch_actions)
3362 MDEBUG_PRINT (" branch-actions:");
3363 if (take_action_list (ic, map->branch_actions) < 0)
3365 MDEBUG_PRINT ("\n");
3369 /* If MAP is still not the root map, shift to the current
3371 if (ic_info->map != ic_info->state->map)
3372 shift_state (ic, ic_info->state->name);
3376 /* MAP is the root map, perform branch actions (if any) or
3377 shift to the initial state. */
3378 if (map->branch_actions)
3380 MDEBUG_PRINT (" branch-actions:");
3381 if (take_action_list (ic, map->branch_actions) < 0)
3383 MDEBUG_PRINT ("\n");
3388 shift_state (ic, Mnil);
3391 MDEBUG_PRINT ("\n");
3395 /* Initialize IC->ic_info. */
3398 init_ic_info (MInputContext *ic)
3400 MInputMethodInfo *im_info = ic->im->info;
3401 MInputContextInfo *ic_info = ic->info;
3404 MLIST_INIT1 (ic_info, keys, 8);;
3406 ic_info->markers = mplist ();
3408 ic_info->vars = mplist ();
3409 if (im_info->configured_vars)
3410 MPLIST_DO (plist, im_info->configured_vars)
3412 MPlist *pl = MPLIST_PLIST (plist);
3413 MSymbol name = MPLIST_SYMBOL (pl);
3415 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3416 if (MPLIST_KEY (pl) != Mt)
3418 MPlist *p = mplist ();
3420 mplist_push (ic_info->vars, Mplist, p);
3421 M17N_OBJECT_UNREF (p);
3422 mplist_add (p, Msymbol, name);
3423 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3426 ic_info->vars_saved = mplist_copy (ic_info->vars);
3428 if (im_info->externals)
3430 MPlist *func_args = mplist (), *plist;
3432 mplist_add (func_args, Mt, ic);
3433 MPLIST_DO (plist, im_info->externals)
3435 MIMExternalModule *external = MPLIST_VAL (plist);
3436 MIMExternalFunc func
3437 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3442 M17N_OBJECT_UNREF (func_args);
3445 ic_info->preedit_saved = mtext ();
3446 ic_info->tick = im_info->tick;
3449 /* Finalize IC->ic_info. */
3452 fini_ic_info (MInputContext *ic)
3454 MInputMethodInfo *im_info = ic->im->info;
3455 MInputContextInfo *ic_info = ic->info;
3457 if (im_info->externals)
3459 MPlist *func_args = mplist (), *plist;
3461 mplist_add (func_args, Mt, ic);
3462 MPLIST_DO (plist, im_info->externals)
3464 MIMExternalModule *external = MPLIST_VAL (plist);
3465 MIMExternalFunc func
3466 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3471 M17N_OBJECT_UNREF (func_args);
3474 MLIST_FREE1 (ic_info, keys);
3475 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3476 M17N_OBJECT_UNREF (ic_info->markers);
3477 M17N_OBJECT_UNREF (ic_info->vars);
3478 M17N_OBJECT_UNREF (ic_info->vars_saved);
3479 M17N_OBJECT_UNREF (ic_info->preceding_text);
3480 M17N_OBJECT_UNREF (ic_info->following_text);
3482 memset (ic_info, 0, sizeof (MInputContextInfo));
3486 re_init_ic (MInputContext *ic, int reload)
3488 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3489 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3490 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3492 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3493 preedit_changed = mtext_nchars (ic->preedit) > 0;
3494 cursor_pos_changed = ic->cursor_pos > 0;
3495 candidates_changed = 0;
3496 if (ic->candidate_list)
3498 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3499 M17N_OBJECT_UNREF (ic->candidate_list);
3500 ic->candidate_list = NULL;
3502 if (ic->candidate_show)
3504 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3505 ic->candidate_show = 0;
3507 if (ic->candidate_index > 0)
3509 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3510 ic->candidate_index = 0;
3511 ic->candidate_from = ic->candidate_to = 0;
3513 if (mtext_nchars (ic->produced) > 0)
3514 mtext_reset (ic->produced);
3515 if (mtext_nchars (ic->preedit) > 0)
3516 mtext_reset (ic->preedit);
3518 M17N_OBJECT_UNREF (ic->plist);
3519 ic->plist = mplist ();
3523 reload_im_info (im_info);
3525 shift_state (ic, Mnil);
3526 ic->status_changed = status_changed;
3527 ic->preedit_changed = preedit_changed;
3528 ic->cursor_pos_changed = cursor_pos_changed;
3529 ic->candidates_changed = candidates_changed;
3533 reset_ic (MInputContext *ic, MSymbol ignore)
3535 MDEBUG_PRINT ("\n [IM] reset\n");
3540 open_im (MInputMethod *im)
3542 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3545 MERROR (MERROR_IM, -1);
3552 close_im (MInputMethod *im)
3558 create_ic (MInputContext *ic)
3560 MInputContextInfo *ic_info;
3562 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3565 shift_state (ic, Mnil);
3570 destroy_ic (MInputContext *ic)
3577 check_reload (MInputContext *ic, MSymbol key)
3579 MInputMethodInfo *im_info = ic->im->info;
3580 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3584 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3588 MPLIST_DO (plist, plist)
3590 MSymbol this_key, alias;
3592 if (MPLIST_MTEXT_P (plist))
3594 MText *mt = MPLIST_MTEXT (plist);
3595 int c = mtext_ref_char (mt, 0);
3599 this_key = one_char_symbol[c];
3603 MPlist *pl = MPLIST_PLIST (plist);
3605 this_key = MPLIST_SYMBOL (pl);
3609 && (alias = msymbol_get (alias, M_key_alias))
3610 && alias != this_key);
3614 if (MPLIST_TAIL_P (plist))
3617 MDEBUG_PRINT ("\n [IM] reload");
3623 /** Handle the input key KEY in the current state and map of IC->info.
3624 If KEY is handled but no text is produced, return 0, otherwise
3630 filter (MInputContext *ic, MSymbol key, void *arg)
3632 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3633 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3636 if (check_reload (ic, key))
3639 if (! ic_info->state)
3641 ic_info->key_unhandled = 1;
3644 mtext_reset (ic->produced);
3645 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3646 M17N_OBJECT_UNREF (ic_info->preceding_text);
3647 M17N_OBJECT_UNREF (ic_info->following_text);
3648 ic_info->preceding_text = ic_info->following_text = NULL;
3649 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3650 ic_info->key_unhandled = 0;
3653 if (handle_key (ic) < 0)
3655 /* KEY was not handled. Delete it from the current key sequence. */
3656 if (ic_info->used > 0)
3658 memmove (ic_info->keys, ic_info->keys + 1,
3659 sizeof (int) * (ic_info->used - 1));
3661 if (ic_info->state_key_head > 0)
3662 ic_info->state_key_head--;
3664 /* This forces returning 1. */
3665 ic_info->key_unhandled = 1;
3671 reset_ic (ic, Mnil);
3672 ic_info->key_unhandled = 1;
3675 /* Break the loop if all keys were handled. */
3676 } while (ic_info->key_head < ic_info->used);
3678 /* If the current map is the root of the initial state, we should
3679 produce any preedit text in ic->produced. */
3680 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3681 preedit_commit (ic);
3683 if (mtext_nchars (ic->produced) > 0)
3685 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3687 if (mdebug__flag & mdebug_mask)
3689 MDEBUG_PRINT (" (produced");
3690 for (i = 0; i < mtext_nchars (ic->produced); i++)
3691 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3696 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3697 Mlanguage, ic->im->language);
3698 if (ic_info->state_key_head > 0)
3700 memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head,
3701 sizeof (int) * (ic_info->used - ic_info->state_key_head));
3702 ic_info->used -= ic_info->state_key_head;
3703 ic_info->key_head -= ic_info->state_key_head;
3704 ic_info->state_key_head = 0;
3708 if (ic_info->key_unhandled)
3711 ic_info->key_head = ic_info->state_key_head = 0;
3714 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3718 /** Return 1 if the last event or key was not handled, otherwise
3721 There is no need of looking up because ic->produced should already
3722 contain the produced text (if any).
3727 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3729 mtext_cat (mt, ic->produced);
3730 mtext_reset (ic->produced);
3731 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3735 /* Input method command handler. */
3737 /* List of all (global and local) commands.
3738 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3739 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3740 Global commands are stored as (t (t COMMAND ...)) */
3743 /* Input method variable handler. */
3746 /* Support functions for mdebug_dump_im. */
3749 dump_im_map (MPlist *map_list, int indent)
3752 MSymbol key = MPLIST_KEY (map_list);
3753 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3755 prefix = (char *) alloca (indent + 1);
3756 memset (prefix, 32, indent);
3757 prefix[indent] = '\0';
3759 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3760 if (map->map_actions)
3761 mdebug_dump_plist (map->map_actions, indent + 2);
3764 MPLIST_DO (map_list, map->submaps)
3766 fprintf (stderr, "\n%s ", prefix);
3767 dump_im_map (map_list, indent + 2);
3770 if (map->branch_actions)
3772 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3773 mdebug_dump_plist (map->branch_actions, indent + 4);
3774 fprintf (stderr, ")");
3776 fprintf (stderr, ")");
3781 dump_im_state (MIMState *state, int indent)
3786 prefix = (char *) alloca (indent + 1);
3787 memset (prefix, 32, indent);
3788 prefix[indent] = '\0';
3790 fprintf (stderr, "(%s", msymbol_name (state->name));
3791 if (state->map->submaps)
3793 MPLIST_DO (map_list, state->map->submaps)
3795 fprintf (stderr, "\n%s ", prefix);
3796 dump_im_map (map_list, indent + 2);
3799 fprintf (stderr, ")");
3807 Minput_driver = msymbol ("input-driver");
3809 Minput_preedit_start = msymbol ("input-preedit-start");
3810 Minput_preedit_done = msymbol ("input-preedit-done");
3811 Minput_preedit_draw = msymbol ("input-preedit-draw");
3812 Minput_status_start = msymbol ("input-status-start");
3813 Minput_status_done = msymbol ("input-status-done");
3814 Minput_status_draw = msymbol ("input-status-draw");
3815 Minput_candidates_start = msymbol ("input-candidates-start");
3816 Minput_candidates_done = msymbol ("input-candidates-done");
3817 Minput_candidates_draw = msymbol ("input-candidates-draw");
3818 Minput_set_spot = msymbol ("input-set-spot");
3819 Minput_focus_move = msymbol ("input-focus-move");
3820 Minput_focus_in = msymbol ("input-focus-in");
3821 Minput_focus_out = msymbol ("input-focus-out");
3822 Minput_toggle = msymbol ("input-toggle");
3823 Minput_reset = msymbol ("input-reset");
3824 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3825 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3826 Mcustomized = msymbol ("customized");
3827 Mconfigured = msymbol ("configured");
3828 Minherited = msymbol ("inherited");
3830 minput_default_driver.open_im = open_im;
3831 minput_default_driver.close_im = close_im;
3832 minput_default_driver.create_ic = create_ic;
3833 minput_default_driver.destroy_ic = destroy_ic;
3834 minput_default_driver.filter = filter;
3835 minput_default_driver.lookup = lookup;
3836 minput_default_driver.callback_list = mplist ();
3837 mplist_put (minput_default_driver.callback_list, Minput_reset,
3839 minput_driver = &minput_default_driver;
3841 fully_initialized = 0;
3848 if (fully_initialized)
3850 free_im_list (im_info_list);
3852 free_im_list (im_custom_list);
3854 free_im_list (im_config_list);
3855 M17N_OBJECT_UNREF (load_im_info_keys);
3858 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3859 M17N_OBJECT_UNREF (minput_driver->callback_list);
3864 minput__callback (MInputContext *ic, MSymbol command)
3866 MInputCallbackFunc func;
3868 if (! ic->im->driver.callback_list)
3870 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3874 (func) (ic, command);
3879 minput__char_to_key (int c)
3881 if (c < 0 || c >= 0x100)
3884 return one_char_symbol[c];
3888 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3893 /*** @addtogroup m17nInputMethod */
3898 @name Variables: Predefined symbols for callback commands.
3900 These are the predefined symbols that are used as the @c COMMAND
3901 argument of callback functions of an input method driver (see
3902 #MInputDriver::callback_list).
3904 Most of them do not require extra argument nor return any value;
3905 exceptions are these:
3907 Minput_get_surrounding_text: When a callback function assigned for
3908 this command is called, the first element of #MInputContext::plist
3909 has key #Minteger and the value specifies which portion of the
3910 surrounding text should be retrieved. If the value is positive,
3911 it specifies the number of characters following the current cursor
3912 position. If the value is negative, the absolute value specifies
3913 the number of characters preceding the current cursor position.
3915 If the surrounding text is currently supported, the callback
3916 function must set the key of this element to #Mtext and the value
3917 to the retrieved M-text. The length of the M-text may be shorter
3918 than the requested number of characters, if the available text is
3919 not that long. The length can be zero in the worst case. Or, the
3920 length may be longer if an application thinks it is more efficient
3921 to return that length.
3923 If the surrounding text is not currently supported, the callback
3924 function should return without changing the first element of
3925 #MInputContext::plist.
3927 Minput_delete_surrounding_text: When a callback function assigned
3928 for this command is called, the first element of
3929 #MInputContext::plist has key #Minteger and the value specifies
3930 which portion of the surrounding text should be deleted in the
3931 same way as the case of Minput_get_surrounding_text. The callback
3932 function must delete the specified text. It should not alter
3933 #MInputContext::plist. */
3935 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3937 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3938 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3940 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
3942 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
3943 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
3944 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
3945 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
3946 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
3949 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
3950 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
3951 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
3952 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
3953 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
3955 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
3956 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѲ½¤µ¤»¤ë¤³¤È¤Ê¤¯ÊÖ¤µ¤Ê¤¯¤Æ
3959 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
3960 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
3961 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
3962 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
3963 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
3964 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
3968 MSymbol Minput_preedit_start;
3969 MSymbol Minput_preedit_done;
3970 MSymbol Minput_preedit_draw;
3971 MSymbol Minput_status_start;
3972 MSymbol Minput_status_done;
3973 MSymbol Minput_status_draw;
3974 MSymbol Minput_candidates_start;
3975 MSymbol Minput_candidates_done;
3976 MSymbol Minput_candidates_draw;
3977 MSymbol Minput_set_spot;
3978 MSymbol Minput_toggle;
3979 MSymbol Minput_reset;
3980 MSymbol Minput_get_surrounding_text;
3981 MSymbol Minput_delete_surrounding_text;
3987 @name Variables: Predefined symbols for special input events.
3989 These are the predefined symbols that are used as the @c KEY
3990 argument of minput_filter (). */
3992 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3994 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
3999 MSymbol Minput_focus_out;
4000 MSymbol Minput_focus_in;
4001 MSymbol Minput_focus_move;
4007 @name Variables: Predefined symbols used in input method information.
4009 These are the predefined symbols describing status of input method
4010 command and variable, and are used in a return value of
4011 minput_get_command () and minput_get_variable (). */
4013 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4015 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4016 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4020 MSymbol Mcustomized;
4021 MSymbol Mconfigured;
4027 @brief The default driver for internal input methods.
4029 The variable #minput_default_driver is the default driver for
4030 internal input methods.
4032 The member MInputDriver::open_im () searches the m17n database for
4033 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4034 $NAME\> and loads it.
4036 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4037 programmers responsibility to set it to a plist of proper callback
4038 functions. Otherwise, no feedback information (e.g. preedit text)
4039 can be shown to users.
4041 The macro M17N_INIT () sets the variable #minput_driver to the
4042 pointer to this driver so that all internal input methods use it.
4044 Therefore, unless @c minput_driver is set differently, the driver
4045 dependent arguments $ARG of the functions whose name begins with
4046 "minput_" are all ignored. */
4048 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4050 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4052 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4053 \< #Minput_method, $LANGUAGE, $NAME\>
4054 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4056 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4057 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4058 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4059 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4061 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4062 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4064 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4065 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4067 MInputDriver minput_default_driver;
4071 @brief The driver for internal input methods.
4073 The variable #minput_driver is a pointer to the input method
4074 driver that is used by internal input methods. The macro
4075 M17N_INIT () initializes it to a pointer to #minput_default_driver
4076 if <m17n<EM></EM>.h> is included. */
4078 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4080 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4081 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4082 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4083 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4085 MInputDriver *minput_driver;
4087 MSymbol Minput_driver;
4102 @brief Open an input method.
4104 The minput_open_im () function opens an input method whose
4105 language and name match $LANGUAGE and $NAME, and returns a pointer
4106 to the input method object newly allocated.
4108 This function at first decides a driver for the input method as
4111 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4112 #minput_driver is used.
4114 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4115 driver pointed to by the property value is used to open the input
4116 method. If $NAME has no such a property, @c NULL is returned.
4118 Then, the member MInputDriver::open_im () of the driver is
4121 $ARG is set in the member @c arg of the structure MInputMethod so
4122 that the driver can refer to it. */
4124 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4126 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4127 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4129 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4131 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4132 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4134 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4135 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4136 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4138 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4140 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4142 @latexonly \IPAlabel{minput_open} @endlatexonly
4147 minput_open_im (MSymbol language, MSymbol name, void *arg)
4150 MInputDriver *driver;
4154 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4155 msymbol_name (language), msymbol_name (name));
4157 driver = minput_driver;
4160 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4162 MERROR (MERROR_IM, NULL);
4165 MSTRUCT_CALLOC (im, MERROR_IM);
4166 im->language = language;
4169 im->driver = *driver;
4170 if ((*im->driver.open_im) (im) < 0)
4172 MDEBUG_PRINT (" failed\n");
4176 MDEBUG_PRINT (" ok\n");
4183 @brief Close an input method.
4185 The minput_close_im () function closes the input method $IM, which
4186 must have been created by minput_open_im (). */
4189 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4191 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4192 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4195 minput_close_im (MInputMethod *im)
4197 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4198 msymbol_name (im->name), msymbol_name (im->language));
4199 (*im->driver.close_im) (im);
4201 MDEBUG_PRINT (" done\n");
4207 @brief Create an input context.
4209 The minput_create_ic () function creates an input context object
4210 associated with input method $IM, and calls callback functions
4211 corresponding to #Minput_preedit_start, #Minput_status_start, and
4212 #Minput_status_draw in this order.
4215 If an input context is successfully created, minput_create_ic ()
4216 returns a pointer to it. Otherwise it returns @c NULL. */
4219 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4221 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4222 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4223 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4224 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4227 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4228 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4232 minput_create_ic (MInputMethod *im, void *arg)
4236 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4237 msymbol_name (im->name), msymbol_name (im->language));
4238 MSTRUCT_CALLOC (ic, MERROR_IM);
4241 ic->preedit = mtext ();
4242 ic->candidate_list = NULL;
4243 ic->produced = mtext ();
4244 ic->spot.x = ic->spot.y = 0;
4246 ic->plist = mplist ();
4247 if ((*im->driver.create_ic) (ic) < 0)
4249 MDEBUG_PRINT (" failed\n");
4250 M17N_OBJECT_UNREF (ic->preedit);
4251 M17N_OBJECT_UNREF (ic->produced);
4252 M17N_OBJECT_UNREF (ic->plist);
4257 if (im->driver.callback_list)
4259 minput__callback (ic, Minput_preedit_start);
4260 minput__callback (ic, Minput_status_start);
4261 minput__callback (ic, Minput_status_draw);
4264 MDEBUG_PRINT (" ok\n");
4271 @brief Destroy an input context.
4273 The minput_destroy_ic () function destroys the input context $IC,
4274 which must have been created by minput_create_ic (). It calls
4275 callback functions corresponding to #Minput_preedit_done,
4276 #Minput_status_done, and #Minput_candidates_done in this order. */
4279 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4281 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4282 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4283 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4284 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4285 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4289 minput_destroy_ic (MInputContext *ic)
4291 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4292 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4293 if (ic->im->driver.callback_list)
4295 minput__callback (ic, Minput_preedit_done);
4296 minput__callback (ic, Minput_status_done);
4297 minput__callback (ic, Minput_candidates_done);
4299 (*ic->im->driver.destroy_ic) (ic);
4300 M17N_OBJECT_UNREF (ic->preedit);
4301 M17N_OBJECT_UNREF (ic->produced);
4302 M17N_OBJECT_UNREF (ic->plist);
4303 MDEBUG_PRINT (" done\n");
4310 @brief Filter an input key.
4312 The minput_filter () function filters input key $KEY according to
4313 input context $IC, and calls callback functions corresponding to
4314 #Minput_preedit_draw, #Minput_status_draw, and
4315 #Minput_candidates_draw if the preedit text, the status, and the
4316 current candidate are changed respectively.
4318 To make the input method commit the current preedit text (if any)
4319 and shift to the initial state, call this function with #Mnil as
4322 To inform the input method about the focus-out event, call this
4323 function with #Minput_focus_out as $KEY.
4325 To inform the input method about the focus-in event, call this
4326 function with #Minput_focus_in as $KEY.
4328 To inform the input method about the focus-move event (i.e. input
4329 spot change within the same input context), call this function
4330 with #Minput_focus_move as $KEY.
4333 If $KEY is filtered out, this function returns 1. In that case,
4334 the caller should discard the key. Otherwise, it returns 0, and
4335 the caller should handle the key, for instance, by calling the
4336 function minput_lookup () with the same key. */
4339 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4341 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4342 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4343 #Minput_preedit_draw, #Minput_status_draw,
4344 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4347 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4348 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4349 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4350 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4352 @latexonly \IPAlabel{minput_filter} @endlatexonly
4356 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4363 ret = (*ic->im->driver.filter) (ic, key, arg);
4365 if (ic->im->driver.callback_list)
4367 if (ic->preedit_changed)
4368 minput__callback (ic, Minput_preedit_draw);
4369 if (ic->status_changed)
4370 minput__callback (ic, Minput_status_draw);
4371 if (ic->candidates_changed)
4372 minput__callback (ic, Minput_candidates_draw);
4381 @brief Look up a text produced in the input context.
4383 The minput_lookup () function looks up a text in the input context
4384 $IC. $KEY must be identical to the one that was used in the previous call of
4387 If a text was produced by the input method, it is concatenated
4390 This function calls #MInputDriver::lookup .
4393 If $KEY was correctly handled by the input method, this function
4394 returns 0. Otherwise, it returns -1, even though some text
4395 might be produced in $MT. */
4398 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4400 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4401 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4403 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4406 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4409 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4410 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4411 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4413 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4416 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4418 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4423 @brief Set the spot of the input context.
4425 The minput_set_spot () function sets the spot of input context $IC
4426 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4427 The semantics of these values depends on the input method driver.
4429 For instance, a driver designed to work in a CUI environment may
4430 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4431 $DESCENT . A driver designed to work in a window system may
4432 interpret $X and $Y as the pixel offsets relative to the origin of the
4433 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4434 descent pixels of the line at ($X . $Y ).
4436 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4438 $MT and $POS are the M-text and the character position at the spot.
4439 $MT may be @c NULL, in which case, the input method cannot get
4440 information about the text around the spot. */
4443 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4445 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4446 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4447 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4449 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4450 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4451 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4452 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4453 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4454 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4456 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4458 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4459 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4463 minput_set_spot (MInputContext *ic, int x, int y,
4464 int ascent, int descent, int fontsize,
4469 ic->spot.ascent = ascent;
4470 ic->spot.descent = descent;
4471 ic->spot.fontsize = fontsize;
4474 if (ic->im->driver.callback_list)
4475 minput__callback (ic, Minput_set_spot);
4480 @brief Toggle input method.
4482 The minput_toggle () function toggles the input method associated
4483 with input context $IC. */
4485 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4487 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4488 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4492 minput_toggle (MInputContext *ic)
4494 if (ic->im->driver.callback_list)
4495 minput__callback (ic, Minput_toggle);
4496 ic->active = ! ic->active;
4502 @brief Reset an input context.
4504 The minput_reset_ic () function resets input context $IC by
4505 calling a callback function corresponding to #Minput_reset. It
4506 resets the status of $IC to its initial one. As the
4507 current preedit text is deleted without commitment, if necessary,
4508 call minput_filter () with the arg @r key #Mnil to force the input
4509 method to commit the preedit in advance. */
4512 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4514 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4515 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4516 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4517 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4518 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4519 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4522 minput_reset_ic (MInputContext *ic)
4524 if (ic->im->driver.callback_list)
4525 minput__callback (ic, Minput_reset);
4531 @brief Get title and icon filename of an input method.
4533 The minput_get_title_icon () function returns a plist containing a
4534 title and icon filename (if any) of an input method specified by
4535 $LANGUAGE and $NAME.
4537 The first element of the plist has key #Mtext and the value is an
4538 M-text of the title for identifying the input method. The second
4539 element (if any) has key #Mtext and the value is an M-text of the
4540 icon image (absolute) filename for the same purpose.
4543 If there exists a specified input method and it defines an title,
4544 a plist is returned. Otherwise, NULL is returned. The caller
4545 must free the plist by m17n_object_unref (). */
4547 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4549 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4550 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4553 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4554 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4555 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¤ÎÀäÂÐ¥Õ¥¡¥¤¥ë¥Í¡¼¥à¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4558 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4559 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4560 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4563 minput_get_title_icon (MSymbol language, MSymbol name)
4565 MInputMethodInfo *im_info;
4572 im_info = get_im_info (language, name, Mnil, Mtitle);
4573 if (! im_info || !im_info->title)
4575 mt = mtext_get_prop (im_info->title, 0, Mtext);
4577 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4580 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4583 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4584 (char *) MSYMBOL_NAME (name));
4585 file = mdatabase__find_file (buf);
4586 if (! file && language == Mt)
4588 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4589 file = mdatabase__find_file (buf);
4594 mplist_add (plist, Mtext, im_info->title);
4597 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4599 mplist_add (plist, Mtext, mt);
4600 M17N_OBJECT_UNREF (mt);
4608 @brief Get description text of an input method.
4610 The minput_get_description () function returns an M-text that
4611 describes the input method specified by $LANGUAGE and $NAME.
4614 If the specified input method has a description text, a pointer to
4615 #MText is returned. The caller has to free it by m17n_object_unref ().
4616 If the input method does not have a description text, @c NULL is
4619 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4621 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4622 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4624 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4625 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4626 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4627 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4630 minput_get_description (MSymbol language, MSymbol name)
4632 MInputMethodInfo *im_info;
4640 extra = language, language = Mt;
4642 im_info = get_im_info (language, name, extra, Mdescription);
4643 if (! im_info || ! im_info->description)
4645 M17N_OBJECT_REF (im_info->description);
4646 return im_info->description;
4652 @brief Get information about input method command(s).
4654 The minput_get_command () function returns information about
4655 the command $COMMAND of the input method specified by $LANGUAGE and
4656 $NAME. An input method command is a pseudo key event to which one
4657 or more actual input key sequences are assigned.
4659 There are two kinds of commands, global and local. A global
4660 command has a global definition, and the description and the key
4661 assignment may be inherited by a local command. Each input method
4662 defines a local command which has a local key assignment. It may
4663 also declare a local command that inherits the definition of a
4664 global command of the same name.
4666 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4667 information about a global command. Otherwise information about a
4668 local command is returned.
4670 If $COMMAND is #Mnil, information about all commands is returned.
4672 The return value is a @e well-formed plist (#m17nPlist) of this
4675 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4677 @c NAME is a symbol representing the command name.
4679 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4680 command has no description.
4682 @c STATUS is a symbol representing how the key assignment is decided.
4683 The value is #Mnil (the default key assignment), #Mcustomized (the
4684 key assignment is customized by per-user configuration file), or
4685 #Mconfigured (the key assignment is set by the call of
4686 minput_config_command ()). For a local command only, it may also
4687 be #Minherited (the key assignment is inherited from the
4688 corresponding global command).
4690 @c KEYSEQ is a plist of one or more symbols representing a key
4691 sequence assigned to the command. If there's no KEYSEQ, the
4692 command is currently disabled (i.e. no key sequence can trigger
4693 actions of the command).
4695 If $COMMAND is not #Mnil, the first element of the returned plist
4696 contains the information about $COMMAND.
4700 If the requested information was found, a pointer to a non-empty
4701 plist is returned. As the plist is kept in the library, the
4702 caller must not modify nor free it.
4704 Otherwise (the specified input method or the specified command
4705 does not exist), @c NULL is returned. */
4707 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4709 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4710 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4711 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4712 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4714 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4715 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4716 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4717 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4718 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4720 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4721 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4724 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4726 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4729 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4731 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4733 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4736 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4737 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4738 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4739 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4740 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4741 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4743 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4744 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4745 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4746 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4748 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4749 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4753 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4754 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4757 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4762 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4764 /* Return a description of the command COMMAND of the input method
4765 specified by LANGUAGE and NAME. */
4766 MPlist *cmd = minput_get_command (langauge, name, command);
4771 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4772 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4773 return (mplist_key (plist) == Mtext
4774 ? (MText *) mplist_value (plist)
4780 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4782 MInputMethodInfo *im_info;
4786 im_info = get_im_info (language, name, Mnil, Mcommand);
4788 || ! im_info->configured_cmds
4789 || MPLIST_TAIL_P (im_info->configured_cmds))
4791 if (command == Mnil)
4792 return im_info->configured_cmds;
4793 return mplist__assq (im_info->configured_cmds, command);
4799 @brief Configure the key sequence of an input method command.
4801 The minput_config_command () function assigns a list of key
4802 sequences $KEYSEQLIST to the command $COMMAND of the input method
4803 specified by $LANGUAGE and $NAME.
4805 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4806 sequences, and each key sequence must be a plist of symbols.
4808 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4810 If $KEYSEQLIST is NULL, the configuration of the command for the
4811 input method is canceled, and the default key sequences become
4812 effective. In such case, if $COMMAND is #Mnil, configurations for
4813 all commands of the input method are canceled.
4815 If $NAME is #Mnil, this function configures the key assignment of a
4816 global command, not that of a specific input method.
4818 The configuration takes effect for input methods opened or
4819 re-opened later in the current session. In order to make the
4820 configuration take effect for the future session, it must be saved
4821 in a per-user configuration file by the function
4822 minput_save_config ().
4826 If the operation was successful, this function returns 0,
4827 otherwise returns -1. The operation fails in these cases:
4829 <li>$KEYSEQLIST is not in a valid form.
4830 <li>$COMMAND is not available for the input method.
4831 <li>$LANGUAGE and $NAME do not specify an existing input method.
4835 minput_get_commands (), minput_save_config ().
4838 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4840 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4841 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4842 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4844 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4845 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4847 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4849 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4850 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4851 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4854 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4855 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4857 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4858 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4859 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4860 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4864 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4866 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4867 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4868 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4872 minput_get_commands (), minput_save_config ().
4876 /* Add "C-x u" to the "start" command of Unicode input method. */
4878 MSymbol start_command = msymbol ("start");
4879 MSymbol unicode = msymbol ("unicode");
4880 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4882 /* At first get the current key-sequence assignment. */
4883 cmd = mplist_get_command (Mt, unicode, start_command);
4886 /* The input method does not have the command "start". Here
4887 should come some error handling code. */
4889 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4890 the part (KEY-SEQUENCE ...). */
4891 plist = mplist_next (mplist_next (mplist_value (cmd)));
4892 /* Copy it because we should not modify it directly. */
4893 key_seq_list = mplist_copy (plist);
4894 m17n_object_unref (cmds);
4896 key_seq = mplist ();
4897 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4898 mplist_add (key_seq, Msymbol, msymbol ("u"));
4899 mplist_add (key_seq_list, Mplist, key_seq);
4900 m17n_object_unref (key_seq);
4902 minput_config_command (Mt, unicode, start_command, key_seq_list);
4903 m17n_object_unref (key_seq_list);
4908 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4911 MInputMethodInfo *im_info, *config;
4918 if (command == Mnil)
4919 MERROR (MERROR_IM, -1);
4920 MPLIST_DO (plist, keyseqlist)
4921 if (! MPLIST_PLIST_P (plist)
4922 || ! check_command_keyseq (plist))
4923 MERROR (MERROR_IM, -1);
4926 im_info = get_im_info (language, name, Mnil, Mcommand);
4928 MERROR (MERROR_IM, -1);
4931 || ! mplist__assq (im_info->cmds, command)))
4932 MERROR (MERROR_IM, -1);
4934 config = get_config_info (im_info);
4937 if (! im_config_list)
4938 im_config_list = mplist ();
4939 config = new_im_info (NULL, language, name, Mnil, im_config_list);
4940 config->cmds = mplist ();
4941 config->vars = mplist ();
4944 if (command == Mnil)
4946 MInputMethodInfo *custom = get_custom_info (im_info);
4948 mplist_set (config->cmds, Mnil, NULL);
4949 if (custom && custom->cmds)
4951 MPLIST_DO (plist, custom->cmds)
4953 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
4955 mplist_add (plist, Msymbol, command);
4956 mplist_push (config->cmds, Mplist, plist);
4957 M17N_OBJECT_UNREF (plist);
4963 plist = mplist__assq (config->cmds, command);
4966 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
4967 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
4968 if (! MPLIST_TAIL_P (plist))
4969 mplist_set (plist, Mnil, NULL); /* () */
4974 mplist_add (config->cmds, Mplist, plist);
4975 M17N_OBJECT_UNREF (plist);
4976 plist = mplist_add (plist, Msymbol, command);
4977 plist = MPLIST_NEXT (plist);
4983 plist = mplist_add (plist, Msymbol, Mnil);
4984 MPLIST_DO (keyseqlist, keyseqlist)
4986 pl = mplist_copy (MPLIST_VAL (keyseqlist));
4987 plist = mplist_add (plist, Mplist, pl);
4988 M17N_OBJECT_UNREF (pl);
4992 config_all_commands (im_info);
4993 im_info->tick = time (NULL);
5000 @brief Get information about input method variable(s).
5002 The minput_get_variable () function returns information about
5003 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5004 An input method variable controls behavior of an input method.
5006 There are two kinds of variables, global and local. A global
5007 variable has a global definition, and the description and the value
5008 may be inherited by a local variable. Each input method defines a
5009 local variable which has local value. It may also declare a
5010 local variable that inherits definition of a global variable of
5013 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5014 variable is returned. Otherwise information about a local variable
5017 If $VARIABLE is #Mnil, information about all variables is
5020 The return value is a @e well-formed plist (#m17nPlist) of this
5023 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5025 @c NAME is a symbol representing the variable name.
5027 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5028 variable has no description.
5030 @c STATUS is a symbol representing how the value is decided. The
5031 value is #Mnil (the default value), #Mcustomized (the value is
5032 customized by per-user configuration file), or #Mconfigured (the
5033 value is set by the call of minput_config_variable ()). For a
5034 local variable only, it may also be #Minherited (the value is
5035 inherited from the corresponding global variable).
5037 @c VALUE is the initial value of the variable. If the key of this
5038 element is #Mt, the variable has no initial value. Otherwise, the
5039 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5042 @c VALID-VALUEs (if any) specify which values the variable can have.
5043 They have the same type (i.e. having the same key) as @c VALUE except
5044 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5045 may be a plist of two integers specifying the range of possible
5048 If there no @c VALID-VALUE, the variable can have any value as long
5049 as the type is the same as @c VALUE.
5051 If $VARIABLE is not #Mnil, the first element of the returned plist
5052 contains the information about $VARIABLE.
5056 If the requested information was found, a pointer to a non-empty
5057 plist is returned. As the plist is kept in the library, the
5058 caller must not modify nor free it.
5060 Otherwise (the specified input method or the specified variable
5061 does not exist), @c NULL is returned. */
5063 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5065 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5066 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5067 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5069 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5070 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5071 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5072 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5075 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5076 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5078 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5080 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5082 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5085 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5087 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5090 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5091 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5092 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5093 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5094 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5095 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5097 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5098 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5099 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5101 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5102 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5103 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5104 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5106 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5109 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5110 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5114 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5115 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5118 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5122 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5124 MInputMethodInfo *im_info;
5128 im_info = get_im_info (language, name, Mnil, Mvariable);
5129 if (! im_info || ! im_info->configured_vars)
5131 if (variable == Mnil)
5132 return im_info->configured_vars;
5133 return mplist__assq (im_info->configured_vars, variable);
5139 @brief Configure the value of an input method variable.
5141 The minput_config_variable () function assigns $VALUE to the
5142 variable $VARIABLE of the input method specified by $LANGUAGE and
5145 If $VALUE is not NULL, it must be a plist of one element whose key
5146 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5149 If $VALUE is NULL, a configuration for the variable for the input
5150 method is canceled, and the variable is initialized to the default
5151 value. In that case, if $VARIABLE is #Mnil, configurations for
5152 all variables of the input method are canceled.
5154 If $NAME is #Mnil, this function configure the value of global
5155 variable, not that of a specific input method.
5157 The configuration takes effect for input methods opened or
5158 re-opened later in the current session. To make the configuration
5159 take effect for the future session, it must be saved in a per-user
5160 configuration file by the function minput_save_config ().
5164 If the operation was successful, this function returns 0,
5165 otherwise returns -1. The operation fails in these cases:
5167 <li>$VALUE is not in a valid form, the type does not match the
5168 definition, or the value is our of range.
5169 <li>$VARIABLE is not available for the input method.
5170 <li>$LANGUAGE and $NAME do not specify an existing input method.
5174 minput_get_variable (), minput_save_config (). */
5176 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5178 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5179 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5181 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5182 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5184 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5185 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5186 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5188 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5189 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5191 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5192 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5193 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5194 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5198 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5200 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5201 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5202 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5206 minput_get_commands (), minput_save_config ().
5209 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5212 MInputMethodInfo *im_info, *config;
5217 im_info = get_im_info (language, name, Mnil, Mvariable);
5219 MERROR (MERROR_IM, -1);
5220 if (variable == Mnil)
5223 MERROR (MERROR_IM, -1);
5225 else if (! im_info->vars
5226 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5227 MERROR (MERROR_IM, -1);
5229 if (variable != Mnil && value)
5231 plist = MPLIST_PLIST (plist);
5232 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5233 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5234 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5235 if (MPLIST_KEY (plist) != Mt
5236 && ! check_variable_value (value, plist))
5237 MERROR (MERROR_IM, -1);
5240 config = get_config_info (im_info);
5243 if (! im_config_list)
5244 im_config_list = mplist ();
5245 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5246 config->cmds = mplist ();
5247 config->vars = mplist ();
5250 if (variable == Mnil)
5252 MInputMethodInfo *custom = get_custom_info (im_info);
5254 mplist_set (config->vars, Mnil, NULL);
5255 if (custom && custom->cmds)
5257 MPLIST_DO (plist, custom->vars)
5259 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5261 mplist_add (plist, Msymbol, variable);
5262 mplist_push (config->vars, Mplist, plist);
5263 M17N_OBJECT_UNREF (plist);
5269 plist = mplist__assq (config->vars, variable);
5272 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5273 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5274 if (! MPLIST_TAIL_P (plist))
5275 mplist_set (plist, Mnil ,NULL); /* () */
5280 mplist_add (config->vars, Mplist, plist);
5281 M17N_OBJECT_UNREF (plist);
5282 plist = mplist_add (plist, Msymbol, variable);
5283 plist = MPLIST_NEXT (plist);
5287 plist = mplist_add (plist, Msymbol, Mnil);
5288 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5291 config_all_variables (im_info);
5292 im_info->tick = time (NULL);
5299 @brief Get the name of per-user configuration file.
5301 The minput_config_file () function returns the absolute path name
5302 of per-user configuration file into which minput_save_config ()
5303 save configurations. It is usually @c "config.mic" under the
5304 directory @c ".m17n.d" of user's home directory. It is not assured
5305 that the file of the returned name exists nor is
5306 readable/writable. If minput_save_config () fails and returns -1,
5307 an application program might check the file, make it
5308 writable (if possible), and try minput_save_config () again.
5312 This function returns a string. As the string is kept in the
5313 library, the caller must not modify nor free it.
5316 minput_save_config ()
5319 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5321 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5322 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5323 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5324 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5325 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5326 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5327 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5332 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5333 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5336 minput_save_config ()
5340 minput_config_file ()
5344 return mdatabase__file (im_custom_mdb);
5350 @brief Save configurations in per-user configuration file.
5352 The minput_save_config () function saves the configurations done
5353 so far in the current session into the per-user configuration
5358 If the operation was successful, 1 is returned. If the per-user
5359 configuration file is currently locked, 0 is returned. In that
5360 case, the caller may wait for a while and try again. If the
5361 configuration file is not writable, -1 is returned. In that case,
5362 the caller may check the name of the file by calling
5363 minput_config_file (), make it writable if possible, and try
5367 minput_config_file () */
5369 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5371 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5372 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5376 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5377 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5378 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5379 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5383 minput_config_file () */
5386 minput_save_config (void)
5388 MPlist *data, *tail, *plist, *p, *elt;
5392 ret = mdatabase__lock (im_custom_mdb);
5395 if (! im_config_list)
5397 update_custom_info ();
5398 if (! im_custom_list)
5399 im_custom_list = mplist ();
5400 data = tail = mplist ();
5402 MPLIST_DO (plist, im_config_list)
5404 MPlist *pl = MPLIST_PLIST (plist);
5405 MSymbol language, name, extra, command, variable;
5406 MInputMethodInfo *custom, *config;
5408 language = MPLIST_SYMBOL (pl);
5409 pl = MPLIST_NEXT (pl);
5410 name = MPLIST_SYMBOL (pl);
5411 pl = MPLIST_NEXT (pl);
5412 extra = MPLIST_SYMBOL (pl);
5413 pl = MPLIST_NEXT (pl);
5414 config = MPLIST_VAL (pl);
5415 custom = get_custom_info (config);
5417 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5419 MPLIST_DO (pl, config->cmds)
5421 elt = MPLIST_PLIST (pl);
5422 command = MPLIST_SYMBOL (elt);
5424 p = mplist__assq (custom->cmds, command);
5426 custom->cmds = mplist (), p = NULL;
5427 elt = MPLIST_NEXT (elt);
5428 if (MPLIST_TAIL_P (elt))
5431 mplist__pop_unref (p);
5435 elt = MPLIST_NEXT (elt);
5438 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5439 mplist_set (p, Mnil, NULL);
5440 mplist__conc (p, elt);
5444 p = MPLIST_PLIST (pl);
5445 mplist_add (custom->cmds, Mplist, p);
5450 MPLIST_DO (pl, config->vars)
5452 elt = MPLIST_PLIST (pl);
5453 variable = MPLIST_SYMBOL (elt);
5455 p = mplist__assq (custom->vars, variable);
5457 custom->vars = mplist (), p = NULL;
5458 elt = MPLIST_NEXT (elt);
5459 if (MPLIST_TAIL_P (elt))
5462 mplist__pop_unref (p);
5466 elt = MPLIST_NEXT (elt);
5469 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5470 mplist_set (p, Mnil, NULL);
5471 mplist__conc (p, elt);
5475 p = MPLIST_PLIST (pl);
5476 mplist_add (custom->vars, Mplist, p);
5481 M17N_OBJECT_UNREF (im_config_list);
5483 MPLIST_DO (plist, im_custom_list)
5485 MPlist *pl = MPLIST_PLIST (plist);
5486 MSymbol language, name, extra;
5487 MInputMethodInfo *custom, *im_info;
5489 language = MPLIST_SYMBOL (pl);
5490 pl = MPLIST_NEXT (pl);
5491 name = MPLIST_SYMBOL (pl);
5492 pl = MPLIST_NEXT (pl);
5493 extra = MPLIST_SYMBOL (pl);
5494 pl = MPLIST_NEXT (pl);
5495 custom = MPLIST_VAL (pl);
5496 im_info = lookup_im_info (im_info_list, language, name, extra);
5500 config_all_commands (im_info);
5502 config_all_variables (im_info);
5506 tail = mplist_add (tail, Mplist, elt);
5507 M17N_OBJECT_UNREF (elt);
5509 elt = mplist_add (elt, Mplist, pl);
5510 M17N_OBJECT_UNREF (pl);
5511 pl = mplist_add (pl, Msymbol, Minput_method);
5512 pl = mplist_add (pl, Msymbol, language);
5513 pl = mplist_add (pl, Msymbol, name);
5515 pl = mplist_add (pl, Msymbol, extra);
5516 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5519 elt = mplist_add (elt, Mplist, pl);
5520 M17N_OBJECT_UNREF (pl);
5521 pl = mplist_add (pl, Msymbol, Mcommand);
5522 MPLIST_DO (p, custom->cmds)
5523 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5525 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5528 elt = mplist_add (elt, Mplist, pl);
5529 M17N_OBJECT_UNREF (pl);
5530 pl = mplist_add (pl, Msymbol, Mvariable);
5531 MPLIST_DO (p, custom->vars)
5532 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5536 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5537 ret = mdatabase__save (im_custom_mdb, data);
5538 mdatabase__unlock (im_custom_mdb);
5539 M17N_OBJECT_UNREF (data);
5540 return (ret < 0 ? -1 : 1);
5547 @name Obsolete functions
5550 @name Obsolete ¤Ê´Ø¿ô
5556 @brief Get a list of variables of an input method (obsolete).
5558 This function is obsolete. Use minput_get_variable () instead.
5560 The minput_get_variables () function returns a plist (#MPlist) of
5561 variables used to control the behavior of the input method
5562 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5563 (#m17nPlist) of the following format:
5566 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5567 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5571 @c VARNAME is a symbol representing the variable name.
5573 @c DOC-MTEXT is an M-text describing the variable.
5575 @c DEFAULT-VALUE is the default value of the variable. It is a
5576 symbol, integer, or M-text.
5578 @c VALUEs (if any) specifies the possible values of the variable.
5579 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5580 @c TO), where @c FROM and @c TO specifies a range of possible
5583 For instance, suppose an input method has the variables:
5585 @li name:intvar, description:"value is an integer",
5586 initial value:0, value-range:0..3,10,20
5588 @li name:symvar, description:"value is a symbol",
5589 initial value:nil, value-range:a, b, c, nil
5591 @li name:txtvar, description:"value is an M-text",
5592 initial value:empty text, no value-range (i.e. any text)
5594 Then, the returned plist is as follows.
5597 (intvar ("value is an integer" 0 (0 3) 10 20)
5598 symvar ("value is a symbol" nil a b c nil)
5599 txtvar ("value is an M-text" ""))
5603 If the input method uses any variables, a pointer to #MPlist is
5604 returned. As the plist is kept in the library, the caller must not
5605 modify nor free it. If the input method does not use any
5606 variable, @c NULL is returned. */
5608 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5610 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5611 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5612 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5616 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5617 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5621 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5623 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5625 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5628 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5629 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5630 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5632 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5634 @li name:intvar, ÀâÌÀ:"value is an integer",
5635 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5637 @li name:symvar, ÀâÌÀ:"value is a symbol",
5638 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5640 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5641 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5643 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5646 (intvar ("value is an integer" 0 (0 3) 10 20)
5647 symvar ("value is a symbol" nil a b c nil)
5648 txtvar ("value is an M-text" ""))
5652 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5653 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5654 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5657 minput_get_variables (MSymbol language, MSymbol name)
5659 MInputMethodInfo *im_info;
5664 im_info = get_im_info (language, name, Mnil, Mvariable);
5665 if (! im_info || ! im_info->configured_vars)
5668 M17N_OBJECT_UNREF (im_info->bc_vars);
5669 im_info->bc_vars = mplist ();
5670 MPLIST_DO (vars, im_info->configured_vars)
5672 MPlist *plist = MPLIST_PLIST (vars);
5673 MPlist *elt = mplist ();
5675 mplist_push (im_info->bc_vars, Mplist, elt);
5676 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5677 elt = MPLIST_NEXT (elt);
5678 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5679 M17N_OBJECT_UNREF (elt);
5681 return im_info->bc_vars;
5687 @brief Set the initial value of an input method variable.
5689 The minput_set_variable () function sets the initial value of
5690 input method variable $VARIABLE to $VALUE for the input method
5691 specified by $LANGUAGE and $NAME.
5693 By default, the initial value is 0.
5695 This setting gets effective in a newly opened input method.
5698 If the operation was successful, 0 is returned. Otherwise -1 is
5699 returned, and #merror_code is set to #MERROR_IM. */
5701 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5703 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5704 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5705 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5707 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5709 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5712 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5713 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5716 minput_set_variable (MSymbol language, MSymbol name,
5717 MSymbol variable, void *value)
5720 MInputMethodInfo *im_info;
5725 if (variable == Mnil)
5726 MERROR (MERROR_IM, -1);
5727 plist = minput_get_variable (language, name, variable);
5728 plist = MPLIST_PLIST (plist);
5729 plist = MPLIST_NEXT (plist);
5731 mplist_add (pl, MPLIST_KEY (plist), value);
5732 ret = minput_config_variable (language, name, variable, pl);
5733 M17N_OBJECT_UNREF (pl);
5736 im_info = get_im_info (language, name, Mnil, Mvariable);
5745 @brief Get information about input method commands.
5747 The minput_get_commands () function returns information about
5748 input method commands of the input method specified by $LANGUAGE
5749 and $NAME. An input method command is a pseudo key event to which
5750 one or more actual input key sequences are assigned.
5752 There are two kinds of commands, global and local. Global
5753 commands are used by multiple input methods for the same purpose,
5754 and have global key assignments. Local commands are used only by
5755 a specific input method, and have only local key assignments.
5757 Each input method may locally change key assignments for global
5758 commands. The global key assignment for a global command is
5759 effective only when the current input method does not have local
5760 key assignments for that command.
5762 If $NAME is #Mnil, information about global commands is returned.
5763 In this case $LANGUAGE is ignored.
5765 If $NAME is not #Mnil, information about those commands that have
5766 local key assignments in the input method specified by $LANGUAGE
5767 and $NAME is returned.
5770 If no input method commands are found, this function returns @c NULL.
5772 Otherwise, a pointer to a plist is returned. The key of each
5773 element in the plist is a symbol representing a command, and the
5774 value is a plist of the form COMMAND-INFO described below.
5776 The first element of COMMAND-INFO has the key #Mtext, and the
5777 value is an M-text describing the command.
5779 If there are no more elements, that means no key sequences are
5780 assigned to the command. Otherwise, each of the remaining
5781 elements has the key #Mplist, and the value is a plist whose keys are
5782 #Msymbol and values are symbols representing input keys, which are
5783 currently assigned to the command.
5785 As the returned plist is kept in the library, the caller must not
5786 modify nor free it. */
5788 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5790 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5791 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5792 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5793 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5795 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5796 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5797 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5798 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5800 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5801 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5802 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5805 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5806 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5808 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5809 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5813 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5815 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5816 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5817 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5819 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5820 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5821 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5824 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5825 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5826 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5827 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5828 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5830 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5831 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5834 minput_get_commands (MSymbol language, MSymbol name)
5836 MInputMethodInfo *im_info;
5841 im_info = get_im_info (language, name, Mnil, Mcommand);
5842 if (! im_info || ! im_info->configured_vars)
5844 M17N_OBJECT_UNREF (im_info->bc_cmds);
5845 im_info->bc_cmds = mplist ();
5846 MPLIST_DO (cmds, im_info->configured_cmds)
5848 MPlist *plist = MPLIST_PLIST (cmds);
5849 MPlist *elt = mplist ();
5851 mplist_push (im_info->bc_cmds, Mplist, elt);
5852 mplist_add (elt, MPLIST_SYMBOL (plist),
5853 mplist_copy (MPLIST_NEXT (plist)));
5854 M17N_OBJECT_UNREF (elt);
5856 return im_info->bc_cmds;
5862 @brief Assign a key sequence to an input method command (obsolete).
5864 This function is obsolete. Use minput_config_command () instead.
5866 The minput_assign_command_keys () function assigns input key
5867 sequence $KEYSEQ to input method command $COMMAND for the input
5868 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5869 key sequence is assigned globally no matter what $LANGUAGE is.
5870 Otherwise the key sequence is assigned locally.
5872 Each element of $KEYSEQ must have the key $Msymbol and the value
5873 must be a symbol representing an input key.
5875 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5876 globally or locally.
5878 This assignment gets effective in a newly opened input method.
5881 If the operation was successful, 0 is returned. Otherwise -1 is
5882 returned, and #merror_code is set to #MERROR_IM. */
5884 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5886 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5887 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5888 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5889 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5890 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5892 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5893 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5895 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5896 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5898 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5901 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5902 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5905 minput_assign_command_keys (MSymbol language, MSymbol name,
5906 MSymbol command, MPlist *keyseq)
5912 if (command == Mnil)
5913 MERROR (MERROR_IM, -1);
5918 if (! check_command_keyseq (keyseq))
5919 MERROR (MERROR_IM, -1);
5921 mplist_add (plist, Mplist, keyseq);
5926 ret = minput_config_command (language, name, command, keyseq);
5927 M17N_OBJECT_UNREF (keyseq);
5934 /*** @addtogroup m17nDebug */
5940 @brief Dump an input method.
5942 The mdebug_dump_im () function prints the input method $IM in a
5943 human readable way to the stderr. $INDENT specifies how many
5944 columns to indent the lines but the first one.
5947 This function returns $IM. */
5949 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
5951 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
5952 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
5955 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
5958 mdebug_dump_im (MInputMethod *im, int indent)
5960 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
5963 prefix = (char *) alloca (indent + 1);
5964 memset (prefix, 32, indent);
5965 prefix[indent] = '\0';
5967 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
5968 msymbol_name (im->name));
5969 mdebug_dump_mtext (im_info->title, 0, 0);
5970 if (im->name != Mnil)
5974 MPLIST_DO (state, im_info->states)
5976 fprintf (stderr, "\n%s ", prefix);
5977 dump_im_state (MPLIST_VAL (state), indent + 2);
5980 fprintf (stderr, ")");