1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
156 #include "m17n-gui.h"
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_mask = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mundo = msymbol ("undo");
406 Mcall = msymbol ("call");
407 Mshift = msymbol ("shift");
408 Mselect = msymbol ("select");
409 Mshow = msymbol ("show");
410 Mhide = msymbol ("hide");
411 Mcommit = msymbol ("commit");
412 Munhandle = msymbol ("unhandle");
413 Mset = msymbol ("set");
414 Madd = msymbol ("add");
415 Msub = msymbol ("sub");
416 Mmul = msymbol ("mul");
417 Mdiv = msymbol ("div");
418 Mequal = msymbol ("=");
419 Mless = msymbol ("<");
420 Mgreater = msymbol (">");
421 Mless_equal = msymbol ("<=");
422 Mgreater_equal = msymbol (">=");
423 Mcond = msymbol ("cond");
424 Mplus = msymbol ("+");
425 Mminus = msymbol ("-");
426 Mstar = msymbol ("*");
427 Mslash = msymbol ("/");
428 Mand = msymbol ("&");
430 Mnot = msymbol ("!");
432 Mat_reload = msymbol ("@reload");
434 Mcandidates_group_size = msymbol ("candidates-group-size");
435 Mcandidates_charset = msymbol ("candidates-charset");
437 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
438 Mcandidate_index = msymbol (" candidate-index");
440 Minit = msymbol ("init");
441 Mfini = msymbol ("fini");
443 Mdescription = msymbol ("description");
444 Mcommand = msymbol ("command");
445 Mvariable = msymbol ("variable");
446 Mglobal = msymbol ("global");
447 Mconfig = msymbol ("config");
448 M_gettext = msymbol ("_");
450 load_im_info_keys = mplist ();
451 mplist_add (load_im_info_keys, Mstate, Mnil);
452 mplist_push (load_im_info_keys, Mmap, Mnil);
454 im_info_list = mplist ();
455 im_config_list = im_custom_list = NULL;
456 im_custom_mdb = NULL;
457 update_custom_info ();
459 update_global_info ();
461 fully_initialized = 1;
464 #define MINPUT__INIT() \
466 if (! fully_initialized) \
467 fully_initialize (); \
472 marker_code (MSymbol sym, int surrounding)
478 name = MSYMBOL_NAME (sym);
479 return (name[0] != '@' ? -1
480 : (((name[1] >= '0' && name[1] <= '9')
481 || name[1] == '<' || name[1] == '>' || name[1] == '='
482 || name[1] == '[' || name[1] == ']'
484 && name[2] == '\0') ? name[1]
485 : (name[1] != '+' && name[1] != '-') ? -1
486 : (name[2] == '\0' || surrounding) ? name[1]
492 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
494 MPlist *plist = mplist__assq (ic_info->vars, var);
498 plist = MPLIST_PLIST (plist);
499 return MPLIST_NEXT (plist);
503 mplist_push (ic_info->vars, Mplist, plist);
504 M17N_OBJECT_UNREF (plist);
505 plist = mplist_add (plist, Msymbol, var);
506 plist = mplist_add (plist, Minteger, (void *) 0);
511 get_surrounding_text (MInputContext *ic, int len)
515 mplist_push (ic->plist, Minteger, (void *) len);
516 if (minput_callback (ic, Minput_get_surrounding_text) >= 0
517 && MPLIST_MTEXT_P (ic->plist))
518 mt = MPLIST_MTEXT (ic->plist);
519 mplist_pop (ic->plist);
524 delete_surrounding_text (MInputContext *ic, int pos)
526 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
528 mplist_push (ic->plist, Minteger, (void *) pos);
529 minput_callback (ic, Minput_delete_surrounding_text);
530 mplist_pop (ic->plist);
533 M17N_OBJECT_UNREF (ic_info->preceding_text);
534 ic_info->preceding_text = NULL;
538 M17N_OBJECT_UNREF (ic_info->following_text);
539 ic_info->following_text = NULL;
544 get_preceding_char (MInputContext *ic, int pos)
546 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
550 if (pos && ic_info->preceding_text)
552 len = mtext_nchars (ic_info->preceding_text);
554 return mtext_ref_char (ic_info->preceding_text, len - pos);
556 mt = get_surrounding_text (ic, - pos);
559 len = mtext_nchars (mt);
560 if (ic_info->preceding_text)
562 if (mtext_nchars (ic_info->preceding_text) < len)
564 M17N_OBJECT_UNREF (ic_info->preceding_text);
565 ic_info->preceding_text = mt;
568 M17N_OBJECT_UNREF (mt);
571 ic_info->preceding_text = mt;
574 return mtext_ref_char (ic_info->preceding_text, len - pos);
578 get_following_char (MInputContext *ic, int pos)
580 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
584 if (ic_info->following_text)
586 len = mtext_nchars (ic_info->following_text);
588 return mtext_ref_char (ic_info->following_text, pos - 1);
590 mt = get_surrounding_text (ic, pos);
593 len = mtext_nchars (mt);
594 if (ic_info->following_text)
596 if (mtext_nchars (ic_info->following_text) < len)
598 M17N_OBJECT_UNREF (ic_info->following_text);
599 ic_info->following_text = mt;
602 M17N_OBJECT_UNREF (mt);
605 ic_info->following_text = mt;
608 return mtext_ref_char (ic_info->following_text, pos - 1);
612 surrounding_pos (MSymbol sym)
618 name = MSYMBOL_NAME (sym);
620 && (name[1] == '-' || name[1] == '+')
621 && name[2] >= '1' && name[2] <= '9')
622 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
627 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
629 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
631 MText *preedit = ic->preedit;
632 int len = mtext_nchars (preedit);
636 if (MPLIST_INTEGER_P (arg))
637 return MPLIST_INTEGER (arg);
639 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
642 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
646 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
649 return ic_info->key_head;
650 if ((code == '-' || code == '+'))
652 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
656 pos = atoi (name + 1);
658 return get_preceding_char (ic, 0);
659 pos = ic->cursor_pos + pos;
662 if (ic->produced && mtext_len (ic->produced) + pos >= 0)
663 return mtext_ref_char (ic->produced,
664 mtext_len (ic->produced) + pos);
665 return get_preceding_char (ic, - pos);
668 return get_following_char (ic, pos - len + 1);
671 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
673 else if (code >= '0' && code <= '9')
675 else if (code == '=')
676 pos = ic->cursor_pos;
677 else if (code == '[')
678 pos = ic->cursor_pos - 1;
679 else if (code == ']')
680 pos = ic->cursor_pos + 1;
681 else if (code == '<')
683 else if (code == '>')
685 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
689 parse_expression (MPlist *plist)
693 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
695 if (! MPLIST_PLIST_P (plist))
697 plist = MPLIST_PLIST (plist);
698 op = MPLIST_SYMBOL (plist);
699 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
700 && op != Mand && op != Mor && op != Mnot
701 && op != Mless && op != Mgreater && op != Mequal
702 && op != Mless_equal && op != Mgreater_equal)
703 MERROR (MERROR_IM, -1);
704 MPLIST_DO (plist, MPLIST_NEXT (plist))
705 if (parse_expression (plist) < 0)
711 resolve_expression (MInputContext *ic, MPlist *plist)
716 if (MPLIST_INTEGER_P (plist))
717 return MPLIST_INTEGER (plist);
718 if (MPLIST_SYMBOL_P (plist))
719 return integer_value (ic, plist, NULL, 1);
720 if (! MPLIST_PLIST_P (plist))
722 plist = MPLIST_PLIST (plist);
723 if (! MPLIST_SYMBOL_P (plist))
725 op = MPLIST_SYMBOL (plist);
726 plist = MPLIST_NEXT (plist);
727 val = resolve_expression (ic, plist);
729 MPLIST_DO (plist, MPLIST_NEXT (plist))
730 val += resolve_expression (ic, plist);
731 else if (op == Mminus)
732 MPLIST_DO (plist, MPLIST_NEXT (plist))
733 val -= resolve_expression (ic, plist);
734 else if (op == Mstar)
735 MPLIST_DO (plist, MPLIST_NEXT (plist))
736 val *= resolve_expression (ic, plist);
737 else if (op == Mslash)
738 MPLIST_DO (plist, MPLIST_NEXT (plist))
739 val /= resolve_expression (ic, plist);
741 MPLIST_DO (plist, MPLIST_NEXT (plist))
742 val &= resolve_expression (ic, plist);
744 MPLIST_DO (plist, MPLIST_NEXT (plist))
745 val |= resolve_expression (ic, plist);
748 else if (op == Mless)
749 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
750 else if (op == Mequal)
751 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
752 else if (op == Mgreater)
753 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
754 else if (op == Mless_equal)
755 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
756 else if (op == Mgreater_equal)
757 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
761 /* Parse PLIST as an action list. PLIST should have this form:
762 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
763 Return 0 if successfully parsed, otherwise return -1. */
766 parse_action_list (MPlist *plist, MPlist *macros)
768 MPLIST_DO (plist, plist)
770 if (MPLIST_MTEXT_P (plist))
772 /* This is a short form of (insert MTEXT). */
773 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
774 MERROR (MERROR_IM, -1); */
776 else if (MPLIST_PLIST_P (plist)
777 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
778 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
782 /* This is a short form of (insert (GROUPS *)). */
783 MPLIST_DO (pl, MPLIST_PLIST (plist))
785 if (MPLIST_PLIST_P (pl))
789 MPLIST_DO (elt, MPLIST_PLIST (pl))
790 if (! MPLIST_MTEXT_P (elt)
791 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
792 MERROR (MERROR_IM, -1);
796 if (! MPLIST_MTEXT_P (pl)
797 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
798 MERROR (MERROR_IM, -1);
802 else if (MPLIST_INTEGER_P (plist))
804 int c = MPLIST_INTEGER (plist);
806 if (c < 0 || c > MCHAR_MAX)
807 MERROR (MERROR_IM, -1);
809 else if (MPLIST_PLIST_P (plist)
810 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
812 MPlist *pl = MPLIST_PLIST (plist);
813 MSymbol action_name = MPLIST_SYMBOL (pl);
815 pl = MPLIST_NEXT (pl);
817 if (action_name == Minsert)
819 if (MPLIST_MTEXT_P (pl))
821 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
822 MERROR (MERROR_IM, -1);
824 else if (MPLIST_PLIST_P (pl))
826 MPLIST_DO (pl, MPLIST_PLIST (pl))
828 if (MPLIST_PLIST_P (pl))
832 MPLIST_DO (elt, MPLIST_PLIST (pl))
833 if (! MPLIST_MTEXT_P (elt)
834 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
835 MERROR (MERROR_IM, -1);
839 if (! MPLIST_MTEXT_P (pl)
840 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
841 MERROR (MERROR_IM, -1);
845 else if (! MPLIST_SYMBOL_P (pl))
846 MERROR (MERROR_IM, -1);
848 else if (action_name == Mselect
849 || action_name == Mdelete
850 || action_name == Mmove)
852 if (parse_expression (pl) < 0)
855 else if (action_name == Mmark
856 || action_name == Mcall
857 || action_name == Mshift)
859 if (! MPLIST_SYMBOL_P (pl))
860 MERROR (MERROR_IM, -1);
862 else if (action_name == Mundo)
864 if (! MPLIST_TAIL_P (pl))
866 if (! MPLIST_SYMBOL_P (pl)
867 && ! MPLIST_INTEGER_P (pl))
868 MERROR (MERROR_IM, -1);
871 else if (action_name == Mpushback)
873 if (MPLIST_MTEXT_P (pl))
875 MText *mt = MPLIST_MTEXT (pl);
877 if (mtext_nchars (mt) != mtext_nbytes (mt))
878 MERROR (MERROR_IM, -1);
880 else if (MPLIST_PLIST_P (pl))
884 MPLIST_DO (p, MPLIST_PLIST (pl))
885 if (! MPLIST_SYMBOL_P (p))
886 MERROR (MERROR_IM, -1);
888 else if (! MPLIST_INTEGER_P (pl))
889 MERROR (MERROR_IM, -1);
891 else if (action_name == Mset || action_name == Madd
892 || action_name == Msub || action_name == Mmul
893 || action_name == Mdiv)
895 if (! MPLIST_SYMBOL_P (pl))
896 MERROR (MERROR_IM, -1);
897 if (parse_expression (MPLIST_NEXT (pl)) < 0)
900 else if (action_name == Mequal || action_name == Mless
901 || action_name == Mgreater || action_name == Mless_equal
902 || action_name == Mgreater_equal)
904 if (parse_expression (pl) < 0
905 || parse_expression (MPLIST_NEXT (pl)) < 0)
907 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
908 if (! MPLIST_PLIST_P (pl))
909 MERROR (MERROR_IM, -1);
910 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
911 MERROR (MERROR_IM, -1);
912 pl = MPLIST_NEXT (pl);
913 if (MPLIST_PLIST_P (pl)
914 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
915 MERROR (MERROR_IM, -1);
917 else if (action_name == Mshow || action_name == Mhide
918 || action_name == Mcommit || action_name == Munhandle)
920 else if (action_name == Mcond)
923 if (! MPLIST_PLIST_P (pl))
924 MERROR (MERROR_IM, -1);
926 else if (! macros || ! mplist_get (macros, action_name))
927 MERROR (MERROR_IM, -1);
929 else if (! MPLIST_SYMBOL_P (plist))
930 MERROR (MERROR_IM, -1);
937 resolve_command (MPlist *cmds, MSymbol command)
941 if (! cmds || ! (plist = mplist__assq (cmds, command)))
943 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
944 plist = MPLIST_NEXT (plist);
945 plist = MPLIST_NEXT (plist);
946 plist = MPLIST_NEXT (plist);
950 /* Load a translation into MAP from PLIST.
952 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
955 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
956 MPlist *branch_actions, MPlist *macros)
961 if (MPLIST_MTEXT_P (keylist))
963 MText *mt = MPLIST_MTEXT (keylist);
965 len = mtext_nchars (mt);
966 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
968 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
969 for (i = 0; i < len; i++)
970 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
976 if (MFAILP (MPLIST_PLIST_P (keylist)))
978 elt = MPLIST_PLIST (keylist);
979 len = MPLIST_LENGTH (elt);
980 if (MFAILP (len > 0))
982 keyseq = (MSymbol *) alloca (sizeof (int) * len);
983 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
985 if (MPLIST_INTEGER_P (elt))
987 int c = MPLIST_INTEGER (elt);
989 if (MFAILP (c >= 0 && c < 0x100))
991 keyseq[i] = one_char_symbol[c];
995 if (MFAILP (MPLIST_SYMBOL_P (elt)))
997 keyseq[i] = MPLIST_SYMBOL (elt);
1002 for (i = 0; i < len; i++)
1004 MIMMap *deeper = NULL;
1007 deeper = mplist_get (map->submaps, keyseq[i]);
1009 map->submaps = mplist ();
1012 /* Fixme: It is better to make all deeper maps at once. */
1013 MSTRUCT_CALLOC (deeper, MERROR_IM);
1014 mplist_put (map->submaps, keyseq[i], deeper);
1019 /* We reach a terminal map. */
1020 if (map->map_actions
1021 || map->branch_actions)
1022 /* This map is already defined. We avoid overriding it. */
1025 if (! MPLIST_TAIL_P (map_actions))
1027 if (parse_action_list (map_actions, macros) < 0)
1028 MERROR (MERROR_IM, -1);
1029 map->map_actions = map_actions;
1033 map->branch_actions = branch_actions;
1034 M17N_OBJECT_REF (branch_actions);
1040 /* Load a branch from PLIST into MAP. PLIST has this form:
1041 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1044 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1047 MPlist *branch_actions;
1049 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1051 map_name = MPLIST_SYMBOL (plist);
1052 plist = MPLIST_NEXT (plist);
1053 if (MPLIST_TAIL_P (plist))
1054 branch_actions = NULL;
1055 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1058 branch_actions = plist;
1059 if (map_name == Mnil)
1061 map->branch_actions = branch_actions;
1063 M17N_OBJECT_REF (branch_actions);
1065 else if (map_name == Mt)
1067 map->map_actions = branch_actions;
1069 M17N_OBJECT_REF (branch_actions);
1071 else if (im_info->maps
1072 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1074 MPLIST_DO (plist, plist)
1076 MPlist *keylist, *map_actions;
1078 if (! MPLIST_PLIST_P (plist))
1079 MERROR (MERROR_IM, -1);
1080 keylist = MPLIST_PLIST (plist);
1081 map_actions = MPLIST_NEXT (keylist);
1082 if (MPLIST_SYMBOL_P (keylist))
1084 MSymbol command = MPLIST_SYMBOL (keylist);
1087 if (MFAILP (command != Mat_reload))
1089 pl = resolve_command (im_info->configured_cmds, command);
1093 load_translation (map, pl, map_actions, branch_actions,
1097 load_translation (map, keylist, map_actions, branch_actions,
1105 /* Load a macro from PLIST into IM_INFO->macros.
1106 PLIST has this from:
1107 PLIST ::= ( MACRO-NAME ACTION * )
1108 IM_INFO->macros is a plist of macro names vs action list. */
1111 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1116 if (! MPLIST_SYMBOL_P (plist))
1117 MERROR (MERROR_IM, -1);
1118 name = MPLIST_SYMBOL (plist);
1119 plist = MPLIST_NEXT (plist);
1120 if (MPLIST_TAIL_P (plist)
1121 || parse_action_list (plist, im_info->macros) < 0)
1122 MERROR (MERROR_IM, -1);
1123 pl = mplist_get (im_info->macros, name);
1124 M17N_OBJECT_UNREF (pl);
1125 mplist_put (im_info->macros, name, plist);
1126 M17N_OBJECT_REF (plist);
1130 /* Load an external module from PLIST into IM_INFO->externals.
1131 PLIST has this form:
1132 PLIST ::= ( MODULE-NAME FUNCTION * )
1133 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1136 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1141 MIMExternalModule *external;
1145 if (MPLIST_MTEXT_P (plist))
1146 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1147 else if (MPLIST_SYMBOL_P (plist))
1148 module = MPLIST_SYMBOL (plist);
1149 module_file = alloca (strlen (MSYMBOL_NAME (module))
1150 + strlen (DLOPEN_SHLIB_EXT) + 1);
1151 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1153 handle = dlopen (module_file, RTLD_NOW);
1154 if (MFAILP (handle))
1156 fprintf (stderr, "%s\n", dlerror ());
1159 func_list = mplist ();
1160 MPLIST_DO (plist, MPLIST_NEXT (plist))
1162 if (! MPLIST_SYMBOL_P (plist))
1163 MERROR_GOTO (MERROR_IM, err_label);
1164 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1167 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1170 MSTRUCT_MALLOC (external, MERROR_IM);
1171 external->handle = handle;
1172 external->func_list = func_list;
1173 mplist_add (im_info->externals, module, external);
1178 M17N_OBJECT_UNREF (func_list);
1183 free_map (MIMMap *map, int top)
1188 M17N_OBJECT_UNREF (map->map_actions);
1191 MPLIST_DO (plist, map->submaps)
1192 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1193 M17N_OBJECT_UNREF (map->submaps);
1195 M17N_OBJECT_UNREF (map->branch_actions);
1200 free_state (void *object)
1202 MIMState *state = object;
1204 M17N_OBJECT_UNREF (state->title);
1206 free_map (state->map, 1);
1210 /** Load a state from PLIST into a newly allocated state object.
1211 PLIST has this form:
1212 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1213 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1214 Return the state object. */
1217 load_state (MInputMethodInfo *im_info, MPlist *plist)
1221 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1223 M17N_OBJECT (state, free_state, MERROR_IM);
1224 state->name = MPLIST_SYMBOL (plist);
1225 plist = MPLIST_NEXT (plist);
1226 if (MPLIST_MTEXT_P (plist))
1228 state->title = MPLIST_MTEXT (plist);
1229 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1230 Mlanguage, im_info->language);
1231 M17N_OBJECT_REF (state->title);
1232 plist = MPLIST_NEXT (plist);
1234 MSTRUCT_CALLOC (state->map, MERROR_IM);
1235 MPLIST_DO (plist, plist)
1237 if (MFAILP (MPLIST_PLIST_P (plist)))
1239 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1244 /* Return a newly created IM_INFO for an input method specified by
1245 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1247 static MInputMethodInfo *
1248 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1251 MInputMethodInfo *im_info;
1254 if (name == Mnil && extra == Mnil)
1255 language = Mt, extra = Mglobal;
1256 MSTRUCT_CALLOC (im_info, MERROR_IM);
1258 im_info->language = language;
1259 im_info->name = name;
1260 im_info->extra = extra;
1263 mplist_add (plist, Mplist, elt);
1264 M17N_OBJECT_UNREF (elt);
1265 elt = mplist_add (elt, Msymbol, language);
1266 elt = mplist_add (elt, Msymbol, name);
1267 elt = mplist_add (elt, Msymbol, extra);
1268 mplist_add (elt, Mt, im_info);
1274 fini_im_info (MInputMethodInfo *im_info)
1278 M17N_OBJECT_UNREF (im_info->cmds);
1279 M17N_OBJECT_UNREF (im_info->configured_cmds);
1280 M17N_OBJECT_UNREF (im_info->bc_cmds);
1281 M17N_OBJECT_UNREF (im_info->vars);
1282 M17N_OBJECT_UNREF (im_info->configured_vars);
1283 M17N_OBJECT_UNREF (im_info->bc_vars);
1284 M17N_OBJECT_UNREF (im_info->description);
1285 M17N_OBJECT_UNREF (im_info->title);
1286 if (im_info->states)
1288 MPLIST_DO (plist, im_info->states)
1290 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1292 M17N_OBJECT_UNREF (state);
1294 M17N_OBJECT_UNREF (im_info->states);
1297 if (im_info->macros)
1299 MPLIST_DO (plist, im_info->macros)
1300 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1301 M17N_OBJECT_UNREF (im_info->macros);
1304 if (im_info->externals)
1306 MPLIST_DO (plist, im_info->externals)
1308 MIMExternalModule *external = MPLIST_VAL (plist);
1310 dlclose (external->handle);
1311 M17N_OBJECT_UNREF (external->func_list);
1313 MPLIST_KEY (plist) = Mt;
1315 M17N_OBJECT_UNREF (im_info->externals);
1319 MPLIST_DO (plist, im_info->maps)
1321 MPlist *p = MPLIST_PLIST (plist);
1323 M17N_OBJECT_UNREF (p);
1325 M17N_OBJECT_UNREF (im_info->maps);
1332 free_im_info (MInputMethodInfo *im_info)
1334 fini_im_info (im_info);
1339 free_im_list (MPlist *plist)
1343 MPLIST_DO (pl, plist)
1345 MInputMethodInfo *im_info;
1347 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1348 im_info = MPLIST_VAL (elt);
1349 free_im_info (im_info);
1351 M17N_OBJECT_UNREF (plist);
1354 static MInputMethodInfo *
1355 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1357 if (name == Mnil && extra == Mnil)
1358 language = Mt, extra = Mglobal;
1359 while ((plist = mplist__assq (plist, language)))
1361 MPlist *elt = MPLIST_PLIST (plist);
1363 plist = MPLIST_NEXT (plist);
1364 elt = MPLIST_NEXT (elt);
1365 if (MPLIST_SYMBOL (elt) != name)
1367 elt = MPLIST_NEXT (elt);
1368 if (MPLIST_SYMBOL (elt) != extra)
1370 elt = MPLIST_NEXT (elt);
1371 return MPLIST_VAL (elt);
1376 static void load_im_info (MPlist *, MInputMethodInfo *);
1378 #define get_custom_info(im_info) \
1380 ? lookup_im_info (im_custom_list, (im_info)->language, \
1381 (im_info)->name, (im_info)->extra) \
1384 #define get_config_info(im_info) \
1386 ? lookup_im_info (im_config_list, (im_info)->language, \
1387 (im_info)->name, (im_info)->extra) \
1391 update_custom_info (void)
1397 if (mdatabase__check (im_custom_mdb) > 0)
1402 MDatabaseInfo *custom_dir_info;
1403 char custom_path[PATH_MAX + 1];
1405 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1406 if (! custom_dir_info->filename
1407 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1409 strcpy (custom_path, custom_dir_info->filename);
1410 strcat (custom_path, CUSTOM_FILE);
1411 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1417 free_im_list (im_custom_list);
1418 im_custom_list = NULL;
1420 plist = mdatabase_load (im_custom_mdb);
1423 im_custom_list = mplist ();
1425 MPLIST_DO (pl, plist)
1427 MSymbol language, name, extra;
1428 MInputMethodInfo *im_info;
1429 MPlist *im_data, *p;
1431 if (! MPLIST_PLIST_P (pl))
1433 p = MPLIST_PLIST (pl);
1434 im_data = MPLIST_NEXT (p);
1435 if (! MPLIST_PLIST_P (p))
1437 p = MPLIST_PLIST (p);
1438 if (! MPLIST_SYMBOL_P (p)
1439 || MPLIST_SYMBOL (p) != Minput_method)
1441 p = MPLIST_NEXT (p);
1442 if (! MPLIST_SYMBOL_P (p))
1444 language = MPLIST_SYMBOL (p);
1445 p = MPLIST_NEXT (p);
1446 if (! MPLIST_SYMBOL_P (p))
1448 name = MPLIST_SYMBOL (p);
1449 if (language == Mnil || name == Mnil)
1451 p = MPLIST_NEXT (p);
1452 if (MPLIST_TAIL_P (p))
1454 else if (MPLIST_SYMBOL_P (p))
1455 extra = MPLIST_SYMBOL (p);
1458 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1459 load_im_info (im_data, im_info);
1461 M17N_OBJECT_UNREF (plist);
1466 update_global_info (void)
1472 int ret = mdatabase__check (global_info->mdb);
1476 fini_im_info (global_info);
1480 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1482 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1484 if (! global_info->mdb
1485 || ! (plist = mdatabase_load (global_info->mdb)))
1488 load_im_info (plist, global_info);
1489 M17N_OBJECT_UNREF (plist);
1494 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1495 and EXTRA. KEY, if not Mnil, tells which kind of information about
1496 the input method is necessary, and the returned IM_INFO may contain
1497 only that information. */
1499 static MInputMethodInfo *
1500 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1503 MInputMethodInfo *im_info;
1506 if (name == Mnil && extra == Mnil)
1507 language = Mt, extra = Mglobal;
1508 im_info = lookup_im_info (im_info_list, language, name, extra);
1511 if (key == Mnil ? im_info->states != NULL
1512 : key == Mcommand ? im_info->cmds != NULL
1513 : key == Mvariable ? im_info->vars != NULL
1514 : key == Mtitle ? im_info->title != NULL
1515 : key == Mdescription ? im_info->description != NULL
1517 /* IM_INFO already contains required information. */
1519 /* We have not yet loaded required information. */
1523 mdb = mdatabase_find (Minput_method, language, name, extra);
1526 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1531 plist = mdatabase_load (im_info->mdb);
1535 mplist_push (load_im_info_keys, key, Mt);
1536 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1537 mplist_pop (load_im_info_keys);
1541 MERROR (MERROR_IM, im_info);
1542 update_global_info ();
1543 load_im_info (plist, im_info);
1544 M17N_OBJECT_UNREF (plist);
1547 if (! im_info->cmds)
1548 im_info->cmds = mplist ();
1549 if (! im_info->vars)
1550 im_info->vars = mplist ();
1552 if (! im_info->title
1553 && (key == Mnil || key == Mtitle))
1554 im_info->title = (name == Mnil ? mtext ()
1555 : mtext_from_data (MSYMBOL_NAME (name),
1556 MSYMBOL_NAMELEN (name),
1557 MTEXT_FORMAT_US_ASCII));
1561 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1562 If updated, but got unloadable, return -1. Otherwise, update
1563 contents of IM_INFO from the new database, and return 1. */
1566 reload_im_info (MInputMethodInfo *im_info)
1571 update_custom_info ();
1572 update_global_info ();
1573 check = mdatabase__check (im_info->mdb);
1576 plist = mdatabase_load (im_info->mdb);
1579 fini_im_info (im_info);
1580 load_im_info (plist, im_info);
1581 M17N_OBJECT_UNREF (plist);
1585 static MInputMethodInfo *
1586 get_im_info_by_tags (MPlist *plist)
1591 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1592 i++, plist = MPLIST_NEXT (plist))
1593 tag[i] = MPLIST_SYMBOL (plist);
1598 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1603 check_description (MPlist *plist)
1607 if (MPLIST_MTEXT_P (plist))
1609 if (MPLIST_PLIST_P (plist))
1611 MPlist *pl = MPLIST_PLIST (plist);
1613 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1615 pl =MPLIST_NEXT (pl);
1616 if (MFAILP (MPLIST_MTEXT_P (pl)))
1618 mt = MPLIST_MTEXT (pl);
1619 M17N_OBJECT_REF (mt);
1622 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1624 if (translated == (char *) MTEXT_DATA (mt))
1625 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1626 if (translated != (char *) MTEXT_DATA (mt))
1628 M17N_OBJECT_UNREF (mt);
1629 mt = mtext__from_data (translated, strlen (translated),
1630 MTEXT_FORMAT_UTF_8, 0);
1634 mplist_set (plist, Mtext, mt);
1635 M17N_OBJECT_UNREF (mt);
1638 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1644 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1648 check_command_keyseq (MPlist *keyseq)
1650 if (MPLIST_PLIST_P (keyseq))
1652 MPlist *p = MPLIST_PLIST (keyseq);
1655 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1659 if (MPLIST_MTEXT_P (keyseq))
1661 MText *mt = MPLIST_MTEXT (keyseq);
1664 for (i = 0; i < mtext_nchars (mt); i++)
1665 if (mtext_ref_char (mt, i) >= 256)
1672 /* Load command defitions from PLIST into IM_INFO->cmds.
1674 PLIST is well-formed and has this form;
1675 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1676 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1677 M-text or a plist of symbols.
1679 The returned list has the same form, but for each element...
1681 (1) If DESCRIPTION and the rest are omitted, the element is not
1682 stored in the returned list.
1684 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1685 description in global_info->cmds (if any). */
1688 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1692 im_info->cmds = tail = mplist ();
1694 MPLIST_DO (plist, MPLIST_NEXT (plist))
1696 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1699 if (MFAILP (MPLIST_PLIST_P (plist)))
1701 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1702 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1704 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1705 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1707 if (MFAILP (im_info != global_info))
1708 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1712 if (! check_description (p))
1713 mplist_set (p, Msymbol, Mnil);
1714 p = MPLIST_NEXT (p);
1715 while (! MPLIST_TAIL_P (p))
1717 if (MFAILP (check_command_keyseq (p)))
1718 mplist__pop_unref (p);
1720 p = MPLIST_NEXT (p);
1723 tail = mplist_add (tail, Mplist, pl);
1728 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1729 MPlist *config_cmds)
1731 MPlist *global = NULL, *custom = NULL, *config = NULL;
1734 MPlist *description = NULL, *keyseq;
1736 name = MPLIST_SYMBOL (plist);
1737 plist = MPLIST_NEXT (plist);
1738 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1739 description = plist;
1740 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1741 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1742 if (MPLIST_TAIL_P (plist))
1745 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1746 global = MPLIST_NEXT (MPLIST_PLIST (global));
1749 keyseq = MPLIST_NEXT (global);
1750 status = Minherited;
1760 keyseq = MPLIST_NEXT (plist);
1764 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1766 config = MPLIST_NEXT (MPLIST_PLIST (config));
1767 if (! MPLIST_TAIL_P (config))
1769 keyseq = MPLIST_NEXT (config);
1770 status = Mconfigured;
1773 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1775 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1776 if (! MPLIST_TAIL_P (custom))
1778 keyseq = MPLIST_NEXT (custom);
1779 status = Mcustomized;
1784 mplist_add (plist, Msymbol, name);
1786 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1788 mplist_add (plist, Msymbol, Mnil);
1789 mplist_add (plist, Msymbol, status);
1790 mplist__conc (plist, keyseq);
1795 config_all_commands (MInputMethodInfo *im_info)
1797 MPlist *global_cmds, *custom_cmds, *config_cmds;
1798 MInputMethodInfo *temp;
1799 MPlist *tail, *plist;
1801 M17N_OBJECT_UNREF (im_info->configured_cmds);
1803 if (MPLIST_TAIL_P (im_info->cmds)
1807 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1808 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1809 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1811 im_info->configured_cmds = tail = mplist ();
1812 MPLIST_DO (plist, im_info->cmds)
1814 MPlist *pl = config_command (MPLIST_PLIST (plist),
1815 global_cmds, custom_cmds, config_cmds);
1818 tail = mplist_add (tail, Mplist, pl);
1819 M17N_OBJECT_UNREF (pl);
1824 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1825 valid, return 0 if not. */
1828 check_variable_value (MPlist *val, MPlist *global)
1830 MSymbol type = MPLIST_KEY (val);
1831 MPlist *valids = MPLIST_NEXT (val);
1833 if (type != Minteger && type != Mtext && type != Msymbol)
1837 if (MPLIST_KEY (global) != Mt
1838 && MPLIST_KEY (global) != MPLIST_KEY (val))
1840 if (MPLIST_TAIL_P (valids))
1841 valids = MPLIST_NEXT (global);
1843 if (MPLIST_TAIL_P (valids))
1846 if (type == Minteger)
1848 int n = MPLIST_INTEGER (val);
1850 MPLIST_DO (valids, valids)
1852 if (MPLIST_INTEGER_P (valids))
1854 if (n == MPLIST_INTEGER (valids))
1857 else if (MPLIST_PLIST_P (valids))
1859 MPlist *p = MPLIST_PLIST (valids);
1860 int min_bound, max_bound;
1862 if (! MPLIST_INTEGER_P (p))
1863 MERROR (MERROR_IM, 0);
1864 min_bound = MPLIST_INTEGER (p);
1865 p = MPLIST_NEXT (p);
1866 if (! MPLIST_INTEGER_P (p))
1867 MERROR (MERROR_IM, 0);
1868 max_bound = MPLIST_INTEGER (p);
1869 if (n >= min_bound && n <= max_bound)
1874 else if (type == Msymbol)
1876 MSymbol sym = MPLIST_SYMBOL (val);
1878 MPLIST_DO (valids, valids)
1880 if (! MPLIST_SYMBOL_P (valids))
1881 MERROR (MERROR_IM, 0);
1882 if (sym == MPLIST_SYMBOL (valids))
1888 MText *mt = MPLIST_MTEXT (val);
1890 MPLIST_DO (valids, valids)
1892 if (! MPLIST_MTEXT_P (valids))
1893 MERROR (MERROR_IM, 0);
1894 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1899 return (MPLIST_TAIL_P (valids));
1902 /* Load variable defitions from PLIST into IM_INFO->vars.
1904 PLIST is well-formed and has this form;
1905 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1907 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1909 The returned list has the same form, but for each element...
1911 (1) If DESCRIPTION and the rest are omitted, the element is not
1912 stored in the returned list.
1914 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1915 description in global_info->vars (if any). */
1918 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1920 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1921 ? global_info->vars : NULL);
1924 im_info->vars = tail = mplist ();
1925 MPLIST_DO (plist, MPLIST_NEXT (plist))
1929 if (MFAILP (MPLIST_PLIST_P (plist)))
1931 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1932 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1934 if (im_info == global_info)
1936 /* Loading a global variable. */
1937 p = MPLIST_NEXT (pl);
1938 if (MPLIST_TAIL_P (p))
1939 mplist_add (p, Msymbol, Mnil);
1942 if (! check_description (p))
1943 mplist_set (p, Msymbol, Mnil);
1944 p = MPLIST_NEXT (p);
1945 if (MFAILP (! MPLIST_TAIL_P (p)
1946 && check_variable_value (p, NULL)))
1947 mplist_set (p, Mt, NULL);
1950 else if (im_info->mdb)
1952 /* Loading a local variable. */
1953 MSymbol name = MPLIST_SYMBOL (pl);
1954 MPlist *global = NULL;
1957 && (p = mplist__assq (global_vars, name)))
1959 /* P ::= ((NAME DESC ...) ...) */
1960 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1961 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1962 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1965 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1966 if (! MPLIST_TAIL_P (p))
1968 if (! check_description (p))
1969 mplist_set (p, Msymbol, Mnil);
1970 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1971 if (MFAILP (! MPLIST_TAIL_P (p)))
1972 mplist_set (p, Mt, NULL);
1975 MPlist *valid_values = MPLIST_NEXT (p);
1977 if (! MPLIST_TAIL_P (valid_values)
1978 ? MFAILP (check_variable_value (p, NULL))
1979 : global && MFAILP (check_variable_value (p, global)))
1980 mplist_set (p, Mt, NULL);
1986 /* Loading a variable customization. */
1987 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1988 if (MFAILP (! MPLIST_TAIL_P (p)))
1990 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1991 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1992 || MPLIST_MTEXT_P (p)))
1995 tail = mplist_add (tail, Mplist, pl);
2000 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
2001 MPlist *config_vars)
2003 MPlist *global = NULL, *custom = NULL, *config = NULL;
2004 MSymbol name = MPLIST_SYMBOL (plist);
2006 MPlist *description = NULL, *value, *valids;
2010 global = mplist__assq (global_vars, name);
2012 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2015 plist = MPLIST_NEXT (plist);
2016 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2017 description = plist;
2019 description = global;
2021 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2023 if (MPLIST_TAIL_P (plist))
2025 /* Inherit from global (if any). */
2029 if (MPLIST_KEY (value) == Mt)
2031 valids = MPLIST_NEXT (global);
2032 status = Minherited;
2044 value = plist = MPLIST_NEXT (plist);
2045 valids = MPLIST_NEXT (value);
2046 if (MPLIST_KEY (value) == Mt)
2048 if (! MPLIST_TAIL_P (valids))
2051 valids = MPLIST_NEXT (global);
2055 if (config_vars && (config = mplist__assq (config_vars, name)))
2057 config = MPLIST_NEXT (MPLIST_PLIST (config));
2058 if (! MPLIST_TAIL_P (config))
2060 value = MPLIST_NEXT (config);
2061 if (MFAILP (check_variable_value (value, global ? global : plist)))
2063 status = Mconfigured;
2066 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2068 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2069 if (! MPLIST_TAIL_P (custom))
2071 value = MPLIST_NEXT (custom);
2072 if (MFAILP (check_variable_value (value, global ? global : plist)))
2074 status = Mcustomized;
2079 mplist_add (plist, Msymbol, name);
2081 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2083 mplist_add (plist, Msymbol, Mnil);
2084 mplist_add (plist, Msymbol, status);
2086 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2088 mplist_add (plist, Mt, NULL);
2089 if (valids && ! MPLIST_TAIL_P (valids))
2090 mplist__conc (plist, valids);
2094 /* Return a configured variable definition list based on
2095 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2096 get it from global_info->vars. */
2099 config_all_variables (MInputMethodInfo *im_info)
2101 MPlist *global_vars, *custom_vars, *config_vars;
2102 MInputMethodInfo *temp;
2103 MPlist *tail, *plist;
2105 M17N_OBJECT_UNREF (im_info->configured_vars);
2107 if (MPLIST_TAIL_P (im_info->vars)
2111 global_vars = im_info != global_info ? global_info->vars : NULL;
2112 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2113 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2115 im_info->configured_vars = tail = mplist ();
2116 MPLIST_DO (plist, im_info->vars)
2118 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2119 global_vars, custom_vars, config_vars);
2122 tail = mplist_add (tail, Mplist, pl);
2123 M17N_OBJECT_UNREF (pl);
2128 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2129 CONFIG contains configuration information of the input method. */
2132 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2136 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2138 load_commands (im_info, MPLIST_PLIST (pl));
2139 config_all_commands (im_info);
2140 pl = mplist_pop (pl);
2141 M17N_OBJECT_UNREF (pl);
2144 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2146 load_variables (im_info, MPLIST_PLIST (pl));
2147 config_all_variables (im_info);
2148 pl = mplist_pop (pl);
2149 M17N_OBJECT_UNREF (pl);
2152 MPLIST_DO (plist, plist)
2153 if (MPLIST_PLIST_P (plist))
2155 MPlist *elt = MPLIST_PLIST (plist);
2158 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2160 key = MPLIST_SYMBOL (elt);
2165 elt = MPLIST_NEXT (elt);
2166 if (MFAILP (MPLIST_MTEXT_P (elt)))
2168 im_info->title = MPLIST_MTEXT (elt);
2169 M17N_OBJECT_REF (im_info->title);
2171 else if (key == Mmap)
2173 pl = mplist__from_alist (MPLIST_NEXT (elt));
2176 if (! im_info->maps)
2180 mplist__conc (im_info->maps, pl);
2181 M17N_OBJECT_UNREF (pl);
2184 else if (key == Mmacro)
2186 if (! im_info->macros)
2187 im_info->macros = mplist ();
2188 MPLIST_DO (elt, MPLIST_NEXT (elt))
2190 if (MFAILP (MPLIST_PLIST_P (elt)))
2192 load_macros (im_info, MPLIST_PLIST (elt));
2195 else if (key == Mmodule)
2197 if (! im_info->externals)
2198 im_info->externals = mplist ();
2199 MPLIST_DO (elt, MPLIST_NEXT (elt))
2201 if (MFAILP (MPLIST_PLIST_P (elt)))
2203 load_external_module (im_info, MPLIST_PLIST (elt));
2206 else if (key == Mstate)
2208 MPLIST_DO (elt, MPLIST_NEXT (elt))
2212 if (MFAILP (MPLIST_PLIST_P (elt)))
2214 pl = MPLIST_PLIST (elt);
2215 if (! im_info->states)
2216 im_info->states = mplist ();
2217 state = load_state (im_info, MPLIST_PLIST (elt));
2220 mplist_put (im_info->states, state->name, state);
2223 else if (key == Minclude)
2225 /* elt ::= include (tag1 tag2 ...) key item ... */
2227 MInputMethodInfo *temp;
2229 elt = MPLIST_NEXT (elt);
2230 if (MFAILP (MPLIST_PLIST_P (elt)))
2232 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2235 elt = MPLIST_NEXT (elt);
2236 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2238 key = MPLIST_SYMBOL (elt);
2239 elt = MPLIST_NEXT (elt);
2242 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2244 if (! im_info->maps)
2245 im_info->maps = mplist ();
2246 MPLIST_DO (pl, temp->maps)
2248 p = MPLIST_VAL (pl);
2249 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2250 M17N_OBJECT_REF (p);
2253 else if (key == Mmacro)
2255 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2257 if (! im_info->macros)
2258 im_info->macros = mplist ();
2259 MPLIST_DO (pl, temp->macros)
2261 p = MPLIST_VAL (pl);
2262 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2263 M17N_OBJECT_REF (p);
2266 else if (key == Mstate)
2268 if (! temp->states || MPLIST_TAIL_P (temp->states))
2270 if (! im_info->states)
2271 im_info->states = mplist ();
2272 MPLIST_DO (pl, temp->states)
2274 MIMState *state = MPLIST_VAL (pl);
2276 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2277 M17N_OBJECT_REF (state);
2281 else if (key == Mdescription)
2283 if (im_info->description)
2285 elt = MPLIST_NEXT (elt);
2286 if (! check_description (elt))
2288 im_info->description = MPLIST_MTEXT (elt);
2289 M17N_OBJECT_REF (im_info->description);
2292 im_info->tick = time (NULL);
2297 static int take_action_list (MInputContext *ic, MPlist *action_list);
2298 static void preedit_commit (MInputContext *ic);
2301 shift_state (MInputContext *ic, MSymbol state_name)
2303 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2304 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2305 MIMState *orig_state = ic_info->state, *state;
2307 /* Find a state to shift to. If not found, shift to the initial
2309 if (state_name == Mt)
2311 if (! ic_info->prev_state)
2313 state = ic_info->prev_state;
2315 else if (state_name == Mnil)
2317 state = (MIMState *) MPLIST_VAL (im_info->states);
2321 state = (MIMState *) mplist_get (im_info->states, state_name);
2323 state = (MIMState *) MPLIST_VAL (im_info->states);
2326 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2328 /* Enter the new state. */
2329 ic_info->state = state;
2330 ic_info->map = state->map;
2331 ic_info->state_key_head = ic_info->key_head;
2332 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2334 /* We have shifted to the initial state. */
2335 preedit_commit (ic);
2336 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2337 ic_info->state_pos = ic->cursor_pos;
2338 if (state != orig_state)
2340 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2342 /* Shifted to the initial state. */
2343 ic_info->prev_state = NULL;
2344 M17N_OBJECT_UNREF (ic_info->vars_saved);
2345 ic_info->vars_saved = mplist_copy (ic_info->vars);
2348 ic_info->prev_state = orig_state;
2351 ic->status = state->title;
2353 ic->status = im_info->title;
2354 ic->status_changed = 1;
2355 if (ic_info->map == ic_info->state->map
2356 && ic_info->map->map_actions)
2358 MDEBUG_PRINT (" init-actions:");
2359 take_action_list (ic, ic_info->map->map_actions);
2364 /* Find a candidate group that contains a candidate number INDEX from
2365 PLIST. Set START_INDEX to the first candidate number of the group,
2366 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2367 candidate group number if they are non-NULL. If INDEX is -1, find
2368 the last candidate group. */
2371 find_candidates_group (MPlist *plist, int index,
2372 int *start_index, int *end_index, int *group_index)
2374 int i = 0, gidx = 0, len;
2376 MPLIST_DO (plist, plist)
2378 if (MPLIST_MTEXT_P (plist))
2379 len = mtext_nchars (MPLIST_MTEXT (plist));
2381 len = mplist_length (MPLIST_PLIST (plist));
2382 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2388 *end_index = i + len;
2390 *group_index = gidx;
2399 /* Adjust markers for the change of preedit text.
2400 If FROM == TO, the change is insertion of INS chars.
2401 If FROM < TO and INS == 0, the change is deletion of the range.
2402 If FROM < TO and INS > 0, the change is replacement. */
2405 adjust_markers (MInputContext *ic, int from, int to, int ins)
2407 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2412 MPLIST_DO (markers, ic_info->markers)
2413 if (MPLIST_INTEGER (markers) > from)
2414 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2415 if (ic->cursor_pos >= from)
2416 ic->cursor_pos += ins;
2420 MPLIST_DO (markers, ic_info->markers)
2422 if (MPLIST_INTEGER (markers) >= to)
2423 MPLIST_VAL (markers)
2424 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2425 else if (MPLIST_INTEGER (markers) > from)
2426 MPLIST_VAL (markers) = (void *) from;
2428 if (ic->cursor_pos >= to)
2429 ic->cursor_pos += ins - (to - from);
2430 else if (ic->cursor_pos > from)
2431 ic->cursor_pos = from;
2437 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2439 int nchars = mt ? mtext_nchars (mt) : 1;
2442 mtext_ins (ic->preedit, pos, mt);
2444 mtext_ins_char (ic->preedit, pos, c, 1);
2445 adjust_markers (ic, pos, pos, nchars);
2446 ic->preedit_changed = 1;
2451 preedit_delete (MInputContext *ic, int from, int to)
2453 mtext_del (ic->preedit, from, to);
2454 adjust_markers (ic, from, to, 0);
2455 ic->preedit_changed = 1;
2459 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2463 mtext_del (ic->preedit, from, to);
2466 mtext_ins (ic->preedit, from, mt);
2467 ins = mtext_nchars (mt);
2471 mtext_ins_char (ic->preedit, from, c, 1);
2474 adjust_markers (ic, from, to, ins);
2475 ic->preedit_changed = 1;
2480 preedit_commit (MInputContext *ic)
2482 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2483 int preedit_len = mtext_nchars (ic->preedit);
2485 if (preedit_len > 0)
2489 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2490 Mcandidate_list, NULL, 0);
2491 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2492 Mcandidate_index, NULL, 0);
2493 mtext_cat (ic->produced, ic->preedit);
2494 if (mdebug__flag & mdebug_mask)
2498 MDEBUG_PRINT (" (commit");
2499 for (i = 0; i < mtext_nchars (ic->preedit); i++)
2500 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->preedit, i));
2504 mtext_reset (ic->preedit);
2505 mtext_reset (ic_info->preedit_saved);
2506 MPLIST_DO (p, ic_info->markers)
2508 ic->cursor_pos = ic_info->state_pos = 0;
2509 ic->preedit_changed = 1;
2510 ic_info->commit_key_head = ic_info->key_head;
2512 if (ic->candidate_list)
2514 M17N_OBJECT_UNREF (ic->candidate_list);
2515 ic->candidate_list = NULL;
2516 ic->candidate_index = 0;
2517 ic->candidate_from = ic->candidate_to = 0;
2518 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2519 if (ic->candidate_show)
2521 ic->candidate_show = 0;
2522 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2528 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2530 int code = marker_code (sym, 0);
2532 if (mt && (code == '[' || code == ']'))
2536 if (code == '[' && current > 0)
2538 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2542 else if (code == ']' && current < mtext_nchars (mt))
2544 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2550 return (code == '<' ? 0
2551 : code == '>' ? limit
2552 : code == '-' ? current - 1
2553 : code == '+' ? current + 1
2554 : code == '=' ? current
2555 : code - '0' > limit ? limit
2559 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2563 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2565 int from = mtext_property_start (prop);
2566 int to = mtext_property_end (prop);
2568 MPlist *candidate_list = mtext_property_value (prop);
2569 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2571 int ingroup_index = idx - start;
2574 if (MPLIST_MTEXT_P (group))
2576 mt = MPLIST_MTEXT (group);
2577 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2585 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2586 i++, plist = MPLIST_NEXT (plist));
2587 mt = MPLIST_MTEXT (plist);
2588 preedit_replace (ic, from, to, mt, 0);
2589 to = from + mtext_nchars (mt);
2591 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2592 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2593 ic->cursor_pos = to;
2597 get_select_charset (MInputContextInfo * ic_info)
2599 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2602 if (! MPLIST_VAL (plist))
2604 sym = MPLIST_SYMBOL (plist);
2607 return MCHARSET (sym);
2611 adjust_candidates (MPlist *plist, MCharset *charset)
2615 /* plist ::= MTEXT ... | PLIST ... */
2616 plist = mplist_copy (plist);
2617 if (MPLIST_MTEXT_P (plist))
2620 while (! MPLIST_TAIL_P (pl))
2622 /* pl ::= MTEXT ... */
2623 MText *mt = MPLIST_MTEXT (pl);
2627 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2629 c = mtext_ref_char (mt, i);
2630 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2634 mt = mtext_dup (mt);
2635 mplist_set (pl, Mtext, mt);
2636 M17N_OBJECT_UNREF (mt);
2639 mtext_del (mt, i, i + 1);
2642 if (mtext_len (mt) > 0)
2643 pl = MPLIST_NEXT (pl);
2647 M17N_OBJECT_UNREF (mt);
2651 else /* MPLIST_PLIST_P (plist) */
2654 while (! MPLIST_TAIL_P (pl))
2656 /* pl ::= (MTEXT ...) ... */
2657 MPlist *p = MPLIST_PLIST (pl);
2659 /* p ::= MTEXT ... */
2663 while (! MPLIST_TAIL_P (p0))
2665 MText *mt = MPLIST_MTEXT (p0);
2668 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2670 c = mtext_ref_char (mt, i);
2671 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2676 p0 = MPLIST_NEXT (p0);
2683 p = mplist_copy (p);
2684 mplist_set (pl, Mplist, p);
2685 M17N_OBJECT_UNREF (p);
2689 p0 = MPLIST_NEXT (p0);
2692 M17N_OBJECT_UNREF (mt);
2695 if (! MPLIST_TAIL_P (p))
2696 pl = MPLIST_NEXT (pl);
2700 M17N_OBJECT_UNREF (p);
2704 if (MPLIST_TAIL_P (plist))
2706 M17N_OBJECT_UNREF (plist);
2713 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2715 MCharset *charset = get_select_charset (ic_info);
2720 plist = resolve_variable (ic_info, Mcandidates_group_size);
2721 column = MPLIST_INTEGER (plist);
2723 plist = MPLIST_PLIST (args);
2725 plist = adjust_candidates (plist, charset);
2727 if (plist && column > 0)
2729 if (MPLIST_MTEXT_P (plist))
2731 MText *mt = MPLIST_MTEXT (plist);
2732 MPlist *next = MPLIST_NEXT (plist);
2734 if (MPLIST_TAIL_P (next))
2735 M17N_OBJECT_REF (mt);
2738 mt = mtext_dup (mt);
2739 while (! MPLIST_TAIL_P (next))
2741 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2742 next = MPLIST_NEXT (next);
2745 M17N_OBJECT_UNREF (plist);
2747 len = mtext_nchars (mt);
2749 mplist_add (plist, Mtext, mt);
2752 for (i = 0; i < len; i += column)
2754 int to = (i + column < len ? i + column : len);
2755 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2757 mplist_add (plist, Mtext, sub);
2758 M17N_OBJECT_UNREF (sub);
2761 M17N_OBJECT_UNREF (mt);
2763 else if (! MPLIST_TAIL_P (plist))
2765 MPlist *tail = plist;
2766 MPlist *new = mplist ();
2767 MPlist *this = mplist ();
2770 MPLIST_DO (tail, tail)
2772 MPlist *p = MPLIST_PLIST (tail);
2776 MText *mt = MPLIST_MTEXT (p);
2778 if (count == column)
2780 mplist_add (new, Mplist, this);
2781 M17N_OBJECT_UNREF (this);
2785 mplist_add (this, Mtext, mt);
2789 mplist_add (new, Mplist, this);
2790 M17N_OBJECT_UNREF (this);
2791 mplist_set (plist, Mnil, NULL);
2792 MPLIST_DO (tail, new)
2794 MPlist *elt = MPLIST_PLIST (tail);
2796 mplist_add (plist, Mplist, elt);
2798 M17N_OBJECT_UNREF (new);
2807 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2809 MPlist *action = NULL;
2813 if (MPLIST_SYMBOL_P (action_list))
2815 MSymbol var = MPLIST_SYMBOL (action_list);
2818 MPLIST_DO (p, ic_info->vars)
2819 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2821 if (MPLIST_TAIL_P (p))
2823 action = MPLIST_NEXT (MPLIST_PLIST (p));
2824 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2827 if (MPLIST_PLIST_P (action_list))
2829 action = MPLIST_PLIST (action_list);
2830 if (MPLIST_SYMBOL_P (action))
2832 name = MPLIST_SYMBOL (action);
2833 args = MPLIST_NEXT (action);
2835 && MPLIST_PLIST_P (args))
2836 mplist_set (action, Msymbol, M_candidates);
2838 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2841 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2842 mplist_push (action, Msymbol, M_candidates);
2843 mplist_set (action_list, Mplist, action);
2844 M17N_OBJECT_UNREF (action);
2847 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2850 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2851 mplist_push (action, Msymbol, Minsert);
2852 mplist_set (action_list, Mplist, action);
2853 M17N_OBJECT_UNREF (action);
2858 /* Perform list of actions in ACTION_LIST for the current input
2859 context IC. If unhandle action was not performed, return 0.
2860 Otherwise, return -1. */
2863 take_action_list (MInputContext *ic, MPlist *action_list)
2865 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2866 MPlist *candidate_list = ic->candidate_list;
2867 int candidate_index = ic->candidate_index;
2868 int candidate_show = ic->candidate_show;
2869 MTextProperty *prop;
2871 MPLIST_DO (action_list, action_list)
2873 MPlist *action = regularize_action (action_list, ic_info);
2879 name = MPLIST_SYMBOL (action);
2880 args = MPLIST_NEXT (action);
2882 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2883 if (name == Minsert)
2885 if (MPLIST_SYMBOL_P (args))
2887 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2888 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2891 if (MPLIST_MTEXT_P (args))
2892 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2893 else /* MPLIST_INTEGER_P (args)) */
2894 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2896 else if (name == M_candidates)
2898 MPlist *plist = get_candidate_list (ic_info, args);
2901 if (! plist || (MPLIST_PLIST_P (plist) && MPLIST_TAIL_P (plist)))
2903 if (MPLIST_MTEXT_P (plist))
2905 preedit_insert (ic, ic->cursor_pos, NULL,
2906 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2909 else if (MPLIST_TAIL_P (MPLIST_PLIST (plist)))
2913 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2915 preedit_insert (ic, ic->cursor_pos, mt, 0);
2916 len = mtext_nchars (mt);
2918 mtext_put_prop (ic->preedit,
2919 ic->cursor_pos - len, ic->cursor_pos,
2920 Mcandidate_list, plist);
2921 mtext_put_prop (ic->preedit,
2922 ic->cursor_pos - len, ic->cursor_pos,
2923 Mcandidate_index, (void *) 0);
2925 else if (name == Mselect)
2928 int code, idx, gindex;
2929 int pos = ic->cursor_pos;
2931 int idx_decided = 0;
2934 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2937 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2938 group = find_candidates_group (mtext_property_value (prop), idx,
2939 &start, &end, &gindex);
2940 if (MPLIST_SYMBOL_P (args))
2942 code = marker_code (MPLIST_SYMBOL (args), 0);
2945 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2946 if (! MPLIST_INTEGER_P (args))
2948 idx = start + MPLIST_INTEGER (args);
2949 if (idx < start || idx >= end)
2957 if (code != '[' && code != ']')
2962 ? new_index (NULL, ic->candidate_index - start,
2963 end - start - 1, MPLIST_SYMBOL (args),
2965 : MPLIST_INTEGER (args)));
2968 find_candidates_group (mtext_property_value (prop), -1,
2973 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2978 int ingroup_index = idx - start;
2981 group = mtext_property_value (prop);
2982 len = mplist_length (group);
2995 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2996 idx += (MPLIST_MTEXT_P (group)
2997 ? mtext_nchars (MPLIST_MTEXT (group))
2998 : mplist_length (MPLIST_PLIST (group)));
2999 len = (MPLIST_MTEXT_P (group)
3000 ? mtext_nchars (MPLIST_MTEXT (group))
3001 : mplist_length (MPLIST_PLIST (group)));
3002 if (ingroup_index >= len)
3003 ingroup_index = len - 1;
3004 idx += ingroup_index;
3006 update_candidate (ic, prop, idx);
3007 MDEBUG_PRINT1 ("(%d)", idx);
3009 else if (name == Mshow)
3010 ic->candidate_show = 1;
3011 else if (name == Mhide)
3012 ic->candidate_show = 0;
3013 else if (name == Mdelete)
3015 int len = mtext_nchars (ic->preedit);
3019 if (MPLIST_SYMBOL_P (args)
3020 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3022 to = ic->cursor_pos + pos;
3025 delete_surrounding_text (ic, to);
3030 delete_surrounding_text (ic, to - len);
3036 to = (MPLIST_SYMBOL_P (args)
3037 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3039 : MPLIST_INTEGER (args));
3045 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3046 if (to < ic->cursor_pos)
3047 preedit_delete (ic, to, ic->cursor_pos);
3048 else if (to > ic->cursor_pos)
3049 preedit_delete (ic, ic->cursor_pos, to);
3051 else if (name == Mmove)
3053 int len = mtext_nchars (ic->preedit);
3055 = (MPLIST_SYMBOL_P (args)
3056 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3058 : MPLIST_INTEGER (args));
3064 if (pos != ic->cursor_pos)
3066 ic->cursor_pos = pos;
3067 ic->preedit_changed = 1;
3069 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3071 else if (name == Mmark)
3073 int code = marker_code (MPLIST_SYMBOL (args), 0);
3077 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3078 (void *) ic->cursor_pos);
3079 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3082 else if (name == Mpushback)
3084 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3088 if (MPLIST_SYMBOL_P (args))
3090 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3091 if (MPLIST_INTEGER_P (args))
3092 num = MPLIST_INTEGER (args);
3097 num = MPLIST_INTEGER (args);
3100 ic_info->key_head -= num;
3102 ic_info->key_head = 0;
3104 ic_info->key_head = - num;
3105 if (ic_info->key_head > ic_info->used)
3106 ic_info->key_head = ic_info->used;
3108 else if (MPLIST_MTEXT_P (args))
3110 MText *mt = MPLIST_MTEXT (args);
3111 int i, len = mtext_nchars (mt);
3114 ic_info->key_head--;
3115 for (i = 0; i < len; i++)
3117 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3118 if (ic_info->key_head + i < ic_info->used)
3119 ic_info->keys[ic_info->key_head + i] = key;
3121 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3126 MPlist *plist = MPLIST_PLIST (args), *pl;
3130 ic_info->key_head--;
3132 MPLIST_DO (pl, plist)
3134 key = MPLIST_SYMBOL (pl);
3135 if (ic_info->key_head < ic_info->used)
3136 ic_info->keys[ic_info->key_head + i] = key;
3138 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3143 else if (name == Mcall)
3145 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3146 MIMExternalFunc func = NULL;
3147 MSymbol module, func_name;
3148 MPlist *func_args, *val;
3151 module = MPLIST_SYMBOL (args);
3152 args = MPLIST_NEXT (args);
3153 func_name = MPLIST_SYMBOL (args);
3155 if (im_info->externals)
3157 MIMExternalModule *external
3158 = (MIMExternalModule *) mplist_get (im_info->externals,
3161 func = (MIMExternalFunc) mplist_get (external->func_list,
3166 func_args = mplist ();
3167 mplist_add (func_args, Mt, ic);
3168 MPLIST_DO (args, MPLIST_NEXT (args))
3172 if (MPLIST_KEY (args) == Msymbol
3173 && MPLIST_KEY (args) != Mnil
3174 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3176 code = new_index (ic, ic->cursor_pos,
3177 mtext_nchars (ic->preedit),
3178 MPLIST_SYMBOL (args), ic->preedit);
3179 mplist_add (func_args, Minteger, (void *) code);
3182 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3184 val = (func) (func_args);
3185 M17N_OBJECT_UNREF (func_args);
3186 if (val && ! MPLIST_TAIL_P (val))
3187 ret = take_action_list (ic, val);
3188 M17N_OBJECT_UNREF (val);
3192 else if (name == Mshift)
3194 shift_state (ic, MPLIST_SYMBOL (args));
3196 else if (name == Mundo)
3198 int intarg = (MPLIST_TAIL_P (args)
3200 : integer_value (ic, args, NULL, 0));
3202 mtext_reset (ic->preedit);
3203 mtext_reset (ic_info->preedit_saved);
3204 mtext_reset (ic->produced);
3205 M17N_OBJECT_UNREF (ic_info->vars);
3206 ic_info->vars = mplist_copy (ic_info->vars_saved);
3207 ic->cursor_pos = ic_info->state_pos = 0;
3208 ic_info->state_key_head = ic_info->key_head
3209 = ic_info->commit_key_head = 0;
3211 shift_state (ic, Mnil);
3214 if (MPLIST_TAIL_P (args))
3219 ic_info->used += intarg;
3222 ic_info->used = intarg;
3225 else if (name == Mset || name == Madd || name == Msub
3226 || name == Mmul || name == Mdiv)
3228 MSymbol sym = MPLIST_SYMBOL (args);
3233 val1 = integer_value (ic, args, &value, 0);
3234 args = MPLIST_NEXT (args);
3235 val2 = resolve_expression (ic, args);
3237 val1 = val2, op = "=";
3238 else if (name == Madd)
3239 val1 += val2, op = "+=";
3240 else if (name == Msub)
3241 val1 -= val2, op = "-=";
3242 else if (name == Mmul)
3243 val1 *= val2, op = "*=";
3245 val1 /= val2, op = "/=";
3246 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3247 MSYMBOL_NAME (sym), op, val1, val1);
3249 mplist_set (value, Minteger, (void *) val1);
3251 else if (name == Mequal || name == Mless || name == Mgreater
3252 || name == Mless_equal || name == Mgreater_equal)
3255 MPlist *actions1, *actions2;
3258 val1 = resolve_expression (ic, args);
3259 args = MPLIST_NEXT (args);
3260 val2 = resolve_expression (ic, args);
3261 args = MPLIST_NEXT (args);
3262 actions1 = MPLIST_PLIST (args);
3263 args = MPLIST_NEXT (args);
3264 if (MPLIST_TAIL_P (args))
3267 actions2 = MPLIST_PLIST (args);
3268 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3269 if (name == Mequal ? val1 == val2
3270 : name == Mless ? val1 < val2
3271 : name == Mgreater ? val1 > val2
3272 : name == Mless_equal ? val1 <= val2
3275 MDEBUG_PRINT ("ok");
3276 ret = take_action_list (ic, actions1);
3280 MDEBUG_PRINT ("no");
3282 ret = take_action_list (ic, actions2);
3287 else if (name == Mcond)
3291 MPLIST_DO (args, args)
3296 if (! MPLIST_PLIST (args))
3298 cond = MPLIST_PLIST (args);
3299 if (resolve_expression (ic, cond) != 0)
3301 MDEBUG_PRINT1 ("(%dth)", idx);
3302 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3308 else if (name == Mcommit)
3310 preedit_commit (ic);
3312 else if (name == Munhandle)
3314 preedit_commit (ic);
3319 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3323 && (actions = mplist_get (im_info->macros, name)))
3325 if (take_action_list (ic, actions) < 0)
3331 if (ic->candidate_list)
3333 M17N_OBJECT_UNREF (ic->candidate_list);
3334 ic->candidate_list = NULL;
3336 if (ic->cursor_pos > 0
3337 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3340 ic->candidate_list = mtext_property_value (prop);
3341 M17N_OBJECT_REF (ic->candidate_list);
3343 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3345 ic->candidate_from = mtext_property_start (prop);
3346 ic->candidate_to = mtext_property_end (prop);
3349 if (candidate_list != ic->candidate_list)
3350 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3351 if (candidate_index != ic->candidate_index)
3352 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3353 if (candidate_show != ic->candidate_show)
3354 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3359 /* Handle the input key KEY in the current state and map specified in
3360 the input context IC. If KEY is handled correctly, return 0.
3361 Otherwise, return -1. */
3364 handle_key (MInputContext *ic)
3366 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3367 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3368 MIMMap *map = ic_info->map;
3369 MIMMap *submap = NULL;
3370 MSymbol key = ic_info->keys[ic_info->key_head];
3371 MSymbol alias = Mnil;
3374 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3375 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3379 submap = mplist_get (map->submaps, key);
3382 && (alias = msymbol_get (alias, M_key_alias))
3384 submap = mplist_get (map->submaps, alias);
3389 if (! alias || alias == key)
3390 MDEBUG_PRINT (" submap-found");
3392 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3393 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3394 ic->preedit_changed = 1;
3395 ic->cursor_pos = ic_info->state_pos;
3396 ic_info->key_head++;
3397 ic_info->map = map = submap;
3398 if (map->map_actions)
3400 MDEBUG_PRINT (" map-actions:");
3401 if (take_action_list (ic, map->map_actions) < 0)
3403 MDEBUG_PRINT ("\n");
3407 else if (map->submaps)
3409 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3411 MSymbol key = ic_info->keys[i];
3412 char *name = msymbol_name (key);
3414 if (! name[0] || ! name[1])
3415 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3419 /* If this is the terminal map or we have shifted to another
3420 state, perform branch actions (if any). */
3421 if (! map->submaps || map != ic_info->map)
3423 if (map->branch_actions)
3425 MDEBUG_PRINT (" branch-actions:");
3426 if (take_action_list (ic, map->branch_actions) < 0)
3428 MDEBUG_PRINT ("\n");
3432 /* If MAP is still not the root map, shift to the current
3434 if (ic_info->map != ic_info->state->map)
3435 shift_state (ic, ic_info->state->name);
3440 /* MAP can not handle KEY. */
3442 /* Perform branch actions if any. */
3443 if (map->branch_actions)
3445 MDEBUG_PRINT (" branch-actions:");
3446 if (take_action_list (ic, map->branch_actions) < 0)
3448 MDEBUG_PRINT ("\n");
3453 if (map == ic_info->map)
3455 /* The above branch actions didn't change the state. */
3457 /* If MAP is the root map of the initial state, it means
3458 that the current input method can not handle KEY. */
3459 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3461 MDEBUG_PRINT (" unhandled\n");
3465 if (map != ic_info->state->map)
3467 /* MAP is not the root map. Shift to the root map of the
3469 shift_state (ic, ic_info->state->name);
3473 /* MAP is the root map. Shift to the initial state. */
3474 shift_state (ic, Mnil);
3478 MDEBUG_PRINT ("\n");
3482 /* Initialize IC->ic_info. */
3485 init_ic_info (MInputContext *ic)
3487 MInputMethodInfo *im_info = ic->im->info;
3488 MInputContextInfo *ic_info = ic->info;
3491 MLIST_INIT1 (ic_info, keys, 8);;
3493 ic_info->markers = mplist ();
3495 ic_info->vars = mplist ();
3496 if (im_info->configured_vars)
3497 MPLIST_DO (plist, im_info->configured_vars)
3499 MPlist *pl = MPLIST_PLIST (plist);
3500 MSymbol name = MPLIST_SYMBOL (pl);
3502 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3503 if (MPLIST_KEY (pl) != Mt)
3505 MPlist *p = mplist ();
3507 mplist_push (ic_info->vars, Mplist, p);
3508 M17N_OBJECT_UNREF (p);
3509 mplist_add (p, Msymbol, name);
3510 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3513 ic_info->vars_saved = mplist_copy (ic_info->vars);
3515 if (im_info->externals)
3517 MPlist *func_args = mplist (), *plist;
3519 mplist_add (func_args, Mt, ic);
3520 MPLIST_DO (plist, im_info->externals)
3522 MIMExternalModule *external = MPLIST_VAL (plist);
3523 MIMExternalFunc func
3524 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3529 M17N_OBJECT_UNREF (func_args);
3532 ic_info->preedit_saved = mtext ();
3533 ic_info->tick = im_info->tick;
3536 /* Finalize IC->ic_info. */
3539 fini_ic_info (MInputContext *ic)
3541 MInputMethodInfo *im_info = ic->im->info;
3542 MInputContextInfo *ic_info = ic->info;
3544 if (im_info->externals)
3546 MPlist *func_args = mplist (), *plist;
3548 mplist_add (func_args, Mt, ic);
3549 MPLIST_DO (plist, im_info->externals)
3551 MIMExternalModule *external = MPLIST_VAL (plist);
3552 MIMExternalFunc func
3553 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3558 M17N_OBJECT_UNREF (func_args);
3561 MLIST_FREE1 (ic_info, keys);
3562 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3563 M17N_OBJECT_UNREF (ic_info->markers);
3564 M17N_OBJECT_UNREF (ic_info->vars);
3565 M17N_OBJECT_UNREF (ic_info->vars_saved);
3566 M17N_OBJECT_UNREF (ic_info->preceding_text);
3567 M17N_OBJECT_UNREF (ic_info->following_text);
3569 memset (ic_info, 0, sizeof (MInputContextInfo));
3573 re_init_ic (MInputContext *ic, int reload)
3575 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3576 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3577 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3579 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3580 preedit_changed = mtext_nchars (ic->preedit) > 0;
3581 cursor_pos_changed = ic->cursor_pos > 0;
3582 candidates_changed = 0;
3583 if (ic->candidate_list)
3585 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3586 M17N_OBJECT_UNREF (ic->candidate_list);
3587 ic->candidate_list = NULL;
3589 if (ic->candidate_show)
3591 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3592 ic->candidate_show = 0;
3594 if (ic->candidate_index > 0)
3596 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3597 ic->candidate_index = 0;
3598 ic->candidate_from = ic->candidate_to = 0;
3600 if (mtext_nchars (ic->produced) > 0)
3601 mtext_reset (ic->produced);
3602 if (mtext_nchars (ic->preedit) > 0)
3603 mtext_reset (ic->preedit);
3605 M17N_OBJECT_UNREF (ic->plist);
3606 ic->plist = mplist ();
3610 reload_im_info (im_info);
3612 shift_state (ic, Mnil);
3613 ic->status_changed = status_changed;
3614 ic->preedit_changed = preedit_changed;
3615 ic->cursor_pos_changed = cursor_pos_changed;
3616 ic->candidates_changed = candidates_changed;
3620 reset_ic (MInputContext *ic, MSymbol ignore)
3622 MDEBUG_PRINT ("\n [IM] reset\n");
3627 open_im (MInputMethod *im)
3629 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3632 MERROR (MERROR_IM, -1);
3639 close_im (MInputMethod *im)
3645 create_ic (MInputContext *ic)
3647 MInputContextInfo *ic_info;
3649 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3652 shift_state (ic, Mnil);
3657 destroy_ic (MInputContext *ic)
3664 check_reload (MInputContext *ic, MSymbol key)
3666 MInputMethodInfo *im_info = ic->im->info;
3667 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3671 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3675 MPLIST_DO (plist, plist)
3677 MSymbol this_key, alias;
3679 if (MPLIST_MTEXT_P (plist))
3681 MText *mt = MPLIST_MTEXT (plist);
3682 int c = mtext_ref_char (mt, 0);
3686 this_key = one_char_symbol[c];
3690 MPlist *pl = MPLIST_PLIST (plist);
3692 this_key = MPLIST_SYMBOL (pl);
3696 && (alias = msymbol_get (alias, M_key_alias))
3697 && alias != this_key);
3701 if (MPLIST_TAIL_P (plist))
3704 MDEBUG_PRINT ("\n [IM] reload");
3710 /** Handle the input key KEY in the current state and map of IC->info.
3711 If KEY is handled but no text is produced, return 0, otherwise
3717 filter (MInputContext *ic, MSymbol key, void *arg)
3719 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3720 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3723 if (check_reload (ic, key))
3726 if (! ic_info->state)
3728 ic_info->key_unhandled = 1;
3731 mtext_reset (ic->produced);
3732 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3733 M17N_OBJECT_UNREF (ic_info->preceding_text);
3734 M17N_OBJECT_UNREF (ic_info->following_text);
3735 ic_info->preceding_text = ic_info->following_text = NULL;
3736 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3737 ic_info->key_unhandled = 0;
3740 if (handle_key (ic) < 0)
3742 /* KEY was not handled. Delete it from the current key sequence. */
3743 if (ic_info->used > 0)
3745 memmove (ic_info->keys, ic_info->keys + 1,
3746 sizeof (int) * (ic_info->used - 1));
3748 if (ic_info->state_key_head > 0)
3749 ic_info->state_key_head--;
3750 if (ic_info->commit_key_head > 0)
3751 ic_info->commit_key_head--;
3753 /* This forces returning 1. */
3754 ic_info->key_unhandled = 1;
3760 reset_ic (ic, Mnil);
3761 ic_info->key_unhandled = 1;
3764 /* Break the loop if all keys were handled. */
3765 } while (ic_info->key_head < ic_info->used);
3767 /* If the current map is the root of the initial state, we should
3768 produce any preedit text in ic->produced. */
3769 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3770 preedit_commit (ic);
3772 if (mtext_nchars (ic->produced) > 0)
3774 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3776 if (mdebug__flag & mdebug_mask)
3778 MDEBUG_PRINT (" (produced");
3779 for (i = 0; i < mtext_nchars (ic->produced); i++)
3780 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3785 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3786 Mlanguage, ic->im->language);
3788 if (ic_info->commit_key_head > 0)
3790 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3791 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3792 ic_info->used -= ic_info->commit_key_head;
3793 ic_info->key_head -= ic_info->commit_key_head;
3794 ic_info->state_key_head -= ic_info->commit_key_head;
3795 ic_info->commit_key_head = 0;
3797 if (ic_info->key_unhandled)
3800 ic_info->key_head = ic_info->state_key_head
3801 = ic_info->commit_key_head = 0;
3804 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3808 /** Return 1 if the last event or key was not handled, otherwise
3811 There is no need of looking up because ic->produced should already
3812 contain the produced text (if any).
3817 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3819 mtext_cat (mt, ic->produced);
3820 mtext_reset (ic->produced);
3821 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3825 /* Input method command handler. */
3827 /* List of all (global and local) commands.
3828 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3829 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3830 Global commands are stored as (t (t COMMAND ...)) */
3833 /* Input method variable handler. */
3836 /* Support functions for mdebug_dump_im. */
3839 dump_im_map (MPlist *map_list, int indent)
3842 MSymbol key = MPLIST_KEY (map_list);
3843 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3845 prefix = (char *) alloca (indent + 1);
3846 memset (prefix, 32, indent);
3847 prefix[indent] = '\0';
3849 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3850 if (map->map_actions)
3851 mdebug_dump_plist (map->map_actions, indent + 2);
3854 MPLIST_DO (map_list, map->submaps)
3856 fprintf (stderr, "\n%s ", prefix);
3857 dump_im_map (map_list, indent + 2);
3860 if (map->branch_actions)
3862 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3863 mdebug_dump_plist (map->branch_actions, indent + 4);
3864 fprintf (stderr, ")");
3866 fprintf (stderr, ")");
3871 dump_im_state (MIMState *state, int indent)
3876 prefix = (char *) alloca (indent + 1);
3877 memset (prefix, 32, indent);
3878 prefix[indent] = '\0';
3880 fprintf (stderr, "(%s", msymbol_name (state->name));
3881 if (state->map->submaps)
3883 MPLIST_DO (map_list, state->map->submaps)
3885 fprintf (stderr, "\n%s ", prefix);
3886 dump_im_map (map_list, indent + 2);
3889 fprintf (stderr, ")");
3897 Minput_driver = msymbol ("input-driver");
3899 Minput_preedit_start = msymbol ("input-preedit-start");
3900 Minput_preedit_done = msymbol ("input-preedit-done");
3901 Minput_preedit_draw = msymbol ("input-preedit-draw");
3902 Minput_status_start = msymbol ("input-status-start");
3903 Minput_status_done = msymbol ("input-status-done");
3904 Minput_status_draw = msymbol ("input-status-draw");
3905 Minput_candidates_start = msymbol ("input-candidates-start");
3906 Minput_candidates_done = msymbol ("input-candidates-done");
3907 Minput_candidates_draw = msymbol ("input-candidates-draw");
3908 Minput_set_spot = msymbol ("input-set-spot");
3909 Minput_focus_move = msymbol ("input-focus-move");
3910 Minput_focus_in = msymbol ("input-focus-in");
3911 Minput_focus_out = msymbol ("input-focus-out");
3912 Minput_toggle = msymbol ("input-toggle");
3913 Minput_reset = msymbol ("input-reset");
3914 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3915 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3916 Mcustomized = msymbol ("customized");
3917 Mconfigured = msymbol ("configured");
3918 Minherited = msymbol ("inherited");
3920 minput_default_driver.open_im = open_im;
3921 minput_default_driver.close_im = close_im;
3922 minput_default_driver.create_ic = create_ic;
3923 minput_default_driver.destroy_ic = destroy_ic;
3924 minput_default_driver.filter = filter;
3925 minput_default_driver.lookup = lookup;
3926 minput_default_driver.callback_list = mplist ();
3927 mplist_put (minput_default_driver.callback_list, Minput_reset,
3929 minput_driver = &minput_default_driver;
3931 fully_initialized = 0;
3938 if (fully_initialized)
3940 free_im_list (im_info_list);
3942 free_im_list (im_custom_list);
3944 free_im_list (im_config_list);
3945 M17N_OBJECT_UNREF (load_im_info_keys);
3948 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3949 M17N_OBJECT_UNREF (minput_driver->callback_list);
3954 minput__char_to_key (int c)
3956 if (c < 0 || c >= 0x100)
3959 return one_char_symbol[c];
3963 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3968 /*** @addtogroup m17nInputMethod */
3973 @name Variables: Predefined symbols for callback commands.
3975 These are the predefined symbols that are used as the @c COMMAND
3976 argument of callback functions of an input method driver (see
3977 #MInputDriver::callback_list).
3979 Most of them do not require extra argument nor return any value;
3980 exceptions are these:
3982 Minput_get_surrounding_text: When a callback function assigned for
3983 this command is called, the first element of #MInputContext::plist
3984 has key #Minteger and the value specifies which portion of the
3985 surrounding text should be retrieved. If the value is positive,
3986 it specifies the number of characters following the current cursor
3987 position. If the value is negative, the absolute value specifies
3988 the number of characters preceding the current cursor position.
3989 If the value is zero, it means that the caller just wants to know
3990 if the surrounding text is currently supported or not.
3992 If the surrounding text is currently supported, the callback
3993 function must set the key of this element to #Mtext and the value
3994 to the retrieved M-text. The length of the M-text may be shorter
3995 than the requested number of characters, if the available text is
3996 not that long. The length can be zero in the worst case. Or, the
3997 length may be longer if an application thinks it is more efficient
3998 to return that length.
4000 If the surrounding text is not currently supported, the callback
4001 function should return without changing the first element of
4002 #MInputContext::plist.
4004 Minput_delete_surrounding_text: When a callback function assigned
4005 for this command is called, the first element of
4006 #MInputContext::plist has key #Minteger and the value specifies
4007 which portion of the surrounding text should be deleted in the
4008 same way as the case of Minput_get_surrounding_text. The callback
4009 function must delete the specified text. It should not alter
4010 #MInputContext::plist. */
4012 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4014 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4015 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4017 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4019 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4020 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4021 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4022 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4023 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4024 ÃÍʬ¤Îʸ»ú¤ò¼è¤ë¡£¸½ºß¥µ¥é¥¦¥ó¥É¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦
4025 ¤«¤òÃΤꤿ¤¤¤À¤±¤Ç¤¢¤ì¤Ð¡¢¤³¤ÎÃͤϥ¼¥í¤Ç¤âÎɤ¤¡£
4027 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4028 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4029 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4030 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4031 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4033 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4034 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѹ¹¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4036 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4037 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4038 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4039 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4040 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4041 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4045 MSymbol Minput_preedit_start;
4046 MSymbol Minput_preedit_done;
4047 MSymbol Minput_preedit_draw;
4048 MSymbol Minput_status_start;
4049 MSymbol Minput_status_done;
4050 MSymbol Minput_status_draw;
4051 MSymbol Minput_candidates_start;
4052 MSymbol Minput_candidates_done;
4053 MSymbol Minput_candidates_draw;
4054 MSymbol Minput_set_spot;
4055 MSymbol Minput_toggle;
4056 MSymbol Minput_reset;
4057 MSymbol Minput_get_surrounding_text;
4058 MSymbol Minput_delete_surrounding_text;
4064 @name Variables: Predefined symbols for special input events.
4066 These are the predefined symbols that are used as the @c KEY
4067 argument of minput_filter (). */
4069 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4071 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4076 MSymbol Minput_focus_out;
4077 MSymbol Minput_focus_in;
4078 MSymbol Minput_focus_move;
4084 @name Variables: Predefined symbols used in input method information.
4086 These are the predefined symbols describing status of input method
4087 command and variable, and are used in a return value of
4088 minput_get_command () and minput_get_variable (). */
4090 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4092 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4093 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4097 MSymbol Mcustomized;
4098 MSymbol Mconfigured;
4104 @brief The default driver for internal input methods.
4106 The variable #minput_default_driver is the default driver for
4107 internal input methods.
4109 The member MInputDriver::open_im () searches the m17n database for
4110 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4111 $NAME\> and loads it.
4113 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4114 programmers responsibility to set it to a plist of proper callback
4115 functions. Otherwise, no feedback information (e.g. preedit text)
4116 can be shown to users.
4118 The macro M17N_INIT () sets the variable #minput_driver to the
4119 pointer to this driver so that all internal input methods use it.
4121 Therefore, unless @c minput_driver is set differently, the driver
4122 dependent arguments $ARG of the functions whose name begins with
4123 "minput_" are all ignored. */
4125 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4127 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4129 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4130 \< #Minput_method, $LANGUAGE, $NAME\>
4131 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4133 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4134 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4135 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4136 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4138 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4139 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4141 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4142 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4144 MInputDriver minput_default_driver;
4148 @brief The driver for internal input methods.
4150 The variable #minput_driver is a pointer to the input method
4151 driver that is used by internal input methods. The macro
4152 M17N_INIT () initializes it to a pointer to #minput_default_driver
4153 if <m17n<EM></EM>.h> is included. */
4155 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4157 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4158 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4159 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4160 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4162 MInputDriver *minput_driver;
4164 MSymbol Minput_driver;
4179 @brief Open an input method.
4181 The minput_open_im () function opens an input method whose
4182 language and name match $LANGUAGE and $NAME, and returns a pointer
4183 to the input method object newly allocated.
4185 This function at first decides a driver for the input method as
4188 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4189 #minput_driver is used.
4191 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4192 driver pointed to by the property value is used to open the input
4193 method. If $NAME has no such a property, @c NULL is returned.
4195 Then, the member MInputDriver::open_im () of the driver is
4198 $ARG is set in the member @c arg of the structure MInputMethod so
4199 that the driver can refer to it. */
4201 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4203 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4204 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4206 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4208 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4209 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4211 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4212 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4213 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4215 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4217 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4219 @latexonly \IPAlabel{minput_open} @endlatexonly
4224 minput_open_im (MSymbol language, MSymbol name, void *arg)
4227 MInputDriver *driver;
4231 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4232 msymbol_name (language), msymbol_name (name));
4234 driver = minput_driver;
4237 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4239 MERROR (MERROR_IM, NULL);
4242 MSTRUCT_CALLOC (im, MERROR_IM);
4243 im->language = language;
4246 im->driver = *driver;
4247 if ((*im->driver.open_im) (im) < 0)
4249 MDEBUG_PRINT (" failed\n");
4253 MDEBUG_PRINT (" ok\n");
4260 @brief Close an input method.
4262 The minput_close_im () function closes the input method $IM, which
4263 must have been created by minput_open_im (). */
4266 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4268 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4269 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4272 minput_close_im (MInputMethod *im)
4274 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4275 msymbol_name (im->name), msymbol_name (im->language));
4276 (*im->driver.close_im) (im);
4278 MDEBUG_PRINT (" done\n");
4284 @brief Create an input context.
4286 The minput_create_ic () function creates an input context object
4287 associated with input method $IM, and calls callback functions
4288 corresponding to #Minput_preedit_start, #Minput_status_start, and
4289 #Minput_status_draw in this order.
4292 If an input context is successfully created, minput_create_ic ()
4293 returns a pointer to it. Otherwise it returns @c NULL. */
4296 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4298 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4299 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4300 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4301 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4304 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4305 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4309 minput_create_ic (MInputMethod *im, void *arg)
4313 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4314 msymbol_name (im->name), msymbol_name (im->language));
4315 MSTRUCT_CALLOC (ic, MERROR_IM);
4318 ic->preedit = mtext ();
4319 ic->candidate_list = NULL;
4320 ic->produced = mtext ();
4321 ic->spot.x = ic->spot.y = 0;
4323 ic->plist = mplist ();
4324 if ((*im->driver.create_ic) (ic) < 0)
4326 MDEBUG_PRINT (" failed\n");
4327 M17N_OBJECT_UNREF (ic->preedit);
4328 M17N_OBJECT_UNREF (ic->produced);
4329 M17N_OBJECT_UNREF (ic->plist);
4334 if (im->driver.callback_list)
4336 minput_callback (ic, Minput_preedit_start);
4337 minput_callback (ic, Minput_status_start);
4338 minput_callback (ic, Minput_status_draw);
4341 MDEBUG_PRINT (" ok\n");
4348 @brief Destroy an input context.
4350 The minput_destroy_ic () function destroys the input context $IC,
4351 which must have been created by minput_create_ic (). It calls
4352 callback functions corresponding to #Minput_preedit_done,
4353 #Minput_status_done, and #Minput_candidates_done in this order. */
4356 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4358 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4359 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4360 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4361 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4362 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4366 minput_destroy_ic (MInputContext *ic)
4368 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4369 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4370 if (ic->im->driver.callback_list)
4372 minput_callback (ic, Minput_preedit_done);
4373 minput_callback (ic, Minput_status_done);
4374 minput_callback (ic, Minput_candidates_done);
4376 (*ic->im->driver.destroy_ic) (ic);
4377 M17N_OBJECT_UNREF (ic->preedit);
4378 M17N_OBJECT_UNREF (ic->produced);
4379 M17N_OBJECT_UNREF (ic->plist);
4380 MDEBUG_PRINT (" done\n");
4387 @brief Filter an input key.
4389 The minput_filter () function filters input key $KEY according to
4390 input context $IC, and calls callback functions corresponding to
4391 #Minput_preedit_draw, #Minput_status_draw, and
4392 #Minput_candidates_draw if the preedit text, the status, and the
4393 current candidate are changed respectively.
4395 To make the input method commit the current preedit text (if any)
4396 and shift to the initial state, call this function with #Mnil as
4399 To inform the input method about the focus-out event, call this
4400 function with #Minput_focus_out as $KEY.
4402 To inform the input method about the focus-in event, call this
4403 function with #Minput_focus_in as $KEY.
4405 To inform the input method about the focus-move event (i.e. input
4406 spot change within the same input context), call this function
4407 with #Minput_focus_move as $KEY.
4410 If $KEY is filtered out, this function returns 1. In that case,
4411 the caller should discard the key. Otherwise, it returns 0, and
4412 the caller should handle the key, for instance, by calling the
4413 function minput_lookup () with the same key. */
4416 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4418 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4419 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4420 #Minput_preedit_draw, #Minput_status_draw,
4421 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4424 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4425 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4426 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4427 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4429 @latexonly \IPAlabel{minput_filter} @endlatexonly
4433 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4440 if (ic->im->driver.callback_list
4441 && mtext_nchars (ic->preedit) > 0)
4442 minput_callback (ic, Minput_preedit_draw);
4444 ret = (*ic->im->driver.filter) (ic, key, arg);
4446 if (ic->im->driver.callback_list)
4448 if (ic->preedit_changed)
4449 minput_callback (ic, Minput_preedit_draw);
4450 if (ic->status_changed)
4451 minput_callback (ic, Minput_status_draw);
4452 if (ic->candidates_changed)
4453 minput_callback (ic, Minput_candidates_draw);
4462 @brief Look up a text produced in the input context.
4464 The minput_lookup () function looks up a text in the input context
4465 $IC. $KEY must be identical to the one that was used in the previous call of
4468 If a text was produced by the input method, it is concatenated
4471 This function calls #MInputDriver::lookup .
4474 If $KEY was correctly handled by the input method, this function
4475 returns 0. Otherwise, it returns -1, even though some text
4476 might be produced in $MT. */
4479 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4481 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4482 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4484 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4487 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4490 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4491 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4492 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4494 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4497 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4499 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4504 @brief Set the spot of the input context.
4506 The minput_set_spot () function sets the spot of input context $IC
4507 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4508 The semantics of these values depends on the input method driver.
4510 For instance, a driver designed to work in a CUI environment may
4511 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4512 $DESCENT . A driver designed to work in a window system may
4513 interpret $X and $Y as the pixel offsets relative to the origin of the
4514 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4515 descent pixels of the line at ($X . $Y ).
4517 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4519 $MT and $POS are the M-text and the character position at the spot.
4520 $MT may be @c NULL, in which case, the input method cannot get
4521 information about the text around the spot. */
4524 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4526 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4527 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4528 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4530 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4531 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4532 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4533 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4534 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4535 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4537 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4539 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4540 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4544 minput_set_spot (MInputContext *ic, int x, int y,
4545 int ascent, int descent, int fontsize,
4550 ic->spot.ascent = ascent;
4551 ic->spot.descent = descent;
4552 ic->spot.fontsize = fontsize;
4555 if (ic->im->driver.callback_list)
4556 minput_callback (ic, Minput_set_spot);
4561 @brief Toggle input method.
4563 The minput_toggle () function toggles the input method associated
4564 with input context $IC. */
4566 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4568 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4569 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4573 minput_toggle (MInputContext *ic)
4575 if (ic->im->driver.callback_list)
4576 minput_callback (ic, Minput_toggle);
4577 ic->active = ! ic->active;
4583 @brief Reset an input context.
4585 The minput_reset_ic () function resets input context $IC by
4586 calling a callback function corresponding to #Minput_reset. It
4587 resets the status of $IC to its initial one. As the
4588 current preedit text is deleted without commitment, if necessary,
4589 call minput_filter () with the arg @r key #Mnil to force the input
4590 method to commit the preedit in advance. */
4593 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4595 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4596 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4597 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4598 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4599 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4600 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4603 minput_reset_ic (MInputContext *ic)
4605 if (ic->im->driver.callback_list)
4606 minput_callback (ic, Minput_reset);
4612 @brief Get title and icon filename of an input method.
4614 The minput_get_title_icon () function returns a plist containing a
4615 title and icon filename (if any) of an input method specified by
4616 $LANGUAGE and $NAME.
4618 The first element of the plist has key #Mtext and the value is an
4619 M-text of the title for identifying the input method. The second
4620 element (if any) has key #Mtext and the value is an M-text of the
4621 icon image (absolute) filename for the same purpose.
4624 If there exists a specified input method and it defines an title,
4625 a plist is returned. Otherwise, NULL is returned. The caller
4626 must free the plist by m17n_object_unref (). */
4628 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4630 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4631 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4634 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4635 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4636 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¥Õ¥¡¥¤¥ë¤ÎÀäÂХѥ¹¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4639 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4640 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4641 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4644 minput_get_title_icon (MSymbol language, MSymbol name)
4646 MInputMethodInfo *im_info;
4653 im_info = get_im_info (language, name, Mnil, Mtitle);
4654 if (! im_info || !im_info->title)
4656 mt = mtext_get_prop (im_info->title, 0, Mtext);
4658 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4661 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4664 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4665 (char *) MSYMBOL_NAME (name));
4666 file = mdatabase__find_file (buf);
4667 if (! file && language == Mt)
4669 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4670 file = mdatabase__find_file (buf);
4675 mplist_add (plist, Mtext, im_info->title);
4678 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4680 mplist_add (plist, Mtext, mt);
4681 M17N_OBJECT_UNREF (mt);
4689 @brief Get description text of an input method.
4691 The minput_get_description () function returns an M-text that
4692 describes the input method specified by $LANGUAGE and $NAME.
4695 If the specified input method has a description text, a pointer to
4696 #MText is returned. The caller has to free it by m17n_object_unref ().
4697 If the input method does not have a description text, @c NULL is
4700 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4702 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4703 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4705 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4706 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4707 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4708 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4711 minput_get_description (MSymbol language, MSymbol name)
4713 MInputMethodInfo *im_info;
4721 extra = language, language = Mt;
4723 im_info = get_im_info (language, name, extra, Mdescription);
4724 if (! im_info || ! im_info->description)
4726 M17N_OBJECT_REF (im_info->description);
4727 return im_info->description;
4733 @brief Get information about input method command(s).
4735 The minput_get_command () function returns information about
4736 the command $COMMAND of the input method specified by $LANGUAGE and
4737 $NAME. An input method command is a pseudo key event to which one
4738 or more actual input key sequences are assigned.
4740 There are two kinds of commands, global and local. A global
4741 command has a global definition, and the description and the key
4742 assignment may be inherited by a local command. Each input method
4743 defines a local command which has a local key assignment. It may
4744 also declare a local command that inherits the definition of a
4745 global command of the same name.
4747 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4748 information about a global command. Otherwise information about a
4749 local command is returned.
4751 If $COMMAND is #Mnil, information about all commands is returned.
4753 The return value is a @e well-formed plist (#m17nPlist) of this
4756 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4758 @c NAME is a symbol representing the command name.
4760 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4761 command has no description.
4763 @c STATUS is a symbol representing how the key assignment is decided.
4764 The value is #Mnil (the default key assignment), #Mcustomized (the
4765 key assignment is customized by per-user configuration file), or
4766 #Mconfigured (the key assignment is set by the call of
4767 minput_config_command ()). For a local command only, it may also
4768 be #Minherited (the key assignment is inherited from the
4769 corresponding global command).
4771 @c KEYSEQ is a plist of one or more symbols representing a key
4772 sequence assigned to the command. If there's no KEYSEQ, the
4773 command is currently disabled (i.e. no key sequence can trigger
4774 actions of the command).
4776 If $COMMAND is not #Mnil, the first element of the returned plist
4777 contains the information about $COMMAND.
4781 If the requested information was found, a pointer to a non-empty
4782 plist is returned. As the plist is kept in the library, the
4783 caller must not modify nor free it.
4785 Otherwise (the specified input method or the specified command
4786 does not exist), @c NULL is returned. */
4788 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4790 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4791 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4792 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4793 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4795 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4796 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4797 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4798 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4799 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4801 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4802 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4805 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4807 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4810 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4812 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4814 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4817 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4818 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4819 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4820 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4821 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4822 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4824 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4825 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4826 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4827 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4829 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4830 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4834 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4835 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4838 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4843 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4845 /* Return a description of the command COMMAND of the input method
4846 specified by LANGUAGE and NAME. */
4847 MPlist *cmd = minput_get_command (langauge, name, command);
4852 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4853 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4854 return (mplist_key (plist) == Mtext
4855 ? (MText *) mplist_value (plist)
4861 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4863 MInputMethodInfo *im_info;
4867 im_info = get_im_info (language, name, Mnil, Mcommand);
4869 || ! im_info->configured_cmds
4870 || MPLIST_TAIL_P (im_info->configured_cmds))
4872 if (command == Mnil)
4873 return im_info->configured_cmds;
4874 return mplist__assq (im_info->configured_cmds, command);
4880 @brief Configure the key sequence of an input method command.
4882 The minput_config_command () function assigns a list of key
4883 sequences $KEYSEQLIST to the command $COMMAND of the input method
4884 specified by $LANGUAGE and $NAME.
4886 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4887 sequences, and each key sequence must be a plist of symbols.
4889 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4891 If $KEYSEQLIST is NULL, the configuration of the command for the
4892 input method is canceled, and the default key sequences become
4893 effective. In such case, if $COMMAND is #Mnil, configurations for
4894 all commands of the input method are canceled.
4896 If $NAME is #Mnil, this function configures the key assignment of a
4897 global command, not that of a specific input method.
4899 The configuration takes effect for input methods opened or
4900 re-opened later in the current session. In order to make the
4901 configuration take effect for the future session, it must be saved
4902 in a per-user configuration file by the function
4903 minput_save_config ().
4907 If the operation was successful, this function returns 0,
4908 otherwise returns -1. The operation fails in these cases:
4910 <li>$KEYSEQLIST is not in a valid form.
4911 <li>$COMMAND is not available for the input method.
4912 <li>$LANGUAGE and $NAME do not specify an existing input method.
4916 minput_get_commands (), minput_save_config ().
4919 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4921 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4922 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4923 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4925 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4926 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4928 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4930 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4931 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4932 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4935 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4936 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4938 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4939 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4940 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4941 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4945 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4947 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4948 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4949 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4953 minput_get_commands (), minput_save_config ().
4957 /* Add "C-x u" to the "start" command of Unicode input method. */
4959 MSymbol start_command = msymbol ("start");
4960 MSymbol unicode = msymbol ("unicode");
4961 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4963 /* At first get the current key-sequence assignment. */
4964 cmd = mplist_get_command (Mt, unicode, start_command);
4967 /* The input method does not have the command "start". Here
4968 should come some error handling code. */
4970 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4971 the part (KEY-SEQUENCE ...). */
4972 plist = mplist_next (mplist_next (mplist_value (cmd)));
4973 /* Copy it because we should not modify it directly. */
4974 key_seq_list = mplist_copy (plist);
4975 m17n_object_unref (cmds);
4977 key_seq = mplist ();
4978 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4979 mplist_add (key_seq, Msymbol, msymbol ("u"));
4980 mplist_add (key_seq_list, Mplist, key_seq);
4981 m17n_object_unref (key_seq);
4983 minput_config_command (Mt, unicode, start_command, key_seq_list);
4984 m17n_object_unref (key_seq_list);
4989 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4992 MInputMethodInfo *im_info, *config;
4999 if (command == Mnil)
5000 MERROR (MERROR_IM, -1);
5001 MPLIST_DO (plist, keyseqlist)
5002 if (! MPLIST_PLIST_P (plist)
5003 || ! check_command_keyseq (plist))
5004 MERROR (MERROR_IM, -1);
5007 im_info = get_im_info (language, name, Mnil, Mcommand);
5009 MERROR (MERROR_IM, -1);
5012 || ! mplist__assq (im_info->cmds, command)))
5013 MERROR (MERROR_IM, -1);
5015 config = get_config_info (im_info);
5018 if (! im_config_list)
5019 im_config_list = mplist ();
5020 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5021 config->cmds = mplist ();
5022 config->vars = mplist ();
5025 if (command == Mnil)
5027 MInputMethodInfo *custom = get_custom_info (im_info);
5029 mplist_set (config->cmds, Mnil, NULL);
5030 if (custom && custom->cmds)
5032 MPLIST_DO (plist, custom->cmds)
5034 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5036 mplist_add (plist, Msymbol, command);
5037 mplist_push (config->cmds, Mplist, plist);
5038 M17N_OBJECT_UNREF (plist);
5044 plist = mplist__assq (config->cmds, command);
5047 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
5048 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
5049 if (! MPLIST_TAIL_P (plist))
5050 mplist_set (plist, Mnil, NULL); /* () */
5055 mplist_add (config->cmds, Mplist, plist);
5056 M17N_OBJECT_UNREF (plist);
5057 plist = mplist_add (plist, Msymbol, command);
5058 plist = MPLIST_NEXT (plist);
5064 plist = mplist_add (plist, Msymbol, Mnil);
5065 MPLIST_DO (keyseqlist, keyseqlist)
5067 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5068 plist = mplist_add (plist, Mplist, pl);
5069 M17N_OBJECT_UNREF (pl);
5073 config_all_commands (im_info);
5074 im_info->tick = time (NULL);
5081 @brief Get information about input method variable(s).
5083 The minput_get_variable () function returns information about
5084 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5085 An input method variable controls behavior of an input method.
5087 There are two kinds of variables, global and local. A global
5088 variable has a global definition, and the description and the value
5089 may be inherited by a local variable. Each input method defines a
5090 local variable which has local value. It may also declare a
5091 local variable that inherits definition of a global variable of
5094 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5095 variable is returned. Otherwise information about a local variable
5098 If $VARIABLE is #Mnil, information about all variables is
5101 The return value is a @e well-formed plist (#m17nPlist) of this
5104 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5106 @c NAME is a symbol representing the variable name.
5108 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5109 variable has no description.
5111 @c STATUS is a symbol representing how the value is decided. The
5112 value is #Mnil (the default value), #Mcustomized (the value is
5113 customized by per-user configuration file), or #Mconfigured (the
5114 value is set by the call of minput_config_variable ()). For a
5115 local variable only, it may also be #Minherited (the value is
5116 inherited from the corresponding global variable).
5118 @c VALUE is the initial value of the variable. If the key of this
5119 element is #Mt, the variable has no initial value. Otherwise, the
5120 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5123 @c VALID-VALUEs (if any) specify which values the variable can have.
5124 They have the same type (i.e. having the same key) as @c VALUE except
5125 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5126 may be a plist of two integers specifying the range of possible
5129 If there no @c VALID-VALUE, the variable can have any value as long
5130 as the type is the same as @c VALUE.
5132 If $VARIABLE is not #Mnil, the first element of the returned plist
5133 contains the information about $VARIABLE.
5137 If the requested information was found, a pointer to a non-empty
5138 plist is returned. As the plist is kept in the library, the
5139 caller must not modify nor free it.
5141 Otherwise (the specified input method or the specified variable
5142 does not exist), @c NULL is returned. */
5144 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5146 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5147 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5148 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5150 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5151 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5152 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5153 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5156 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5157 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5159 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5161 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5163 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5166 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5168 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5171 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5172 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5173 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5174 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5175 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5176 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5178 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5179 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5180 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5182 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5183 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5184 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5185 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5187 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5190 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5191 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5195 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5196 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5199 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5203 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5205 MInputMethodInfo *im_info;
5209 im_info = get_im_info (language, name, Mnil, Mvariable);
5210 if (! im_info || ! im_info->configured_vars)
5212 if (variable == Mnil)
5213 return im_info->configured_vars;
5214 return mplist__assq (im_info->configured_vars, variable);
5220 @brief Configure the value of an input method variable.
5222 The minput_config_variable () function assigns $VALUE to the
5223 variable $VARIABLE of the input method specified by $LANGUAGE and
5226 If $VALUE is not NULL, it must be a plist of one element whose key
5227 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5230 If $VALUE is NULL, a configuration for the variable for the input
5231 method is canceled, and the variable is initialized to the default
5232 value. In that case, if $VARIABLE is #Mnil, configurations for
5233 all variables of the input method are canceled.
5235 If $NAME is #Mnil, this function configure the value of global
5236 variable, not that of a specific input method.
5238 The configuration takes effect for input methods opened or
5239 re-opened later in the current session. To make the configuration
5240 take effect for the future session, it must be saved in a per-user
5241 configuration file by the function minput_save_config ().
5245 If the operation was successful, this function returns 0,
5246 otherwise returns -1. The operation fails in these cases:
5248 <li>$VALUE is not in a valid form, the type does not match the
5249 definition, or the value is our of range.
5250 <li>$VARIABLE is not available for the input method.
5251 <li>$LANGUAGE and $NAME do not specify an existing input method.
5255 minput_get_variable (), minput_save_config (). */
5257 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5259 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5260 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5262 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5263 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5265 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5266 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5267 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5269 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5270 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5272 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5273 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5274 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5275 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5279 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5281 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5282 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5283 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5287 minput_get_commands (), minput_save_config ().
5290 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5293 MInputMethodInfo *im_info, *config;
5298 im_info = get_im_info (language, name, Mnil, Mvariable);
5300 MERROR (MERROR_IM, -1);
5301 if (variable == Mnil)
5304 MERROR (MERROR_IM, -1);
5306 else if (! im_info->vars
5307 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5308 MERROR (MERROR_IM, -1);
5310 if (variable != Mnil && value)
5312 plist = MPLIST_PLIST (plist);
5313 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5314 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5315 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5316 if (MPLIST_KEY (plist) != Mt
5317 && ! check_variable_value (value, plist))
5318 MERROR (MERROR_IM, -1);
5321 config = get_config_info (im_info);
5324 if (! im_config_list)
5325 im_config_list = mplist ();
5326 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5327 config->cmds = mplist ();
5328 config->vars = mplist ();
5331 if (variable == Mnil)
5333 MInputMethodInfo *custom = get_custom_info (im_info);
5335 mplist_set (config->vars, Mnil, NULL);
5336 if (custom && custom->cmds)
5338 MPLIST_DO (plist, custom->vars)
5340 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5342 mplist_add (plist, Msymbol, variable);
5343 mplist_push (config->vars, Mplist, plist);
5344 M17N_OBJECT_UNREF (plist);
5350 plist = mplist__assq (config->vars, variable);
5353 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5354 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5355 if (! MPLIST_TAIL_P (plist))
5356 mplist_set (plist, Mnil ,NULL); /* () */
5361 mplist_add (config->vars, Mplist, plist);
5362 M17N_OBJECT_UNREF (plist);
5363 plist = mplist_add (plist, Msymbol, variable);
5364 plist = MPLIST_NEXT (plist);
5368 plist = mplist_add (plist, Msymbol, Mnil);
5369 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5372 config_all_variables (im_info);
5373 im_info->tick = time (NULL);
5380 @brief Get the name of per-user configuration file.
5382 The minput_config_file () function returns the absolute path name
5383 of per-user configuration file into which minput_save_config ()
5384 save configurations. It is usually @c "config.mic" under the
5385 directory @c ".m17n.d" of user's home directory. It is not assured
5386 that the file of the returned name exists nor is
5387 readable/writable. If minput_save_config () fails and returns -1,
5388 an application program might check the file, make it
5389 writable (if possible), and try minput_save_config () again.
5393 This function returns a string. As the string is kept in the
5394 library, the caller must not modify nor free it.
5397 minput_save_config ()
5400 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5402 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5403 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5404 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5405 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5406 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5407 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5408 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5413 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5414 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5417 minput_save_config ()
5421 minput_config_file ()
5425 return mdatabase__file (im_custom_mdb);
5431 @brief Save configurations in per-user configuration file.
5433 The minput_save_config () function saves the configurations done
5434 so far in the current session into the per-user configuration
5439 If the operation was successful, 1 is returned. If the per-user
5440 configuration file is currently locked, 0 is returned. In that
5441 case, the caller may wait for a while and try again. If the
5442 configuration file is not writable, -1 is returned. In that case,
5443 the caller may check the name of the file by calling
5444 minput_config_file (), make it writable if possible, and try
5448 minput_config_file () */
5450 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5452 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5453 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5457 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5458 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5459 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5460 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5464 minput_config_file () */
5467 minput_save_config (void)
5469 MPlist *data, *tail, *plist, *p, *elt;
5473 ret = mdatabase__lock (im_custom_mdb);
5476 if (! im_config_list)
5478 update_custom_info ();
5479 if (! im_custom_list)
5480 im_custom_list = mplist ();
5481 data = tail = mplist ();
5483 MPLIST_DO (plist, im_config_list)
5485 MPlist *pl = MPLIST_PLIST (plist);
5486 MSymbol language, name, extra, command, variable;
5487 MInputMethodInfo *custom, *config;
5489 language = MPLIST_SYMBOL (pl);
5490 pl = MPLIST_NEXT (pl);
5491 name = MPLIST_SYMBOL (pl);
5492 pl = MPLIST_NEXT (pl);
5493 extra = MPLIST_SYMBOL (pl);
5494 pl = MPLIST_NEXT (pl);
5495 config = MPLIST_VAL (pl);
5496 custom = get_custom_info (config);
5498 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5500 MPLIST_DO (pl, config->cmds)
5502 elt = MPLIST_PLIST (pl);
5503 command = MPLIST_SYMBOL (elt);
5505 p = mplist__assq (custom->cmds, command);
5507 custom->cmds = mplist (), p = NULL;
5508 elt = MPLIST_NEXT (elt);
5509 if (MPLIST_TAIL_P (elt))
5512 mplist__pop_unref (p);
5516 elt = MPLIST_NEXT (elt);
5519 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5520 mplist_set (p, Mnil, NULL);
5521 mplist__conc (p, elt);
5525 p = MPLIST_PLIST (pl);
5526 mplist_add (custom->cmds, Mplist, p);
5531 MPLIST_DO (pl, config->vars)
5533 elt = MPLIST_PLIST (pl);
5534 variable = MPLIST_SYMBOL (elt);
5536 p = mplist__assq (custom->vars, variable);
5538 custom->vars = mplist (), p = NULL;
5539 elt = MPLIST_NEXT (elt);
5540 if (MPLIST_TAIL_P (elt))
5543 mplist__pop_unref (p);
5547 elt = MPLIST_NEXT (elt);
5550 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5551 mplist_set (p, Mnil, NULL);
5552 mplist__conc (p, elt);
5556 p = MPLIST_PLIST (pl);
5557 mplist_add (custom->vars, Mplist, p);
5562 M17N_OBJECT_UNREF (im_config_list);
5564 MPLIST_DO (plist, im_custom_list)
5566 MPlist *pl = MPLIST_PLIST (plist);
5567 MSymbol language, name, extra;
5568 MInputMethodInfo *custom, *im_info;
5570 language = MPLIST_SYMBOL (pl);
5571 pl = MPLIST_NEXT (pl);
5572 name = MPLIST_SYMBOL (pl);
5573 pl = MPLIST_NEXT (pl);
5574 extra = MPLIST_SYMBOL (pl);
5575 pl = MPLIST_NEXT (pl);
5576 custom = MPLIST_VAL (pl);
5577 im_info = lookup_im_info (im_info_list, language, name, extra);
5581 config_all_commands (im_info);
5583 config_all_variables (im_info);
5587 tail = mplist_add (tail, Mplist, elt);
5588 M17N_OBJECT_UNREF (elt);
5590 elt = mplist_add (elt, Mplist, pl);
5591 M17N_OBJECT_UNREF (pl);
5592 pl = mplist_add (pl, Msymbol, Minput_method);
5593 pl = mplist_add (pl, Msymbol, language);
5594 pl = mplist_add (pl, Msymbol, name);
5596 pl = mplist_add (pl, Msymbol, extra);
5597 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5600 elt = mplist_add (elt, Mplist, pl);
5601 M17N_OBJECT_UNREF (pl);
5602 pl = mplist_add (pl, Msymbol, Mcommand);
5603 MPLIST_DO (p, custom->cmds)
5604 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5606 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5609 elt = mplist_add (elt, Mplist, pl);
5610 M17N_OBJECT_UNREF (pl);
5611 pl = mplist_add (pl, Msymbol, Mvariable);
5612 MPLIST_DO (p, custom->vars)
5613 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5617 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5618 ret = mdatabase__save (im_custom_mdb, data);
5619 mdatabase__unlock (im_custom_mdb);
5620 M17N_OBJECT_UNREF (data);
5621 return (ret < 0 ? -1 : 1);
5628 @name Obsolete functions
5631 @name Obsolete ¤Ê´Ø¿ô
5637 @brief Get a list of variables of an input method (obsolete).
5639 This function is obsolete. Use minput_get_variable () instead.
5641 The minput_get_variables () function returns a plist (#MPlist) of
5642 variables used to control the behavior of the input method
5643 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5644 (#m17nPlist) of the following format:
5647 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5648 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5652 @c VARNAME is a symbol representing the variable name.
5654 @c DOC-MTEXT is an M-text describing the variable.
5656 @c DEFAULT-VALUE is the default value of the variable. It is a
5657 symbol, integer, or M-text.
5659 @c VALUEs (if any) specifies the possible values of the variable.
5660 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5661 @c TO), where @c FROM and @c TO specifies a range of possible
5664 For instance, suppose an input method has the variables:
5666 @li name:intvar, description:"value is an integer",
5667 initial value:0, value-range:0..3,10,20
5669 @li name:symvar, description:"value is a symbol",
5670 initial value:nil, value-range:a, b, c, nil
5672 @li name:txtvar, description:"value is an M-text",
5673 initial value:empty text, no value-range (i.e. any text)
5675 Then, the returned plist is as follows.
5678 (intvar ("value is an integer" 0 (0 3) 10 20)
5679 symvar ("value is a symbol" nil a b c nil)
5680 txtvar ("value is an M-text" ""))
5684 If the input method uses any variables, a pointer to #MPlist is
5685 returned. As the plist is kept in the library, the caller must not
5686 modify nor free it. If the input method does not use any
5687 variable, @c NULL is returned. */
5689 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5691 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5692 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5693 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5697 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5698 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5702 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5704 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5706 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5709 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5710 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5711 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5713 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5715 @li name:intvar, ÀâÌÀ:"value is an integer",
5716 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5718 @li name:symvar, ÀâÌÀ:"value is a symbol",
5719 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5721 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5722 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5724 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5727 (intvar ("value is an integer" 0 (0 3) 10 20)
5728 symvar ("value is a symbol" nil a b c nil)
5729 txtvar ("value is an M-text" ""))
5733 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5734 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5735 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5738 minput_get_variables (MSymbol language, MSymbol name)
5740 MInputMethodInfo *im_info;
5745 im_info = get_im_info (language, name, Mnil, Mvariable);
5746 if (! im_info || ! im_info->configured_vars)
5749 M17N_OBJECT_UNREF (im_info->bc_vars);
5750 im_info->bc_vars = mplist ();
5751 MPLIST_DO (vars, im_info->configured_vars)
5753 MPlist *plist = MPLIST_PLIST (vars);
5754 MPlist *elt = mplist ();
5756 mplist_push (im_info->bc_vars, Mplist, elt);
5757 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5758 elt = MPLIST_NEXT (elt);
5759 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5760 M17N_OBJECT_UNREF (elt);
5762 return im_info->bc_vars;
5768 @brief Set the initial value of an input method variable.
5770 The minput_set_variable () function sets the initial value of
5771 input method variable $VARIABLE to $VALUE for the input method
5772 specified by $LANGUAGE and $NAME.
5774 By default, the initial value is 0.
5776 This setting gets effective in a newly opened input method.
5779 If the operation was successful, 0 is returned. Otherwise -1 is
5780 returned, and #merror_code is set to #MERROR_IM. */
5782 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5784 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5785 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5786 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5788 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5790 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5793 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5794 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5797 minput_set_variable (MSymbol language, MSymbol name,
5798 MSymbol variable, void *value)
5801 MInputMethodInfo *im_info;
5806 if (variable == Mnil)
5807 MERROR (MERROR_IM, -1);
5808 plist = minput_get_variable (language, name, variable);
5809 plist = MPLIST_PLIST (plist);
5810 plist = MPLIST_NEXT (plist);
5812 mplist_add (pl, MPLIST_KEY (plist), value);
5813 ret = minput_config_variable (language, name, variable, pl);
5814 M17N_OBJECT_UNREF (pl);
5817 im_info = get_im_info (language, name, Mnil, Mvariable);
5826 @brief Get information about input method commands.
5828 The minput_get_commands () function returns information about
5829 input method commands of the input method specified by $LANGUAGE
5830 and $NAME. An input method command is a pseudo key event to which
5831 one or more actual input key sequences are assigned.
5833 There are two kinds of commands, global and local. Global
5834 commands are used by multiple input methods for the same purpose,
5835 and have global key assignments. Local commands are used only by
5836 a specific input method, and have only local key assignments.
5838 Each input method may locally change key assignments for global
5839 commands. The global key assignment for a global command is
5840 effective only when the current input method does not have local
5841 key assignments for that command.
5843 If $NAME is #Mnil, information about global commands is returned.
5844 In this case $LANGUAGE is ignored.
5846 If $NAME is not #Mnil, information about those commands that have
5847 local key assignments in the input method specified by $LANGUAGE
5848 and $NAME is returned.
5851 If no input method commands are found, this function returns @c NULL.
5853 Otherwise, a pointer to a plist is returned. The key of each
5854 element in the plist is a symbol representing a command, and the
5855 value is a plist of the form COMMAND-INFO described below.
5857 The first element of COMMAND-INFO has the key #Mtext, and the
5858 value is an M-text describing the command.
5860 If there are no more elements, that means no key sequences are
5861 assigned to the command. Otherwise, each of the remaining
5862 elements has the key #Mplist, and the value is a plist whose keys are
5863 #Msymbol and values are symbols representing input keys, which are
5864 currently assigned to the command.
5866 As the returned plist is kept in the library, the caller must not
5867 modify nor free it. */
5869 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5871 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5872 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5873 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5874 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5876 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5877 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5878 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5879 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5881 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5882 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5883 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5886 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5887 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5889 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5890 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5894 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5896 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5897 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5898 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5900 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5901 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5902 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5905 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5906 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5907 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5908 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5909 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5911 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5912 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5915 minput_get_commands (MSymbol language, MSymbol name)
5917 MInputMethodInfo *im_info;
5922 im_info = get_im_info (language, name, Mnil, Mcommand);
5923 if (! im_info || ! im_info->configured_vars)
5925 M17N_OBJECT_UNREF (im_info->bc_cmds);
5926 im_info->bc_cmds = mplist ();
5927 MPLIST_DO (cmds, im_info->configured_cmds)
5929 MPlist *plist = MPLIST_PLIST (cmds);
5930 MPlist *elt = mplist ();
5932 mplist_push (im_info->bc_cmds, Mplist, elt);
5933 mplist_add (elt, MPLIST_SYMBOL (plist),
5934 mplist_copy (MPLIST_NEXT (plist)));
5935 M17N_OBJECT_UNREF (elt);
5937 return im_info->bc_cmds;
5943 @brief Assign a key sequence to an input method command (obsolete).
5945 This function is obsolete. Use minput_config_command () instead.
5947 The minput_assign_command_keys () function assigns input key
5948 sequence $KEYSEQ to input method command $COMMAND for the input
5949 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5950 key sequence is assigned globally no matter what $LANGUAGE is.
5951 Otherwise the key sequence is assigned locally.
5953 Each element of $KEYSEQ must have the key $Msymbol and the value
5954 must be a symbol representing an input key.
5956 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5957 globally or locally.
5959 This assignment gets effective in a newly opened input method.
5962 If the operation was successful, 0 is returned. Otherwise -1 is
5963 returned, and #merror_code is set to #MERROR_IM. */
5965 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5967 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5968 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5969 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5970 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5971 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5973 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5974 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5976 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5977 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5979 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5982 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5983 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5986 minput_assign_command_keys (MSymbol language, MSymbol name,
5987 MSymbol command, MPlist *keyseq)
5993 if (command == Mnil)
5994 MERROR (MERROR_IM, -1);
5999 if (! check_command_keyseq (keyseq))
6000 MERROR (MERROR_IM, -1);
6002 mplist_add (plist, Mplist, keyseq);
6007 ret = minput_config_command (language, name, command, keyseq);
6008 M17N_OBJECT_UNREF (keyseq);
6015 @brief Call a callback function
6017 The minput_callback () functions calls a callback function
6018 $COMMAND assigned for the input context $IC. The caller must set
6019 specific elements in $IC->plist if the callback function requires.
6022 If there exists a specified callback function, 0 is returned.
6023 Otherwise -1 is returned. By side effects, $IC->plist may be
6027 minput_callback (MInputContext *ic, MSymbol command)
6029 MInputCallbackFunc func;
6031 if (! ic->im->driver.callback_list)
6033 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
6037 (func) (ic, command);
6044 /*** @addtogroup m17nDebug */
6050 @brief Dump an input method.
6052 The mdebug_dump_im () function prints the input method $IM in a
6053 human readable way to the stderr. $INDENT specifies how many
6054 columns to indent the lines but the first one.
6057 This function returns $IM. */
6059 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6061 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6062 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6065 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6068 mdebug_dump_im (MInputMethod *im, int indent)
6070 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6073 prefix = (char *) alloca (indent + 1);
6074 memset (prefix, 32, indent);
6075 prefix[indent] = '\0';
6077 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6078 msymbol_name (im->name));
6079 mdebug_dump_mtext (im_info->title, 0, 0);
6080 if (im->name != Mnil)
6084 MPLIST_DO (state, im_info->states)
6086 fprintf (stderr, "\n%s ", prefix);
6087 dump_im_state (MPLIST_VAL (state), indent + 2);
6090 fprintf (stderr, ")");