1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
156 #include "m17n-gui.h"
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_mask = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mundo = msymbol ("undo");
406 Mcall = msymbol ("call");
407 Mshift = msymbol ("shift");
408 Mselect = msymbol ("select");
409 Mshow = msymbol ("show");
410 Mhide = msymbol ("hide");
411 Mcommit = msymbol ("commit");
412 Munhandle = msymbol ("unhandle");
413 Mset = msymbol ("set");
414 Madd = msymbol ("add");
415 Msub = msymbol ("sub");
416 Mmul = msymbol ("mul");
417 Mdiv = msymbol ("div");
418 Mequal = msymbol ("=");
419 Mless = msymbol ("<");
420 Mgreater = msymbol (">");
421 Mless_equal = msymbol ("<=");
422 Mgreater_equal = msymbol (">=");
423 Mcond = msymbol ("cond");
424 Mplus = msymbol ("+");
425 Mminus = msymbol ("-");
426 Mstar = msymbol ("*");
427 Mslash = msymbol ("/");
428 Mand = msymbol ("&");
430 Mnot = msymbol ("!");
432 Mat_reload = msymbol ("@reload");
434 Mcandidates_group_size = msymbol ("candidates-group-size");
435 Mcandidates_charset = msymbol ("candidates-charset");
437 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
438 Mcandidate_index = msymbol (" candidate-index");
440 Minit = msymbol ("init");
441 Mfini = msymbol ("fini");
443 Mdescription = msymbol ("description");
444 Mcommand = msymbol ("command");
445 Mvariable = msymbol ("variable");
446 Mglobal = msymbol ("global");
447 Mconfig = msymbol ("config");
448 M_gettext = msymbol ("_");
450 load_im_info_keys = mplist ();
451 mplist_add (load_im_info_keys, Mstate, Mnil);
452 mplist_push (load_im_info_keys, Mmap, Mnil);
454 im_info_list = mplist ();
455 im_config_list = im_custom_list = NULL;
456 im_custom_mdb = NULL;
457 update_custom_info ();
459 update_global_info ();
461 fully_initialized = 1;
464 #define MINPUT__INIT() \
466 if (! fully_initialized) \
467 fully_initialize (); \
472 marker_code (MSymbol sym, int surrounding)
478 name = MSYMBOL_NAME (sym);
479 return (name[0] != '@' ? -1
480 : (((name[1] >= '0' && name[1] <= '9')
481 || name[1] == '<' || name[1] == '>' || name[1] == '='
482 || name[1] == '[' || name[1] == ']'
484 && name[2] == '\0') ? name[1]
485 : (name[1] != '+' && name[1] != '-') ? -1
486 : (name[2] == '\0' || surrounding) ? name[1]
492 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
494 MPlist *plist = mplist__assq (ic_info->vars, var);
498 plist = MPLIST_PLIST (plist);
499 return MPLIST_NEXT (plist);
503 mplist_push (ic_info->vars, Mplist, plist);
504 M17N_OBJECT_UNREF (plist);
505 plist = mplist_add (plist, Msymbol, var);
506 plist = mplist_add (plist, Minteger, (void *) 0);
511 get_surrounding_text (MInputContext *ic, int len)
515 mplist_push (ic->plist, Minteger, (void *) len);
516 if (minput__callback (ic, Minput_get_surrounding_text) >= 0
517 && MPLIST_MTEXT_P (ic->plist))
518 mt = MPLIST_MTEXT (ic->plist);
519 mplist_pop (ic->plist);
524 delete_surrounding_text (MInputContext *ic, int pos)
526 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
528 mplist_push (ic->plist, Minteger, (void *) pos);
529 minput__callback (ic, Minput_delete_surrounding_text);
530 mplist_pop (ic->plist);
533 M17N_OBJECT_UNREF (ic_info->preceding_text);
534 ic_info->preceding_text = NULL;
538 M17N_OBJECT_UNREF (ic_info->following_text);
539 ic_info->following_text = NULL;
544 get_preceding_char (MInputContext *ic, int pos)
546 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
550 if (pos && ic_info->preceding_text)
552 len = mtext_nchars (ic_info->preceding_text);
554 return mtext_ref_char (ic_info->preceding_text, len - pos);
556 mt = get_surrounding_text (ic, - pos);
559 len = mtext_nchars (mt);
560 if (ic_info->preceding_text)
562 if (mtext_nchars (ic_info->preceding_text) < len)
564 M17N_OBJECT_UNREF (ic_info->preceding_text);
565 ic_info->preceding_text = mt;
569 ic_info->preceding_text = mt;
572 return mtext_ref_char (ic_info->preceding_text, len - pos);
576 get_following_char (MInputContext *ic, int pos)
578 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
582 if (ic_info->following_text)
584 len = mtext_nchars (ic_info->following_text);
586 return mtext_ref_char (ic_info->following_text, pos - 1);
588 mt = get_surrounding_text (ic, pos);
591 len = mtext_nchars (mt);
592 if (ic_info->following_text)
594 if (mtext_nchars (ic_info->following_text) < len)
596 M17N_OBJECT_UNREF (ic_info->following_text);
597 ic_info->following_text = mt;
601 ic_info->following_text = mt;
604 return mtext_ref_char (ic_info->following_text, pos - 1);
608 surrounding_pos (MSymbol sym)
614 name = MSYMBOL_NAME (sym);
616 && (name[1] == '-' || name[1] == '+')
617 && name[2] >= '1' && name[2] <= '9')
618 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
623 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
625 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
627 MText *preedit = ic->preedit;
628 int len = mtext_nchars (preedit);
632 if (MPLIST_INTEGER_P (arg))
633 return MPLIST_INTEGER (arg);
635 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
638 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
642 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
645 return ic_info->key_head;
646 if ((code == '-' || code == '+'))
648 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
652 pos = atoi (name + 1);
654 return get_preceding_char (ic, 0);
655 pos = ic->cursor_pos + pos;
657 return get_preceding_char (ic, - pos);
659 return get_following_char (ic, pos - len + 1);
662 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
664 else if (code >= '0' && code <= '9')
666 else if (code == '=')
667 pos = ic->cursor_pos;
668 else if (code == '[')
669 pos = ic->cursor_pos - 1;
670 else if (code == ']')
671 pos = ic->cursor_pos + 1;
672 else if (code == '<')
674 else if (code == '>')
676 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
680 parse_expression (MPlist *plist)
684 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
686 if (! MPLIST_PLIST_P (plist))
688 plist = MPLIST_PLIST (plist);
689 op = MPLIST_SYMBOL (plist);
690 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
691 && op != Mand && op != Mor && op != Mnot
692 && op != Mless && op != Mgreater && op != Mequal
693 && op != Mless_equal && op != Mgreater_equal)
694 MERROR (MERROR_IM, -1);
695 MPLIST_DO (plist, MPLIST_NEXT (plist))
696 if (parse_expression (plist) < 0)
702 resolve_expression (MInputContext *ic, MPlist *plist)
707 if (MPLIST_INTEGER_P (plist))
708 return MPLIST_INTEGER (plist);
709 if (MPLIST_SYMBOL_P (plist))
710 return integer_value (ic, plist, NULL, 1);
711 if (! MPLIST_PLIST_P (plist))
713 plist = MPLIST_PLIST (plist);
714 if (! MPLIST_SYMBOL_P (plist))
716 op = MPLIST_SYMBOL (plist);
717 plist = MPLIST_NEXT (plist);
718 val = resolve_expression (ic, plist);
720 MPLIST_DO (plist, MPLIST_NEXT (plist))
721 val += resolve_expression (ic, plist);
722 else if (op == Mminus)
723 MPLIST_DO (plist, MPLIST_NEXT (plist))
724 val -= resolve_expression (ic, plist);
725 else if (op == Mstar)
726 MPLIST_DO (plist, MPLIST_NEXT (plist))
727 val *= resolve_expression (ic, plist);
728 else if (op == Mslash)
729 MPLIST_DO (plist, MPLIST_NEXT (plist))
730 val /= resolve_expression (ic, plist);
732 MPLIST_DO (plist, MPLIST_NEXT (plist))
733 val &= resolve_expression (ic, plist);
735 MPLIST_DO (plist, MPLIST_NEXT (plist))
736 val |= resolve_expression (ic, plist);
739 else if (op == Mless)
740 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
741 else if (op == Mequal)
742 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
743 else if (op == Mgreater)
744 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
745 else if (op == Mless_equal)
746 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
747 else if (op == Mgreater_equal)
748 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
752 /* Parse PLIST as an action list. PLIST should have this form:
753 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
754 Return 0 if successfully parsed, otherwise return -1. */
757 parse_action_list (MPlist *plist, MPlist *macros)
759 MPLIST_DO (plist, plist)
761 if (MPLIST_MTEXT_P (plist))
763 /* This is a short form of (insert MTEXT). */
764 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
765 MERROR (MERROR_IM, -1); */
767 else if (MPLIST_PLIST_P (plist)
768 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
769 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
773 /* This is a short form of (insert (GROUPS *)). */
774 MPLIST_DO (pl, MPLIST_PLIST (plist))
776 if (MPLIST_PLIST_P (pl))
780 MPLIST_DO (elt, MPLIST_PLIST (pl))
781 if (! MPLIST_MTEXT_P (elt)
782 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
783 MERROR (MERROR_IM, -1);
787 if (! MPLIST_MTEXT_P (pl)
788 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
789 MERROR (MERROR_IM, -1);
793 else if (MPLIST_INTEGER_P (plist))
795 int c = MPLIST_INTEGER (plist);
797 if (c < 0 || c > MCHAR_MAX)
798 MERROR (MERROR_IM, -1);
800 else if (MPLIST_PLIST_P (plist)
801 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
803 MPlist *pl = MPLIST_PLIST (plist);
804 MSymbol action_name = MPLIST_SYMBOL (pl);
806 pl = MPLIST_NEXT (pl);
808 if (action_name == Minsert)
810 if (MPLIST_MTEXT_P (pl))
812 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
813 MERROR (MERROR_IM, -1);
815 else if (MPLIST_PLIST_P (pl))
819 if (MPLIST_PLIST_P (pl))
823 MPLIST_DO (elt, MPLIST_PLIST (pl))
824 if (! MPLIST_MTEXT_P (elt)
825 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
826 MERROR (MERROR_IM, -1);
830 if (! MPLIST_MTEXT_P (pl)
831 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
832 MERROR (MERROR_IM, -1);
836 else if (! MPLIST_SYMBOL_P (pl))
837 MERROR (MERROR_IM, -1);
839 else if (action_name == Mselect
840 || action_name == Mdelete
841 || action_name == Mmove)
843 if (parse_expression (pl) < 0)
846 else if (action_name == Mmark
847 || action_name == Mcall
848 || action_name == Mshift)
850 if (! MPLIST_SYMBOL_P (pl))
851 MERROR (MERROR_IM, -1);
853 else if (action_name == Mundo)
855 if (! MPLIST_TAIL_P (pl))
857 if (! MPLIST_SYMBOL_P (pl)
858 && (! MPLIST_INTEGER_P (pl)
859 || MPLIST_INTEGER (pl) == 0))
860 MERROR (MERROR_IM, -1);
863 else if (action_name == Mpushback)
865 if (MPLIST_MTEXT_P (pl))
867 MText *mt = MPLIST_MTEXT (pl);
869 if (mtext_nchars (mt) != mtext_nbytes (mt))
870 MERROR (MERROR_IM, -1);
872 else if (MPLIST_PLIST_P (pl))
876 MPLIST_DO (p, MPLIST_PLIST (pl))
877 if (! MPLIST_SYMBOL_P (p))
878 MERROR (MERROR_IM, -1);
880 else if (! MPLIST_INTEGER_P (pl))
881 MERROR (MERROR_IM, -1);
883 else if (action_name == Mset || action_name == Madd
884 || action_name == Msub || action_name == Mmul
885 || action_name == Mdiv)
887 if (! MPLIST_SYMBOL_P (pl))
888 MERROR (MERROR_IM, -1);
889 if (parse_expression (MPLIST_NEXT (pl)) < 0)
892 else if (action_name == Mequal || action_name == Mless
893 || action_name == Mgreater || action_name == Mless_equal
894 || action_name == Mgreater_equal)
896 if (parse_expression (pl) < 0
897 || parse_expression (MPLIST_NEXT (pl)) < 0)
899 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
900 if (! MPLIST_PLIST_P (pl))
901 MERROR (MERROR_IM, -1);
902 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
903 MERROR (MERROR_IM, -1);
904 pl = MPLIST_NEXT (pl);
905 if (MPLIST_PLIST_P (pl)
906 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
907 MERROR (MERROR_IM, -1);
909 else if (action_name == Mshow || action_name == Mhide
910 || action_name == Mcommit || action_name == Munhandle)
912 else if (action_name == Mcond)
915 if (! MPLIST_PLIST_P (pl))
916 MERROR (MERROR_IM, -1);
918 else if (! macros || ! mplist_get (macros, action_name))
919 MERROR (MERROR_IM, -1);
921 else if (! MPLIST_SYMBOL_P (plist))
922 MERROR (MERROR_IM, -1);
929 resolve_command (MPlist *cmds, MSymbol command)
933 if (! cmds || ! (plist = mplist__assq (cmds, command)))
935 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
936 plist = MPLIST_NEXT (plist);
937 plist = MPLIST_NEXT (plist);
938 plist = MPLIST_NEXT (plist);
942 /* Load a translation into MAP from PLIST.
944 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
947 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
948 MPlist *branch_actions, MPlist *macros)
953 if (MPLIST_MTEXT_P (keylist))
955 MText *mt = MPLIST_MTEXT (keylist);
957 len = mtext_nchars (mt);
958 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
960 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
961 for (i = 0; i < len; i++)
962 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
968 if (MFAILP (MPLIST_PLIST_P (keylist)))
970 elt = MPLIST_PLIST (keylist);
971 len = MPLIST_LENGTH (elt);
972 if (MFAILP (len > 0))
974 keyseq = (MSymbol *) alloca (sizeof (int) * len);
975 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
977 if (MPLIST_INTEGER_P (elt))
979 int c = MPLIST_INTEGER (elt);
981 if (MFAILP (c >= 0 && c < 0x100))
983 keyseq[i] = one_char_symbol[c];
987 if (MFAILP (MPLIST_SYMBOL_P (elt)))
989 keyseq[i] = MPLIST_SYMBOL (elt);
994 for (i = 0; i < len; i++)
996 MIMMap *deeper = NULL;
999 deeper = mplist_get (map->submaps, keyseq[i]);
1001 map->submaps = mplist ();
1004 /* Fixme: It is better to make all deeper maps at once. */
1005 MSTRUCT_CALLOC (deeper, MERROR_IM);
1006 mplist_put (map->submaps, keyseq[i], deeper);
1011 /* We reach a terminal map. */
1012 if (map->map_actions
1013 || map->branch_actions)
1014 /* This map is already defined. We avoid overriding it. */
1017 if (! MPLIST_TAIL_P (map_actions))
1019 if (parse_action_list (map_actions, macros) < 0)
1020 MERROR (MERROR_IM, -1);
1021 map->map_actions = map_actions;
1025 map->branch_actions = branch_actions;
1026 M17N_OBJECT_REF (branch_actions);
1032 /* Load a branch from PLIST into MAP. PLIST has this form:
1033 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1036 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1039 MPlist *branch_actions;
1041 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1043 map_name = MPLIST_SYMBOL (plist);
1044 plist = MPLIST_NEXT (plist);
1045 if (MPLIST_TAIL_P (plist))
1046 branch_actions = NULL;
1047 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1050 branch_actions = plist;
1051 if (map_name == Mnil)
1053 map->branch_actions = branch_actions;
1055 M17N_OBJECT_REF (branch_actions);
1057 else if (map_name == Mt)
1059 map->map_actions = branch_actions;
1061 M17N_OBJECT_REF (branch_actions);
1063 else if (im_info->maps
1064 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1066 MPLIST_DO (plist, plist)
1068 MPlist *keylist, *map_actions;
1070 if (! MPLIST_PLIST_P (plist))
1071 MERROR (MERROR_IM, -1);
1072 keylist = MPLIST_PLIST (plist);
1073 map_actions = MPLIST_NEXT (keylist);
1074 if (MPLIST_SYMBOL_P (keylist))
1076 MSymbol command = MPLIST_SYMBOL (keylist);
1079 if (MFAILP (command != Mat_reload))
1081 pl = resolve_command (im_info->configured_cmds, command);
1085 load_translation (map, pl, map_actions, branch_actions,
1089 load_translation (map, keylist, map_actions, branch_actions,
1097 /* Load a macro from PLIST into IM_INFO->macros.
1098 PLIST has this from:
1099 PLIST ::= ( MACRO-NAME ACTION * )
1100 IM_INFO->macros is a plist of macro names vs action list. */
1103 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1108 if (! MPLIST_SYMBOL_P (plist))
1109 MERROR (MERROR_IM, -1);
1110 name = MPLIST_SYMBOL (plist);
1111 plist = MPLIST_NEXT (plist);
1112 if (MPLIST_TAIL_P (plist)
1113 || parse_action_list (plist, im_info->macros) < 0)
1114 MERROR (MERROR_IM, -1);
1115 pl = mplist_get (im_info->macros, name);
1116 M17N_OBJECT_UNREF (pl);
1117 mplist_put (im_info->macros, name, plist);
1118 M17N_OBJECT_REF (plist);
1122 /* Load an external module from PLIST into IM_INFO->externals.
1123 PLIST has this form:
1124 PLIST ::= ( MODULE-NAME FUNCTION * )
1125 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1128 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1133 MIMExternalModule *external;
1137 if (MPLIST_MTEXT_P (plist))
1138 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1139 else if (MPLIST_SYMBOL_P (plist))
1140 module = MPLIST_SYMBOL (plist);
1141 module_file = alloca (strlen (MSYMBOL_NAME (module))
1142 + strlen (DLOPEN_SHLIB_EXT) + 1);
1143 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1145 handle = dlopen (module_file, RTLD_NOW);
1146 if (MFAILP (handle))
1148 fprintf (stderr, "%s\n", dlerror ());
1151 func_list = mplist ();
1152 MPLIST_DO (plist, MPLIST_NEXT (plist))
1154 if (! MPLIST_SYMBOL_P (plist))
1155 MERROR_GOTO (MERROR_IM, err_label);
1156 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1159 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1162 MSTRUCT_MALLOC (external, MERROR_IM);
1163 external->handle = handle;
1164 external->func_list = func_list;
1165 mplist_add (im_info->externals, module, external);
1170 M17N_OBJECT_UNREF (func_list);
1175 free_map (MIMMap *map, int top)
1180 M17N_OBJECT_UNREF (map->map_actions);
1183 MPLIST_DO (plist, map->submaps)
1184 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1185 M17N_OBJECT_UNREF (map->submaps);
1187 M17N_OBJECT_UNREF (map->branch_actions);
1192 free_state (void *object)
1194 MIMState *state = object;
1196 M17N_OBJECT_UNREF (state->title);
1198 free_map (state->map, 1);
1202 /** Load a state from PLIST into a newly allocated state object.
1203 PLIST has this form:
1204 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1205 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1206 Return the state object. */
1209 load_state (MInputMethodInfo *im_info, MPlist *plist)
1213 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1215 M17N_OBJECT (state, free_state, MERROR_IM);
1216 state->name = MPLIST_SYMBOL (plist);
1217 plist = MPLIST_NEXT (plist);
1218 if (MPLIST_MTEXT_P (plist))
1220 state->title = MPLIST_MTEXT (plist);
1221 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1222 Mlanguage, im_info->language);
1223 M17N_OBJECT_REF (state->title);
1224 plist = MPLIST_NEXT (plist);
1226 MSTRUCT_CALLOC (state->map, MERROR_IM);
1227 MPLIST_DO (plist, plist)
1229 if (MFAILP (MPLIST_PLIST_P (plist)))
1231 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1236 /* Return a newly created IM_INFO for an input method specified by
1237 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1239 static MInputMethodInfo *
1240 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1243 MInputMethodInfo *im_info;
1246 if (name == Mnil && extra == Mnil)
1247 language = Mt, extra = Mglobal;
1248 MSTRUCT_CALLOC (im_info, MERROR_IM);
1250 im_info->language = language;
1251 im_info->name = name;
1252 im_info->extra = extra;
1255 mplist_add (plist, Mplist, elt);
1256 M17N_OBJECT_UNREF (elt);
1257 elt = mplist_add (elt, Msymbol, language);
1258 elt = mplist_add (elt, Msymbol, name);
1259 elt = mplist_add (elt, Msymbol, extra);
1260 mplist_add (elt, Mt, im_info);
1266 fini_im_info (MInputMethodInfo *im_info)
1270 M17N_OBJECT_UNREF (im_info->cmds);
1271 M17N_OBJECT_UNREF (im_info->configured_cmds);
1272 M17N_OBJECT_UNREF (im_info->bc_cmds);
1273 M17N_OBJECT_UNREF (im_info->vars);
1274 M17N_OBJECT_UNREF (im_info->configured_vars);
1275 M17N_OBJECT_UNREF (im_info->bc_vars);
1276 M17N_OBJECT_UNREF (im_info->description);
1277 M17N_OBJECT_UNREF (im_info->title);
1278 if (im_info->states)
1280 MPLIST_DO (plist, im_info->states)
1282 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1284 M17N_OBJECT_UNREF (state);
1286 M17N_OBJECT_UNREF (im_info->states);
1289 if (im_info->macros)
1291 MPLIST_DO (plist, im_info->macros)
1292 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1293 M17N_OBJECT_UNREF (im_info->macros);
1296 if (im_info->externals)
1298 MPLIST_DO (plist, im_info->externals)
1300 MIMExternalModule *external = MPLIST_VAL (plist);
1302 dlclose (external->handle);
1303 M17N_OBJECT_UNREF (external->func_list);
1305 MPLIST_KEY (plist) = Mt;
1307 M17N_OBJECT_UNREF (im_info->externals);
1311 MPLIST_DO (plist, im_info->maps)
1313 MPlist *p = MPLIST_PLIST (plist);
1315 M17N_OBJECT_UNREF (p);
1317 M17N_OBJECT_UNREF (im_info->maps);
1324 free_im_info (MInputMethodInfo *im_info)
1326 fini_im_info (im_info);
1331 free_im_list (MPlist *plist)
1335 MPLIST_DO (pl, plist)
1337 MInputMethodInfo *im_info;
1339 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1340 im_info = MPLIST_VAL (elt);
1341 free_im_info (im_info);
1343 M17N_OBJECT_UNREF (plist);
1346 static MInputMethodInfo *
1347 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1349 if (name == Mnil && extra == Mnil)
1350 language = Mt, extra = Mglobal;
1351 while ((plist = mplist__assq (plist, language)))
1353 MPlist *elt = MPLIST_PLIST (plist);
1355 plist = MPLIST_NEXT (plist);
1356 elt = MPLIST_NEXT (elt);
1357 if (MPLIST_SYMBOL (elt) != name)
1359 elt = MPLIST_NEXT (elt);
1360 if (MPLIST_SYMBOL (elt) != extra)
1362 elt = MPLIST_NEXT (elt);
1363 return MPLIST_VAL (elt);
1368 static void load_im_info (MPlist *, MInputMethodInfo *);
1370 #define get_custom_info(im_info) \
1372 ? lookup_im_info (im_custom_list, (im_info)->language, \
1373 (im_info)->name, (im_info)->extra) \
1376 #define get_config_info(im_info) \
1378 ? lookup_im_info (im_config_list, (im_info)->language, \
1379 (im_info)->name, (im_info)->extra) \
1383 update_custom_info (void)
1389 if (mdatabase__check (im_custom_mdb) > 0)
1394 MDatabaseInfo *custom_dir_info;
1395 char custom_path[PATH_MAX + 1];
1397 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1398 if (! custom_dir_info->filename
1399 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1401 strcpy (custom_path, custom_dir_info->filename);
1402 strcat (custom_path, CUSTOM_FILE);
1403 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1409 free_im_list (im_custom_list);
1410 im_custom_list = NULL;
1412 plist = mdatabase_load (im_custom_mdb);
1415 im_custom_list = mplist ();
1417 MPLIST_DO (pl, plist)
1419 MSymbol language, name, extra;
1420 MInputMethodInfo *im_info;
1421 MPlist *im_data, *p;
1423 if (! MPLIST_PLIST_P (pl))
1425 p = MPLIST_PLIST (pl);
1426 im_data = MPLIST_NEXT (p);
1427 if (! MPLIST_PLIST_P (p))
1429 p = MPLIST_PLIST (p);
1430 if (! MPLIST_SYMBOL_P (p)
1431 || MPLIST_SYMBOL (p) != Minput_method)
1433 p = MPLIST_NEXT (p);
1434 if (! MPLIST_SYMBOL_P (p))
1436 language = MPLIST_SYMBOL (p);
1437 p = MPLIST_NEXT (p);
1438 if (! MPLIST_SYMBOL_P (p))
1440 name = MPLIST_SYMBOL (p);
1441 if (language == Mnil || name == Mnil)
1443 p = MPLIST_NEXT (p);
1444 if (MPLIST_TAIL_P (p))
1446 else if (MPLIST_SYMBOL_P (p))
1447 extra = MPLIST_SYMBOL (p);
1450 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1451 load_im_info (im_data, im_info);
1453 M17N_OBJECT_UNREF (plist);
1458 update_global_info (void)
1464 int ret = mdatabase__check (global_info->mdb);
1468 fini_im_info (global_info);
1472 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1474 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1476 if (! global_info->mdb
1477 || ! (plist = mdatabase_load (global_info->mdb)))
1480 load_im_info (plist, global_info);
1481 M17N_OBJECT_UNREF (plist);
1486 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1487 and EXTRA. KEY, if not Mnil, tells which kind of information about
1488 the input method is necessary, and the returned IM_INFO may contain
1489 only that information. */
1491 static MInputMethodInfo *
1492 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1495 MInputMethodInfo *im_info;
1498 if (name == Mnil && extra == Mnil)
1499 language = Mt, extra = Mglobal;
1500 im_info = lookup_im_info (im_info_list, language, name, extra);
1503 if (key == Mnil ? im_info->states != NULL
1504 : key == Mcommand ? im_info->cmds != NULL
1505 : key == Mvariable ? im_info->vars != NULL
1506 : key == Mtitle ? im_info->title != NULL
1507 : key == Mdescription ? im_info->description != NULL
1509 /* IM_INFO already contains required information. */
1511 /* We have not yet loaded required information. */
1515 mdb = mdatabase_find (Minput_method, language, name, extra);
1518 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1523 plist = mdatabase_load (im_info->mdb);
1527 mplist_push (load_im_info_keys, key, Mt);
1528 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1529 mplist_pop (load_im_info_keys);
1533 MERROR (MERROR_IM, im_info);
1534 update_global_info ();
1535 load_im_info (plist, im_info);
1536 M17N_OBJECT_UNREF (plist);
1539 if (! im_info->cmds)
1540 im_info->cmds = mplist ();
1541 if (! im_info->vars)
1542 im_info->vars = mplist ();
1544 if (! im_info->title
1545 && (key == Mnil || key == Mtitle))
1546 im_info->title = (name == Mnil ? mtext ()
1547 : mtext_from_data (MSYMBOL_NAME (name),
1548 MSYMBOL_NAMELEN (name),
1549 MTEXT_FORMAT_US_ASCII));
1553 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1554 If updated, but got unloadable, return -1. Otherwise, update
1555 contents of IM_INFO from the new database, and return 1. */
1558 reload_im_info (MInputMethodInfo *im_info)
1563 update_custom_info ();
1564 update_global_info ();
1565 check = mdatabase__check (im_info->mdb);
1568 plist = mdatabase_load (im_info->mdb);
1571 fini_im_info (im_info);
1572 load_im_info (plist, im_info);
1573 M17N_OBJECT_UNREF (plist);
1577 static MInputMethodInfo *
1578 get_im_info_by_tags (MPlist *plist)
1583 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1584 i++, plist = MPLIST_NEXT (plist))
1585 tag[i] = MPLIST_SYMBOL (plist);
1590 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1595 check_description (MPlist *plist)
1599 if (MPLIST_MTEXT_P (plist))
1601 if (MPLIST_PLIST_P (plist))
1603 MPlist *pl = MPLIST_PLIST (plist);
1605 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1607 pl =MPLIST_NEXT (pl);
1608 if (MFAILP (MPLIST_MTEXT_P (pl)))
1610 mt = MPLIST_MTEXT (pl);
1611 M17N_OBJECT_REF (mt);
1614 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1616 if (translated == (char *) MTEXT_DATA (mt))
1617 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1618 if (translated != (char *) MTEXT_DATA (mt))
1620 M17N_OBJECT_UNREF (mt);
1621 mt = mtext__from_data (translated, strlen (translated),
1622 MTEXT_FORMAT_UTF_8, 0);
1626 mplist_set (plist, Mtext, mt);
1627 M17N_OBJECT_UNREF (mt);
1630 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1636 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1640 check_command_keyseq (MPlist *keyseq)
1642 if (MPLIST_PLIST_P (keyseq))
1644 MPlist *p = MPLIST_PLIST (keyseq);
1647 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1651 if (MPLIST_MTEXT_P (keyseq))
1653 MText *mt = MPLIST_MTEXT (keyseq);
1656 for (i = 0; i < mtext_nchars (mt); i++)
1657 if (mtext_ref_char (mt, i) >= 256)
1664 /* Load command defitions from PLIST into IM_INFO->cmds.
1666 PLIST is well-formed and has this form;
1667 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1668 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1669 M-text or a plist of symbols.
1671 The returned list has the same form, but for each element...
1673 (1) If DESCRIPTION and the rest are omitted, the element is not
1674 stored in the returned list.
1676 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1677 description in global_info->cmds (if any). */
1680 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1684 im_info->cmds = tail = mplist ();
1686 MPLIST_DO (plist, MPLIST_NEXT (plist))
1688 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1691 if (MFAILP (MPLIST_PLIST_P (plist)))
1693 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1694 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1696 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1697 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1699 if (MFAILP (im_info != global_info))
1700 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1704 if (! check_description (p))
1705 mplist_set (p, Msymbol, Mnil);
1706 p = MPLIST_NEXT (p);
1707 while (! MPLIST_TAIL_P (p))
1709 if (MFAILP (check_command_keyseq (p)))
1710 mplist__pop_unref (p);
1712 p = MPLIST_NEXT (p);
1715 tail = mplist_add (tail, Mplist, pl);
1720 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1721 MPlist *config_cmds)
1723 MPlist *global = NULL, *custom = NULL, *config = NULL;
1726 MPlist *description = NULL, *keyseq;
1728 name = MPLIST_SYMBOL (plist);
1729 plist = MPLIST_NEXT (plist);
1730 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1731 description = plist;
1732 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1733 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1734 if (MPLIST_TAIL_P (plist))
1737 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1738 global = MPLIST_NEXT (MPLIST_PLIST (global));
1741 keyseq = MPLIST_NEXT (global);
1742 status = Minherited;
1752 keyseq = MPLIST_NEXT (plist);
1756 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1758 config = MPLIST_NEXT (MPLIST_PLIST (config));
1759 if (! MPLIST_TAIL_P (config))
1761 keyseq = MPLIST_NEXT (config);
1762 status = Mconfigured;
1765 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1767 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1768 if (! MPLIST_TAIL_P (custom))
1770 keyseq = MPLIST_NEXT (custom);
1771 status = Mcustomized;
1776 mplist_add (plist, Msymbol, name);
1778 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1780 mplist_add (plist, Msymbol, Mnil);
1781 mplist_add (plist, Msymbol, status);
1782 mplist__conc (plist, keyseq);
1787 config_all_commands (MInputMethodInfo *im_info)
1789 MPlist *global_cmds, *custom_cmds, *config_cmds;
1790 MInputMethodInfo *temp;
1791 MPlist *tail, *plist;
1793 M17N_OBJECT_UNREF (im_info->configured_cmds);
1795 if (MPLIST_TAIL_P (im_info->cmds)
1799 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1800 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1801 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1803 im_info->configured_cmds = tail = mplist ();
1804 MPLIST_DO (plist, im_info->cmds)
1806 MPlist *pl = config_command (MPLIST_PLIST (plist),
1807 global_cmds, custom_cmds, config_cmds);
1810 tail = mplist_add (tail, Mplist, pl);
1811 M17N_OBJECT_UNREF (pl);
1816 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1817 valid, return 0 if not. */
1820 check_variable_value (MPlist *val, MPlist *global)
1822 MSymbol type = MPLIST_KEY (val);
1823 MPlist *valids = MPLIST_NEXT (val);
1825 if (type != Minteger && type != Mtext && type != Msymbol)
1829 if (MPLIST_KEY (global) != Mt
1830 && MPLIST_KEY (global) != MPLIST_KEY (val))
1832 if (MPLIST_TAIL_P (valids))
1833 valids = MPLIST_NEXT (global);
1835 if (MPLIST_TAIL_P (valids))
1838 if (type == Minteger)
1840 int n = MPLIST_INTEGER (val);
1842 MPLIST_DO (valids, valids)
1844 if (MPLIST_INTEGER_P (valids))
1846 if (n == MPLIST_INTEGER (valids))
1849 else if (MPLIST_PLIST_P (valids))
1851 MPlist *p = MPLIST_PLIST (valids);
1852 int min_bound, max_bound;
1854 if (! MPLIST_INTEGER_P (p))
1855 MERROR (MERROR_IM, 0);
1856 min_bound = MPLIST_INTEGER (p);
1857 p = MPLIST_NEXT (p);
1858 if (! MPLIST_INTEGER_P (p))
1859 MERROR (MERROR_IM, 0);
1860 max_bound = MPLIST_INTEGER (p);
1861 if (n >= min_bound && n <= max_bound)
1866 else if (type == Msymbol)
1868 MSymbol sym = MPLIST_SYMBOL (val);
1870 MPLIST_DO (valids, valids)
1872 if (! MPLIST_SYMBOL_P (valids))
1873 MERROR (MERROR_IM, 0);
1874 if (sym == MPLIST_SYMBOL (valids))
1880 MText *mt = MPLIST_MTEXT (val);
1882 MPLIST_DO (valids, valids)
1884 if (! MPLIST_MTEXT_P (valids))
1885 MERROR (MERROR_IM, 0);
1886 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1891 return (MPLIST_TAIL_P (valids));
1894 /* Load variable defitions from PLIST into IM_INFO->vars.
1896 PLIST is well-formed and has this form;
1897 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1899 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1901 The returned list has the same form, but for each element...
1903 (1) If DESCRIPTION and the rest are omitted, the element is not
1904 stored in the returned list.
1906 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1907 description in global_info->vars (if any). */
1910 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1912 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1913 ? global_info->vars : NULL);
1916 im_info->vars = tail = mplist ();
1917 MPLIST_DO (plist, MPLIST_NEXT (plist))
1921 if (MFAILP (MPLIST_PLIST_P (plist)))
1923 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1924 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1926 if (im_info == global_info)
1928 /* Loading a global variable. */
1929 p = MPLIST_NEXT (pl);
1930 if (MPLIST_TAIL_P (p))
1931 mplist_add (p, Msymbol, Mnil);
1934 if (! check_description (p))
1935 mplist_set (p, Msymbol, Mnil);
1936 p = MPLIST_NEXT (p);
1937 if (MFAILP (! MPLIST_TAIL_P (p)
1938 && check_variable_value (p, NULL)))
1939 mplist_set (p, Mt, NULL);
1942 else if (im_info->mdb)
1944 /* Loading a local variable. */
1945 MSymbol name = MPLIST_SYMBOL (pl);
1946 MPlist *global = NULL;
1949 && (p = mplist__assq (global_vars, name)))
1951 /* P ::= ((NAME DESC ...) ...) */
1952 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1953 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1954 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1957 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1958 if (! MPLIST_TAIL_P (p))
1960 if (! check_description (p))
1961 mplist_set (p, Msymbol, Mnil);
1962 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1963 if (MFAILP (! MPLIST_TAIL_P (p)))
1964 mplist_set (p, Mt, NULL);
1967 MPlist *valid_values = MPLIST_NEXT (p);
1969 if (! MPLIST_TAIL_P (valid_values)
1970 ? MFAILP (check_variable_value (p, NULL))
1971 : global && MFAILP (check_variable_value (p, global)))
1972 mplist_set (p, Mt, NULL);
1978 /* Loading a variable customization. */
1979 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1980 if (MFAILP (! MPLIST_TAIL_P (p)))
1982 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1983 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1984 || MPLIST_MTEXT_P (p)))
1987 tail = mplist_add (tail, Mplist, pl);
1992 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
1993 MPlist *config_vars)
1995 MPlist *global = NULL, *custom = NULL, *config = NULL;
1996 MSymbol name = MPLIST_SYMBOL (plist);
1998 MPlist *description = NULL, *value, *valids;
2002 global = mplist__assq (global_vars, name);
2004 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2007 plist = MPLIST_NEXT (plist);
2008 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2009 description = plist;
2011 description = global;
2013 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2015 if (MPLIST_TAIL_P (plist))
2017 /* Inherit from global (if any). */
2021 if (MPLIST_KEY (value) == Mt)
2023 valids = MPLIST_NEXT (global);
2024 status = Minherited;
2036 value = plist = MPLIST_NEXT (plist);
2037 valids = MPLIST_NEXT (value);
2038 if (MPLIST_KEY (value) == Mt)
2040 if (! MPLIST_TAIL_P (valids))
2043 valids = MPLIST_NEXT (global);
2047 if (config_vars && (config = mplist__assq (config_vars, name)))
2049 config = MPLIST_NEXT (MPLIST_PLIST (config));
2050 if (! MPLIST_TAIL_P (config))
2052 value = MPLIST_NEXT (config);
2053 if (MFAILP (check_variable_value (value, global ? global : plist)))
2055 status = Mconfigured;
2058 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2060 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2061 if (! MPLIST_TAIL_P (custom))
2063 value = MPLIST_NEXT (custom);
2064 if (MFAILP (check_variable_value (value, global ? global : plist)))
2066 status = Mcustomized;
2071 mplist_add (plist, Msymbol, name);
2073 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2075 mplist_add (plist, Msymbol, Mnil);
2076 mplist_add (plist, Msymbol, status);
2078 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2080 mplist_add (plist, Mt, NULL);
2081 if (valids && ! MPLIST_TAIL_P (valids))
2082 mplist__conc (plist, valids);
2086 /* Return a configured variable definition list based on
2087 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2088 get it from global_info->vars. */
2091 config_all_variables (MInputMethodInfo *im_info)
2093 MPlist *global_vars, *custom_vars, *config_vars;
2094 MInputMethodInfo *temp;
2095 MPlist *tail, *plist;
2097 M17N_OBJECT_UNREF (im_info->configured_vars);
2099 if (MPLIST_TAIL_P (im_info->vars)
2103 global_vars = im_info != global_info ? global_info->vars : NULL;
2104 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2105 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2107 im_info->configured_vars = tail = mplist ();
2108 MPLIST_DO (plist, im_info->vars)
2110 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2111 global_vars, custom_vars, config_vars);
2114 tail = mplist_add (tail, Mplist, pl);
2115 M17N_OBJECT_UNREF (pl);
2120 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2121 CONFIG contains configuration information of the input method. */
2124 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2128 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2130 load_commands (im_info, MPLIST_PLIST (pl));
2131 config_all_commands (im_info);
2132 pl = mplist_pop (pl);
2133 M17N_OBJECT_UNREF (pl);
2136 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2138 load_variables (im_info, MPLIST_PLIST (pl));
2139 config_all_variables (im_info);
2140 pl = mplist_pop (pl);
2141 M17N_OBJECT_UNREF (pl);
2144 MPLIST_DO (plist, plist)
2145 if (MPLIST_PLIST_P (plist))
2147 MPlist *elt = MPLIST_PLIST (plist);
2150 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2152 key = MPLIST_SYMBOL (elt);
2157 elt = MPLIST_NEXT (elt);
2158 if (MFAILP (MPLIST_MTEXT_P (elt)))
2160 im_info->title = MPLIST_MTEXT (elt);
2161 M17N_OBJECT_REF (im_info->title);
2163 else if (key == Mmap)
2165 pl = mplist__from_alist (MPLIST_NEXT (elt));
2168 if (! im_info->maps)
2172 mplist__conc (im_info->maps, pl);
2173 M17N_OBJECT_UNREF (pl);
2176 else if (key == Mmacro)
2178 if (! im_info->macros)
2179 im_info->macros = mplist ();
2180 MPLIST_DO (elt, MPLIST_NEXT (elt))
2182 if (MFAILP (MPLIST_PLIST_P (elt)))
2184 load_macros (im_info, MPLIST_PLIST (elt));
2187 else if (key == Mmodule)
2189 if (! im_info->externals)
2190 im_info->externals = mplist ();
2191 MPLIST_DO (elt, MPLIST_NEXT (elt))
2193 if (MFAILP (MPLIST_PLIST_P (elt)))
2195 load_external_module (im_info, MPLIST_PLIST (elt));
2198 else if (key == Mstate)
2200 MPLIST_DO (elt, MPLIST_NEXT (elt))
2204 if (MFAILP (MPLIST_PLIST_P (elt)))
2206 pl = MPLIST_PLIST (elt);
2207 if (! im_info->states)
2208 im_info->states = mplist ();
2209 state = load_state (im_info, MPLIST_PLIST (elt));
2212 mplist_put (im_info->states, state->name, state);
2215 else if (key == Minclude)
2217 /* elt ::= include (tag1 tag2 ...) key item ... */
2219 MInputMethodInfo *temp;
2221 elt = MPLIST_NEXT (elt);
2222 if (MFAILP (MPLIST_PLIST_P (elt)))
2224 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2227 elt = MPLIST_NEXT (elt);
2228 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2230 key = MPLIST_SYMBOL (elt);
2231 elt = MPLIST_NEXT (elt);
2234 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2236 if (! im_info->maps)
2237 im_info->maps = mplist ();
2238 MPLIST_DO (pl, temp->maps)
2240 p = MPLIST_VAL (pl);
2241 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2242 M17N_OBJECT_REF (p);
2245 else if (key == Mmacro)
2247 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2249 if (! im_info->macros)
2250 im_info->macros = mplist ();
2251 MPLIST_DO (pl, temp->macros)
2253 p = MPLIST_VAL (pl);
2254 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2255 M17N_OBJECT_REF (p);
2258 else if (key == Mstate)
2260 if (! temp->states || MPLIST_TAIL_P (temp->states))
2262 if (! im_info->states)
2263 im_info->states = mplist ();
2264 MPLIST_DO (pl, temp->states)
2266 MIMState *state = MPLIST_VAL (pl);
2268 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2269 M17N_OBJECT_REF (state);
2273 else if (key == Mdescription)
2275 if (im_info->description)
2277 elt = MPLIST_NEXT (elt);
2278 if (! check_description (elt))
2280 im_info->description = MPLIST_MTEXT (elt);
2281 M17N_OBJECT_REF (im_info->description);
2284 im_info->tick = time (NULL);
2289 static int take_action_list (MInputContext *ic, MPlist *action_list);
2290 static void preedit_commit (MInputContext *ic);
2293 shift_state (MInputContext *ic, MSymbol state_name)
2295 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2296 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2297 MIMState *orig_state = ic_info->state, *state;
2299 /* Find a state to shift to. If not found, shift to the initial
2301 if (state_name == Mt)
2303 if (! ic_info->prev_state)
2305 state = ic_info->prev_state;
2307 else if (state_name == Mnil)
2309 state = (MIMState *) MPLIST_VAL (im_info->states);
2313 state = (MIMState *) mplist_get (im_info->states, state_name);
2315 state = (MIMState *) MPLIST_VAL (im_info->states);
2318 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2320 /* Enter the new state. */
2321 ic_info->state = state;
2322 ic_info->map = state->map;
2323 ic_info->state_key_head = ic_info->key_head;
2324 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2326 /* We have shifted to the initial state. */
2327 preedit_commit (ic);
2328 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2329 ic_info->state_pos = ic->cursor_pos;
2330 if (state != orig_state)
2332 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2334 /* Shifted to the initial state. */
2335 ic_info->prev_state = NULL;
2336 M17N_OBJECT_UNREF (ic_info->vars_saved);
2337 ic_info->vars_saved = mplist_copy (ic_info->vars);
2340 ic_info->prev_state = orig_state;
2343 ic->status = state->title;
2345 ic->status = im_info->title;
2346 ic->status_changed = 1;
2347 if (ic_info->map == ic_info->state->map
2348 && ic_info->map->map_actions)
2350 MDEBUG_PRINT (" init-actions:");
2351 take_action_list (ic, ic_info->map->map_actions);
2356 /* Find a candidate group that contains a candidate number INDEX from
2357 PLIST. Set START_INDEX to the first candidate number of the group,
2358 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2359 candidate group number if they are non-NULL. If INDEX is -1, find
2360 the last candidate group. */
2363 find_candidates_group (MPlist *plist, int index,
2364 int *start_index, int *end_index, int *group_index)
2366 int i = 0, gidx = 0, len;
2368 MPLIST_DO (plist, plist)
2370 if (MPLIST_MTEXT_P (plist))
2371 len = mtext_nchars (MPLIST_MTEXT (plist));
2373 len = mplist_length (MPLIST_PLIST (plist));
2374 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2380 *end_index = i + len;
2382 *group_index = gidx;
2392 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2394 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2396 int nchars = mt ? mtext_nchars (mt) : 1;
2399 mtext_ins (ic->preedit, pos, mt);
2401 mtext_ins_char (ic->preedit, pos, c, 1);
2402 MPLIST_DO (markers, ic_info->markers)
2403 if (MPLIST_INTEGER (markers) > pos)
2404 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars);
2405 if (ic->cursor_pos >= pos)
2406 ic->cursor_pos += nchars;
2407 ic->preedit_changed = 1;
2412 preedit_delete (MInputContext *ic, int from, int to)
2414 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2417 mtext_del (ic->preedit, from, to);
2418 MPLIST_DO (markers, ic_info->markers)
2420 if (MPLIST_INTEGER (markers) > to)
2421 MPLIST_VAL (markers)
2422 = (void *) (MPLIST_INTEGER (markers) - (to - from));
2423 else if (MPLIST_INTEGER (markers) > from)
2424 MPLIST_VAL (markers) = (void *) from;
2426 if (ic->cursor_pos >= to)
2427 ic->cursor_pos -= to - from;
2428 else if (ic->cursor_pos > from)
2429 ic->cursor_pos = from;
2430 ic->preedit_changed = 1;
2434 preedit_commit (MInputContext *ic)
2436 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2437 int preedit_len = mtext_nchars (ic->preedit);
2439 if (preedit_len > 0)
2443 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2444 Mcandidate_list, NULL, 0);
2445 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2446 Mcandidate_index, NULL, 0);
2447 mtext_cat (ic->produced, ic->preedit);
2448 mtext_reset (ic->preedit);
2449 mtext_reset (ic_info->preedit_saved);
2450 MPLIST_DO (p, ic_info->markers)
2452 ic->cursor_pos = ic_info->state_pos = 0;
2453 ic->preedit_changed = 1;
2454 ic_info->commit_key_head = ic_info->key_head;
2456 if (ic->candidate_list)
2458 M17N_OBJECT_UNREF (ic->candidate_list);
2459 ic->candidate_list = NULL;
2460 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2461 if (ic->candidate_show)
2463 ic->candidate_show = 0;
2464 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2470 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2472 int code = marker_code (sym, 0);
2474 if (mt && (code == '[' || code == ']'))
2478 if (code == '[' && current > 0)
2480 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2484 else if (code == ']' && current < mtext_nchars (mt))
2486 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2492 return (code == '<' ? 0
2493 : code == '>' ? limit
2494 : code == '-' ? current - 1
2495 : code == '+' ? current + 1
2496 : code == '=' ? current
2497 : code - '0' > limit ? limit
2501 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2505 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2507 int from = mtext_property_start (prop);
2508 int to = mtext_property_end (prop);
2510 MPlist *candidate_list = mtext_property_value (prop);
2511 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2513 int ingroup_index = idx - start;
2516 preedit_delete (ic, from, to);
2517 if (MPLIST_MTEXT_P (group))
2519 mt = MPLIST_MTEXT (group);
2520 preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index));
2528 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2529 i++, plist = MPLIST_NEXT (plist));
2530 mt = MPLIST_MTEXT (plist);
2531 preedit_insert (ic, from, mt, 0);
2532 to = from + mtext_nchars (mt);
2534 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2535 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2536 ic->cursor_pos = to;
2540 get_select_charset (MInputContextInfo * ic_info)
2542 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2545 if (! MPLIST_VAL (plist))
2547 sym = MPLIST_SYMBOL (plist);
2550 return MCHARSET (sym);
2554 adjust_candidates (MPlist *plist, MCharset *charset)
2558 /* plist ::= MTEXT ... | PLIST ... */
2559 plist = mplist_copy (plist);
2560 if (MPLIST_MTEXT_P (plist))
2563 while (! MPLIST_TAIL_P (pl))
2565 /* pl ::= MTEXT ... */
2566 MText *mt = MPLIST_MTEXT (pl);
2570 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2572 c = mtext_ref_char (mt, i);
2573 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2577 mt = mtext_dup (mt);
2578 mplist_set (pl, Mtext, mt);
2579 M17N_OBJECT_UNREF (mt);
2582 mtext_del (mt, i, i + 1);
2585 if (mtext_len (mt) > 0)
2586 pl = MPLIST_NEXT (pl);
2590 M17N_OBJECT_UNREF (mt);
2594 else /* MPLIST_PLIST_P (plist) */
2597 while (! MPLIST_TAIL_P (pl))
2599 /* pl ::= (MTEXT ...) ... */
2600 MPlist *p = MPLIST_PLIST (pl);
2602 /* p ::= MTEXT ... */
2606 while (! MPLIST_TAIL_P (p0))
2608 MText *mt = MPLIST_MTEXT (p0);
2611 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2613 c = mtext_ref_char (mt, i);
2614 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2619 p0 = MPLIST_NEXT (p0);
2626 p = mplist_copy (p);
2627 mplist_set (pl, Mplist, p);
2628 M17N_OBJECT_UNREF (p);
2632 p0 = MPLIST_NEXT (p0);
2635 M17N_OBJECT_UNREF (mt);
2638 if (! MPLIST_TAIL_P (p))
2639 pl = MPLIST_NEXT (pl);
2643 M17N_OBJECT_UNREF (p);
2647 if (MPLIST_TAIL_P (plist))
2649 M17N_OBJECT_UNREF (plist);
2656 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2658 MCharset *charset = get_select_charset (ic_info);
2663 plist = resolve_variable (ic_info, Mcandidates_group_size);
2664 column = MPLIST_INTEGER (plist);
2666 plist = MPLIST_PLIST (args);
2668 plist = adjust_candidates (plist, charset);
2670 if (plist && column > 0)
2672 if (MPLIST_MTEXT_P (plist))
2674 MText *mt = MPLIST_MTEXT (plist);
2675 MPlist *next = MPLIST_NEXT (plist);
2677 if (MPLIST_TAIL_P (next))
2678 M17N_OBJECT_REF (mt);
2681 mt = mtext_dup (mt);
2682 while (! MPLIST_TAIL_P (next))
2684 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2685 next = MPLIST_NEXT (next);
2688 M17N_OBJECT_UNREF (plist);
2690 len = mtext_nchars (mt);
2692 mplist_add (plist, Mtext, mt);
2695 for (i = 0; i < len; i += column)
2697 int to = (i + column < len ? i + column : len);
2698 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2700 mplist_add (plist, Mtext, sub);
2701 M17N_OBJECT_UNREF (sub);
2704 M17N_OBJECT_UNREF (mt);
2706 else /* MPLIST_PLIST_P (plist) */
2708 MPlist *pl = MPLIST_PLIST (plist), *p;
2709 MPlist *next = MPLIST_NEXT (plist);
2712 if (MPLIST_TAIL_P (next))
2713 M17N_OBJECT_REF (pl);
2716 pl = mplist_copy (pl);
2717 while (! MPLIST_TAIL_P (next))
2719 p = mplist_copy (MPLIST_PLIST (next));
2720 pl = mplist__conc (pl, p);
2721 M17N_OBJECT_UNREF (p);
2722 next = MPLIST_NEXT (next);
2725 M17N_OBJECT_UNREF (plist);
2727 len = mplist_length (pl);
2729 mplist_add (plist, Mplist, pl);
2734 for (i = 0; i < len; i += column)
2737 mplist_add (plist, Mplist, p);
2738 M17N_OBJECT_UNREF (p);
2739 for (j = 0; j < column && i + j < len; j++)
2741 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
2742 p0 = MPLIST_NEXT (p0);
2746 M17N_OBJECT_UNREF (pl);
2755 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2757 MPlist *action = NULL;
2761 if (MPLIST_SYMBOL_P (action_list))
2763 MSymbol var = MPLIST_SYMBOL (action_list);
2766 MPLIST_DO (p, ic_info->vars)
2767 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2769 if (MPLIST_TAIL_P (p))
2771 action = MPLIST_NEXT (MPLIST_PLIST (p));
2772 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2775 if (MPLIST_PLIST_P (action_list))
2777 action = MPLIST_PLIST (action_list);
2778 if (MPLIST_SYMBOL_P (action))
2780 name = MPLIST_SYMBOL (action);
2781 args = MPLIST_NEXT (action);
2783 && MPLIST_PLIST_P (args))
2784 mplist_set (action, Msymbol, M_candidates);
2786 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2789 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2790 mplist_push (action, Msymbol, M_candidates);
2791 mplist_set (action_list, Mplist, action);
2792 M17N_OBJECT_UNREF (action);
2795 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2798 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2799 mplist_push (action, Msymbol, Minsert);
2800 mplist_set (action_list, Mplist, action);
2801 M17N_OBJECT_UNREF (action);
2806 /* Perform list of actions in ACTION_LIST for the current input
2807 context IC. If all actions are performed without error, return 0.
2808 Otherwise, return -1. */
2811 take_action_list (MInputContext *ic, MPlist *action_list)
2813 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2814 MPlist *candidate_list = ic->candidate_list;
2815 int candidate_index = ic->candidate_index;
2816 int candidate_show = ic->candidate_show;
2817 MTextProperty *prop;
2819 MPLIST_DO (action_list, action_list)
2821 MPlist *action = regularize_action (action_list, ic_info);
2827 name = MPLIST_SYMBOL (action);
2828 args = MPLIST_NEXT (action);
2830 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2831 if (name == Minsert)
2833 if (MPLIST_SYMBOL_P (args))
2835 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2836 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2839 if (MPLIST_MTEXT_P (args))
2840 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2841 else /* MPLIST_INTEGER_P (args)) */
2842 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2844 else if (name == M_candidates)
2846 MPlist *plist = get_candidate_list (ic_info, args);
2851 if (MPLIST_MTEXT_P (plist))
2853 preedit_insert (ic, ic->cursor_pos, NULL,
2854 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2859 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2861 preedit_insert (ic, ic->cursor_pos, mt, 0);
2862 len = mtext_nchars (mt);
2864 mtext_put_prop (ic->preedit,
2865 ic->cursor_pos - len, ic->cursor_pos,
2866 Mcandidate_list, plist);
2867 mtext_put_prop (ic->preedit,
2868 ic->cursor_pos - len, ic->cursor_pos,
2869 Mcandidate_index, (void *) 0);
2871 else if (name == Mselect)
2874 int code, idx, gindex;
2875 int pos = ic->cursor_pos;
2877 int idx_decided = 0;
2880 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2883 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2884 group = find_candidates_group (mtext_property_value (prop), idx,
2885 &start, &end, &gindex);
2886 if (MPLIST_SYMBOL_P (args))
2888 code = marker_code (MPLIST_SYMBOL (args), 0);
2891 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2892 if (! MPLIST_INTEGER_P (args))
2894 idx = start + MPLIST_INTEGER (args);
2895 if (idx < start || idx >= end)
2903 if (code != '[' && code != ']')
2908 ? new_index (NULL, ic->candidate_index - start,
2909 end - start - 1, MPLIST_SYMBOL (args),
2911 : MPLIST_INTEGER (args)));
2914 find_candidates_group (mtext_property_value (prop), -1,
2919 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2924 int ingroup_index = idx - start;
2927 group = mtext_property_value (prop);
2928 len = mplist_length (group);
2941 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2942 idx += (MPLIST_MTEXT_P (group)
2943 ? mtext_nchars (MPLIST_MTEXT (group))
2944 : mplist_length (MPLIST_PLIST (group)));
2945 len = (MPLIST_MTEXT_P (group)
2946 ? mtext_nchars (MPLIST_MTEXT (group))
2947 : mplist_length (MPLIST_PLIST (group)));
2948 if (ingroup_index >= len)
2949 ingroup_index = len - 1;
2950 idx += ingroup_index;
2952 update_candidate (ic, prop, idx);
2953 MDEBUG_PRINT1 ("(%d)", idx);
2955 else if (name == Mshow)
2956 ic->candidate_show = 1;
2957 else if (name == Mhide)
2958 ic->candidate_show = 0;
2959 else if (name == Mdelete)
2961 int len = mtext_nchars (ic->preedit);
2965 if (MPLIST_SYMBOL_P (args)
2966 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
2968 to = ic->cursor_pos + pos;
2971 delete_surrounding_text (ic, to);
2976 delete_surrounding_text (ic, to - len);
2982 to = (MPLIST_SYMBOL_P (args)
2983 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
2985 : MPLIST_INTEGER (args));
2991 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
2992 if (to < ic->cursor_pos)
2993 preedit_delete (ic, to, ic->cursor_pos);
2994 else if (to > ic->cursor_pos)
2995 preedit_delete (ic, ic->cursor_pos, to);
2997 else if (name == Mmove)
2999 int len = mtext_nchars (ic->preedit);
3001 = (MPLIST_SYMBOL_P (args)
3002 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3004 : MPLIST_INTEGER (args));
3010 if (pos != ic->cursor_pos)
3012 ic->cursor_pos = pos;
3013 ic->preedit_changed = 1;
3015 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3017 else if (name == Mmark)
3019 int code = marker_code (MPLIST_SYMBOL (args), 0);
3023 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3024 (void *) ic->cursor_pos);
3025 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3028 else if (name == Mpushback)
3030 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3034 if (MPLIST_SYMBOL_P (args))
3036 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3037 if (MPLIST_INTEGER_P (args))
3038 num = MPLIST_INTEGER (args);
3043 num = MPLIST_INTEGER (args);
3046 ic_info->key_head -= num;
3048 ic_info->key_head = 0;
3050 ic_info->key_head = - num;
3051 if (ic_info->key_head > ic_info->used)
3052 ic_info->key_head = ic_info->used;
3054 else if (MPLIST_MTEXT_P (args))
3056 MText *mt = MPLIST_MTEXT (args);
3057 int i, len = mtext_nchars (mt);
3060 ic_info->key_head--;
3061 for (i = 0; i < len; i++)
3063 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3064 if (ic_info->key_head + i < ic_info->used)
3065 ic_info->keys[ic_info->key_head + i] = key;
3067 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3072 MPlist *plist = MPLIST_PLIST (args), *pl;
3076 ic_info->key_head--;
3078 MPLIST_DO (pl, plist)
3080 key = MPLIST_SYMBOL (pl);
3081 if (ic_info->key_head < ic_info->used)
3082 ic_info->keys[ic_info->key_head + i] = key;
3084 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3089 else if (name == Mcall)
3091 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3092 MIMExternalFunc func = NULL;
3093 MSymbol module, func_name;
3094 MPlist *func_args, *val;
3097 module = MPLIST_SYMBOL (args);
3098 args = MPLIST_NEXT (args);
3099 func_name = MPLIST_SYMBOL (args);
3101 if (im_info->externals)
3103 MIMExternalModule *external
3104 = (MIMExternalModule *) mplist_get (im_info->externals,
3107 func = (MIMExternalFunc) mplist_get (external->func_list,
3112 func_args = mplist ();
3113 mplist_add (func_args, Mt, ic);
3114 MPLIST_DO (args, MPLIST_NEXT (args))
3118 if (MPLIST_KEY (args) == Msymbol
3119 && MPLIST_KEY (args) != Mnil
3120 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3122 code = new_index (ic, ic->cursor_pos,
3123 mtext_nchars (ic->preedit),
3124 MPLIST_SYMBOL (args), ic->preedit);
3125 mplist_add (func_args, Minteger, (void *) code);
3128 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3130 val = (func) (func_args);
3131 M17N_OBJECT_UNREF (func_args);
3132 if (val && ! MPLIST_TAIL_P (val))
3133 ret = take_action_list (ic, val);
3134 M17N_OBJECT_UNREF (val);
3138 else if (name == Mshift)
3140 shift_state (ic, MPLIST_SYMBOL (args));
3142 else if (name == Mundo)
3144 int intarg = (MPLIST_TAIL_P (args)
3146 : integer_value (ic, args, NULL, 0));
3148 mtext_reset (ic->preedit);
3149 mtext_reset (ic_info->preedit_saved);
3150 mtext_reset (ic->produced);
3151 M17N_OBJECT_UNREF (ic_info->vars);
3152 ic_info->vars = mplist_copy (ic_info->vars_saved);
3153 ic->cursor_pos = ic_info->state_pos = 0;
3154 ic_info->state_key_head = ic_info->key_head
3155 = ic_info->commit_key_head = 0;
3157 shift_state (ic, Mnil);
3160 if (MPLIST_TAIL_P (args))
3165 ic_info->used += intarg;
3168 ic_info->used = intarg;
3171 else if (name == Mset || name == Madd || name == Msub
3172 || name == Mmul || name == Mdiv)
3174 MSymbol sym = MPLIST_SYMBOL (args);
3179 val1 = integer_value (ic, args, &value, 0);
3180 args = MPLIST_NEXT (args);
3181 val2 = resolve_expression (ic, args);
3183 val1 = val2, op = "=";
3184 else if (name == Madd)
3185 val1 += val2, op = "+=";
3186 else if (name == Msub)
3187 val1 -= val2, op = "-=";
3188 else if (name == Mmul)
3189 val1 *= val2, op = "*=";
3191 val1 /= val2, op = "/=";
3192 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3193 MSYMBOL_NAME (sym), op, val1, val1);
3195 mplist_set (value, Minteger, (void *) val1);
3197 else if (name == Mequal || name == Mless || name == Mgreater
3198 || name == Mless_equal || name == Mgreater_equal)
3201 MPlist *actions1, *actions2;
3204 val1 = resolve_expression (ic, args);
3205 args = MPLIST_NEXT (args);
3206 val2 = resolve_expression (ic, args);
3207 args = MPLIST_NEXT (args);
3208 actions1 = MPLIST_PLIST (args);
3209 args = MPLIST_NEXT (args);
3210 if (MPLIST_TAIL_P (args))
3213 actions2 = MPLIST_PLIST (args);
3214 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3215 if (name == Mequal ? val1 == val2
3216 : name == Mless ? val1 < val2
3217 : name == Mgreater ? val1 > val2
3218 : name == Mless_equal ? val1 <= val2
3221 MDEBUG_PRINT ("ok");
3222 ret = take_action_list (ic, actions1);
3226 MDEBUG_PRINT ("no");
3228 ret = take_action_list (ic, actions2);
3233 else if (name == Mcond)
3237 MPLIST_DO (args, args)
3242 if (! MPLIST_PLIST (args))
3244 cond = MPLIST_PLIST (args);
3245 if (resolve_expression (ic, cond) != 0)
3247 MDEBUG_PRINT1 ("(%dth)", idx);
3248 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3254 else if (name == Mcommit)
3256 preedit_commit (ic);
3258 else if (name == Munhandle)
3260 preedit_commit (ic);
3265 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3269 && (actions = mplist_get (im_info->macros, name)))
3271 if (take_action_list (ic, actions) < 0)
3277 if (ic->candidate_list)
3279 M17N_OBJECT_UNREF (ic->candidate_list);
3280 ic->candidate_list = NULL;
3282 if (ic->cursor_pos > 0
3283 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3286 ic->candidate_list = mtext_property_value (prop);
3287 M17N_OBJECT_REF (ic->candidate_list);
3289 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3291 ic->candidate_from = mtext_property_start (prop);
3292 ic->candidate_to = mtext_property_end (prop);
3295 if (candidate_list != ic->candidate_list)
3296 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3297 if (candidate_index != ic->candidate_index)
3298 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3299 if (candidate_show != ic->candidate_show)
3300 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3305 /* Handle the input key KEY in the current state and map specified in
3306 the input context IC. If KEY is handled correctly, return 0.
3307 Otherwise, return -1. */
3310 handle_key (MInputContext *ic)
3312 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3313 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3314 MIMMap *map = ic_info->map;
3315 MIMMap *submap = NULL;
3316 MSymbol key = ic_info->keys[ic_info->key_head];
3317 MSymbol alias = Mnil;
3320 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3321 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3325 submap = mplist_get (map->submaps, key);
3328 && (alias = msymbol_get (alias, M_key_alias))
3330 submap = mplist_get (map->submaps, alias);
3335 if (! alias || alias == key)
3336 MDEBUG_PRINT (" submap-found");
3338 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3339 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3340 ic->preedit_changed = 1;
3341 ic->cursor_pos = ic_info->state_pos;
3342 ic_info->key_head++;
3343 ic_info->map = map = submap;
3344 if (map->map_actions)
3346 MDEBUG_PRINT (" map-actions:");
3347 if (take_action_list (ic, map->map_actions) < 0)
3349 MDEBUG_PRINT ("\n");
3353 else if (map->submaps)
3355 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3357 MSymbol key = ic_info->keys[i];
3358 char *name = msymbol_name (key);
3360 if (! name[0] || ! name[1])
3361 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3365 /* If this is the terminal map or we have shifted to another
3366 state, perform branch actions (if any). */
3367 if (! map->submaps || map != ic_info->map)
3369 if (map->branch_actions)
3371 MDEBUG_PRINT (" branch-actions:");
3372 if (take_action_list (ic, map->branch_actions) < 0)
3374 MDEBUG_PRINT ("\n");
3378 /* If MAP is still not the root map, shift to the current
3380 if (ic_info->map != ic_info->state->map)
3381 shift_state (ic, ic_info->state->name);
3386 /* MAP can not handle KEY. */
3388 /* If MAP is the root map of the initial state, it means that
3389 the current input method can not handle KEY. */
3390 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3392 MDEBUG_PRINT (" unhandled\n");
3396 if (map != ic_info->state->map)
3398 /* If MAP is not the root map... */
3399 /* If MAP has branch actions, perform them. */
3400 if (map->branch_actions)
3402 MDEBUG_PRINT (" branch-actions:");
3403 if (take_action_list (ic, map->branch_actions) < 0)
3405 MDEBUG_PRINT ("\n");
3409 /* If MAP is still not the root map, shift to the current
3411 if (ic_info->map != ic_info->state->map)
3412 shift_state (ic, ic_info->state->name);
3416 /* MAP is the root map, perform branch actions (if any) or
3417 shift to the initial state. */
3418 if (map->branch_actions)
3420 MDEBUG_PRINT (" branch-actions:");
3421 if (take_action_list (ic, map->branch_actions) < 0)
3423 MDEBUG_PRINT ("\n");
3428 shift_state (ic, Mnil);
3431 MDEBUG_PRINT ("\n");
3435 /* Initialize IC->ic_info. */
3438 init_ic_info (MInputContext *ic)
3440 MInputMethodInfo *im_info = ic->im->info;
3441 MInputContextInfo *ic_info = ic->info;
3444 MLIST_INIT1 (ic_info, keys, 8);;
3446 ic_info->markers = mplist ();
3448 ic_info->vars = mplist ();
3449 if (im_info->configured_vars)
3450 MPLIST_DO (plist, im_info->configured_vars)
3452 MPlist *pl = MPLIST_PLIST (plist);
3453 MSymbol name = MPLIST_SYMBOL (pl);
3455 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3456 if (MPLIST_KEY (pl) != Mt)
3458 MPlist *p = mplist ();
3460 mplist_push (ic_info->vars, Mplist, p);
3461 M17N_OBJECT_UNREF (p);
3462 mplist_add (p, Msymbol, name);
3463 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3466 ic_info->vars_saved = mplist_copy (ic_info->vars);
3468 if (im_info->externals)
3470 MPlist *func_args = mplist (), *plist;
3472 mplist_add (func_args, Mt, ic);
3473 MPLIST_DO (plist, im_info->externals)
3475 MIMExternalModule *external = MPLIST_VAL (plist);
3476 MIMExternalFunc func
3477 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3482 M17N_OBJECT_UNREF (func_args);
3485 ic_info->preedit_saved = mtext ();
3486 ic_info->tick = im_info->tick;
3489 /* Finalize IC->ic_info. */
3492 fini_ic_info (MInputContext *ic)
3494 MInputMethodInfo *im_info = ic->im->info;
3495 MInputContextInfo *ic_info = ic->info;
3497 if (im_info->externals)
3499 MPlist *func_args = mplist (), *plist;
3501 mplist_add (func_args, Mt, ic);
3502 MPLIST_DO (plist, im_info->externals)
3504 MIMExternalModule *external = MPLIST_VAL (plist);
3505 MIMExternalFunc func
3506 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3511 M17N_OBJECT_UNREF (func_args);
3514 MLIST_FREE1 (ic_info, keys);
3515 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3516 M17N_OBJECT_UNREF (ic_info->markers);
3517 M17N_OBJECT_UNREF (ic_info->vars);
3518 M17N_OBJECT_UNREF (ic_info->vars_saved);
3519 M17N_OBJECT_UNREF (ic_info->preceding_text);
3520 M17N_OBJECT_UNREF (ic_info->following_text);
3522 memset (ic_info, 0, sizeof (MInputContextInfo));
3526 re_init_ic (MInputContext *ic, int reload)
3528 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3529 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3530 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3532 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3533 preedit_changed = mtext_nchars (ic->preedit) > 0;
3534 cursor_pos_changed = ic->cursor_pos > 0;
3535 candidates_changed = 0;
3536 if (ic->candidate_list)
3538 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3539 M17N_OBJECT_UNREF (ic->candidate_list);
3540 ic->candidate_list = NULL;
3542 if (ic->candidate_show)
3544 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3545 ic->candidate_show = 0;
3547 if (ic->candidate_index > 0)
3549 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3550 ic->candidate_index = 0;
3551 ic->candidate_from = ic->candidate_to = 0;
3553 if (mtext_nchars (ic->produced) > 0)
3554 mtext_reset (ic->produced);
3555 if (mtext_nchars (ic->preedit) > 0)
3556 mtext_reset (ic->preedit);
3558 M17N_OBJECT_UNREF (ic->plist);
3559 ic->plist = mplist ();
3563 reload_im_info (im_info);
3565 shift_state (ic, Mnil);
3566 ic->status_changed = status_changed;
3567 ic->preedit_changed = preedit_changed;
3568 ic->cursor_pos_changed = cursor_pos_changed;
3569 ic->candidates_changed = candidates_changed;
3573 reset_ic (MInputContext *ic, MSymbol ignore)
3575 MDEBUG_PRINT ("\n [IM] reset\n");
3580 open_im (MInputMethod *im)
3582 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3585 MERROR (MERROR_IM, -1);
3592 close_im (MInputMethod *im)
3598 create_ic (MInputContext *ic)
3600 MInputContextInfo *ic_info;
3602 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3605 shift_state (ic, Mnil);
3610 destroy_ic (MInputContext *ic)
3617 check_reload (MInputContext *ic, MSymbol key)
3619 MInputMethodInfo *im_info = ic->im->info;
3620 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3624 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3628 MPLIST_DO (plist, plist)
3630 MSymbol this_key, alias;
3632 if (MPLIST_MTEXT_P (plist))
3634 MText *mt = MPLIST_MTEXT (plist);
3635 int c = mtext_ref_char (mt, 0);
3639 this_key = one_char_symbol[c];
3643 MPlist *pl = MPLIST_PLIST (plist);
3645 this_key = MPLIST_SYMBOL (pl);
3649 && (alias = msymbol_get (alias, M_key_alias))
3650 && alias != this_key);
3654 if (MPLIST_TAIL_P (plist))
3657 MDEBUG_PRINT ("\n [IM] reload");
3663 /** Handle the input key KEY in the current state and map of IC->info.
3664 If KEY is handled but no text is produced, return 0, otherwise
3670 filter (MInputContext *ic, MSymbol key, void *arg)
3672 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3673 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3676 if (check_reload (ic, key))
3679 if (! ic_info->state)
3681 ic_info->key_unhandled = 1;
3684 mtext_reset (ic->produced);
3685 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3686 M17N_OBJECT_UNREF (ic_info->preceding_text);
3687 M17N_OBJECT_UNREF (ic_info->following_text);
3688 ic_info->preceding_text = ic_info->following_text = NULL;
3689 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3690 ic_info->key_unhandled = 0;
3693 if (handle_key (ic) < 0)
3695 /* KEY was not handled. Delete it from the current key sequence. */
3696 if (ic_info->used > 0)
3698 memmove (ic_info->keys, ic_info->keys + 1,
3699 sizeof (int) * (ic_info->used - 1));
3701 if (ic_info->state_key_head > 0)
3702 ic_info->state_key_head--;
3703 if (ic_info->commit_key_head > 0)
3704 ic_info->commit_key_head--;
3706 /* This forces returning 1. */
3707 ic_info->key_unhandled = 1;
3713 reset_ic (ic, Mnil);
3714 ic_info->key_unhandled = 1;
3717 /* Break the loop if all keys were handled. */
3718 } while (ic_info->key_head < ic_info->used);
3720 /* If the current map is the root of the initial state, we should
3721 produce any preedit text in ic->produced. */
3722 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3723 preedit_commit (ic);
3725 if (mtext_nchars (ic->produced) > 0)
3727 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3729 if (mdebug__flag & mdebug_mask)
3731 MDEBUG_PRINT (" (produced");
3732 for (i = 0; i < mtext_nchars (ic->produced); i++)
3733 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3738 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3739 Mlanguage, ic->im->language);
3740 if (ic_info->commit_key_head > 0)
3742 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3743 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3744 ic_info->used -= ic_info->commit_key_head;
3745 ic_info->key_head -= ic_info->commit_key_head;
3746 ic_info->state_key_head -= ic_info->commit_key_head;
3747 ic_info->commit_key_head = 0;
3751 if (ic_info->key_unhandled)
3754 ic_info->key_head = ic_info->state_key_head
3755 = ic_info->commit_key_head = 0;
3758 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3762 /** Return 1 if the last event or key was not handled, otherwise
3765 There is no need of looking up because ic->produced should already
3766 contain the produced text (if any).
3771 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3773 mtext_cat (mt, ic->produced);
3774 mtext_reset (ic->produced);
3775 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3779 /* Input method command handler. */
3781 /* List of all (global and local) commands.
3782 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3783 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3784 Global commands are stored as (t (t COMMAND ...)) */
3787 /* Input method variable handler. */
3790 /* Support functions for mdebug_dump_im. */
3793 dump_im_map (MPlist *map_list, int indent)
3796 MSymbol key = MPLIST_KEY (map_list);
3797 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3799 prefix = (char *) alloca (indent + 1);
3800 memset (prefix, 32, indent);
3801 prefix[indent] = '\0';
3803 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3804 if (map->map_actions)
3805 mdebug_dump_plist (map->map_actions, indent + 2);
3808 MPLIST_DO (map_list, map->submaps)
3810 fprintf (stderr, "\n%s ", prefix);
3811 dump_im_map (map_list, indent + 2);
3814 if (map->branch_actions)
3816 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3817 mdebug_dump_plist (map->branch_actions, indent + 4);
3818 fprintf (stderr, ")");
3820 fprintf (stderr, ")");
3825 dump_im_state (MIMState *state, int indent)
3830 prefix = (char *) alloca (indent + 1);
3831 memset (prefix, 32, indent);
3832 prefix[indent] = '\0';
3834 fprintf (stderr, "(%s", msymbol_name (state->name));
3835 if (state->map->submaps)
3837 MPLIST_DO (map_list, state->map->submaps)
3839 fprintf (stderr, "\n%s ", prefix);
3840 dump_im_map (map_list, indent + 2);
3843 fprintf (stderr, ")");
3851 Minput_driver = msymbol ("input-driver");
3853 Minput_preedit_start = msymbol ("input-preedit-start");
3854 Minput_preedit_done = msymbol ("input-preedit-done");
3855 Minput_preedit_draw = msymbol ("input-preedit-draw");
3856 Minput_status_start = msymbol ("input-status-start");
3857 Minput_status_done = msymbol ("input-status-done");
3858 Minput_status_draw = msymbol ("input-status-draw");
3859 Minput_candidates_start = msymbol ("input-candidates-start");
3860 Minput_candidates_done = msymbol ("input-candidates-done");
3861 Minput_candidates_draw = msymbol ("input-candidates-draw");
3862 Minput_set_spot = msymbol ("input-set-spot");
3863 Minput_focus_move = msymbol ("input-focus-move");
3864 Minput_focus_in = msymbol ("input-focus-in");
3865 Minput_focus_out = msymbol ("input-focus-out");
3866 Minput_toggle = msymbol ("input-toggle");
3867 Minput_reset = msymbol ("input-reset");
3868 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3869 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3870 Mcustomized = msymbol ("customized");
3871 Mconfigured = msymbol ("configured");
3872 Minherited = msymbol ("inherited");
3874 minput_default_driver.open_im = open_im;
3875 minput_default_driver.close_im = close_im;
3876 minput_default_driver.create_ic = create_ic;
3877 minput_default_driver.destroy_ic = destroy_ic;
3878 minput_default_driver.filter = filter;
3879 minput_default_driver.lookup = lookup;
3880 minput_default_driver.callback_list = mplist ();
3881 mplist_put (minput_default_driver.callback_list, Minput_reset,
3883 minput_driver = &minput_default_driver;
3885 fully_initialized = 0;
3892 if (fully_initialized)
3894 free_im_list (im_info_list);
3896 free_im_list (im_custom_list);
3898 free_im_list (im_config_list);
3899 M17N_OBJECT_UNREF (load_im_info_keys);
3902 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3903 M17N_OBJECT_UNREF (minput_driver->callback_list);
3908 minput__callback (MInputContext *ic, MSymbol command)
3910 MInputCallbackFunc func;
3912 if (! ic->im->driver.callback_list)
3914 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3918 (func) (ic, command);
3923 minput__char_to_key (int c)
3925 if (c < 0 || c >= 0x100)
3928 return one_char_symbol[c];
3932 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3937 /*** @addtogroup m17nInputMethod */
3942 @name Variables: Predefined symbols for callback commands.
3944 These are the predefined symbols that are used as the @c COMMAND
3945 argument of callback functions of an input method driver (see
3946 #MInputDriver::callback_list).
3948 Most of them do not require extra argument nor return any value;
3949 exceptions are these:
3951 Minput_get_surrounding_text: When a callback function assigned for
3952 this command is called, the first element of #MInputContext::plist
3953 has key #Minteger and the value specifies which portion of the
3954 surrounding text should be retrieved. If the value is positive,
3955 it specifies the number of characters following the current cursor
3956 position. If the value is negative, the absolute value specifies
3957 the number of characters preceding the current cursor position.
3959 If the surrounding text is currently supported, the callback
3960 function must set the key of this element to #Mtext and the value
3961 to the retrieved M-text. The length of the M-text may be shorter
3962 than the requested number of characters, if the available text is
3963 not that long. The length can be zero in the worst case. Or, the
3964 length may be longer if an application thinks it is more efficient
3965 to return that length.
3967 If the surrounding text is not currently supported, the callback
3968 function should return without changing the first element of
3969 #MInputContext::plist.
3971 Minput_delete_surrounding_text: When a callback function assigned
3972 for this command is called, the first element of
3973 #MInputContext::plist has key #Minteger and the value specifies
3974 which portion of the surrounding text should be deleted in the
3975 same way as the case of Minput_get_surrounding_text. The callback
3976 function must delete the specified text. It should not alter
3977 #MInputContext::plist. */
3979 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
3981 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
3982 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
3984 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
3986 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
3987 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
3988 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
3989 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
3990 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
3993 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
3994 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
3995 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
3996 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
3997 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
3999 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4000 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѲ½¤µ¤»¤ë¤³¤È¤Ê¤¯ÊÖ¤µ¤Ê¤¯¤Æ
4003 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4004 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4005 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4006 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4007 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4008 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4012 MSymbol Minput_preedit_start;
4013 MSymbol Minput_preedit_done;
4014 MSymbol Minput_preedit_draw;
4015 MSymbol Minput_status_start;
4016 MSymbol Minput_status_done;
4017 MSymbol Minput_status_draw;
4018 MSymbol Minput_candidates_start;
4019 MSymbol Minput_candidates_done;
4020 MSymbol Minput_candidates_draw;
4021 MSymbol Minput_set_spot;
4022 MSymbol Minput_toggle;
4023 MSymbol Minput_reset;
4024 MSymbol Minput_get_surrounding_text;
4025 MSymbol Minput_delete_surrounding_text;
4031 @name Variables: Predefined symbols for special input events.
4033 These are the predefined symbols that are used as the @c KEY
4034 argument of minput_filter (). */
4036 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4038 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4043 MSymbol Minput_focus_out;
4044 MSymbol Minput_focus_in;
4045 MSymbol Minput_focus_move;
4051 @name Variables: Predefined symbols used in input method information.
4053 These are the predefined symbols describing status of input method
4054 command and variable, and are used in a return value of
4055 minput_get_command () and minput_get_variable (). */
4057 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4059 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4060 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4064 MSymbol Mcustomized;
4065 MSymbol Mconfigured;
4071 @brief The default driver for internal input methods.
4073 The variable #minput_default_driver is the default driver for
4074 internal input methods.
4076 The member MInputDriver::open_im () searches the m17n database for
4077 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4078 $NAME\> and loads it.
4080 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4081 programmers responsibility to set it to a plist of proper callback
4082 functions. Otherwise, no feedback information (e.g. preedit text)
4083 can be shown to users.
4085 The macro M17N_INIT () sets the variable #minput_driver to the
4086 pointer to this driver so that all internal input methods use it.
4088 Therefore, unless @c minput_driver is set differently, the driver
4089 dependent arguments $ARG of the functions whose name begins with
4090 "minput_" are all ignored. */
4092 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4094 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4096 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4097 \< #Minput_method, $LANGUAGE, $NAME\>
4098 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4100 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4101 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4102 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4103 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4105 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4106 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4108 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4109 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4111 MInputDriver minput_default_driver;
4115 @brief The driver for internal input methods.
4117 The variable #minput_driver is a pointer to the input method
4118 driver that is used by internal input methods. The macro
4119 M17N_INIT () initializes it to a pointer to #minput_default_driver
4120 if <m17n<EM></EM>.h> is included. */
4122 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4124 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4125 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4126 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4127 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4129 MInputDriver *minput_driver;
4131 MSymbol Minput_driver;
4146 @brief Open an input method.
4148 The minput_open_im () function opens an input method whose
4149 language and name match $LANGUAGE and $NAME, and returns a pointer
4150 to the input method object newly allocated.
4152 This function at first decides a driver for the input method as
4155 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4156 #minput_driver is used.
4158 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4159 driver pointed to by the property value is used to open the input
4160 method. If $NAME has no such a property, @c NULL is returned.
4162 Then, the member MInputDriver::open_im () of the driver is
4165 $ARG is set in the member @c arg of the structure MInputMethod so
4166 that the driver can refer to it. */
4168 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4170 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4171 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4173 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4175 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4176 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4178 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4179 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4180 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4182 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4184 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4186 @latexonly \IPAlabel{minput_open} @endlatexonly
4191 minput_open_im (MSymbol language, MSymbol name, void *arg)
4194 MInputDriver *driver;
4198 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4199 msymbol_name (language), msymbol_name (name));
4201 driver = minput_driver;
4204 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4206 MERROR (MERROR_IM, NULL);
4209 MSTRUCT_CALLOC (im, MERROR_IM);
4210 im->language = language;
4213 im->driver = *driver;
4214 if ((*im->driver.open_im) (im) < 0)
4216 MDEBUG_PRINT (" failed\n");
4220 MDEBUG_PRINT (" ok\n");
4227 @brief Close an input method.
4229 The minput_close_im () function closes the input method $IM, which
4230 must have been created by minput_open_im (). */
4233 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4235 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4236 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4239 minput_close_im (MInputMethod *im)
4241 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4242 msymbol_name (im->name), msymbol_name (im->language));
4243 (*im->driver.close_im) (im);
4245 MDEBUG_PRINT (" done\n");
4251 @brief Create an input context.
4253 The minput_create_ic () function creates an input context object
4254 associated with input method $IM, and calls callback functions
4255 corresponding to #Minput_preedit_start, #Minput_status_start, and
4256 #Minput_status_draw in this order.
4259 If an input context is successfully created, minput_create_ic ()
4260 returns a pointer to it. Otherwise it returns @c NULL. */
4263 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4265 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4266 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4267 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4268 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4271 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4272 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4276 minput_create_ic (MInputMethod *im, void *arg)
4280 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4281 msymbol_name (im->name), msymbol_name (im->language));
4282 MSTRUCT_CALLOC (ic, MERROR_IM);
4285 ic->preedit = mtext ();
4286 ic->candidate_list = NULL;
4287 ic->produced = mtext ();
4288 ic->spot.x = ic->spot.y = 0;
4290 ic->plist = mplist ();
4291 if ((*im->driver.create_ic) (ic) < 0)
4293 MDEBUG_PRINT (" failed\n");
4294 M17N_OBJECT_UNREF (ic->preedit);
4295 M17N_OBJECT_UNREF (ic->produced);
4296 M17N_OBJECT_UNREF (ic->plist);
4301 if (im->driver.callback_list)
4303 minput__callback (ic, Minput_preedit_start);
4304 minput__callback (ic, Minput_status_start);
4305 minput__callback (ic, Minput_status_draw);
4308 MDEBUG_PRINT (" ok\n");
4315 @brief Destroy an input context.
4317 The minput_destroy_ic () function destroys the input context $IC,
4318 which must have been created by minput_create_ic (). It calls
4319 callback functions corresponding to #Minput_preedit_done,
4320 #Minput_status_done, and #Minput_candidates_done in this order. */
4323 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4325 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4326 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4327 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4328 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4329 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4333 minput_destroy_ic (MInputContext *ic)
4335 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4336 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4337 if (ic->im->driver.callback_list)
4339 minput__callback (ic, Minput_preedit_done);
4340 minput__callback (ic, Minput_status_done);
4341 minput__callback (ic, Minput_candidates_done);
4343 (*ic->im->driver.destroy_ic) (ic);
4344 M17N_OBJECT_UNREF (ic->preedit);
4345 M17N_OBJECT_UNREF (ic->produced);
4346 M17N_OBJECT_UNREF (ic->plist);
4347 MDEBUG_PRINT (" done\n");
4354 @brief Filter an input key.
4356 The minput_filter () function filters input key $KEY according to
4357 input context $IC, and calls callback functions corresponding to
4358 #Minput_preedit_draw, #Minput_status_draw, and
4359 #Minput_candidates_draw if the preedit text, the status, and the
4360 current candidate are changed respectively.
4362 To make the input method commit the current preedit text (if any)
4363 and shift to the initial state, call this function with #Mnil as
4366 To inform the input method about the focus-out event, call this
4367 function with #Minput_focus_out as $KEY.
4369 To inform the input method about the focus-in event, call this
4370 function with #Minput_focus_in as $KEY.
4372 To inform the input method about the focus-move event (i.e. input
4373 spot change within the same input context), call this function
4374 with #Minput_focus_move as $KEY.
4377 If $KEY is filtered out, this function returns 1. In that case,
4378 the caller should discard the key. Otherwise, it returns 0, and
4379 the caller should handle the key, for instance, by calling the
4380 function minput_lookup () with the same key. */
4383 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4385 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4386 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4387 #Minput_preedit_draw, #Minput_status_draw,
4388 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4391 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4392 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4393 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4394 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4396 @latexonly \IPAlabel{minput_filter} @endlatexonly
4400 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4407 ret = (*ic->im->driver.filter) (ic, key, arg);
4409 if (ic->im->driver.callback_list)
4411 if (ic->preedit_changed)
4412 minput__callback (ic, Minput_preedit_draw);
4413 if (ic->status_changed)
4414 minput__callback (ic, Minput_status_draw);
4415 if (ic->candidates_changed)
4416 minput__callback (ic, Minput_candidates_draw);
4425 @brief Look up a text produced in the input context.
4427 The minput_lookup () function looks up a text in the input context
4428 $IC. $KEY must be identical to the one that was used in the previous call of
4431 If a text was produced by the input method, it is concatenated
4434 This function calls #MInputDriver::lookup .
4437 If $KEY was correctly handled by the input method, this function
4438 returns 0. Otherwise, it returns -1, even though some text
4439 might be produced in $MT. */
4442 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4444 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4445 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4447 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4450 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4453 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4454 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4455 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4457 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4460 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4462 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4467 @brief Set the spot of the input context.
4469 The minput_set_spot () function sets the spot of input context $IC
4470 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4471 The semantics of these values depends on the input method driver.
4473 For instance, a driver designed to work in a CUI environment may
4474 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4475 $DESCENT . A driver designed to work in a window system may
4476 interpret $X and $Y as the pixel offsets relative to the origin of the
4477 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4478 descent pixels of the line at ($X . $Y ).
4480 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4482 $MT and $POS are the M-text and the character position at the spot.
4483 $MT may be @c NULL, in which case, the input method cannot get
4484 information about the text around the spot. */
4487 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4489 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4490 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4491 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4493 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4494 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4495 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4496 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4497 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4498 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4500 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4502 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4503 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4507 minput_set_spot (MInputContext *ic, int x, int y,
4508 int ascent, int descent, int fontsize,
4513 ic->spot.ascent = ascent;
4514 ic->spot.descent = descent;
4515 ic->spot.fontsize = fontsize;
4518 if (ic->im->driver.callback_list)
4519 minput__callback (ic, Minput_set_spot);
4524 @brief Toggle input method.
4526 The minput_toggle () function toggles the input method associated
4527 with input context $IC. */
4529 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4531 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4532 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4536 minput_toggle (MInputContext *ic)
4538 if (ic->im->driver.callback_list)
4539 minput__callback (ic, Minput_toggle);
4540 ic->active = ! ic->active;
4546 @brief Reset an input context.
4548 The minput_reset_ic () function resets input context $IC by
4549 calling a callback function corresponding to #Minput_reset. It
4550 resets the status of $IC to its initial one. As the
4551 current preedit text is deleted without commitment, if necessary,
4552 call minput_filter () with the arg @r key #Mnil to force the input
4553 method to commit the preedit in advance. */
4556 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4558 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4559 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4560 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4561 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4562 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4563 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4566 minput_reset_ic (MInputContext *ic)
4568 if (ic->im->driver.callback_list)
4569 minput__callback (ic, Minput_reset);
4575 @brief Get title and icon filename of an input method.
4577 The minput_get_title_icon () function returns a plist containing a
4578 title and icon filename (if any) of an input method specified by
4579 $LANGUAGE and $NAME.
4581 The first element of the plist has key #Mtext and the value is an
4582 M-text of the title for identifying the input method. The second
4583 element (if any) has key #Mtext and the value is an M-text of the
4584 icon image (absolute) filename for the same purpose.
4587 If there exists a specified input method and it defines an title,
4588 a plist is returned. Otherwise, NULL is returned. The caller
4589 must free the plist by m17n_object_unref (). */
4591 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4593 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4594 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4597 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4598 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4599 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¤ÎÀäÂÐ¥Õ¥¡¥¤¥ë¥Í¡¼¥à¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4602 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4603 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4604 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4607 minput_get_title_icon (MSymbol language, MSymbol name)
4609 MInputMethodInfo *im_info;
4616 im_info = get_im_info (language, name, Mnil, Mtitle);
4617 if (! im_info || !im_info->title)
4619 mt = mtext_get_prop (im_info->title, 0, Mtext);
4621 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4624 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4627 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4628 (char *) MSYMBOL_NAME (name));
4629 file = mdatabase__find_file (buf);
4630 if (! file && language == Mt)
4632 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4633 file = mdatabase__find_file (buf);
4638 mplist_add (plist, Mtext, im_info->title);
4641 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4643 mplist_add (plist, Mtext, mt);
4644 M17N_OBJECT_UNREF (mt);
4652 @brief Get description text of an input method.
4654 The minput_get_description () function returns an M-text that
4655 describes the input method specified by $LANGUAGE and $NAME.
4658 If the specified input method has a description text, a pointer to
4659 #MText is returned. The caller has to free it by m17n_object_unref ().
4660 If the input method does not have a description text, @c NULL is
4663 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4665 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4666 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4668 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4669 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4670 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4671 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4674 minput_get_description (MSymbol language, MSymbol name)
4676 MInputMethodInfo *im_info;
4684 extra = language, language = Mt;
4686 im_info = get_im_info (language, name, extra, Mdescription);
4687 if (! im_info || ! im_info->description)
4689 M17N_OBJECT_REF (im_info->description);
4690 return im_info->description;
4696 @brief Get information about input method command(s).
4698 The minput_get_command () function returns information about
4699 the command $COMMAND of the input method specified by $LANGUAGE and
4700 $NAME. An input method command is a pseudo key event to which one
4701 or more actual input key sequences are assigned.
4703 There are two kinds of commands, global and local. A global
4704 command has a global definition, and the description and the key
4705 assignment may be inherited by a local command. Each input method
4706 defines a local command which has a local key assignment. It may
4707 also declare a local command that inherits the definition of a
4708 global command of the same name.
4710 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4711 information about a global command. Otherwise information about a
4712 local command is returned.
4714 If $COMMAND is #Mnil, information about all commands is returned.
4716 The return value is a @e well-formed plist (#m17nPlist) of this
4719 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4721 @c NAME is a symbol representing the command name.
4723 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4724 command has no description.
4726 @c STATUS is a symbol representing how the key assignment is decided.
4727 The value is #Mnil (the default key assignment), #Mcustomized (the
4728 key assignment is customized by per-user configuration file), or
4729 #Mconfigured (the key assignment is set by the call of
4730 minput_config_command ()). For a local command only, it may also
4731 be #Minherited (the key assignment is inherited from the
4732 corresponding global command).
4734 @c KEYSEQ is a plist of one or more symbols representing a key
4735 sequence assigned to the command. If there's no KEYSEQ, the
4736 command is currently disabled (i.e. no key sequence can trigger
4737 actions of the command).
4739 If $COMMAND is not #Mnil, the first element of the returned plist
4740 contains the information about $COMMAND.
4744 If the requested information was found, a pointer to a non-empty
4745 plist is returned. As the plist is kept in the library, the
4746 caller must not modify nor free it.
4748 Otherwise (the specified input method or the specified command
4749 does not exist), @c NULL is returned. */
4751 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4753 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4754 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4755 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4756 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4758 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4759 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4760 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4761 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4762 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4764 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4765 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4768 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4770 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4773 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4775 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4777 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4780 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4781 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4782 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4783 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4784 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4785 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4787 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4788 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4789 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4790 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4792 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4793 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4797 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4798 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4801 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4806 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4808 /* Return a description of the command COMMAND of the input method
4809 specified by LANGUAGE and NAME. */
4810 MPlist *cmd = minput_get_command (langauge, name, command);
4815 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4816 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4817 return (mplist_key (plist) == Mtext
4818 ? (MText *) mplist_value (plist)
4824 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4826 MInputMethodInfo *im_info;
4830 im_info = get_im_info (language, name, Mnil, Mcommand);
4832 || ! im_info->configured_cmds
4833 || MPLIST_TAIL_P (im_info->configured_cmds))
4835 if (command == Mnil)
4836 return im_info->configured_cmds;
4837 return mplist__assq (im_info->configured_cmds, command);
4843 @brief Configure the key sequence of an input method command.
4845 The minput_config_command () function assigns a list of key
4846 sequences $KEYSEQLIST to the command $COMMAND of the input method
4847 specified by $LANGUAGE and $NAME.
4849 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4850 sequences, and each key sequence must be a plist of symbols.
4852 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4854 If $KEYSEQLIST is NULL, the configuration of the command for the
4855 input method is canceled, and the default key sequences become
4856 effective. In such case, if $COMMAND is #Mnil, configurations for
4857 all commands of the input method are canceled.
4859 If $NAME is #Mnil, this function configures the key assignment of a
4860 global command, not that of a specific input method.
4862 The configuration takes effect for input methods opened or
4863 re-opened later in the current session. In order to make the
4864 configuration take effect for the future session, it must be saved
4865 in a per-user configuration file by the function
4866 minput_save_config ().
4870 If the operation was successful, this function returns 0,
4871 otherwise returns -1. The operation fails in these cases:
4873 <li>$KEYSEQLIST is not in a valid form.
4874 <li>$COMMAND is not available for the input method.
4875 <li>$LANGUAGE and $NAME do not specify an existing input method.
4879 minput_get_commands (), minput_save_config ().
4882 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4884 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4885 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4886 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4888 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4889 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4891 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4893 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4894 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4895 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4898 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4899 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4901 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4902 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4903 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4904 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4908 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4910 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4911 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4912 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4916 minput_get_commands (), minput_save_config ().
4920 /* Add "C-x u" to the "start" command of Unicode input method. */
4922 MSymbol start_command = msymbol ("start");
4923 MSymbol unicode = msymbol ("unicode");
4924 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4926 /* At first get the current key-sequence assignment. */
4927 cmd = mplist_get_command (Mt, unicode, start_command);
4930 /* The input method does not have the command "start". Here
4931 should come some error handling code. */
4933 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4934 the part (KEY-SEQUENCE ...). */
4935 plist = mplist_next (mplist_next (mplist_value (cmd)));
4936 /* Copy it because we should not modify it directly. */
4937 key_seq_list = mplist_copy (plist);
4938 m17n_object_unref (cmds);
4940 key_seq = mplist ();
4941 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4942 mplist_add (key_seq, Msymbol, msymbol ("u"));
4943 mplist_add (key_seq_list, Mplist, key_seq);
4944 m17n_object_unref (key_seq);
4946 minput_config_command (Mt, unicode, start_command, key_seq_list);
4947 m17n_object_unref (key_seq_list);
4952 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4955 MInputMethodInfo *im_info, *config;
4962 if (command == Mnil)
4963 MERROR (MERROR_IM, -1);
4964 MPLIST_DO (plist, keyseqlist)
4965 if (! MPLIST_PLIST_P (plist)
4966 || ! check_command_keyseq (plist))
4967 MERROR (MERROR_IM, -1);
4970 im_info = get_im_info (language, name, Mnil, Mcommand);
4972 MERROR (MERROR_IM, -1);
4975 || ! mplist__assq (im_info->cmds, command)))
4976 MERROR (MERROR_IM, -1);
4978 config = get_config_info (im_info);
4981 if (! im_config_list)
4982 im_config_list = mplist ();
4983 config = new_im_info (NULL, language, name, Mnil, im_config_list);
4984 config->cmds = mplist ();
4985 config->vars = mplist ();
4988 if (command == Mnil)
4990 MInputMethodInfo *custom = get_custom_info (im_info);
4992 mplist_set (config->cmds, Mnil, NULL);
4993 if (custom && custom->cmds)
4995 MPLIST_DO (plist, custom->cmds)
4997 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
4999 mplist_add (plist, Msymbol, command);
5000 mplist_push (config->cmds, Mplist, plist);
5001 M17N_OBJECT_UNREF (plist);
5007 plist = mplist__assq (config->cmds, command);
5010 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
5011 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
5012 if (! MPLIST_TAIL_P (plist))
5013 mplist_set (plist, Mnil, NULL); /* () */
5018 mplist_add (config->cmds, Mplist, plist);
5019 M17N_OBJECT_UNREF (plist);
5020 plist = mplist_add (plist, Msymbol, command);
5021 plist = MPLIST_NEXT (plist);
5027 plist = mplist_add (plist, Msymbol, Mnil);
5028 MPLIST_DO (keyseqlist, keyseqlist)
5030 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5031 plist = mplist_add (plist, Mplist, pl);
5032 M17N_OBJECT_UNREF (pl);
5036 config_all_commands (im_info);
5037 im_info->tick = time (NULL);
5044 @brief Get information about input method variable(s).
5046 The minput_get_variable () function returns information about
5047 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5048 An input method variable controls behavior of an input method.
5050 There are two kinds of variables, global and local. A global
5051 variable has a global definition, and the description and the value
5052 may be inherited by a local variable. Each input method defines a
5053 local variable which has local value. It may also declare a
5054 local variable that inherits definition of a global variable of
5057 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5058 variable is returned. Otherwise information about a local variable
5061 If $VARIABLE is #Mnil, information about all variables is
5064 The return value is a @e well-formed plist (#m17nPlist) of this
5067 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5069 @c NAME is a symbol representing the variable name.
5071 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5072 variable has no description.
5074 @c STATUS is a symbol representing how the value is decided. The
5075 value is #Mnil (the default value), #Mcustomized (the value is
5076 customized by per-user configuration file), or #Mconfigured (the
5077 value is set by the call of minput_config_variable ()). For a
5078 local variable only, it may also be #Minherited (the value is
5079 inherited from the corresponding global variable).
5081 @c VALUE is the initial value of the variable. If the key of this
5082 element is #Mt, the variable has no initial value. Otherwise, the
5083 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5086 @c VALID-VALUEs (if any) specify which values the variable can have.
5087 They have the same type (i.e. having the same key) as @c VALUE except
5088 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5089 may be a plist of two integers specifying the range of possible
5092 If there no @c VALID-VALUE, the variable can have any value as long
5093 as the type is the same as @c VALUE.
5095 If $VARIABLE is not #Mnil, the first element of the returned plist
5096 contains the information about $VARIABLE.
5100 If the requested information was found, a pointer to a non-empty
5101 plist is returned. As the plist is kept in the library, the
5102 caller must not modify nor free it.
5104 Otherwise (the specified input method or the specified variable
5105 does not exist), @c NULL is returned. */
5107 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5109 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5110 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5111 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5113 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5114 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5115 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5116 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5119 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5120 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5122 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5124 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5126 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5129 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5131 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5134 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5135 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5136 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5137 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5138 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5139 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5141 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5142 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5143 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5145 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5146 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5147 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5148 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5150 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5153 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5154 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5158 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5159 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5162 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5166 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5168 MInputMethodInfo *im_info;
5172 im_info = get_im_info (language, name, Mnil, Mvariable);
5173 if (! im_info || ! im_info->configured_vars)
5175 if (variable == Mnil)
5176 return im_info->configured_vars;
5177 return mplist__assq (im_info->configured_vars, variable);
5183 @brief Configure the value of an input method variable.
5185 The minput_config_variable () function assigns $VALUE to the
5186 variable $VARIABLE of the input method specified by $LANGUAGE and
5189 If $VALUE is not NULL, it must be a plist of one element whose key
5190 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5193 If $VALUE is NULL, a configuration for the variable for the input
5194 method is canceled, and the variable is initialized to the default
5195 value. In that case, if $VARIABLE is #Mnil, configurations for
5196 all variables of the input method are canceled.
5198 If $NAME is #Mnil, this function configure the value of global
5199 variable, not that of a specific input method.
5201 The configuration takes effect for input methods opened or
5202 re-opened later in the current session. To make the configuration
5203 take effect for the future session, it must be saved in a per-user
5204 configuration file by the function minput_save_config ().
5208 If the operation was successful, this function returns 0,
5209 otherwise returns -1. The operation fails in these cases:
5211 <li>$VALUE is not in a valid form, the type does not match the
5212 definition, or the value is our of range.
5213 <li>$VARIABLE is not available for the input method.
5214 <li>$LANGUAGE and $NAME do not specify an existing input method.
5218 minput_get_variable (), minput_save_config (). */
5220 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5222 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5223 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5225 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5226 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5228 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5229 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5230 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5232 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5233 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5235 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5236 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5237 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5238 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5242 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5244 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5245 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5246 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5250 minput_get_commands (), minput_save_config ().
5253 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5256 MInputMethodInfo *im_info, *config;
5261 im_info = get_im_info (language, name, Mnil, Mvariable);
5263 MERROR (MERROR_IM, -1);
5264 if (variable == Mnil)
5267 MERROR (MERROR_IM, -1);
5269 else if (! im_info->vars
5270 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5271 MERROR (MERROR_IM, -1);
5273 if (variable != Mnil && value)
5275 plist = MPLIST_PLIST (plist);
5276 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5277 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5278 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5279 if (MPLIST_KEY (plist) != Mt
5280 && ! check_variable_value (value, plist))
5281 MERROR (MERROR_IM, -1);
5284 config = get_config_info (im_info);
5287 if (! im_config_list)
5288 im_config_list = mplist ();
5289 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5290 config->cmds = mplist ();
5291 config->vars = mplist ();
5294 if (variable == Mnil)
5296 MInputMethodInfo *custom = get_custom_info (im_info);
5298 mplist_set (config->vars, Mnil, NULL);
5299 if (custom && custom->cmds)
5301 MPLIST_DO (plist, custom->vars)
5303 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5305 mplist_add (plist, Msymbol, variable);
5306 mplist_push (config->vars, Mplist, plist);
5307 M17N_OBJECT_UNREF (plist);
5313 plist = mplist__assq (config->vars, variable);
5316 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5317 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5318 if (! MPLIST_TAIL_P (plist))
5319 mplist_set (plist, Mnil ,NULL); /* () */
5324 mplist_add (config->vars, Mplist, plist);
5325 M17N_OBJECT_UNREF (plist);
5326 plist = mplist_add (plist, Msymbol, variable);
5327 plist = MPLIST_NEXT (plist);
5331 plist = mplist_add (plist, Msymbol, Mnil);
5332 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5335 config_all_variables (im_info);
5336 im_info->tick = time (NULL);
5343 @brief Get the name of per-user configuration file.
5345 The minput_config_file () function returns the absolute path name
5346 of per-user configuration file into which minput_save_config ()
5347 save configurations. It is usually @c "config.mic" under the
5348 directory @c ".m17n.d" of user's home directory. It is not assured
5349 that the file of the returned name exists nor is
5350 readable/writable. If minput_save_config () fails and returns -1,
5351 an application program might check the file, make it
5352 writable (if possible), and try minput_save_config () again.
5356 This function returns a string. As the string is kept in the
5357 library, the caller must not modify nor free it.
5360 minput_save_config ()
5363 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5365 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5366 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5367 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5368 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5369 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5370 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5371 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5376 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5377 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5380 minput_save_config ()
5384 minput_config_file ()
5388 return mdatabase__file (im_custom_mdb);
5394 @brief Save configurations in per-user configuration file.
5396 The minput_save_config () function saves the configurations done
5397 so far in the current session into the per-user configuration
5402 If the operation was successful, 1 is returned. If the per-user
5403 configuration file is currently locked, 0 is returned. In that
5404 case, the caller may wait for a while and try again. If the
5405 configuration file is not writable, -1 is returned. In that case,
5406 the caller may check the name of the file by calling
5407 minput_config_file (), make it writable if possible, and try
5411 minput_config_file () */
5413 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5415 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5416 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5420 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5421 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5422 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5423 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5427 minput_config_file () */
5430 minput_save_config (void)
5432 MPlist *data, *tail, *plist, *p, *elt;
5436 ret = mdatabase__lock (im_custom_mdb);
5439 if (! im_config_list)
5441 update_custom_info ();
5442 if (! im_custom_list)
5443 im_custom_list = mplist ();
5444 data = tail = mplist ();
5446 MPLIST_DO (plist, im_config_list)
5448 MPlist *pl = MPLIST_PLIST (plist);
5449 MSymbol language, name, extra, command, variable;
5450 MInputMethodInfo *custom, *config;
5452 language = MPLIST_SYMBOL (pl);
5453 pl = MPLIST_NEXT (pl);
5454 name = MPLIST_SYMBOL (pl);
5455 pl = MPLIST_NEXT (pl);
5456 extra = MPLIST_SYMBOL (pl);
5457 pl = MPLIST_NEXT (pl);
5458 config = MPLIST_VAL (pl);
5459 custom = get_custom_info (config);
5461 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5463 MPLIST_DO (pl, config->cmds)
5465 elt = MPLIST_PLIST (pl);
5466 command = MPLIST_SYMBOL (elt);
5468 p = mplist__assq (custom->cmds, command);
5470 custom->cmds = mplist (), p = NULL;
5471 elt = MPLIST_NEXT (elt);
5472 if (MPLIST_TAIL_P (elt))
5475 mplist__pop_unref (p);
5479 elt = MPLIST_NEXT (elt);
5482 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5483 mplist_set (p, Mnil, NULL);
5484 mplist__conc (p, elt);
5488 p = MPLIST_PLIST (pl);
5489 mplist_add (custom->cmds, Mplist, p);
5494 MPLIST_DO (pl, config->vars)
5496 elt = MPLIST_PLIST (pl);
5497 variable = MPLIST_SYMBOL (elt);
5499 p = mplist__assq (custom->vars, variable);
5501 custom->vars = mplist (), p = NULL;
5502 elt = MPLIST_NEXT (elt);
5503 if (MPLIST_TAIL_P (elt))
5506 mplist__pop_unref (p);
5510 elt = MPLIST_NEXT (elt);
5513 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5514 mplist_set (p, Mnil, NULL);
5515 mplist__conc (p, elt);
5519 p = MPLIST_PLIST (pl);
5520 mplist_add (custom->vars, Mplist, p);
5525 M17N_OBJECT_UNREF (im_config_list);
5527 MPLIST_DO (plist, im_custom_list)
5529 MPlist *pl = MPLIST_PLIST (plist);
5530 MSymbol language, name, extra;
5531 MInputMethodInfo *custom, *im_info;
5533 language = MPLIST_SYMBOL (pl);
5534 pl = MPLIST_NEXT (pl);
5535 name = MPLIST_SYMBOL (pl);
5536 pl = MPLIST_NEXT (pl);
5537 extra = MPLIST_SYMBOL (pl);
5538 pl = MPLIST_NEXT (pl);
5539 custom = MPLIST_VAL (pl);
5540 im_info = lookup_im_info (im_info_list, language, name, extra);
5544 config_all_commands (im_info);
5546 config_all_variables (im_info);
5550 tail = mplist_add (tail, Mplist, elt);
5551 M17N_OBJECT_UNREF (elt);
5553 elt = mplist_add (elt, Mplist, pl);
5554 M17N_OBJECT_UNREF (pl);
5555 pl = mplist_add (pl, Msymbol, Minput_method);
5556 pl = mplist_add (pl, Msymbol, language);
5557 pl = mplist_add (pl, Msymbol, name);
5559 pl = mplist_add (pl, Msymbol, extra);
5560 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5563 elt = mplist_add (elt, Mplist, pl);
5564 M17N_OBJECT_UNREF (pl);
5565 pl = mplist_add (pl, Msymbol, Mcommand);
5566 MPLIST_DO (p, custom->cmds)
5567 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5569 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5572 elt = mplist_add (elt, Mplist, pl);
5573 M17N_OBJECT_UNREF (pl);
5574 pl = mplist_add (pl, Msymbol, Mvariable);
5575 MPLIST_DO (p, custom->vars)
5576 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5580 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5581 ret = mdatabase__save (im_custom_mdb, data);
5582 mdatabase__unlock (im_custom_mdb);
5583 M17N_OBJECT_UNREF (data);
5584 return (ret < 0 ? -1 : 1);
5591 @name Obsolete functions
5594 @name Obsolete ¤Ê´Ø¿ô
5600 @brief Get a list of variables of an input method (obsolete).
5602 This function is obsolete. Use minput_get_variable () instead.
5604 The minput_get_variables () function returns a plist (#MPlist) of
5605 variables used to control the behavior of the input method
5606 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5607 (#m17nPlist) of the following format:
5610 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5611 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5615 @c VARNAME is a symbol representing the variable name.
5617 @c DOC-MTEXT is an M-text describing the variable.
5619 @c DEFAULT-VALUE is the default value of the variable. It is a
5620 symbol, integer, or M-text.
5622 @c VALUEs (if any) specifies the possible values of the variable.
5623 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5624 @c TO), where @c FROM and @c TO specifies a range of possible
5627 For instance, suppose an input method has the variables:
5629 @li name:intvar, description:"value is an integer",
5630 initial value:0, value-range:0..3,10,20
5632 @li name:symvar, description:"value is a symbol",
5633 initial value:nil, value-range:a, b, c, nil
5635 @li name:txtvar, description:"value is an M-text",
5636 initial value:empty text, no value-range (i.e. any text)
5638 Then, the returned plist is as follows.
5641 (intvar ("value is an integer" 0 (0 3) 10 20)
5642 symvar ("value is a symbol" nil a b c nil)
5643 txtvar ("value is an M-text" ""))
5647 If the input method uses any variables, a pointer to #MPlist is
5648 returned. As the plist is kept in the library, the caller must not
5649 modify nor free it. If the input method does not use any
5650 variable, @c NULL is returned. */
5652 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5654 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5655 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5656 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5660 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5661 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5665 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5667 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5669 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5672 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5673 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5674 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5676 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5678 @li name:intvar, ÀâÌÀ:"value is an integer",
5679 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5681 @li name:symvar, ÀâÌÀ:"value is a symbol",
5682 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5684 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5685 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5687 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5690 (intvar ("value is an integer" 0 (0 3) 10 20)
5691 symvar ("value is a symbol" nil a b c nil)
5692 txtvar ("value is an M-text" ""))
5696 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5697 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5698 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5701 minput_get_variables (MSymbol language, MSymbol name)
5703 MInputMethodInfo *im_info;
5708 im_info = get_im_info (language, name, Mnil, Mvariable);
5709 if (! im_info || ! im_info->configured_vars)
5712 M17N_OBJECT_UNREF (im_info->bc_vars);
5713 im_info->bc_vars = mplist ();
5714 MPLIST_DO (vars, im_info->configured_vars)
5716 MPlist *plist = MPLIST_PLIST (vars);
5717 MPlist *elt = mplist ();
5719 mplist_push (im_info->bc_vars, Mplist, elt);
5720 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5721 elt = MPLIST_NEXT (elt);
5722 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5723 M17N_OBJECT_UNREF (elt);
5725 return im_info->bc_vars;
5731 @brief Set the initial value of an input method variable.
5733 The minput_set_variable () function sets the initial value of
5734 input method variable $VARIABLE to $VALUE for the input method
5735 specified by $LANGUAGE and $NAME.
5737 By default, the initial value is 0.
5739 This setting gets effective in a newly opened input method.
5742 If the operation was successful, 0 is returned. Otherwise -1 is
5743 returned, and #merror_code is set to #MERROR_IM. */
5745 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5747 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5748 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5749 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5751 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5753 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5756 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5757 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5760 minput_set_variable (MSymbol language, MSymbol name,
5761 MSymbol variable, void *value)
5764 MInputMethodInfo *im_info;
5769 if (variable == Mnil)
5770 MERROR (MERROR_IM, -1);
5771 plist = minput_get_variable (language, name, variable);
5772 plist = MPLIST_PLIST (plist);
5773 plist = MPLIST_NEXT (plist);
5775 mplist_add (pl, MPLIST_KEY (plist), value);
5776 ret = minput_config_variable (language, name, variable, pl);
5777 M17N_OBJECT_UNREF (pl);
5780 im_info = get_im_info (language, name, Mnil, Mvariable);
5789 @brief Get information about input method commands.
5791 The minput_get_commands () function returns information about
5792 input method commands of the input method specified by $LANGUAGE
5793 and $NAME. An input method command is a pseudo key event to which
5794 one or more actual input key sequences are assigned.
5796 There are two kinds of commands, global and local. Global
5797 commands are used by multiple input methods for the same purpose,
5798 and have global key assignments. Local commands are used only by
5799 a specific input method, and have only local key assignments.
5801 Each input method may locally change key assignments for global
5802 commands. The global key assignment for a global command is
5803 effective only when the current input method does not have local
5804 key assignments for that command.
5806 If $NAME is #Mnil, information about global commands is returned.
5807 In this case $LANGUAGE is ignored.
5809 If $NAME is not #Mnil, information about those commands that have
5810 local key assignments in the input method specified by $LANGUAGE
5811 and $NAME is returned.
5814 If no input method commands are found, this function returns @c NULL.
5816 Otherwise, a pointer to a plist is returned. The key of each
5817 element in the plist is a symbol representing a command, and the
5818 value is a plist of the form COMMAND-INFO described below.
5820 The first element of COMMAND-INFO has the key #Mtext, and the
5821 value is an M-text describing the command.
5823 If there are no more elements, that means no key sequences are
5824 assigned to the command. Otherwise, each of the remaining
5825 elements has the key #Mplist, and the value is a plist whose keys are
5826 #Msymbol and values are symbols representing input keys, which are
5827 currently assigned to the command.
5829 As the returned plist is kept in the library, the caller must not
5830 modify nor free it. */
5832 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5834 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5835 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5836 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5837 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5839 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5840 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5841 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5842 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5844 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5845 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5846 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5849 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5850 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5852 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5853 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5857 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5859 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5860 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5861 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5863 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5864 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5865 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5868 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5869 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5870 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5871 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5872 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5874 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5875 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5878 minput_get_commands (MSymbol language, MSymbol name)
5880 MInputMethodInfo *im_info;
5885 im_info = get_im_info (language, name, Mnil, Mcommand);
5886 if (! im_info || ! im_info->configured_vars)
5888 M17N_OBJECT_UNREF (im_info->bc_cmds);
5889 im_info->bc_cmds = mplist ();
5890 MPLIST_DO (cmds, im_info->configured_cmds)
5892 MPlist *plist = MPLIST_PLIST (cmds);
5893 MPlist *elt = mplist ();
5895 mplist_push (im_info->bc_cmds, Mplist, elt);
5896 mplist_add (elt, MPLIST_SYMBOL (plist),
5897 mplist_copy (MPLIST_NEXT (plist)));
5898 M17N_OBJECT_UNREF (elt);
5900 return im_info->bc_cmds;
5906 @brief Assign a key sequence to an input method command (obsolete).
5908 This function is obsolete. Use minput_config_command () instead.
5910 The minput_assign_command_keys () function assigns input key
5911 sequence $KEYSEQ to input method command $COMMAND for the input
5912 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5913 key sequence is assigned globally no matter what $LANGUAGE is.
5914 Otherwise the key sequence is assigned locally.
5916 Each element of $KEYSEQ must have the key $Msymbol and the value
5917 must be a symbol representing an input key.
5919 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5920 globally or locally.
5922 This assignment gets effective in a newly opened input method.
5925 If the operation was successful, 0 is returned. Otherwise -1 is
5926 returned, and #merror_code is set to #MERROR_IM. */
5928 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5930 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5931 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5932 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5933 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5934 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5936 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5937 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5939 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5940 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5942 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5945 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5946 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5949 minput_assign_command_keys (MSymbol language, MSymbol name,
5950 MSymbol command, MPlist *keyseq)
5956 if (command == Mnil)
5957 MERROR (MERROR_IM, -1);
5962 if (! check_command_keyseq (keyseq))
5963 MERROR (MERROR_IM, -1);
5965 mplist_add (plist, Mplist, keyseq);
5970 ret = minput_config_command (language, name, command, keyseq);
5971 M17N_OBJECT_UNREF (keyseq);
5978 /*** @addtogroup m17nDebug */
5984 @brief Dump an input method.
5986 The mdebug_dump_im () function prints the input method $IM in a
5987 human readable way to the stderr. $INDENT specifies how many
5988 columns to indent the lines but the first one.
5991 This function returns $IM. */
5993 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
5995 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
5996 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
5999 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6002 mdebug_dump_im (MInputMethod *im, int indent)
6004 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6007 prefix = (char *) alloca (indent + 1);
6008 memset (prefix, 32, indent);
6009 prefix[indent] = '\0';
6011 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6012 msymbol_name (im->name));
6013 mdebug_dump_mtext (im_info->title, 0, 0);
6014 if (im->name != Mnil)
6018 MPLIST_DO (state, im_info->states)
6020 fprintf (stderr, "\n%s ", prefix);
6021 dump_im_state (MPLIST_VAL (state), indent + 2);
6024 fprintf (stderr, ")");