1 /* input.c -- input method module.
2 Copyright (C) 2003, 2004, 2005, 2006
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @addtogroup m17nInputMethod
25 @brief API for Input method.
27 An input method is an object to enable inputting various
28 characters. An input method is identified by a pair of symbols,
29 LANGUAGE and NAME. This pair decides an input method driver of the
30 input method. An input method driver is a set of functions for
31 handling the input method. There are two kinds of input methods;
32 internal one and foreign one.
35 <li> Internal Input Method
37 An internal input method has non @c Mnil LANGUAGE, and its body is
38 defined in the m17n database by the tag <Minput_method, LANGUAGE,
39 NAME>. For this kind of input methods, the m17n library uses two
40 predefined input method drivers, one for CUI use and the other for
41 GUI use. Those drivers utilize the input processing engine
42 provided by the m17n library itself. The m17n database may
43 provide input methods that are not limited to a specific language.
44 The database uses @c Mt as LANGUAGE of those input methods.
46 An internal input method accepts an input key which is a symbol
47 associated with an input event. As there is no way for the @c
48 m17n @c library to know how input events are represented in an
49 application program, an application programmer has to convert an
50 input event to an input key by himself. See the documentation of
51 the function minput_event_to_key () for the detail.
53 <li> Foreign Input Method
55 A foreign input method has @c Mnil LANGUAGE, and its body is
56 defined in an external resource (e.g. XIM of X Window System).
57 For this kind of input methods, the symbol NAME must have a
58 property of key @c Minput_driver, and the value must be a pointer
59 to an input method driver. Therefore, by preparing a proper
60 driver, any kind of input method can be treated in the framework
61 of the @c m17n @c library.
63 For convenience, the m17n-X library provides an input method
64 driver that enables the input style of OverTheSpot for XIM, and
65 stores @c Minput_driver property of the symbol @c Mxim with a
66 pointer to the driver. See the documentation of m17n GUI API for
73 The typical processing flow of handling an input method is:
75 @li open an input method
76 @li create an input context for the input method
77 @li filter an input key
78 @li look up a produced text in the input context */
82 @addtogroup m17nInputMethod
83 @brief ÆþÎϥ᥽¥Ã¥ÉÍÑAPI.
85 ÆþÎϥ᥽¥Ã¥É¤Ï¿ÍͤÊʸ»ú¤òÆþÎϤ¹¤ë¤¿¤á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£
86 ÆþÎϥ᥽¥Ã¥É¤Ï¥·¥ó¥Ü¥ë LANGUAGE ¤È NAME ¤ÎÁȤˤè¤Ã¤Æ¼±Ê̤µ¤ì¡¢
87 ¤³¤ÎÁȹ礻¤Ë¤è¤Ã¤ÆÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤¬·èÄꤹ¤ë¡£
88 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤È¤Ï¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤ò°·¤¦¤¿¤á¤Î´Ø¿ô¤Î½¸¤Þ¤ê¤Ç¤¢¤ë¡£
89 ÆþÎϥ᥽¥Ã¥É¤Ë¤ÏÆâÉô¥á¥½¥Ã¥É¤È³°Éô¥á¥½¥Ã¥É¤ÎÆó¼ïÎब¤¢¤ë¡£
94 ÆâÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil °Ê³°¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂÎ
95 ¤Ïm17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë<Minput_method, LANGUAGE, NAME> ¤È¤¤¤¦¥¿¥°¤òÉÕ
96 ¤±¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤ËÂФ·¤Æ¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ç
97 ¤ÏCUI ÍÑ¤È GUI ÍѤ½¤ì¤¾¤ì¤ÎÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤ò¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ
98 ¤¤¤ë¡£¤³¤ì¤é¤Î¥É¥é¥¤¥Ð¤Ï m17n ¥é¥¤¥Ö¥é¥ê¼«ÂΤÎÆþÎϽèÍý¥¨¥ó¥¸¥ó¤òÍø
99 ÍѤ¹¤ë¡£m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤Ï¡¢ÆÃÄê¤Î¸À¸ìÀìÍѤǤʤ¤ÆþÎϥ᥽¥Ã¥É¤òÄê
100 µÁ¤¹¤ë¤³¤È¤â¤Ç¤¡¢¤½¤Î¤è¤¦¤ÊÆþÎϥ᥽¥Ã¥É¤Î LANGUAGE ¤Ï @c Mt ¤Ç¤¢¤ë¡£
102 ÆâÉôÆþÎϥ᥽¥Ã¥É¤Ï¡¢¥æ¡¼¥¶¤ÎÆþÎÏ¥¤¥Ù¥ó¥È¤ËÂбþ¤·¤¿¥·¥ó¥Ü¥ë¤Ç¤¢¤ëÆþ
103 ÎÏ¥¡¼¤ò¼õ¤±¼è¤ë¡£@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÏÆþÎÏ¥¤¥Ù¥ó¥È¤¬¥¢¥×¥ê¥±¡¼
104 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ç¤É¤¦É½¸½¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Æþ
105 ÎÏ¥¤¥Ù¥ó¥È¤«¤éÆþÎÏ¥¡¼¤Ø¤ÎÊÑ´¹¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥Þ¤ÎÀÕǤ¤Ç
106 ¹Ô¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï´Ø¿ô minput_event_to_key () ¤Î
109 <li> ³°ÉôÆþÎϥ᥽¥Ã¥É
111 ³°ÉôÆþÎϥ᥽¥Ã¥É¤È¤Ï LANGUAGE ¤¬ @c Mnil ¤Î¤â¤Î¤Ç¤¢¤ê¡¢¤½¤ÎËÜÂΤϳ°
112 Éô¤Î¥ê¥½¡¼¥¹¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£¡Ê¤¿¤È¤¨¤ÐX Window System ¤ÎXIM ¤Ê
113 ¤É¡£) ¤³¤Î¼ï¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë NAME ¤Ï@c Minput_driver ¤ò
114 ¥¡¼¤È¤¹¤ë¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Á¡¢¤½¤ÎÃͤÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó
115 ¥¿¤Ç¤¢¤ë¡£¤³¤Î¤³¤È¤Ë¤è¤ê¡¢Å¬Àڤʥɥ饤¥Ð¤ò½àÈ÷¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤¤
116 ¤«¤Ê¤ë¼ïÎà¤ÎÆþÎϥ᥽¥Ã¥É¤â@c m17n @c ¥é¥¤¥Ö¥é¥ê ¤ÎÏÈÁȤÎÃæ¤Ç°·¤¦»ö
119 ÍøÊØÀ¤Î´ÑÅÀ¤«¤é¡¢m17n X ¥é¥¤¥Ö¥é¥ê¤Ï XIM ¤Î OverTheSpot ¤ÎÆþÎÏ¥¹¥¿
120 ¥¤¥ë¤ò¼Â¸½¤¹¤ëÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤òÄ󶡤·¡¢¤Þ¤¿¥·¥ó¥Ü¥ë @c Mxim ¤Î
121 @c Minput_driver ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ¤½¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÝ»ý
122 ¤·¤Æ¤¤¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï m17n GUI API ¤Î¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
128 ÆþÎϥ᥽¥Ã¥É½èÍý¤Îŵ·¿Åª¤Ê½èÍý¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
130 @li ÆþÎϥ᥽¥Ã¥É¤Î¥ª¡¼¥×¥ó
131 @li ¤½¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ÎÀ¸À®
132 @li ÆþÎÏ¥¤¥Ù¥ó¥È¤Î¥Õ¥£¥ë¥¿
133 @li ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ç¤ÎÀ¸À®¥Æ¥¥¹¥È¤Î¸¡º÷ */
137 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
138 /*** @addtogroup m17nInternal
144 #include <sys/types.h>
146 #include <sys/stat.h>
156 #include "m17n-gui.h"
157 #include "m17n-misc.h"
158 #include "internal.h"
163 #include "database.h"
166 static int mdebug_mask = MDEBUG_INPUT;
168 static int fully_initialized;
170 static MSymbol Minput_method;
172 /** Symbols to load an input method data. */
173 static MSymbol Mtitle, Mmacro, Mmodule, Mstate, Minclude;
175 /** Symbols for actions. */
176 static MSymbol Minsert, Mdelete, Mmark, Mmove, Mpushback, Mundo, Mcall, Mshift;
177 static MSymbol Mselect, Mshow, Mhide, Mcommit, Munhandle;
178 static MSymbol Mset, Madd, Msub, Mmul, Mdiv, Mequal, Mless, Mgreater;
179 static MSymbol Mless_equal, Mgreater_equal;
180 static MSymbol Mcond;
181 static MSymbol Mplus, Mminus, Mstar, Mslash, Mand, Mor, Mnot;
183 /** Special action symbol. */
184 static MSymbol Mat_reload;
186 static MSymbol M_candidates;
188 static MSymbol Mcandidate_list, Mcandidate_index;
190 static MSymbol Minit, Mfini;
192 /** Symbols for variables. */
193 static MSymbol Mcandidates_group_size, Mcandidates_charset;
195 /** Symbols for key events. */
196 static MSymbol one_char_symbol[256];
198 static MSymbol M_key_alias;
200 static MSymbol Mdescription, Mcommand, Mvariable, Mglobal, Mconfig;
202 static MSymbol M_gettext;
204 /** Structure to hold a map. */
208 /** List of actions to take when we reach the map. In a root map,
209 the actions are executed only when there is no more key. */
212 /** List of deeper maps. If NULL, this is a terminal map. */
215 /** List of actions to take when we leave the map successfully. In
216 a root map, the actions are executed only when none of submaps
217 handle the current key. */
218 MPlist *branch_actions;
221 typedef MPlist *(*MIMExternalFunc) (MPlist *plist);
226 MPlist *func_list; /* function name vs (MIMExternalFunc *) */
233 /** Name of the state. */
236 /** Title of the state, or NULL. */
239 /** Key translation map of the state. Built by merging all maps of
244 #define CUSTOM_FILE "config.mic"
246 static MPlist *load_im_info_keys;
248 /* List of input method information. The format is:
249 (LANGUAGE NAME t:IM_INFO ... ... ...) */
250 static MPlist *im_info_list;
252 /* Database for user's customization file. */
253 static MDatabase *im_custom_mdb;
255 /* List of input method information loaded from im_custom_mdb. The
256 format is the same as im_info_list. */
257 static MPlist *im_custom_list;
259 /* List of input method information configured by
260 minput_config_command and minput_config_variable. The format is
261 the same as im_info_list. */
262 static MPlist *im_config_list;
264 /* Global input method information. It points into the element of
265 im_info_list corresponding to LANGUAGE == `nil' and NAME ==
267 static MInputMethodInfo *global_info;
269 static int update_global_info (void);
270 static int update_custom_info (void);
271 static MInputMethodInfo *get_im_info (MSymbol, MSymbol, MSymbol, MSymbol);
278 = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
279 "BackSpace", "Tab", "Linefeed", "Clear", NULL, "Return", NULL, NULL,
280 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
281 NULL, NULL, NULL, "Escape", NULL, NULL, NULL, NULL };
282 char buf[6], buf2[32];
284 /* Maximum case: C-M-a, C-M-A, M-Return, C-A-a, C-A-A, A-Return. */
287 M_key_alias = msymbol (" key-alias");
292 for (i = 0, buf[2] = '@'; i < ' '; i++, buf[2]++)
294 one_char_symbol[i] = msymbol (buf);
295 if (key_names[i] || (buf[2] >= 'A' && buf[2] <= 'Z'))
298 alias[j++] = one_char_symbol[i];
301 /* Ex: `Escape' == `C-[' */
302 alias[j++] = msymbol (key_names[i]);
304 if (buf[2] >= 'A' && buf[2] <= 'Z')
306 /* Ex: `C-a' == `C-A' */
308 alias[j++] = msymbol (buf);
311 /* Establish cyclic alias chain. */
314 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
318 for (i = buf[2] = ' '; i < 127; i++, buf[2]++)
320 one_char_symbol[i] = msymbol (buf + 2);
321 if (i >= 'A' && i <= 'Z')
323 /* Ex: `A' == `S-A' == `S-a'. */
324 alias[0] = alias[3] = one_char_symbol[i];
325 alias[1] = msymbol (buf);
327 alias[2] = msymbol (buf);
329 for (j = 0; j < 3; j++)
330 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
335 alias[0] = alias[2] = one_char_symbol[127] = msymbol ("Delete");
336 alias[1] = msymbol ("C-?");
337 for (j = 0; j < 2; j++)
338 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
343 for (i = 128, buf[4] = '@'; i < 160; i++, buf[4]++)
346 /* `C-M-a' == `C-A-a' */
348 alias[j++] = one_char_symbol[i] = msymbol (buf);
350 alias[j++] = msymbol (buf);
351 if (key_names[i - 128])
353 /* Ex: `M-Escape' == `A-Escape' == `C-M-['. */
355 strcpy (buf2 + 2, key_names[i - 128]);
356 alias[j++] = msymbol (buf2);
358 alias[j++] = msymbol (buf2);
360 if (buf[4] >= 'A' && buf[4] <= 'Z')
362 /* Ex: `C-M-a' == `C-M-A'. */
365 alias[j++] = msymbol (buf);
367 alias[j++] = msymbol (buf);
370 /* Establish cyclic alias chain. */
373 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
375 for (i = 160, buf[4] = ' '; i < 256; i++, buf[4]++)
378 alias[0] = alias[2] = one_char_symbol[i] = msymbol (buf + 2);
380 alias[1] = msymbol (buf + 2);
381 for (j = 0; j < 2; j++)
382 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
385 alias[0] = alias[4] = one_char_symbol[255] = msymbol ("M-Delete");
386 alias[1] = msymbol ("A-Delete");
387 alias[2] = msymbol ("C-M-?");
388 alias[3] = msymbol ("C-A-?");
389 for (j = 0; j < 4; j++)
390 msymbol_put (alias[j], M_key_alias, alias[j + 1]);
392 Minput_method = msymbol ("input-method");
393 Mtitle = msymbol ("title");
394 Mmacro = msymbol ("macro");
395 Mmodule = msymbol ("module");
396 Mmap = msymbol ("map");
397 Mstate = msymbol ("state");
398 Minclude = msymbol ("include");
399 Minsert = msymbol ("insert");
400 M_candidates = msymbol (" candidates");
401 Mdelete = msymbol ("delete");
402 Mmove = msymbol ("move");
403 Mmark = msymbol ("mark");
404 Mpushback = msymbol ("pushback");
405 Mundo = msymbol ("undo");
406 Mcall = msymbol ("call");
407 Mshift = msymbol ("shift");
408 Mselect = msymbol ("select");
409 Mshow = msymbol ("show");
410 Mhide = msymbol ("hide");
411 Mcommit = msymbol ("commit");
412 Munhandle = msymbol ("unhandle");
413 Mset = msymbol ("set");
414 Madd = msymbol ("add");
415 Msub = msymbol ("sub");
416 Mmul = msymbol ("mul");
417 Mdiv = msymbol ("div");
418 Mequal = msymbol ("=");
419 Mless = msymbol ("<");
420 Mgreater = msymbol (">");
421 Mless_equal = msymbol ("<=");
422 Mgreater_equal = msymbol (">=");
423 Mcond = msymbol ("cond");
424 Mplus = msymbol ("+");
425 Mminus = msymbol ("-");
426 Mstar = msymbol ("*");
427 Mslash = msymbol ("/");
428 Mand = msymbol ("&");
430 Mnot = msymbol ("!");
432 Mat_reload = msymbol ("@reload");
434 Mcandidates_group_size = msymbol ("candidates-group-size");
435 Mcandidates_charset = msymbol ("candidates-charset");
437 Mcandidate_list = msymbol_as_managing_key (" candidate-list");
438 Mcandidate_index = msymbol (" candidate-index");
440 Minit = msymbol ("init");
441 Mfini = msymbol ("fini");
443 Mdescription = msymbol ("description");
444 Mcommand = msymbol ("command");
445 Mvariable = msymbol ("variable");
446 Mglobal = msymbol ("global");
447 Mconfig = msymbol ("config");
448 M_gettext = msymbol ("_");
450 load_im_info_keys = mplist ();
451 mplist_add (load_im_info_keys, Mstate, Mnil);
452 mplist_push (load_im_info_keys, Mmap, Mnil);
454 im_info_list = mplist ();
455 im_config_list = im_custom_list = NULL;
456 im_custom_mdb = NULL;
457 update_custom_info ();
459 update_global_info ();
461 fully_initialized = 1;
464 #define MINPUT__INIT() \
466 if (! fully_initialized) \
467 fully_initialize (); \
472 marker_code (MSymbol sym, int surrounding)
478 name = MSYMBOL_NAME (sym);
479 return (name[0] != '@' ? -1
480 : (((name[1] >= '0' && name[1] <= '9')
481 || name[1] == '<' || name[1] == '>' || name[1] == '='
482 || name[1] == '[' || name[1] == ']'
484 && name[2] == '\0') ? name[1]
485 : (name[1] != '+' && name[1] != '-') ? -1
486 : (name[2] == '\0' || surrounding) ? name[1]
492 resolve_variable (MInputContextInfo *ic_info, MSymbol var)
494 MPlist *plist = mplist__assq (ic_info->vars, var);
498 plist = MPLIST_PLIST (plist);
499 return MPLIST_NEXT (plist);
503 mplist_push (ic_info->vars, Mplist, plist);
504 M17N_OBJECT_UNREF (plist);
505 plist = mplist_add (plist, Msymbol, var);
506 plist = mplist_add (plist, Minteger, (void *) 0);
511 get_surrounding_text (MInputContext *ic, int len)
515 mplist_push (ic->plist, Minteger, (void *) len);
516 if (minput__callback (ic, Minput_get_surrounding_text) >= 0
517 && MPLIST_MTEXT_P (ic->plist))
518 mt = MPLIST_MTEXT (ic->plist);
519 mplist_pop (ic->plist);
524 delete_surrounding_text (MInputContext *ic, int pos)
526 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
528 mplist_push (ic->plist, Minteger, (void *) pos);
529 minput__callback (ic, Minput_delete_surrounding_text);
530 mplist_pop (ic->plist);
533 M17N_OBJECT_UNREF (ic_info->preceding_text);
534 ic_info->preceding_text = NULL;
538 M17N_OBJECT_UNREF (ic_info->following_text);
539 ic_info->following_text = NULL;
544 get_preceding_char (MInputContext *ic, int pos)
546 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
550 if (pos && ic_info->preceding_text)
552 len = mtext_nchars (ic_info->preceding_text);
554 return mtext_ref_char (ic_info->preceding_text, len - pos);
556 mt = get_surrounding_text (ic, - pos);
559 len = mtext_nchars (mt);
560 if (ic_info->preceding_text)
562 if (mtext_nchars (ic_info->preceding_text) < len)
564 M17N_OBJECT_UNREF (ic_info->preceding_text);
565 ic_info->preceding_text = mt;
569 ic_info->preceding_text = mt;
572 return mtext_ref_char (ic_info->preceding_text, len - pos);
576 get_following_char (MInputContext *ic, int pos)
578 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
582 if (ic_info->following_text)
584 len = mtext_nchars (ic_info->following_text);
586 return mtext_ref_char (ic_info->following_text, pos - 1);
588 mt = get_surrounding_text (ic, pos);
591 len = mtext_nchars (mt);
592 if (ic_info->following_text)
594 if (mtext_nchars (ic_info->following_text) < len)
596 M17N_OBJECT_UNREF (ic_info->following_text);
597 ic_info->following_text = mt;
601 ic_info->following_text = mt;
604 return mtext_ref_char (ic_info->following_text, pos - 1);
608 surrounding_pos (MSymbol sym)
614 name = MSYMBOL_NAME (sym);
616 && (name[1] == '-' || name[1] == '+')
617 && name[2] >= '1' && name[2] <= '9')
618 return (name[1] == '-' ? - atoi (name + 2) : atoi (name + 2));
623 integer_value (MInputContext *ic, MPlist *arg, MPlist **value, int surrounding)
625 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
627 MText *preedit = ic->preedit;
628 int len = mtext_nchars (preedit);
632 if (MPLIST_INTEGER_P (arg))
633 return MPLIST_INTEGER (arg);
635 code = marker_code (MPLIST_SYMBOL (arg), surrounding);
638 MPlist *val = resolve_variable (ic_info, MPLIST_SYMBOL (arg));
642 return (MPLIST_INTEGER_P (val) ? MPLIST_INTEGER (val) : 0);
645 return ic_info->key_head;
646 if ((code == '-' || code == '+'))
648 char *name = MSYMBOL_NAME (MPLIST_SYMBOL (arg));
652 pos = atoi (name + 1);
654 return get_preceding_char (ic, 0);
655 pos = ic->cursor_pos + pos;
657 return get_preceding_char (ic, - pos);
659 return get_following_char (ic, pos - len + 1);
662 pos = ic->cursor_pos + (code == '+' ? 1 : -1);
664 else if (code >= '0' && code <= '9')
666 else if (code == '=')
667 pos = ic->cursor_pos;
668 else if (code == '[')
669 pos = ic->cursor_pos - 1;
670 else if (code == ']')
671 pos = ic->cursor_pos + 1;
672 else if (code == '<')
674 else if (code == '>')
676 return (pos >= 0 && pos < len ? mtext_ref_char (preedit, pos) : -1);
680 parse_expression (MPlist *plist)
684 if (MPLIST_INTEGER_P (plist) || MPLIST_SYMBOL_P (plist))
686 if (! MPLIST_PLIST_P (plist))
688 plist = MPLIST_PLIST (plist);
689 op = MPLIST_SYMBOL (plist);
690 if (op != Mplus && op != Mminus && op != Mstar && op != Mslash
691 && op != Mand && op != Mor && op != Mnot
692 && op != Mless && op != Mgreater && op != Mequal
693 && op != Mless_equal && op != Mgreater_equal)
694 MERROR (MERROR_IM, -1);
695 MPLIST_DO (plist, MPLIST_NEXT (plist))
696 if (parse_expression (plist) < 0)
702 resolve_expression (MInputContext *ic, MPlist *plist)
707 if (MPLIST_INTEGER_P (plist))
708 return MPLIST_INTEGER (plist);
709 if (MPLIST_SYMBOL_P (plist))
710 return integer_value (ic, plist, NULL, 1);
711 if (! MPLIST_PLIST_P (plist))
713 plist = MPLIST_PLIST (plist);
714 if (! MPLIST_SYMBOL_P (plist))
716 op = MPLIST_SYMBOL (plist);
717 plist = MPLIST_NEXT (plist);
718 val = resolve_expression (ic, plist);
720 MPLIST_DO (plist, MPLIST_NEXT (plist))
721 val += resolve_expression (ic, plist);
722 else if (op == Mminus)
723 MPLIST_DO (plist, MPLIST_NEXT (plist))
724 val -= resolve_expression (ic, plist);
725 else if (op == Mstar)
726 MPLIST_DO (plist, MPLIST_NEXT (plist))
727 val *= resolve_expression (ic, plist);
728 else if (op == Mslash)
729 MPLIST_DO (plist, MPLIST_NEXT (plist))
730 val /= resolve_expression (ic, plist);
732 MPLIST_DO (plist, MPLIST_NEXT (plist))
733 val &= resolve_expression (ic, plist);
735 MPLIST_DO (plist, MPLIST_NEXT (plist))
736 val |= resolve_expression (ic, plist);
739 else if (op == Mless)
740 val = val < resolve_expression (ic, MPLIST_NEXT (plist));
741 else if (op == Mequal)
742 val = val == resolve_expression (ic, MPLIST_NEXT (plist));
743 else if (op == Mgreater)
744 val = val > resolve_expression (ic, MPLIST_NEXT (plist));
745 else if (op == Mless_equal)
746 val = val <= resolve_expression (ic, MPLIST_NEXT (plist));
747 else if (op == Mgreater_equal)
748 val = val >= resolve_expression (ic, MPLIST_NEXT (plist));
752 /* Parse PLIST as an action list. PLIST should have this form:
753 PLIST ::= ( (ACTION-NAME ACTION-ARG *) *).
754 Return 0 if successfully parsed, otherwise return -1. */
757 parse_action_list (MPlist *plist, MPlist *macros)
759 MPLIST_DO (plist, plist)
761 if (MPLIST_MTEXT_P (plist))
763 /* This is a short form of (insert MTEXT). */
764 /* if (mtext_nchars (MPLIST_MTEXT (plist)) == 0)
765 MERROR (MERROR_IM, -1); */
767 else if (MPLIST_PLIST_P (plist)
768 && (MPLIST_MTEXT_P (MPLIST_PLIST (plist))
769 || MPLIST_PLIST_P (MPLIST_PLIST (plist))))
773 /* This is a short form of (insert (GROUPS *)). */
774 MPLIST_DO (pl, MPLIST_PLIST (plist))
776 if (MPLIST_PLIST_P (pl))
780 MPLIST_DO (elt, MPLIST_PLIST (pl))
781 if (! MPLIST_MTEXT_P (elt)
782 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
783 MERROR (MERROR_IM, -1);
787 if (! MPLIST_MTEXT_P (pl)
788 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
789 MERROR (MERROR_IM, -1);
793 else if (MPLIST_INTEGER_P (plist))
795 int c = MPLIST_INTEGER (plist);
797 if (c < 0 || c > MCHAR_MAX)
798 MERROR (MERROR_IM, -1);
800 else if (MPLIST_PLIST_P (plist)
801 && MPLIST_SYMBOL_P (MPLIST_PLIST (plist)))
803 MPlist *pl = MPLIST_PLIST (plist);
804 MSymbol action_name = MPLIST_SYMBOL (pl);
806 pl = MPLIST_NEXT (pl);
808 if (action_name == Minsert)
810 if (MPLIST_MTEXT_P (pl))
812 if (mtext_nchars (MPLIST_MTEXT (pl)) == 0)
813 MERROR (MERROR_IM, -1);
815 else if (MPLIST_PLIST_P (pl))
819 if (MPLIST_PLIST_P (pl))
823 MPLIST_DO (elt, MPLIST_PLIST (pl))
824 if (! MPLIST_MTEXT_P (elt)
825 || mtext_nchars (MPLIST_MTEXT (elt)) == 0)
826 MERROR (MERROR_IM, -1);
830 if (! MPLIST_MTEXT_P (pl)
831 || mtext_nchars (MPLIST_MTEXT (pl)) == 0)
832 MERROR (MERROR_IM, -1);
836 else if (! MPLIST_SYMBOL_P (pl))
837 MERROR (MERROR_IM, -1);
839 else if (action_name == Mselect
840 || action_name == Mdelete
841 || action_name == Mmove)
843 if (parse_expression (pl) < 0)
846 else if (action_name == Mmark
847 || action_name == Mcall
848 || action_name == Mshift)
850 if (! MPLIST_SYMBOL_P (pl))
851 MERROR (MERROR_IM, -1);
853 else if (action_name == Mundo)
855 if (! MPLIST_TAIL_P (pl))
857 if (! MPLIST_SYMBOL_P (pl)
858 && ! MPLIST_INTEGER_P (pl))
859 MERROR (MERROR_IM, -1);
862 else if (action_name == Mpushback)
864 if (MPLIST_MTEXT_P (pl))
866 MText *mt = MPLIST_MTEXT (pl);
868 if (mtext_nchars (mt) != mtext_nbytes (mt))
869 MERROR (MERROR_IM, -1);
871 else if (MPLIST_PLIST_P (pl))
875 MPLIST_DO (p, MPLIST_PLIST (pl))
876 if (! MPLIST_SYMBOL_P (p))
877 MERROR (MERROR_IM, -1);
879 else if (! MPLIST_INTEGER_P (pl))
880 MERROR (MERROR_IM, -1);
882 else if (action_name == Mset || action_name == Madd
883 || action_name == Msub || action_name == Mmul
884 || action_name == Mdiv)
886 if (! MPLIST_SYMBOL_P (pl))
887 MERROR (MERROR_IM, -1);
888 if (parse_expression (MPLIST_NEXT (pl)) < 0)
891 else if (action_name == Mequal || action_name == Mless
892 || action_name == Mgreater || action_name == Mless_equal
893 || action_name == Mgreater_equal)
895 if (parse_expression (pl) < 0
896 || parse_expression (MPLIST_NEXT (pl)) < 0)
898 pl = MPLIST_NEXT (MPLIST_NEXT (pl));
899 if (! MPLIST_PLIST_P (pl))
900 MERROR (MERROR_IM, -1);
901 if (parse_action_list (MPLIST_PLIST (pl), macros) < 0)
902 MERROR (MERROR_IM, -1);
903 pl = MPLIST_NEXT (pl);
904 if (MPLIST_PLIST_P (pl)
905 && parse_action_list (MPLIST_PLIST (pl), macros) < 0)
906 MERROR (MERROR_IM, -1);
908 else if (action_name == Mshow || action_name == Mhide
909 || action_name == Mcommit || action_name == Munhandle)
911 else if (action_name == Mcond)
914 if (! MPLIST_PLIST_P (pl))
915 MERROR (MERROR_IM, -1);
917 else if (! macros || ! mplist_get (macros, action_name))
918 MERROR (MERROR_IM, -1);
920 else if (! MPLIST_SYMBOL_P (plist))
921 MERROR (MERROR_IM, -1);
928 resolve_command (MPlist *cmds, MSymbol command)
932 if (! cmds || ! (plist = mplist__assq (cmds, command)))
934 plist = MPLIST_PLIST (plist); /* (NAME DESC STATUS [KEYSEQ ...]) */
935 plist = MPLIST_NEXT (plist);
936 plist = MPLIST_NEXT (plist);
937 plist = MPLIST_NEXT (plist);
941 /* Load a translation into MAP from PLIST.
943 PLIST ::= ( KEYSEQ MAP-ACTION * ) */
946 load_translation (MIMMap *map, MPlist *keylist, MPlist *map_actions,
947 MPlist *branch_actions, MPlist *macros)
952 if (MPLIST_MTEXT_P (keylist))
954 MText *mt = MPLIST_MTEXT (keylist);
956 len = mtext_nchars (mt);
957 if (MFAILP (len > 0 && len == mtext_nbytes (mt)))
959 keyseq = (MSymbol *) alloca (sizeof (MSymbol) * len);
960 for (i = 0; i < len; i++)
961 keyseq[i] = one_char_symbol[MTEXT_DATA (mt)[i]];
967 if (MFAILP (MPLIST_PLIST_P (keylist)))
969 elt = MPLIST_PLIST (keylist);
970 len = MPLIST_LENGTH (elt);
971 if (MFAILP (len > 0))
973 keyseq = (MSymbol *) alloca (sizeof (int) * len);
974 for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt))
976 if (MPLIST_INTEGER_P (elt))
978 int c = MPLIST_INTEGER (elt);
980 if (MFAILP (c >= 0 && c < 0x100))
982 keyseq[i] = one_char_symbol[c];
986 if (MFAILP (MPLIST_SYMBOL_P (elt)))
988 keyseq[i] = MPLIST_SYMBOL (elt);
993 for (i = 0; i < len; i++)
995 MIMMap *deeper = NULL;
998 deeper = mplist_get (map->submaps, keyseq[i]);
1000 map->submaps = mplist ();
1003 /* Fixme: It is better to make all deeper maps at once. */
1004 MSTRUCT_CALLOC (deeper, MERROR_IM);
1005 mplist_put (map->submaps, keyseq[i], deeper);
1010 /* We reach a terminal map. */
1011 if (map->map_actions
1012 || map->branch_actions)
1013 /* This map is already defined. We avoid overriding it. */
1016 if (! MPLIST_TAIL_P (map_actions))
1018 if (parse_action_list (map_actions, macros) < 0)
1019 MERROR (MERROR_IM, -1);
1020 map->map_actions = map_actions;
1024 map->branch_actions = branch_actions;
1025 M17N_OBJECT_REF (branch_actions);
1031 /* Load a branch from PLIST into MAP. PLIST has this form:
1032 PLIST ::= ( MAP-NAME BRANCH-ACTION * ) */
1035 load_branch (MInputMethodInfo *im_info, MPlist *plist, MIMMap *map)
1038 MPlist *branch_actions;
1040 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1042 map_name = MPLIST_SYMBOL (plist);
1043 plist = MPLIST_NEXT (plist);
1044 if (MPLIST_TAIL_P (plist))
1045 branch_actions = NULL;
1046 else if (MFAILP (parse_action_list (plist, im_info->macros) >= 0))
1049 branch_actions = plist;
1050 if (map_name == Mnil)
1052 map->branch_actions = branch_actions;
1054 M17N_OBJECT_REF (branch_actions);
1056 else if (map_name == Mt)
1058 map->map_actions = branch_actions;
1060 M17N_OBJECT_REF (branch_actions);
1062 else if (im_info->maps
1063 && (plist = (MPlist *) mplist_get (im_info->maps, map_name)))
1065 MPLIST_DO (plist, plist)
1067 MPlist *keylist, *map_actions;
1069 if (! MPLIST_PLIST_P (plist))
1070 MERROR (MERROR_IM, -1);
1071 keylist = MPLIST_PLIST (plist);
1072 map_actions = MPLIST_NEXT (keylist);
1073 if (MPLIST_SYMBOL_P (keylist))
1075 MSymbol command = MPLIST_SYMBOL (keylist);
1078 if (MFAILP (command != Mat_reload))
1080 pl = resolve_command (im_info->configured_cmds, command);
1084 load_translation (map, pl, map_actions, branch_actions,
1088 load_translation (map, keylist, map_actions, branch_actions,
1096 /* Load a macro from PLIST into IM_INFO->macros.
1097 PLIST has this from:
1098 PLIST ::= ( MACRO-NAME ACTION * )
1099 IM_INFO->macros is a plist of macro names vs action list. */
1102 load_macros (MInputMethodInfo *im_info, MPlist *plist)
1107 if (! MPLIST_SYMBOL_P (plist))
1108 MERROR (MERROR_IM, -1);
1109 name = MPLIST_SYMBOL (plist);
1110 plist = MPLIST_NEXT (plist);
1111 if (MPLIST_TAIL_P (plist)
1112 || parse_action_list (plist, im_info->macros) < 0)
1113 MERROR (MERROR_IM, -1);
1114 pl = mplist_get (im_info->macros, name);
1115 M17N_OBJECT_UNREF (pl);
1116 mplist_put (im_info->macros, name, plist);
1117 M17N_OBJECT_REF (plist);
1121 /* Load an external module from PLIST into IM_INFO->externals.
1122 PLIST has this form:
1123 PLIST ::= ( MODULE-NAME FUNCTION * )
1124 IM_INFO->externals is a plist of MODULE-NAME vs (MIMExternalModule *). */
1127 load_external_module (MInputMethodInfo *im_info, MPlist *plist)
1132 MIMExternalModule *external;
1136 if (MPLIST_MTEXT_P (plist))
1137 module = msymbol ((char *) MTEXT_DATA (MPLIST_MTEXT (plist)));
1138 else if (MPLIST_SYMBOL_P (plist))
1139 module = MPLIST_SYMBOL (plist);
1140 module_file = alloca (strlen (MSYMBOL_NAME (module))
1141 + strlen (DLOPEN_SHLIB_EXT) + 1);
1142 sprintf (module_file, "%s%s", MSYMBOL_NAME (module), DLOPEN_SHLIB_EXT);
1144 handle = dlopen (module_file, RTLD_NOW);
1145 if (MFAILP (handle))
1147 fprintf (stderr, "%s\n", dlerror ());
1150 func_list = mplist ();
1151 MPLIST_DO (plist, MPLIST_NEXT (plist))
1153 if (! MPLIST_SYMBOL_P (plist))
1154 MERROR_GOTO (MERROR_IM, err_label);
1155 func = dlsym (handle, MSYMBOL_NAME (MPLIST_SYMBOL (plist)));
1158 mplist_add (func_list, MPLIST_SYMBOL (plist), func);
1161 MSTRUCT_MALLOC (external, MERROR_IM);
1162 external->handle = handle;
1163 external->func_list = func_list;
1164 mplist_add (im_info->externals, module, external);
1169 M17N_OBJECT_UNREF (func_list);
1174 free_map (MIMMap *map, int top)
1179 M17N_OBJECT_UNREF (map->map_actions);
1182 MPLIST_DO (plist, map->submaps)
1183 free_map ((MIMMap *) MPLIST_VAL (plist), 0);
1184 M17N_OBJECT_UNREF (map->submaps);
1186 M17N_OBJECT_UNREF (map->branch_actions);
1191 free_state (void *object)
1193 MIMState *state = object;
1195 M17N_OBJECT_UNREF (state->title);
1197 free_map (state->map, 1);
1201 /** Load a state from PLIST into a newly allocated state object.
1202 PLIST has this form:
1203 PLIST ::= ( STATE-NAME STATE-TITLE ? BRANCH * )
1204 BRANCH ::= ( MAP-NAME BRANCH-ACTION * )
1205 Return the state object. */
1208 load_state (MInputMethodInfo *im_info, MPlist *plist)
1212 if (MFAILP (MPLIST_SYMBOL_P (plist)))
1214 M17N_OBJECT (state, free_state, MERROR_IM);
1215 state->name = MPLIST_SYMBOL (plist);
1216 plist = MPLIST_NEXT (plist);
1217 if (MPLIST_MTEXT_P (plist))
1219 state->title = MPLIST_MTEXT (plist);
1220 mtext_put_prop (state->title, 0, mtext_nchars (state->title),
1221 Mlanguage, im_info->language);
1222 M17N_OBJECT_REF (state->title);
1223 plist = MPLIST_NEXT (plist);
1225 MSTRUCT_CALLOC (state->map, MERROR_IM);
1226 MPLIST_DO (plist, plist)
1228 if (MFAILP (MPLIST_PLIST_P (plist)))
1230 load_branch (im_info, MPLIST_PLIST (plist), state->map);
1235 /* Return a newly created IM_INFO for an input method specified by
1236 LANUAGE, NAME, and EXTRA. IM_INFO is stored in PLIST. */
1238 static MInputMethodInfo *
1239 new_im_info (MDatabase *mdb, MSymbol language, MSymbol name, MSymbol extra,
1242 MInputMethodInfo *im_info;
1245 if (name == Mnil && extra == Mnil)
1246 language = Mt, extra = Mglobal;
1247 MSTRUCT_CALLOC (im_info, MERROR_IM);
1249 im_info->language = language;
1250 im_info->name = name;
1251 im_info->extra = extra;
1254 mplist_add (plist, Mplist, elt);
1255 M17N_OBJECT_UNREF (elt);
1256 elt = mplist_add (elt, Msymbol, language);
1257 elt = mplist_add (elt, Msymbol, name);
1258 elt = mplist_add (elt, Msymbol, extra);
1259 mplist_add (elt, Mt, im_info);
1265 fini_im_info (MInputMethodInfo *im_info)
1269 M17N_OBJECT_UNREF (im_info->cmds);
1270 M17N_OBJECT_UNREF (im_info->configured_cmds);
1271 M17N_OBJECT_UNREF (im_info->bc_cmds);
1272 M17N_OBJECT_UNREF (im_info->vars);
1273 M17N_OBJECT_UNREF (im_info->configured_vars);
1274 M17N_OBJECT_UNREF (im_info->bc_vars);
1275 M17N_OBJECT_UNREF (im_info->description);
1276 M17N_OBJECT_UNREF (im_info->title);
1277 if (im_info->states)
1279 MPLIST_DO (plist, im_info->states)
1281 MIMState *state = (MIMState *) MPLIST_VAL (plist);
1283 M17N_OBJECT_UNREF (state);
1285 M17N_OBJECT_UNREF (im_info->states);
1288 if (im_info->macros)
1290 MPLIST_DO (plist, im_info->macros)
1291 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1292 M17N_OBJECT_UNREF (im_info->macros);
1295 if (im_info->externals)
1297 MPLIST_DO (plist, im_info->externals)
1299 MIMExternalModule *external = MPLIST_VAL (plist);
1301 dlclose (external->handle);
1302 M17N_OBJECT_UNREF (external->func_list);
1304 MPLIST_KEY (plist) = Mt;
1306 M17N_OBJECT_UNREF (im_info->externals);
1310 MPLIST_DO (plist, im_info->maps)
1312 MPlist *p = MPLIST_PLIST (plist);
1314 M17N_OBJECT_UNREF (p);
1316 M17N_OBJECT_UNREF (im_info->maps);
1323 free_im_info (MInputMethodInfo *im_info)
1325 fini_im_info (im_info);
1330 free_im_list (MPlist *plist)
1334 MPLIST_DO (pl, plist)
1336 MInputMethodInfo *im_info;
1338 elt = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (pl))));
1339 im_info = MPLIST_VAL (elt);
1340 free_im_info (im_info);
1342 M17N_OBJECT_UNREF (plist);
1345 static MInputMethodInfo *
1346 lookup_im_info (MPlist *plist, MSymbol language, MSymbol name, MSymbol extra)
1348 if (name == Mnil && extra == Mnil)
1349 language = Mt, extra = Mglobal;
1350 while ((plist = mplist__assq (plist, language)))
1352 MPlist *elt = MPLIST_PLIST (plist);
1354 plist = MPLIST_NEXT (plist);
1355 elt = MPLIST_NEXT (elt);
1356 if (MPLIST_SYMBOL (elt) != name)
1358 elt = MPLIST_NEXT (elt);
1359 if (MPLIST_SYMBOL (elt) != extra)
1361 elt = MPLIST_NEXT (elt);
1362 return MPLIST_VAL (elt);
1367 static void load_im_info (MPlist *, MInputMethodInfo *);
1369 #define get_custom_info(im_info) \
1371 ? lookup_im_info (im_custom_list, (im_info)->language, \
1372 (im_info)->name, (im_info)->extra) \
1375 #define get_config_info(im_info) \
1377 ? lookup_im_info (im_config_list, (im_info)->language, \
1378 (im_info)->name, (im_info)->extra) \
1382 update_custom_info (void)
1388 if (mdatabase__check (im_custom_mdb) > 0)
1393 MDatabaseInfo *custom_dir_info;
1394 char custom_path[PATH_MAX + 1];
1396 custom_dir_info = MPLIST_VAL (mdatabase__dir_list);
1397 if (! custom_dir_info->filename
1398 || custom_dir_info->len + strlen (CUSTOM_FILE) > PATH_MAX)
1400 strcpy (custom_path, custom_dir_info->filename);
1401 strcat (custom_path, CUSTOM_FILE);
1402 im_custom_mdb = mdatabase_define (Minput_method, Mt, Mnil, Mconfig,
1408 free_im_list (im_custom_list);
1409 im_custom_list = NULL;
1411 plist = mdatabase_load (im_custom_mdb);
1414 im_custom_list = mplist ();
1416 MPLIST_DO (pl, plist)
1418 MSymbol language, name, extra;
1419 MInputMethodInfo *im_info;
1420 MPlist *im_data, *p;
1422 if (! MPLIST_PLIST_P (pl))
1424 p = MPLIST_PLIST (pl);
1425 im_data = MPLIST_NEXT (p);
1426 if (! MPLIST_PLIST_P (p))
1428 p = MPLIST_PLIST (p);
1429 if (! MPLIST_SYMBOL_P (p)
1430 || MPLIST_SYMBOL (p) != Minput_method)
1432 p = MPLIST_NEXT (p);
1433 if (! MPLIST_SYMBOL_P (p))
1435 language = MPLIST_SYMBOL (p);
1436 p = MPLIST_NEXT (p);
1437 if (! MPLIST_SYMBOL_P (p))
1439 name = MPLIST_SYMBOL (p);
1440 if (language == Mnil || name == Mnil)
1442 p = MPLIST_NEXT (p);
1443 if (MPLIST_TAIL_P (p))
1445 else if (MPLIST_SYMBOL_P (p))
1446 extra = MPLIST_SYMBOL (p);
1449 im_info = new_im_info (NULL, language, name, extra, im_custom_list);
1450 load_im_info (im_data, im_info);
1452 M17N_OBJECT_UNREF (plist);
1457 update_global_info (void)
1463 int ret = mdatabase__check (global_info->mdb);
1467 fini_im_info (global_info);
1471 MDatabase *mdb = mdatabase_find (Minput_method, Mt, Mnil, Mglobal);
1473 global_info = new_im_info (mdb, Mt, Mnil, Mglobal, im_info_list);
1475 if (! global_info->mdb
1476 || ! (plist = mdatabase_load (global_info->mdb)))
1479 load_im_info (plist, global_info);
1480 M17N_OBJECT_UNREF (plist);
1485 /* Return an IM_INFO for the an method specified by LANGUAGE, NAME,
1486 and EXTRA. KEY, if not Mnil, tells which kind of information about
1487 the input method is necessary, and the returned IM_INFO may contain
1488 only that information. */
1490 static MInputMethodInfo *
1491 get_im_info (MSymbol language, MSymbol name, MSymbol extra, MSymbol key)
1494 MInputMethodInfo *im_info;
1497 if (name == Mnil && extra == Mnil)
1498 language = Mt, extra = Mglobal;
1499 im_info = lookup_im_info (im_info_list, language, name, extra);
1502 if (key == Mnil ? im_info->states != NULL
1503 : key == Mcommand ? im_info->cmds != NULL
1504 : key == Mvariable ? im_info->vars != NULL
1505 : key == Mtitle ? im_info->title != NULL
1506 : key == Mdescription ? im_info->description != NULL
1508 /* IM_INFO already contains required information. */
1510 /* We have not yet loaded required information. */
1514 mdb = mdatabase_find (Minput_method, language, name, extra);
1517 im_info = new_im_info (mdb, language, name, extra, im_info_list);
1522 plist = mdatabase_load (im_info->mdb);
1526 mplist_push (load_im_info_keys, key, Mt);
1527 plist = mdatabase__load_for_keys (im_info->mdb, load_im_info_keys);
1528 mplist_pop (load_im_info_keys);
1532 MERROR (MERROR_IM, im_info);
1533 update_global_info ();
1534 load_im_info (plist, im_info);
1535 M17N_OBJECT_UNREF (plist);
1538 if (! im_info->cmds)
1539 im_info->cmds = mplist ();
1540 if (! im_info->vars)
1541 im_info->vars = mplist ();
1543 if (! im_info->title
1544 && (key == Mnil || key == Mtitle))
1545 im_info->title = (name == Mnil ? mtext ()
1546 : mtext_from_data (MSYMBOL_NAME (name),
1547 MSYMBOL_NAMELEN (name),
1548 MTEXT_FORMAT_US_ASCII));
1552 /* Check if IM_INFO->mdb is updated or not. If not updated, return 0.
1553 If updated, but got unloadable, return -1. Otherwise, update
1554 contents of IM_INFO from the new database, and return 1. */
1557 reload_im_info (MInputMethodInfo *im_info)
1562 update_custom_info ();
1563 update_global_info ();
1564 check = mdatabase__check (im_info->mdb);
1567 plist = mdatabase_load (im_info->mdb);
1570 fini_im_info (im_info);
1571 load_im_info (plist, im_info);
1572 M17N_OBJECT_UNREF (plist);
1576 static MInputMethodInfo *
1577 get_im_info_by_tags (MPlist *plist)
1582 for (i = 0; i < 3 && MPLIST_SYMBOL_P (plist);
1583 i++, plist = MPLIST_NEXT (plist))
1584 tag[i] = MPLIST_SYMBOL (plist);
1589 return get_im_info (tag[0], tag[1], tag[2], Mnil);
1594 check_description (MPlist *plist)
1598 if (MPLIST_MTEXT_P (plist))
1600 if (MPLIST_PLIST_P (plist))
1602 MPlist *pl = MPLIST_PLIST (plist);
1604 if (MFAILP (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == M_gettext))
1606 pl =MPLIST_NEXT (pl);
1607 if (MFAILP (MPLIST_MTEXT_P (pl)))
1609 mt = MPLIST_MTEXT (pl);
1610 M17N_OBJECT_REF (mt);
1613 char *translated = dgettext ("m17n-db", (char *) MTEXT_DATA (mt));
1615 if (translated == (char *) MTEXT_DATA (mt))
1616 translated = dgettext ("m17n-contrib", (char *) MTEXT_DATA (mt));
1617 if (translated != (char *) MTEXT_DATA (mt))
1619 M17N_OBJECT_UNREF (mt);
1620 mt = mtext__from_data (translated, strlen (translated),
1621 MTEXT_FORMAT_UTF_8, 0);
1625 mplist_set (plist, Mtext, mt);
1626 M17N_OBJECT_UNREF (mt);
1629 if (MFAILP (MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) == Mnil))
1635 /* Check KEYSEQ, and return 1 if it is valid as a key sequence, return
1639 check_command_keyseq (MPlist *keyseq)
1641 if (MPLIST_PLIST_P (keyseq))
1643 MPlist *p = MPLIST_PLIST (keyseq);
1646 if (! MPLIST_SYMBOL_P (p) && ! MPLIST_INTEGER_P (p))
1650 if (MPLIST_MTEXT_P (keyseq))
1652 MText *mt = MPLIST_MTEXT (keyseq);
1655 for (i = 0; i < mtext_nchars (mt); i++)
1656 if (mtext_ref_char (mt, i) >= 256)
1663 /* Load command defitions from PLIST into IM_INFO->cmds.
1665 PLIST is well-formed and has this form;
1666 (command (NAME [DESCRIPTION KEYSEQ ...]) ...)
1667 NAME is a symbol. DESCRIPTION is an M-text or `nil'. KEYSEQ is an
1668 M-text or a plist of symbols.
1670 The returned list has the same form, but for each element...
1672 (1) If DESCRIPTION and the rest are omitted, the element is not
1673 stored in the returned list.
1675 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1676 description in global_info->cmds (if any). */
1679 load_commands (MInputMethodInfo *im_info, MPlist *plist)
1683 im_info->cmds = tail = mplist ();
1685 MPLIST_DO (plist, MPLIST_NEXT (plist))
1687 /* PLIST ::= ((NAME DESC KEYSEQ ...) ...) */
1690 if (MFAILP (MPLIST_PLIST_P (plist)))
1692 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC KEYSEQ ...) */
1693 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1695 p = MPLIST_NEXT (pl); /* P ::= (DESC KEYSEQ ...) */
1696 if (MPLIST_TAIL_P (p)) /* PL ::= (NAME) */
1698 if (MFAILP (im_info != global_info))
1699 mplist_add (p, Msymbol, Mnil); /* PL ::= (NAME nil) */
1703 if (! check_description (p))
1704 mplist_set (p, Msymbol, Mnil);
1705 p = MPLIST_NEXT (p);
1706 while (! MPLIST_TAIL_P (p))
1708 if (MFAILP (check_command_keyseq (p)))
1709 mplist__pop_unref (p);
1711 p = MPLIST_NEXT (p);
1714 tail = mplist_add (tail, Mplist, pl);
1719 config_command (MPlist *plist, MPlist *global_cmds, MPlist *custom_cmds,
1720 MPlist *config_cmds)
1722 MPlist *global = NULL, *custom = NULL, *config = NULL;
1725 MPlist *description = NULL, *keyseq;
1727 name = MPLIST_SYMBOL (plist);
1728 plist = MPLIST_NEXT (plist);
1729 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
1730 description = plist;
1731 else if (global_cmds && ((global = mplist__assq (global_cmds, name))))
1732 description = global = MPLIST_NEXT (MPLIST_PLIST (global));
1733 if (MPLIST_TAIL_P (plist))
1736 && global_cmds && ((global = mplist__assq (global_cmds, name))))
1737 global = MPLIST_NEXT (MPLIST_PLIST (global));
1740 keyseq = MPLIST_NEXT (global);
1741 status = Minherited;
1751 keyseq = MPLIST_NEXT (plist);
1755 if (config_cmds && (config = mplist__assq (config_cmds, name)))
1757 config = MPLIST_NEXT (MPLIST_PLIST (config));
1758 if (! MPLIST_TAIL_P (config))
1760 keyseq = MPLIST_NEXT (config);
1761 status = Mconfigured;
1764 else if (custom_cmds && (custom = mplist__assq (custom_cmds, name)))
1766 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
1767 if (! MPLIST_TAIL_P (custom))
1769 keyseq = MPLIST_NEXT (custom);
1770 status = Mcustomized;
1775 mplist_add (plist, Msymbol, name);
1777 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
1779 mplist_add (plist, Msymbol, Mnil);
1780 mplist_add (plist, Msymbol, status);
1781 mplist__conc (plist, keyseq);
1786 config_all_commands (MInputMethodInfo *im_info)
1788 MPlist *global_cmds, *custom_cmds, *config_cmds;
1789 MInputMethodInfo *temp;
1790 MPlist *tail, *plist;
1792 M17N_OBJECT_UNREF (im_info->configured_cmds);
1794 if (MPLIST_TAIL_P (im_info->cmds)
1798 global_cmds = im_info != global_info ? global_info->cmds : NULL;
1799 custom_cmds = ((temp = get_custom_info (im_info)) ? temp->cmds : NULL);
1800 config_cmds = ((temp = get_config_info (im_info)) ? temp->cmds : NULL);
1802 im_info->configured_cmds = tail = mplist ();
1803 MPLIST_DO (plist, im_info->cmds)
1805 MPlist *pl = config_command (MPLIST_PLIST (plist),
1806 global_cmds, custom_cmds, config_cmds);
1809 tail = mplist_add (tail, Mplist, pl);
1810 M17N_OBJECT_UNREF (pl);
1815 /* Check VAL's value against VALID_VALUES, and return 1 if it is
1816 valid, return 0 if not. */
1819 check_variable_value (MPlist *val, MPlist *global)
1821 MSymbol type = MPLIST_KEY (val);
1822 MPlist *valids = MPLIST_NEXT (val);
1824 if (type != Minteger && type != Mtext && type != Msymbol)
1828 if (MPLIST_KEY (global) != Mt
1829 && MPLIST_KEY (global) != MPLIST_KEY (val))
1831 if (MPLIST_TAIL_P (valids))
1832 valids = MPLIST_NEXT (global);
1834 if (MPLIST_TAIL_P (valids))
1837 if (type == Minteger)
1839 int n = MPLIST_INTEGER (val);
1841 MPLIST_DO (valids, valids)
1843 if (MPLIST_INTEGER_P (valids))
1845 if (n == MPLIST_INTEGER (valids))
1848 else if (MPLIST_PLIST_P (valids))
1850 MPlist *p = MPLIST_PLIST (valids);
1851 int min_bound, max_bound;
1853 if (! MPLIST_INTEGER_P (p))
1854 MERROR (MERROR_IM, 0);
1855 min_bound = MPLIST_INTEGER (p);
1856 p = MPLIST_NEXT (p);
1857 if (! MPLIST_INTEGER_P (p))
1858 MERROR (MERROR_IM, 0);
1859 max_bound = MPLIST_INTEGER (p);
1860 if (n >= min_bound && n <= max_bound)
1865 else if (type == Msymbol)
1867 MSymbol sym = MPLIST_SYMBOL (val);
1869 MPLIST_DO (valids, valids)
1871 if (! MPLIST_SYMBOL_P (valids))
1872 MERROR (MERROR_IM, 0);
1873 if (sym == MPLIST_SYMBOL (valids))
1879 MText *mt = MPLIST_MTEXT (val);
1881 MPLIST_DO (valids, valids)
1883 if (! MPLIST_MTEXT_P (valids))
1884 MERROR (MERROR_IM, 0);
1885 if (mtext_cmp (mt, MPLIST_MTEXT (valids)) == 0)
1890 return (MPLIST_TAIL_P (valids));
1893 /* Load variable defitions from PLIST into IM_INFO->vars.
1895 PLIST is well-formed and has this form;
1896 ((NAME [DESCRIPTION DEFAULT-VALUE VALID-VALUE ...])
1898 NAME is a symbol. DESCRIPTION is an M-text or `nil'.
1900 The returned list has the same form, but for each element...
1902 (1) If DESCRIPTION and the rest are omitted, the element is not
1903 stored in the returned list.
1905 (2) If DESCRIPTION is nil, it is complemented by the corresponding
1906 description in global_info->vars (if any). */
1909 load_variables (MInputMethodInfo *im_info, MPlist *plist)
1911 MPlist *global_vars = ((im_info->mdb && im_info != global_info)
1912 ? global_info->vars : NULL);
1915 im_info->vars = tail = mplist ();
1916 MPLIST_DO (plist, MPLIST_NEXT (plist))
1920 if (MFAILP (MPLIST_PLIST_P (plist)))
1922 pl = MPLIST_PLIST (plist); /* PL ::= (NAME DESC VALUE VALID ...) */
1923 if (MFAILP (MPLIST_SYMBOL_P (pl)))
1925 if (im_info == global_info)
1927 /* Loading a global variable. */
1928 p = MPLIST_NEXT (pl);
1929 if (MPLIST_TAIL_P (p))
1930 mplist_add (p, Msymbol, Mnil);
1933 if (! check_description (p))
1934 mplist_set (p, Msymbol, Mnil);
1935 p = MPLIST_NEXT (p);
1936 if (MFAILP (! MPLIST_TAIL_P (p)
1937 && check_variable_value (p, NULL)))
1938 mplist_set (p, Mt, NULL);
1941 else if (im_info->mdb)
1943 /* Loading a local variable. */
1944 MSymbol name = MPLIST_SYMBOL (pl);
1945 MPlist *global = NULL;
1948 && (p = mplist__assq (global_vars, name)))
1950 /* P ::= ((NAME DESC ...) ...) */
1951 p = MPLIST_PLIST (p); /* P ::= (NAME DESC ...) */
1952 global = MPLIST_NEXT (p); /* P ::= (DESC VALUE ...) */
1953 global = MPLIST_NEXT (global); /* P ::= (VALUE ...) */
1956 p = MPLIST_NEXT (pl); /* P ::= (DESC VALUE VALID ...) */
1957 if (! MPLIST_TAIL_P (p))
1959 if (! check_description (p))
1960 mplist_set (p, Msymbol, Mnil);
1961 p = MPLIST_NEXT (p); /* P ::= (VALUE VALID ...) */
1962 if (MFAILP (! MPLIST_TAIL_P (p)))
1963 mplist_set (p, Mt, NULL);
1966 MPlist *valid_values = MPLIST_NEXT (p);
1968 if (! MPLIST_TAIL_P (valid_values)
1969 ? MFAILP (check_variable_value (p, NULL))
1970 : global && MFAILP (check_variable_value (p, global)))
1971 mplist_set (p, Mt, NULL);
1977 /* Loading a variable customization. */
1978 p = MPLIST_NEXT (pl); /* P ::= (nil VALUE) */
1979 if (MFAILP (! MPLIST_TAIL_P (p)))
1981 p = MPLIST_NEXT (p); /* P ::= (VALUE) */
1982 if (MFAILP (MPLIST_INTEGER_P (p) || MPLIST_SYMBOL_P (p)
1983 || MPLIST_MTEXT_P (p)))
1986 tail = mplist_add (tail, Mplist, pl);
1991 config_variable (MPlist *plist, MPlist *global_vars, MPlist *custom_vars,
1992 MPlist *config_vars)
1994 MPlist *global = NULL, *custom = NULL, *config = NULL;
1995 MSymbol name = MPLIST_SYMBOL (plist);
1997 MPlist *description = NULL, *value, *valids;
2001 global = mplist__assq (global_vars, name);
2003 global = MPLIST_NEXT (MPLIST_PLIST (global)); /* (DESC VALUE ...) */
2006 plist = MPLIST_NEXT (plist);
2007 if (MPLIST_MTEXT_P (plist) || MPLIST_PLIST_P (plist))
2008 description = plist;
2010 description = global;
2012 global = MPLIST_NEXT (global); /* (VALUE VALIDS ...) */
2014 if (MPLIST_TAIL_P (plist))
2016 /* Inherit from global (if any). */
2020 if (MPLIST_KEY (value) == Mt)
2022 valids = MPLIST_NEXT (global);
2023 status = Minherited;
2035 value = plist = MPLIST_NEXT (plist);
2036 valids = MPLIST_NEXT (value);
2037 if (MPLIST_KEY (value) == Mt)
2039 if (! MPLIST_TAIL_P (valids))
2042 valids = MPLIST_NEXT (global);
2046 if (config_vars && (config = mplist__assq (config_vars, name)))
2048 config = MPLIST_NEXT (MPLIST_PLIST (config));
2049 if (! MPLIST_TAIL_P (config))
2051 value = MPLIST_NEXT (config);
2052 if (MFAILP (check_variable_value (value, global ? global : plist)))
2054 status = Mconfigured;
2057 else if (custom_vars && (custom = mplist__assq (custom_vars, name)))
2059 custom = MPLIST_NEXT (MPLIST_PLIST (custom));
2060 if (! MPLIST_TAIL_P (custom))
2062 value = MPLIST_NEXT (custom);
2063 if (MFAILP (check_variable_value (value, global ? global : plist)))
2065 status = Mcustomized;
2070 mplist_add (plist, Msymbol, name);
2072 mplist_add (plist, MPLIST_KEY (description), MPLIST_VAL (description));
2074 mplist_add (plist, Msymbol, Mnil);
2075 mplist_add (plist, Msymbol, status);
2077 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
2079 mplist_add (plist, Mt, NULL);
2080 if (valids && ! MPLIST_TAIL_P (valids))
2081 mplist__conc (plist, valids);
2085 /* Return a configured variable definition list based on
2086 IM_INFO->vars. If a variable in it doesn't contain a value, try to
2087 get it from global_info->vars. */
2090 config_all_variables (MInputMethodInfo *im_info)
2092 MPlist *global_vars, *custom_vars, *config_vars;
2093 MInputMethodInfo *temp;
2094 MPlist *tail, *plist;
2096 M17N_OBJECT_UNREF (im_info->configured_vars);
2098 if (MPLIST_TAIL_P (im_info->vars)
2102 global_vars = im_info != global_info ? global_info->vars : NULL;
2103 custom_vars = ((temp = get_custom_info (im_info)) ? temp->vars : NULL);
2104 config_vars = ((temp = get_config_info (im_info)) ? temp->vars : NULL);
2106 im_info->configured_vars = tail = mplist ();
2107 MPLIST_DO (plist, im_info->vars)
2109 MPlist *pl = config_variable (MPLIST_PLIST (plist),
2110 global_vars, custom_vars, config_vars);
2113 tail = mplist_add (tail, Mplist, pl);
2114 M17N_OBJECT_UNREF (pl);
2119 /* Load an input method (LANGUAGE NAME) from PLIST into IM_INFO.
2120 CONFIG contains configuration information of the input method. */
2123 load_im_info (MPlist *plist, MInputMethodInfo *im_info)
2127 if (! im_info->cmds && (pl = mplist__assq (plist, Mcommand)))
2129 load_commands (im_info, MPLIST_PLIST (pl));
2130 config_all_commands (im_info);
2131 pl = mplist_pop (pl);
2132 M17N_OBJECT_UNREF (pl);
2135 if (! im_info->vars && (pl = mplist__assq (plist, Mvariable)))
2137 load_variables (im_info, MPLIST_PLIST (pl));
2138 config_all_variables (im_info);
2139 pl = mplist_pop (pl);
2140 M17N_OBJECT_UNREF (pl);
2143 MPLIST_DO (plist, plist)
2144 if (MPLIST_PLIST_P (plist))
2146 MPlist *elt = MPLIST_PLIST (plist);
2149 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2151 key = MPLIST_SYMBOL (elt);
2156 elt = MPLIST_NEXT (elt);
2157 if (MFAILP (MPLIST_MTEXT_P (elt)))
2159 im_info->title = MPLIST_MTEXT (elt);
2160 M17N_OBJECT_REF (im_info->title);
2162 else if (key == Mmap)
2164 pl = mplist__from_alist (MPLIST_NEXT (elt));
2167 if (! im_info->maps)
2171 mplist__conc (im_info->maps, pl);
2172 M17N_OBJECT_UNREF (pl);
2175 else if (key == Mmacro)
2177 if (! im_info->macros)
2178 im_info->macros = mplist ();
2179 MPLIST_DO (elt, MPLIST_NEXT (elt))
2181 if (MFAILP (MPLIST_PLIST_P (elt)))
2183 load_macros (im_info, MPLIST_PLIST (elt));
2186 else if (key == Mmodule)
2188 if (! im_info->externals)
2189 im_info->externals = mplist ();
2190 MPLIST_DO (elt, MPLIST_NEXT (elt))
2192 if (MFAILP (MPLIST_PLIST_P (elt)))
2194 load_external_module (im_info, MPLIST_PLIST (elt));
2197 else if (key == Mstate)
2199 MPLIST_DO (elt, MPLIST_NEXT (elt))
2203 if (MFAILP (MPLIST_PLIST_P (elt)))
2205 pl = MPLIST_PLIST (elt);
2206 if (! im_info->states)
2207 im_info->states = mplist ();
2208 state = load_state (im_info, MPLIST_PLIST (elt));
2211 mplist_put (im_info->states, state->name, state);
2214 else if (key == Minclude)
2216 /* elt ::= include (tag1 tag2 ...) key item ... */
2218 MInputMethodInfo *temp;
2220 elt = MPLIST_NEXT (elt);
2221 if (MFAILP (MPLIST_PLIST_P (elt)))
2223 temp = get_im_info_by_tags (MPLIST_PLIST (elt));
2226 elt = MPLIST_NEXT (elt);
2227 if (MFAILP (MPLIST_SYMBOL_P (elt)))
2229 key = MPLIST_SYMBOL (elt);
2230 elt = MPLIST_NEXT (elt);
2233 if (! temp->maps || MPLIST_TAIL_P (temp->maps))
2235 if (! im_info->maps)
2236 im_info->maps = mplist ();
2237 MPLIST_DO (pl, temp->maps)
2239 p = MPLIST_VAL (pl);
2240 MPLIST_ADD_PLIST (im_info->maps, MPLIST_KEY (pl), p);
2241 M17N_OBJECT_REF (p);
2244 else if (key == Mmacro)
2246 if (! temp->macros || MPLIST_TAIL_P (temp->macros))
2248 if (! im_info->macros)
2249 im_info->macros = mplist ();
2250 MPLIST_DO (pl, temp->macros)
2252 p = MPLIST_VAL (pl);
2253 MPLIST_ADD_PLIST (im_info->macros, MPLIST_KEY (pl), p);
2254 M17N_OBJECT_REF (p);
2257 else if (key == Mstate)
2259 if (! temp->states || MPLIST_TAIL_P (temp->states))
2261 if (! im_info->states)
2262 im_info->states = mplist ();
2263 MPLIST_DO (pl, temp->states)
2265 MIMState *state = MPLIST_VAL (pl);
2267 mplist_add (im_info->states, MPLIST_KEY (pl), state);
2268 M17N_OBJECT_REF (state);
2272 else if (key == Mdescription)
2274 if (im_info->description)
2276 elt = MPLIST_NEXT (elt);
2277 if (! check_description (elt))
2279 im_info->description = MPLIST_MTEXT (elt);
2280 M17N_OBJECT_REF (im_info->description);
2283 im_info->tick = time (NULL);
2288 static int take_action_list (MInputContext *ic, MPlist *action_list);
2289 static void preedit_commit (MInputContext *ic);
2292 shift_state (MInputContext *ic, MSymbol state_name)
2294 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
2295 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2296 MIMState *orig_state = ic_info->state, *state;
2298 /* Find a state to shift to. If not found, shift to the initial
2300 if (state_name == Mt)
2302 if (! ic_info->prev_state)
2304 state = ic_info->prev_state;
2306 else if (state_name == Mnil)
2308 state = (MIMState *) MPLIST_VAL (im_info->states);
2312 state = (MIMState *) mplist_get (im_info->states, state_name);
2314 state = (MIMState *) MPLIST_VAL (im_info->states);
2317 MDEBUG_PRINT1 ("\n [IM] (shift %s)", MSYMBOL_NAME (state->name));
2319 /* Enter the new state. */
2320 ic_info->state = state;
2321 ic_info->map = state->map;
2322 ic_info->state_key_head = ic_info->key_head;
2323 if (state == (MIMState *) MPLIST_VAL (im_info->states)
2325 /* We have shifted to the initial state. */
2326 preedit_commit (ic);
2327 mtext_cpy (ic_info->preedit_saved, ic->preedit);
2328 ic_info->state_pos = ic->cursor_pos;
2329 if (state != orig_state)
2331 if (state == (MIMState *) MPLIST_VAL (im_info->states))
2333 /* Shifted to the initial state. */
2334 ic_info->prev_state = NULL;
2335 M17N_OBJECT_UNREF (ic_info->vars_saved);
2336 ic_info->vars_saved = mplist_copy (ic_info->vars);
2339 ic_info->prev_state = orig_state;
2342 ic->status = state->title;
2344 ic->status = im_info->title;
2345 ic->status_changed = 1;
2346 if (ic_info->map == ic_info->state->map
2347 && ic_info->map->map_actions)
2349 MDEBUG_PRINT (" init-actions:");
2350 take_action_list (ic, ic_info->map->map_actions);
2355 /* Find a candidate group that contains a candidate number INDEX from
2356 PLIST. Set START_INDEX to the first candidate number of the group,
2357 END_INDEX to the last candidate number plus 1, GROUP_INDEX to the
2358 candidate group number if they are non-NULL. If INDEX is -1, find
2359 the last candidate group. */
2362 find_candidates_group (MPlist *plist, int index,
2363 int *start_index, int *end_index, int *group_index)
2365 int i = 0, gidx = 0, len;
2367 MPLIST_DO (plist, plist)
2369 if (MPLIST_MTEXT_P (plist))
2370 len = mtext_nchars (MPLIST_MTEXT (plist));
2372 len = mplist_length (MPLIST_PLIST (plist));
2373 if (index < 0 ? MPLIST_TAIL_P (MPLIST_NEXT (plist))
2379 *end_index = i + len;
2381 *group_index = gidx;
2390 /* Adjust markers for the change of preedit text.
2391 If FROM == TO, the change is insertion of INS chars.
2392 If FROM < TO and INS == 0, the change is deletion of the range.
2393 If FROM < TO and INS > 0, the change is replacement. */
2396 adjust_markers (MInputContext *ic, int from, int to, int ins)
2398 MInputContextInfo *ic_info = ((MInputContext *) ic)->info;
2403 MPLIST_DO (markers, ic_info->markers)
2404 if (MPLIST_INTEGER (markers) > from)
2405 MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins);
2406 if (ic->cursor_pos >= from)
2407 ic->cursor_pos += ins;
2411 MPLIST_DO (markers, ic_info->markers)
2413 if (MPLIST_INTEGER (markers) >= to)
2414 MPLIST_VAL (markers)
2415 = (void *) (MPLIST_INTEGER (markers) + ins - (to - from));
2416 else if (MPLIST_INTEGER (markers) > from)
2417 MPLIST_VAL (markers) = (void *) from;
2419 if (ic->cursor_pos >= to)
2420 ic->cursor_pos += ins - (to - from);
2421 else if (ic->cursor_pos > from)
2422 ic->cursor_pos = from;
2428 preedit_insert (MInputContext *ic, int pos, MText *mt, int c)
2430 int nchars = mt ? mtext_nchars (mt) : 1;
2433 mtext_ins (ic->preedit, pos, mt);
2435 mtext_ins_char (ic->preedit, pos, c, 1);
2436 adjust_markers (ic, pos, pos, nchars);
2437 ic->preedit_changed = 1;
2442 preedit_delete (MInputContext *ic, int from, int to)
2444 mtext_del (ic->preedit, from, to);
2445 adjust_markers (ic, from, to, 0);
2446 ic->preedit_changed = 1;
2450 preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c)
2454 mtext_del (ic->preedit, from, to);
2457 mtext_ins (ic->preedit, from, mt);
2458 ins = mtext_nchars (mt);
2462 mtext_ins_char (ic->preedit, from, c, 1);
2465 adjust_markers (ic, from, to, ins);
2466 ic->preedit_changed = 1;
2471 preedit_commit (MInputContext *ic)
2473 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2474 int preedit_len = mtext_nchars (ic->preedit);
2476 if (preedit_len > 0)
2480 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2481 Mcandidate_list, NULL, 0);
2482 mtext_put_prop_values (ic->preedit, 0, mtext_nchars (ic->preedit),
2483 Mcandidate_index, NULL, 0);
2484 mtext_cat (ic->produced, ic->preedit);
2485 mtext_reset (ic->preedit);
2486 mtext_reset (ic_info->preedit_saved);
2487 MPLIST_DO (p, ic_info->markers)
2489 ic->cursor_pos = ic_info->state_pos = 0;
2490 ic->preedit_changed = 1;
2491 ic_info->commit_key_head = ic_info->key_head;
2493 if (ic->candidate_list)
2495 M17N_OBJECT_UNREF (ic->candidate_list);
2496 ic->candidate_list = NULL;
2497 ic->candidates_changed = MINPUT_CANDIDATES_LIST_CHANGED;
2498 if (ic->candidate_show)
2500 ic->candidate_show = 0;
2501 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
2507 new_index (MInputContext *ic, int current, int limit, MSymbol sym, MText *mt)
2509 int code = marker_code (sym, 0);
2511 if (mt && (code == '[' || code == ']'))
2515 if (code == '[' && current > 0)
2517 if (mtext_prop_range (mt, Mcandidate_list, pos - 1, &pos, NULL, 1)
2521 else if (code == ']' && current < mtext_nchars (mt))
2523 if (mtext_prop_range (mt, Mcandidate_list, pos, NULL, &pos, 1))
2529 return (code == '<' ? 0
2530 : code == '>' ? limit
2531 : code == '-' ? current - 1
2532 : code == '+' ? current + 1
2533 : code == '=' ? current
2534 : code - '0' > limit ? limit
2538 return (int) mplist_get (((MInputContextInfo *) ic->info)->markers, sym);
2542 update_candidate (MInputContext *ic, MTextProperty *prop, int idx)
2544 int from = mtext_property_start (prop);
2545 int to = mtext_property_end (prop);
2547 MPlist *candidate_list = mtext_property_value (prop);
2548 MPlist *group = find_candidates_group (candidate_list, idx, &start,
2550 int ingroup_index = idx - start;
2553 if (MPLIST_MTEXT_P (group))
2555 mt = MPLIST_MTEXT (group);
2556 preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index));
2564 for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index;
2565 i++, plist = MPLIST_NEXT (plist));
2566 mt = MPLIST_MTEXT (plist);
2567 preedit_replace (ic, from, to, mt, 0);
2568 to = from + mtext_nchars (mt);
2570 mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list);
2571 mtext_put_prop (ic->preedit, from, to, Mcandidate_index, (void *) idx);
2572 ic->cursor_pos = to;
2576 get_select_charset (MInputContextInfo * ic_info)
2578 MPlist *plist = resolve_variable (ic_info, Mcandidates_charset);
2581 if (! MPLIST_VAL (plist))
2583 sym = MPLIST_SYMBOL (plist);
2586 return MCHARSET (sym);
2590 adjust_candidates (MPlist *plist, MCharset *charset)
2594 /* plist ::= MTEXT ... | PLIST ... */
2595 plist = mplist_copy (plist);
2596 if (MPLIST_MTEXT_P (plist))
2599 while (! MPLIST_TAIL_P (pl))
2601 /* pl ::= MTEXT ... */
2602 MText *mt = MPLIST_MTEXT (pl);
2606 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2608 c = mtext_ref_char (mt, i);
2609 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2613 mt = mtext_dup (mt);
2614 mplist_set (pl, Mtext, mt);
2615 M17N_OBJECT_UNREF (mt);
2618 mtext_del (mt, i, i + 1);
2621 if (mtext_len (mt) > 0)
2622 pl = MPLIST_NEXT (pl);
2626 M17N_OBJECT_UNREF (mt);
2630 else /* MPLIST_PLIST_P (plist) */
2633 while (! MPLIST_TAIL_P (pl))
2635 /* pl ::= (MTEXT ...) ... */
2636 MPlist *p = MPLIST_PLIST (pl);
2638 /* p ::= MTEXT ... */
2642 while (! MPLIST_TAIL_P (p0))
2644 MText *mt = MPLIST_MTEXT (p0);
2647 for (i = mtext_nchars (mt) - 1; i >= 0; i--)
2649 c = mtext_ref_char (mt, i);
2650 if (ENCODE_CHAR (charset, c) == MCHAR_INVALID_CODE)
2655 p0 = MPLIST_NEXT (p0);
2662 p = mplist_copy (p);
2663 mplist_set (pl, Mplist, p);
2664 M17N_OBJECT_UNREF (p);
2668 p0 = MPLIST_NEXT (p0);
2671 M17N_OBJECT_UNREF (mt);
2674 if (! MPLIST_TAIL_P (p))
2675 pl = MPLIST_NEXT (pl);
2679 M17N_OBJECT_UNREF (p);
2683 if (MPLIST_TAIL_P (plist))
2685 M17N_OBJECT_UNREF (plist);
2692 get_candidate_list (MInputContextInfo *ic_info, MPlist *args)
2694 MCharset *charset = get_select_charset (ic_info);
2699 plist = resolve_variable (ic_info, Mcandidates_group_size);
2700 column = MPLIST_INTEGER (plist);
2702 plist = MPLIST_PLIST (args);
2704 plist = adjust_candidates (plist, charset);
2706 if (plist && column > 0)
2708 if (MPLIST_MTEXT_P (plist))
2710 MText *mt = MPLIST_MTEXT (plist);
2711 MPlist *next = MPLIST_NEXT (plist);
2713 if (MPLIST_TAIL_P (next))
2714 M17N_OBJECT_REF (mt);
2717 mt = mtext_dup (mt);
2718 while (! MPLIST_TAIL_P (next))
2720 mt = mtext_cat (mt, MPLIST_MTEXT (next));
2721 next = MPLIST_NEXT (next);
2724 M17N_OBJECT_UNREF (plist);
2726 len = mtext_nchars (mt);
2728 mplist_add (plist, Mtext, mt);
2731 for (i = 0; i < len; i += column)
2733 int to = (i + column < len ? i + column : len);
2734 MText *sub = mtext_copy (mtext (), 0, mt, i, to);
2736 mplist_add (plist, Mtext, sub);
2737 M17N_OBJECT_UNREF (sub);
2740 M17N_OBJECT_UNREF (mt);
2742 else /* MPLIST_PLIST_P (plist) */
2744 MPlist *pl = MPLIST_PLIST (plist), *p;
2745 MPlist *next = MPLIST_NEXT (plist);
2748 if (MPLIST_TAIL_P (next))
2749 M17N_OBJECT_REF (pl);
2752 pl = mplist_copy (pl);
2753 while (! MPLIST_TAIL_P (next))
2755 p = mplist_copy (MPLIST_PLIST (next));
2756 pl = mplist__conc (pl, p);
2757 M17N_OBJECT_UNREF (p);
2758 next = MPLIST_NEXT (next);
2761 M17N_OBJECT_UNREF (plist);
2763 len = mplist_length (pl);
2765 mplist_add (plist, Mplist, pl);
2770 for (i = 0; i < len; i += column)
2773 mplist_add (plist, Mplist, p);
2774 M17N_OBJECT_UNREF (p);
2775 for (j = 0; j < column && i + j < len; j++)
2777 p = mplist_add (p, Mtext, MPLIST_VAL (p0));
2778 p0 = MPLIST_NEXT (p0);
2782 M17N_OBJECT_UNREF (pl);
2791 regularize_action (MPlist *action_list, MInputContextInfo *ic_info)
2793 MPlist *action = NULL;
2797 if (MPLIST_SYMBOL_P (action_list))
2799 MSymbol var = MPLIST_SYMBOL (action_list);
2802 MPLIST_DO (p, ic_info->vars)
2803 if (MPLIST_SYMBOL (MPLIST_PLIST (p)) == var)
2805 if (MPLIST_TAIL_P (p))
2807 action = MPLIST_NEXT (MPLIST_PLIST (p));
2808 mplist_set (action_list, MPLIST_KEY (action), MPLIST_VAL (action));
2811 if (MPLIST_PLIST_P (action_list))
2813 action = MPLIST_PLIST (action_list);
2814 if (MPLIST_SYMBOL_P (action))
2816 name = MPLIST_SYMBOL (action);
2817 args = MPLIST_NEXT (action);
2819 && MPLIST_PLIST_P (args))
2820 mplist_set (action, Msymbol, M_candidates);
2822 else if (MPLIST_MTEXT_P (action) || MPLIST_PLIST_P (action))
2825 mplist_push (action, Mplist, MPLIST_VAL (action_list));
2826 mplist_push (action, Msymbol, M_candidates);
2827 mplist_set (action_list, Mplist, action);
2828 M17N_OBJECT_UNREF (action);
2831 else if (MPLIST_MTEXT_P (action_list) || MPLIST_INTEGER_P (action_list))
2834 mplist_push (action, MPLIST_KEY (action_list), MPLIST_VAL (action_list));
2835 mplist_push (action, Msymbol, Minsert);
2836 mplist_set (action_list, Mplist, action);
2837 M17N_OBJECT_UNREF (action);
2842 /* Perform list of actions in ACTION_LIST for the current input
2843 context IC. If all actions are performed without error, return 0.
2844 Otherwise, return -1. */
2847 take_action_list (MInputContext *ic, MPlist *action_list)
2849 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
2850 MPlist *candidate_list = ic->candidate_list;
2851 int candidate_index = ic->candidate_index;
2852 int candidate_show = ic->candidate_show;
2853 MTextProperty *prop;
2855 MPLIST_DO (action_list, action_list)
2857 MPlist *action = regularize_action (action_list, ic_info);
2863 name = MPLIST_SYMBOL (action);
2864 args = MPLIST_NEXT (action);
2866 MDEBUG_PRINT1 (" %s", MSYMBOL_NAME (name));
2867 if (name == Minsert)
2869 if (MPLIST_SYMBOL_P (args))
2871 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2872 if (! MPLIST_MTEXT_P (args) && ! MPLIST_INTEGER_P (args))
2875 if (MPLIST_MTEXT_P (args))
2876 preedit_insert (ic, ic->cursor_pos, MPLIST_MTEXT (args), 0);
2877 else /* MPLIST_INTEGER_P (args)) */
2878 preedit_insert (ic, ic->cursor_pos, NULL, MPLIST_INTEGER (args));
2880 else if (name == M_candidates)
2882 MPlist *plist = get_candidate_list (ic_info, args);
2887 if (MPLIST_MTEXT_P (plist))
2889 preedit_insert (ic, ic->cursor_pos, NULL,
2890 mtext_ref_char (MPLIST_MTEXT (plist), 0));
2895 MText * mt = MPLIST_MTEXT (MPLIST_PLIST (plist));
2897 preedit_insert (ic, ic->cursor_pos, mt, 0);
2898 len = mtext_nchars (mt);
2900 mtext_put_prop (ic->preedit,
2901 ic->cursor_pos - len, ic->cursor_pos,
2902 Mcandidate_list, plist);
2903 mtext_put_prop (ic->preedit,
2904 ic->cursor_pos - len, ic->cursor_pos,
2905 Mcandidate_index, (void *) 0);
2907 else if (name == Mselect)
2910 int code, idx, gindex;
2911 int pos = ic->cursor_pos;
2913 int idx_decided = 0;
2916 || ! (prop = mtext_get_property (ic->preedit, pos - 1,
2919 idx = (int) mtext_get_prop (ic->preedit, pos - 1, Mcandidate_index);
2920 group = find_candidates_group (mtext_property_value (prop), idx,
2921 &start, &end, &gindex);
2922 if (MPLIST_SYMBOL_P (args))
2924 code = marker_code (MPLIST_SYMBOL (args), 0);
2927 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
2928 if (! MPLIST_INTEGER_P (args))
2930 idx = start + MPLIST_INTEGER (args);
2931 if (idx < start || idx >= end)
2939 if (code != '[' && code != ']')
2944 ? new_index (NULL, ic->candidate_index - start,
2945 end - start - 1, MPLIST_SYMBOL (args),
2947 : MPLIST_INTEGER (args)));
2950 find_candidates_group (mtext_property_value (prop), -1,
2955 && MPLIST_TAIL_P (MPLIST_NEXT (group)))
2960 int ingroup_index = idx - start;
2963 group = mtext_property_value (prop);
2964 len = mplist_length (group);
2977 for (idx = 0; gindex > 0; gindex--, group = MPLIST_NEXT (group))
2978 idx += (MPLIST_MTEXT_P (group)
2979 ? mtext_nchars (MPLIST_MTEXT (group))
2980 : mplist_length (MPLIST_PLIST (group)));
2981 len = (MPLIST_MTEXT_P (group)
2982 ? mtext_nchars (MPLIST_MTEXT (group))
2983 : mplist_length (MPLIST_PLIST (group)));
2984 if (ingroup_index >= len)
2985 ingroup_index = len - 1;
2986 idx += ingroup_index;
2988 update_candidate (ic, prop, idx);
2989 MDEBUG_PRINT1 ("(%d)", idx);
2991 else if (name == Mshow)
2992 ic->candidate_show = 1;
2993 else if (name == Mhide)
2994 ic->candidate_show = 0;
2995 else if (name == Mdelete)
2997 int len = mtext_nchars (ic->preedit);
3001 if (MPLIST_SYMBOL_P (args)
3002 && (pos = surrounding_pos (MPLIST_SYMBOL (args))) != 0)
3004 to = ic->cursor_pos + pos;
3007 delete_surrounding_text (ic, to);
3012 delete_surrounding_text (ic, to - len);
3018 to = (MPLIST_SYMBOL_P (args)
3019 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3021 : MPLIST_INTEGER (args));
3027 MDEBUG_PRINT1 ("(%d)", to - ic->cursor_pos);
3028 if (to < ic->cursor_pos)
3029 preedit_delete (ic, to, ic->cursor_pos);
3030 else if (to > ic->cursor_pos)
3031 preedit_delete (ic, ic->cursor_pos, to);
3033 else if (name == Mmove)
3035 int len = mtext_nchars (ic->preedit);
3037 = (MPLIST_SYMBOL_P (args)
3038 ? new_index (ic, ic->cursor_pos, len, MPLIST_SYMBOL (args),
3040 : MPLIST_INTEGER (args));
3046 if (pos != ic->cursor_pos)
3048 ic->cursor_pos = pos;
3049 ic->preedit_changed = 1;
3051 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3053 else if (name == Mmark)
3055 int code = marker_code (MPLIST_SYMBOL (args), 0);
3059 mplist_put (ic_info->markers, MPLIST_SYMBOL (args),
3060 (void *) ic->cursor_pos);
3061 MDEBUG_PRINT1 ("(%d)", ic->cursor_pos);
3064 else if (name == Mpushback)
3066 if (MPLIST_INTEGER_P (args) || MPLIST_SYMBOL_P (args))
3070 if (MPLIST_SYMBOL_P (args))
3072 args = resolve_variable (ic_info, MPLIST_SYMBOL (args));
3073 if (MPLIST_INTEGER_P (args))
3074 num = MPLIST_INTEGER (args);
3079 num = MPLIST_INTEGER (args);
3082 ic_info->key_head -= num;
3084 ic_info->key_head = 0;
3086 ic_info->key_head = - num;
3087 if (ic_info->key_head > ic_info->used)
3088 ic_info->key_head = ic_info->used;
3090 else if (MPLIST_MTEXT_P (args))
3092 MText *mt = MPLIST_MTEXT (args);
3093 int i, len = mtext_nchars (mt);
3096 ic_info->key_head--;
3097 for (i = 0; i < len; i++)
3099 key = one_char_symbol[MTEXT_DATA (mt)[i]];
3100 if (ic_info->key_head + i < ic_info->used)
3101 ic_info->keys[ic_info->key_head + i] = key;
3103 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3108 MPlist *plist = MPLIST_PLIST (args), *pl;
3112 ic_info->key_head--;
3114 MPLIST_DO (pl, plist)
3116 key = MPLIST_SYMBOL (pl);
3117 if (ic_info->key_head < ic_info->used)
3118 ic_info->keys[ic_info->key_head + i] = key;
3120 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3125 else if (name == Mcall)
3127 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3128 MIMExternalFunc func = NULL;
3129 MSymbol module, func_name;
3130 MPlist *func_args, *val;
3133 module = MPLIST_SYMBOL (args);
3134 args = MPLIST_NEXT (args);
3135 func_name = MPLIST_SYMBOL (args);
3137 if (im_info->externals)
3139 MIMExternalModule *external
3140 = (MIMExternalModule *) mplist_get (im_info->externals,
3143 func = (MIMExternalFunc) mplist_get (external->func_list,
3148 func_args = mplist ();
3149 mplist_add (func_args, Mt, ic);
3150 MPLIST_DO (args, MPLIST_NEXT (args))
3154 if (MPLIST_KEY (args) == Msymbol
3155 && MPLIST_KEY (args) != Mnil
3156 && (code = marker_code (MPLIST_SYMBOL (args), 0)) >= 0)
3158 code = new_index (ic, ic->cursor_pos,
3159 mtext_nchars (ic->preedit),
3160 MPLIST_SYMBOL (args), ic->preedit);
3161 mplist_add (func_args, Minteger, (void *) code);
3164 mplist_add (func_args, MPLIST_KEY (args), MPLIST_VAL (args));
3166 val = (func) (func_args);
3167 M17N_OBJECT_UNREF (func_args);
3168 if (val && ! MPLIST_TAIL_P (val))
3169 ret = take_action_list (ic, val);
3170 M17N_OBJECT_UNREF (val);
3174 else if (name == Mshift)
3176 shift_state (ic, MPLIST_SYMBOL (args));
3178 else if (name == Mundo)
3180 int intarg = (MPLIST_TAIL_P (args)
3182 : integer_value (ic, args, NULL, 0));
3184 mtext_reset (ic->preedit);
3185 mtext_reset (ic_info->preedit_saved);
3186 mtext_reset (ic->produced);
3187 M17N_OBJECT_UNREF (ic_info->vars);
3188 ic_info->vars = mplist_copy (ic_info->vars_saved);
3189 ic->cursor_pos = ic_info->state_pos = 0;
3190 ic_info->state_key_head = ic_info->key_head
3191 = ic_info->commit_key_head = 0;
3193 shift_state (ic, Mnil);
3196 if (MPLIST_TAIL_P (args))
3201 ic_info->used += intarg;
3204 ic_info->used = intarg;
3207 else if (name == Mset || name == Madd || name == Msub
3208 || name == Mmul || name == Mdiv)
3210 MSymbol sym = MPLIST_SYMBOL (args);
3215 val1 = integer_value (ic, args, &value, 0);
3216 args = MPLIST_NEXT (args);
3217 val2 = resolve_expression (ic, args);
3219 val1 = val2, op = "=";
3220 else if (name == Madd)
3221 val1 += val2, op = "+=";
3222 else if (name == Msub)
3223 val1 -= val2, op = "-=";
3224 else if (name == Mmul)
3225 val1 *= val2, op = "*=";
3227 val1 /= val2, op = "/=";
3228 MDEBUG_PRINT4 ("(%s %s 0x%X(%d))",
3229 MSYMBOL_NAME (sym), op, val1, val1);
3231 mplist_set (value, Minteger, (void *) val1);
3233 else if (name == Mequal || name == Mless || name == Mgreater
3234 || name == Mless_equal || name == Mgreater_equal)
3237 MPlist *actions1, *actions2;
3240 val1 = resolve_expression (ic, args);
3241 args = MPLIST_NEXT (args);
3242 val2 = resolve_expression (ic, args);
3243 args = MPLIST_NEXT (args);
3244 actions1 = MPLIST_PLIST (args);
3245 args = MPLIST_NEXT (args);
3246 if (MPLIST_TAIL_P (args))
3249 actions2 = MPLIST_PLIST (args);
3250 MDEBUG_PRINT3 ("(%d %s %d)? ", val1, MSYMBOL_NAME (name), val2);
3251 if (name == Mequal ? val1 == val2
3252 : name == Mless ? val1 < val2
3253 : name == Mgreater ? val1 > val2
3254 : name == Mless_equal ? val1 <= val2
3257 MDEBUG_PRINT ("ok");
3258 ret = take_action_list (ic, actions1);
3262 MDEBUG_PRINT ("no");
3264 ret = take_action_list (ic, actions2);
3269 else if (name == Mcond)
3273 MPLIST_DO (args, args)
3278 if (! MPLIST_PLIST (args))
3280 cond = MPLIST_PLIST (args);
3281 if (resolve_expression (ic, cond) != 0)
3283 MDEBUG_PRINT1 ("(%dth)", idx);
3284 if (take_action_list (ic, MPLIST_NEXT (cond)) < 0)
3290 else if (name == Mcommit)
3292 preedit_commit (ic);
3294 else if (name == Munhandle)
3296 preedit_commit (ic);
3301 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3305 && (actions = mplist_get (im_info->macros, name)))
3307 if (take_action_list (ic, actions) < 0)
3313 if (ic->candidate_list)
3315 M17N_OBJECT_UNREF (ic->candidate_list);
3316 ic->candidate_list = NULL;
3318 if (ic->cursor_pos > 0
3319 && (prop = mtext_get_property (ic->preedit, ic->cursor_pos - 1,
3322 ic->candidate_list = mtext_property_value (prop);
3323 M17N_OBJECT_REF (ic->candidate_list);
3325 = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1,
3327 ic->candidate_from = mtext_property_start (prop);
3328 ic->candidate_to = mtext_property_end (prop);
3331 if (candidate_list != ic->candidate_list)
3332 ic->candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3333 if (candidate_index != ic->candidate_index)
3334 ic->candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3335 if (candidate_show != ic->candidate_show)
3336 ic->candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3341 /* Handle the input key KEY in the current state and map specified in
3342 the input context IC. If KEY is handled correctly, return 0.
3343 Otherwise, return -1. */
3346 handle_key (MInputContext *ic)
3348 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3349 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3350 MIMMap *map = ic_info->map;
3351 MIMMap *submap = NULL;
3352 MSymbol key = ic_info->keys[ic_info->key_head];
3353 MSymbol alias = Mnil;
3356 MDEBUG_PRINT2 (" [IM] handle `%s' in state %s",
3357 msymbol_name (key), MSYMBOL_NAME (ic_info->state->name));
3361 submap = mplist_get (map->submaps, key);
3364 && (alias = msymbol_get (alias, M_key_alias))
3366 submap = mplist_get (map->submaps, alias);
3371 if (! alias || alias == key)
3372 MDEBUG_PRINT (" submap-found");
3374 MDEBUG_PRINT1 (" submap-found (by alias `%s')", MSYMBOL_NAME (alias));
3375 mtext_cpy (ic->preedit, ic_info->preedit_saved);
3376 ic->preedit_changed = 1;
3377 ic->cursor_pos = ic_info->state_pos;
3378 ic_info->key_head++;
3379 ic_info->map = map = submap;
3380 if (map->map_actions)
3382 MDEBUG_PRINT (" map-actions:");
3383 if (take_action_list (ic, map->map_actions) < 0)
3385 MDEBUG_PRINT ("\n");
3389 else if (map->submaps)
3391 for (i = ic_info->state_key_head; i < ic_info->key_head; i++)
3393 MSymbol key = ic_info->keys[i];
3394 char *name = msymbol_name (key);
3396 if (! name[0] || ! name[1])
3397 mtext_ins_char (ic->preedit, ic->cursor_pos++, name[0], 1);
3401 /* If this is the terminal map or we have shifted to another
3402 state, perform branch actions (if any). */
3403 if (! map->submaps || map != ic_info->map)
3405 if (map->branch_actions)
3407 MDEBUG_PRINT (" branch-actions:");
3408 if (take_action_list (ic, map->branch_actions) < 0)
3410 MDEBUG_PRINT ("\n");
3414 /* If MAP is still not the root map, shift to the current
3416 if (ic_info->map != ic_info->state->map)
3417 shift_state (ic, ic_info->state->name);
3422 /* MAP can not handle KEY. */
3424 /* If MAP is the root map of the initial state, it means that
3425 the current input method can not handle KEY. */
3426 if (map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3428 MDEBUG_PRINT (" unhandled\n");
3432 if (map != ic_info->state->map)
3434 /* If MAP is not the root map... */
3435 /* If MAP has branch actions, perform them. */
3436 if (map->branch_actions)
3438 MDEBUG_PRINT (" branch-actions:");
3439 if (take_action_list (ic, map->branch_actions) < 0)
3441 MDEBUG_PRINT ("\n");
3445 /* If MAP is still not the root map, shift to the current
3447 if (ic_info->map != ic_info->state->map)
3448 shift_state (ic, ic_info->state->name);
3452 /* MAP is the root map, perform branch actions (if any) or
3453 shift to the initial state. */
3454 if (map->branch_actions)
3456 MDEBUG_PRINT (" branch-actions:");
3457 if (take_action_list (ic, map->branch_actions) < 0)
3459 MDEBUG_PRINT ("\n");
3464 shift_state (ic, Mnil);
3467 MDEBUG_PRINT ("\n");
3471 /* Initialize IC->ic_info. */
3474 init_ic_info (MInputContext *ic)
3476 MInputMethodInfo *im_info = ic->im->info;
3477 MInputContextInfo *ic_info = ic->info;
3480 MLIST_INIT1 (ic_info, keys, 8);;
3482 ic_info->markers = mplist ();
3484 ic_info->vars = mplist ();
3485 if (im_info->configured_vars)
3486 MPLIST_DO (plist, im_info->configured_vars)
3488 MPlist *pl = MPLIST_PLIST (plist);
3489 MSymbol name = MPLIST_SYMBOL (pl);
3491 pl = MPLIST_NEXT (MPLIST_NEXT (MPLIST_NEXT (pl)));
3492 if (MPLIST_KEY (pl) != Mt)
3494 MPlist *p = mplist ();
3496 mplist_push (ic_info->vars, Mplist, p);
3497 M17N_OBJECT_UNREF (p);
3498 mplist_add (p, Msymbol, name);
3499 mplist_add (p, MPLIST_KEY (pl), MPLIST_VAL (pl));
3502 ic_info->vars_saved = mplist_copy (ic_info->vars);
3504 if (im_info->externals)
3506 MPlist *func_args = mplist (), *plist;
3508 mplist_add (func_args, Mt, ic);
3509 MPLIST_DO (plist, im_info->externals)
3511 MIMExternalModule *external = MPLIST_VAL (plist);
3512 MIMExternalFunc func
3513 = (MIMExternalFunc) mplist_get (external->func_list, Minit);
3518 M17N_OBJECT_UNREF (func_args);
3521 ic_info->preedit_saved = mtext ();
3522 ic_info->tick = im_info->tick;
3525 /* Finalize IC->ic_info. */
3528 fini_ic_info (MInputContext *ic)
3530 MInputMethodInfo *im_info = ic->im->info;
3531 MInputContextInfo *ic_info = ic->info;
3533 if (im_info->externals)
3535 MPlist *func_args = mplist (), *plist;
3537 mplist_add (func_args, Mt, ic);
3538 MPLIST_DO (plist, im_info->externals)
3540 MIMExternalModule *external = MPLIST_VAL (plist);
3541 MIMExternalFunc func
3542 = (MIMExternalFunc) mplist_get (external->func_list, Mfini);
3547 M17N_OBJECT_UNREF (func_args);
3550 MLIST_FREE1 (ic_info, keys);
3551 M17N_OBJECT_UNREF (ic_info->preedit_saved);
3552 M17N_OBJECT_UNREF (ic_info->markers);
3553 M17N_OBJECT_UNREF (ic_info->vars);
3554 M17N_OBJECT_UNREF (ic_info->vars_saved);
3555 M17N_OBJECT_UNREF (ic_info->preceding_text);
3556 M17N_OBJECT_UNREF (ic_info->following_text);
3558 memset (ic_info, 0, sizeof (MInputContextInfo));
3562 re_init_ic (MInputContext *ic, int reload)
3564 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3565 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3566 int status_changed, preedit_changed, cursor_pos_changed, candidates_changed;
3568 status_changed = ic_info->state != (MIMState *) MPLIST_VAL (im_info->states);
3569 preedit_changed = mtext_nchars (ic->preedit) > 0;
3570 cursor_pos_changed = ic->cursor_pos > 0;
3571 candidates_changed = 0;
3572 if (ic->candidate_list)
3574 candidates_changed |= MINPUT_CANDIDATES_LIST_CHANGED;
3575 M17N_OBJECT_UNREF (ic->candidate_list);
3576 ic->candidate_list = NULL;
3578 if (ic->candidate_show)
3580 candidates_changed |= MINPUT_CANDIDATES_SHOW_CHANGED;
3581 ic->candidate_show = 0;
3583 if (ic->candidate_index > 0)
3585 candidates_changed |= MINPUT_CANDIDATES_INDEX_CHANGED;
3586 ic->candidate_index = 0;
3587 ic->candidate_from = ic->candidate_to = 0;
3589 if (mtext_nchars (ic->produced) > 0)
3590 mtext_reset (ic->produced);
3591 if (mtext_nchars (ic->preedit) > 0)
3592 mtext_reset (ic->preedit);
3594 M17N_OBJECT_UNREF (ic->plist);
3595 ic->plist = mplist ();
3599 reload_im_info (im_info);
3601 shift_state (ic, Mnil);
3602 ic->status_changed = status_changed;
3603 ic->preedit_changed = preedit_changed;
3604 ic->cursor_pos_changed = cursor_pos_changed;
3605 ic->candidates_changed = candidates_changed;
3609 reset_ic (MInputContext *ic, MSymbol ignore)
3611 MDEBUG_PRINT ("\n [IM] reset\n");
3616 open_im (MInputMethod *im)
3618 MInputMethodInfo *im_info = get_im_info (im->language, im->name, Mnil, Mnil);
3621 MERROR (MERROR_IM, -1);
3628 close_im (MInputMethod *im)
3634 create_ic (MInputContext *ic)
3636 MInputContextInfo *ic_info;
3638 MSTRUCT_CALLOC (ic_info, MERROR_IM);
3641 shift_state (ic, Mnil);
3646 destroy_ic (MInputContext *ic)
3653 check_reload (MInputContext *ic, MSymbol key)
3655 MInputMethodInfo *im_info = ic->im->info;
3656 MPlist *plist = resolve_command (im_info->configured_cmds, Mat_reload);
3660 plist = resolve_command (global_info->configured_cmds, Mat_reload);
3664 MPLIST_DO (plist, plist)
3666 MSymbol this_key, alias;
3668 if (MPLIST_MTEXT_P (plist))
3670 MText *mt = MPLIST_MTEXT (plist);
3671 int c = mtext_ref_char (mt, 0);
3675 this_key = one_char_symbol[c];
3679 MPlist *pl = MPLIST_PLIST (plist);
3681 this_key = MPLIST_SYMBOL (pl);
3685 && (alias = msymbol_get (alias, M_key_alias))
3686 && alias != this_key);
3690 if (MPLIST_TAIL_P (plist))
3693 MDEBUG_PRINT ("\n [IM] reload");
3699 /** Handle the input key KEY in the current state and map of IC->info.
3700 If KEY is handled but no text is produced, return 0, otherwise
3706 filter (MInputContext *ic, MSymbol key, void *arg)
3708 MInputMethodInfo *im_info = (MInputMethodInfo *) ic->im->info;
3709 MInputContextInfo *ic_info = (MInputContextInfo *) ic->info;
3712 if (check_reload (ic, key))
3715 if (! ic_info->state)
3717 ic_info->key_unhandled = 1;
3720 mtext_reset (ic->produced);
3721 ic->status_changed = ic->preedit_changed = ic->candidates_changed = 0;
3722 M17N_OBJECT_UNREF (ic_info->preceding_text);
3723 M17N_OBJECT_UNREF (ic_info->following_text);
3724 ic_info->preceding_text = ic_info->following_text = NULL;
3725 MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
3726 ic_info->key_unhandled = 0;
3729 if (handle_key (ic) < 0)
3731 /* KEY was not handled. Delete it from the current key sequence. */
3732 if (ic_info->used > 0)
3734 memmove (ic_info->keys, ic_info->keys + 1,
3735 sizeof (int) * (ic_info->used - 1));
3737 if (ic_info->state_key_head > 0)
3738 ic_info->state_key_head--;
3739 if (ic_info->commit_key_head > 0)
3740 ic_info->commit_key_head--;
3742 /* This forces returning 1. */
3743 ic_info->key_unhandled = 1;
3749 reset_ic (ic, Mnil);
3750 ic_info->key_unhandled = 1;
3753 /* Break the loop if all keys were handled. */
3754 } while (ic_info->key_head < ic_info->used);
3756 /* If the current map is the root of the initial state, we should
3757 produce any preedit text in ic->produced. */
3758 if (ic_info->map == ((MIMState *) MPLIST_VAL (im_info->states))->map)
3759 preedit_commit (ic);
3761 if (mtext_nchars (ic->produced) > 0)
3763 MSymbol lang = msymbol_get (ic->im->language, Mlanguage);
3765 if (mdebug__flag & mdebug_mask)
3767 MDEBUG_PRINT (" (produced");
3768 for (i = 0; i < mtext_nchars (ic->produced); i++)
3769 MDEBUG_PRINT1 (" U+%04X", mtext_ref_char (ic->produced, i));
3774 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
3775 Mlanguage, ic->im->language);
3777 if (ic_info->commit_key_head > 0)
3779 memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head,
3780 sizeof (int) * (ic_info->used - ic_info->commit_key_head));
3781 ic_info->used -= ic_info->commit_key_head;
3782 ic_info->key_head -= ic_info->commit_key_head;
3783 ic_info->state_key_head -= ic_info->commit_key_head;
3784 ic_info->commit_key_head = 0;
3786 if (ic_info->key_unhandled)
3789 ic_info->key_head = ic_info->state_key_head
3790 = ic_info->commit_key_head = 0;
3793 return (! ic_info->key_unhandled && mtext_nchars (ic->produced) == 0);
3797 /** Return 1 if the last event or key was not handled, otherwise
3800 There is no need of looking up because ic->produced should already
3801 contain the produced text (if any).
3806 lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
3808 mtext_cat (mt, ic->produced);
3809 mtext_reset (ic->produced);
3810 return (((MInputContextInfo *) ic->info)->key_unhandled ? -1 : 0);
3814 /* Input method command handler. */
3816 /* List of all (global and local) commands.
3817 (LANG:(IM-NAME:(COMMAND ...) ...) ...) ...
3818 COMMAND is CMD-NAME:(mtext:DESCRIPTION plist:KEYSEQ ...))
3819 Global commands are stored as (t (t COMMAND ...)) */
3822 /* Input method variable handler. */
3825 /* Support functions for mdebug_dump_im. */
3828 dump_im_map (MPlist *map_list, int indent)
3831 MSymbol key = MPLIST_KEY (map_list);
3832 MIMMap *map = (MIMMap *) MPLIST_VAL (map_list);
3834 prefix = (char *) alloca (indent + 1);
3835 memset (prefix, 32, indent);
3836 prefix[indent] = '\0';
3838 fprintf (stderr, "(\"%s\" ", msymbol_name (key));
3839 if (map->map_actions)
3840 mdebug_dump_plist (map->map_actions, indent + 2);
3843 MPLIST_DO (map_list, map->submaps)
3845 fprintf (stderr, "\n%s ", prefix);
3846 dump_im_map (map_list, indent + 2);
3849 if (map->branch_actions)
3851 fprintf (stderr, "\n%s (branch\n%s ", prefix, prefix);
3852 mdebug_dump_plist (map->branch_actions, indent + 4);
3853 fprintf (stderr, ")");
3855 fprintf (stderr, ")");
3860 dump_im_state (MIMState *state, int indent)
3865 prefix = (char *) alloca (indent + 1);
3866 memset (prefix, 32, indent);
3867 prefix[indent] = '\0';
3869 fprintf (stderr, "(%s", msymbol_name (state->name));
3870 if (state->map->submaps)
3872 MPLIST_DO (map_list, state->map->submaps)
3874 fprintf (stderr, "\n%s ", prefix);
3875 dump_im_map (map_list, indent + 2);
3878 fprintf (stderr, ")");
3886 Minput_driver = msymbol ("input-driver");
3888 Minput_preedit_start = msymbol ("input-preedit-start");
3889 Minput_preedit_done = msymbol ("input-preedit-done");
3890 Minput_preedit_draw = msymbol ("input-preedit-draw");
3891 Minput_status_start = msymbol ("input-status-start");
3892 Minput_status_done = msymbol ("input-status-done");
3893 Minput_status_draw = msymbol ("input-status-draw");
3894 Minput_candidates_start = msymbol ("input-candidates-start");
3895 Minput_candidates_done = msymbol ("input-candidates-done");
3896 Minput_candidates_draw = msymbol ("input-candidates-draw");
3897 Minput_set_spot = msymbol ("input-set-spot");
3898 Minput_focus_move = msymbol ("input-focus-move");
3899 Minput_focus_in = msymbol ("input-focus-in");
3900 Minput_focus_out = msymbol ("input-focus-out");
3901 Minput_toggle = msymbol ("input-toggle");
3902 Minput_reset = msymbol ("input-reset");
3903 Minput_get_surrounding_text = msymbol ("input-get-surrounding-text");
3904 Minput_delete_surrounding_text = msymbol ("input-delete-surrounding-text");
3905 Mcustomized = msymbol ("customized");
3906 Mconfigured = msymbol ("configured");
3907 Minherited = msymbol ("inherited");
3909 minput_default_driver.open_im = open_im;
3910 minput_default_driver.close_im = close_im;
3911 minput_default_driver.create_ic = create_ic;
3912 minput_default_driver.destroy_ic = destroy_ic;
3913 minput_default_driver.filter = filter;
3914 minput_default_driver.lookup = lookup;
3915 minput_default_driver.callback_list = mplist ();
3916 mplist_put (minput_default_driver.callback_list, Minput_reset,
3918 minput_driver = &minput_default_driver;
3920 fully_initialized = 0;
3927 if (fully_initialized)
3929 free_im_list (im_info_list);
3931 free_im_list (im_custom_list);
3933 free_im_list (im_config_list);
3934 M17N_OBJECT_UNREF (load_im_info_keys);
3937 M17N_OBJECT_UNREF (minput_default_driver.callback_list);
3938 M17N_OBJECT_UNREF (minput_driver->callback_list);
3943 minput__callback (MInputContext *ic, MSymbol command)
3945 MInputCallbackFunc func;
3947 if (! ic->im->driver.callback_list)
3949 func = (MInputCallbackFunc) mplist_get (ic->im->driver.callback_list,
3953 (func) (ic, command);
3958 minput__char_to_key (int c)
3960 if (c < 0 || c >= 0x100)
3963 return one_char_symbol[c];
3967 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
3972 /*** @addtogroup m17nInputMethod */
3977 @name Variables: Predefined symbols for callback commands.
3979 These are the predefined symbols that are used as the @c COMMAND
3980 argument of callback functions of an input method driver (see
3981 #MInputDriver::callback_list).
3983 Most of them do not require extra argument nor return any value;
3984 exceptions are these:
3986 Minput_get_surrounding_text: When a callback function assigned for
3987 this command is called, the first element of #MInputContext::plist
3988 has key #Minteger and the value specifies which portion of the
3989 surrounding text should be retrieved. If the value is positive,
3990 it specifies the number of characters following the current cursor
3991 position. If the value is negative, the absolute value specifies
3992 the number of characters preceding the current cursor position.
3994 If the surrounding text is currently supported, the callback
3995 function must set the key of this element to #Mtext and the value
3996 to the retrieved M-text. The length of the M-text may be shorter
3997 than the requested number of characters, if the available text is
3998 not that long. The length can be zero in the worst case. Or, the
3999 length may be longer if an application thinks it is more efficient
4000 to return that length.
4002 If the surrounding text is not currently supported, the callback
4003 function should return without changing the first element of
4004 #MInputContext::plist.
4006 Minput_delete_surrounding_text: When a callback function assigned
4007 for this command is called, the first element of
4008 #MInputContext::plist has key #Minteger and the value specifies
4009 which portion of the surrounding text should be deleted in the
4010 same way as the case of Minput_get_surrounding_text. The callback
4011 function must delete the specified text. It should not alter
4012 #MInputContext::plist. */
4014 @name ÊÑ¿ô¡§ ¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥ÉÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4016 ÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Î¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ë¤ª¤¤¤Æ @c COMMAND
4017 °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë (#MInputDriver::callback_list »²¾È)¡£
4019 ¤Û¤È¤ó¤É¤ÏÄɲäΰú¿ô¤òɬÍפȤ·¤Ê¤¤¤·ÃͤòÊÖ¤µ¤Ê¤¤¤¬¡¢°Ê²¼¤ÏÎã³°¤Ç¤¢¤ë¡£
4021 Minput_get_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë¥Ð¥Ã
4022 ¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢ #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϥ¡¼¤È¤·
4023 ¤Æ#Minteger ¤ò¤È¤ê¡¢¤½¤ÎÃͤϥµ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤Î¤¦¤Á¤É¤ÎÉôʬ
4024 ¤ò¼è¤Ã¤ÆÍè¤ë¤«¤ò»ØÄꤹ¤ë¡£Ãͤ¬Àµ¤Ç¤¢¤ì¤Ð¡¢¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˳¤¯
4025 ÃͤθĿôʬ¤Îʸ»ú¤ò¼è¤ë¡£Éé¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥½¥ë°ÌÃÖ¤ËÀè¹Ô¤¹¤ëÃͤÎÀäÂÐ
4028 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Ï
4029 ¤³¤ÎÍ×ÁǤΥ¡¼¤ò #Mtext ¤Ë¡¢Ãͤò¼è¤ê¹þ¤ó¤ÀM-text ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê
4030 ¤é¤Ê¤¤¡£¤â¤·¥Æ¥¥¹¥È¤ÎŤµ¤¬½¼Ê¬¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î M-text ¤ÎŤµ¤ÏÍ×
4031 µá¤µ¤ì¤Æ¤¤¤ëʸ»ú¿ô¤è¤êû¤¯¤ÆÎɤ¤¡£ºÇ°¤Î¾ì¹ç 0 ¤Ç¤â¤è¤¤¤·¡¢¥¢¥×¥ê¥±¡¼
4032 ¥·¥ç¥ó¦¤ÇɬÍפǸúΨŪ¤À¤È»×¤¨¤ÐŤ¯¤Æ¤âÎɤ¤¡£
4034 ¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥³¡¼¥ë¥Ð¥Ã¥¯´Ø
4035 ¿ô¤Ï #MInputContext::plist ¤ÎÂè°ìÍ×ÁǤòÊѲ½¤µ¤»¤ë¤³¤È¤Ê¤¯ÊÖ¤µ¤Ê¤¯¤Æ
4038 Minput_delete_surrounding_text: ¤³¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥³¡¼¥ë
4039 ¥Ð¥Ã¥¯´Ø¿ô¤¬¸Æ¤Ð¤ì¤¿ºÝ¤Ë¤Ï¡¢#MInputContext::plist ¤ÎÂè°ìÍ×ÁǤϡ¢¥¡¼
4040 ¤È¤·¤Æ#Minteger ¤ò¤È¤ê¡¢ÃͤϺï½ü¤¹¤ë¤Ù¤¥µ¥é¥¦¥ó¥Ç¥£¥ó¥°¥Æ¥¥¹¥È¤ò
4041 Minput_get_surrounding_text ¤ÈƱÍͤΤä¤êÊý¤Ç»ØÄꤹ¤ë¡£¥³¡¼¥ë¥Ð¥Ã¥¯
4042 ´Ø¿ô¤Ï»ØÄꤵ¤ì¤¿¥Æ¥¥¹¥È¤òºï½ü¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤Þ¤¿
4043 #MInputContext::plist ¤òÊѤ¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4047 MSymbol Minput_preedit_start;
4048 MSymbol Minput_preedit_done;
4049 MSymbol Minput_preedit_draw;
4050 MSymbol Minput_status_start;
4051 MSymbol Minput_status_done;
4052 MSymbol Minput_status_draw;
4053 MSymbol Minput_candidates_start;
4054 MSymbol Minput_candidates_done;
4055 MSymbol Minput_candidates_draw;
4056 MSymbol Minput_set_spot;
4057 MSymbol Minput_toggle;
4058 MSymbol Minput_reset;
4059 MSymbol Minput_get_surrounding_text;
4060 MSymbol Minput_delete_surrounding_text;
4066 @name Variables: Predefined symbols for special input events.
4068 These are the predefined symbols that are used as the @c KEY
4069 argument of minput_filter (). */
4071 @name ÊÑ¿ô: ÆÃÊ̤ÊÆþÎÏ¥¤¥Ù¥ó¥ÈÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4073 minput_filter () ¤Î @c KEY °ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4078 MSymbol Minput_focus_out;
4079 MSymbol Minput_focus_in;
4080 MSymbol Minput_focus_move;
4086 @name Variables: Predefined symbols used in input method information.
4088 These are the predefined symbols describing status of input method
4089 command and variable, and are used in a return value of
4090 minput_get_command () and minput_get_variable (). */
4092 @name ÊÑ¿ô: ÆþÎϥ᥽¥Ã¥É¾ðÊóÍÑÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë.
4094 ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤äÊÑ¿ô¤Î¾õÂÖ¤òɽ¤·¡¢minput_get_command () ¤È
4095 minput_get_variable () ¤ÎÌá¤êÃͤȤ·¤ÆÍѤ¤¤é¤ì¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë¡£ */
4099 MSymbol Mcustomized;
4100 MSymbol Mconfigured;
4106 @brief The default driver for internal input methods.
4108 The variable #minput_default_driver is the default driver for
4109 internal input methods.
4111 The member MInputDriver::open_im () searches the m17n database for
4112 an input method that matches the tag \< #Minput_method, $LANGUAGE,
4113 $NAME\> and loads it.
4115 The member MInputDriver::callback_list () is @c NULL. Thus, it is
4116 programmers responsibility to set it to a plist of proper callback
4117 functions. Otherwise, no feedback information (e.g. preedit text)
4118 can be shown to users.
4120 The macro M17N_INIT () sets the variable #minput_driver to the
4121 pointer to this driver so that all internal input methods use it.
4123 Therefore, unless @c minput_driver is set differently, the driver
4124 dependent arguments $ARG of the functions whose name begins with
4125 "minput_" are all ignored. */
4127 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥǥե©¥ë¥È¥É¥é¥¤¥Ð.
4129 ÊÑ¿ô #minput_default_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤΥǥե©¥ë¥È¤Î¥É¥é¥¤¥Ð¤òɽ¤¹¡£
4131 ¥á¥ó¥Ð MInputDriver::open_im () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é¥¿¥°
4132 \< #Minput_method, $LANGUAGE, $NAME\>
4133 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤òõ¤·¡¢¤½¤ì¤ò¥í¡¼¥É¤¹¤ë¡£
4135 ¥á¥ó¥Ð MInputDriver::callback_list () ¤Ï @c NULL ¤Ç¤¢¤ê¡¢
4136 ¤·¤¿¤¬¤Ã¤Æ¡¢¥×¥í¥°¥é¥Þ¦¤ÇÀÕǤ¤ò»ý¤Ã¤Æ ŬÀڤʥ³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤Î plist
4137 ¤ËÀßÄꤷ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤µ¤â¤Ê¤¤¤È¡¢preedit
4138 ¥Æ¥¥¹¥È¤Ê¤É¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¾ðÊ󤬥桼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡£
4140 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô #minput_driver
4141 ¤ò¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¡£
4143 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
4144 ¤Ç»Ï¤Þ¤ë´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô $ARG ¤Ï¤¹¤Ù¤Æ̵»ë¤µ¤ì¤ë¡£ */
4146 MInputDriver minput_default_driver;
4150 @brief The driver for internal input methods.
4152 The variable #minput_driver is a pointer to the input method
4153 driver that is used by internal input methods. The macro
4154 M17N_INIT () initializes it to a pointer to #minput_default_driver
4155 if <m17n<EM></EM>.h> is included. */
4157 @brief ÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѥɥ饤¥Ð.
4159 ÊÑ¿ô #minput_driver ¤ÏÆâÉôÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ëÆþÎÏ¥á
4160 ¥½¥Ã¥É¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥Þ¥¯¥í M17N_INIT () ¤Ï¤³¤Î¥Ý¥¤¥ó
4161 ¥¿¤ò#minput_default_driver (<m17n<EM></EM>.h> ¤¬ include ¤µ¤ì¤Æ¤¤¤ë
4162 »þ) ¤Ë½é´ü²½¤¹¤ë¡£ */
4164 MInputDriver *minput_driver;
4166 MSymbol Minput_driver;
4181 @brief Open an input method.
4183 The minput_open_im () function opens an input method whose
4184 language and name match $LANGUAGE and $NAME, and returns a pointer
4185 to the input method object newly allocated.
4187 This function at first decides a driver for the input method as
4190 If $LANGUAGE is not #Mnil, the driver pointed by the variable
4191 #minput_driver is used.
4193 If $LANGUAGE is #Mnil and $NAME has the property #Minput_driver, the
4194 driver pointed to by the property value is used to open the input
4195 method. If $NAME has no such a property, @c NULL is returned.
4197 Then, the member MInputDriver::open_im () of the driver is
4200 $ARG is set in the member @c arg of the structure MInputMethod so
4201 that the driver can refer to it. */
4203 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë.
4205 ´Ø¿ô minput_open_im () ¤Ï¸À¸ì $LANGUAGE ¤È̾Á° $NAME
4206 ¤Ë¹çÃפ¹¤ëÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤·¡¢¿·¤¿¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
4208 ¤³¤Î´Ø¿ô¤Ï¡¢¤Þ¤ºÆþÎϥ᥽¥Ã¥ÉÍѤΥɥ饤¥Ð¤ò°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ·èÄꤹ¤ë¡£
4210 $LANGUAGE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô #minput_driver
4211 ¤Ç»Ø¤µ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÍѤ¤¤ë¡£
4213 $LANGUAGE ¤¬ #Mnil ¤Ç¤¢¤ê¡¢$NAME ¤¬ #Minput_driver
4214 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤǻؤµ¤ì¤Æ¤¤¤ëÆþÎϥɥ饤¥Ð¤òÍѤ¤¤ÆÆþÎϥ᥽¥Ã¥É¤ò¥ª¡¼¥×¥ó¤¹¤ë¡£
4215 $NAME ¤Ë¤½¤Î¤è¤¦¤Ê¥×¥í¥Ñ¥Æ¥£¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4217 ¼¡¤¤¤Ç¡¢¥É¥é¥¤¥Ð¤Î¥á¥ó¥Ð MInputDriver::open_im () ¤¬¸Æ¤Ð¤ì¤ë¡£
4219 $ARG ¤Ï¹½Â¤ÂÎ MInputMethod ¤Î¥á¥ó¥Ð @c arg ¤ËÀßÄꤵ¤ì¡¢¥É¥é¥¤¥Ð¤«¤é»²¾È¤Ç¤¤ë¡£
4221 @latexonly \IPAlabel{minput_open} @endlatexonly
4226 minput_open_im (MSymbol language, MSymbol name, void *arg)
4229 MInputDriver *driver;
4233 MDEBUG_PRINT2 (" [IM] opening (%s %s) ... ",
4234 msymbol_name (language), msymbol_name (name));
4236 driver = minput_driver;
4239 driver = (MInputDriver *) msymbol_get (name, Minput_driver);
4241 MERROR (MERROR_IM, NULL);
4244 MSTRUCT_CALLOC (im, MERROR_IM);
4245 im->language = language;
4248 im->driver = *driver;
4249 if ((*im->driver.open_im) (im) < 0)
4251 MDEBUG_PRINT (" failed\n");
4255 MDEBUG_PRINT (" ok\n");
4262 @brief Close an input method.
4264 The minput_close_im () function closes the input method $IM, which
4265 must have been created by minput_open_im (). */
4268 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥¯¥í¡¼¥º¤¹¤ë.
4270 ´Ø¿ô minput_close_im () ¤Ï¡¢ÆþÎϥ᥽¥Ã¥É $IM ¤ò¥¯¥í¡¼¥º¤¹¤ë¡£
4271 ¤³¤ÎÆþÎϥ᥽¥Ã¥É $IM ¤Ï minput_open_im () ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£ */
4274 minput_close_im (MInputMethod *im)
4276 MDEBUG_PRINT2 (" [IM] closing (%s %s) ... ",
4277 msymbol_name (im->name), msymbol_name (im->language));
4278 (*im->driver.close_im) (im);
4280 MDEBUG_PRINT (" done\n");
4286 @brief Create an input context.
4288 The minput_create_ic () function creates an input context object
4289 associated with input method $IM, and calls callback functions
4290 corresponding to #Minput_preedit_start, #Minput_status_start, and
4291 #Minput_status_draw in this order.
4294 If an input context is successfully created, minput_create_ic ()
4295 returns a pointer to it. Otherwise it returns @c NULL. */
4298 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÀ¸À®¤¹¤ë.
4300 ´Ø¿ô minput_create_ic () ¤ÏÆþÎϥ᥽¥Ã¥É $IM
4301 ¤ËÂбþ¤¹¤ëÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¡¢
4302 #Minput_preedit_start, #Minput_status_start, #Minput_status_draw
4303 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4306 ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤¬À¸À®¤µ¤ì¤¿¾ì¹ç¡¢minput_create_ic ()
4307 ¤Ï¤½¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£
4311 minput_create_ic (MInputMethod *im, void *arg)
4315 MDEBUG_PRINT2 (" [IM] creating context (%s %s) ... ",
4316 msymbol_name (im->name), msymbol_name (im->language));
4317 MSTRUCT_CALLOC (ic, MERROR_IM);
4320 ic->preedit = mtext ();
4321 ic->candidate_list = NULL;
4322 ic->produced = mtext ();
4323 ic->spot.x = ic->spot.y = 0;
4325 ic->plist = mplist ();
4326 if ((*im->driver.create_ic) (ic) < 0)
4328 MDEBUG_PRINT (" failed\n");
4329 M17N_OBJECT_UNREF (ic->preedit);
4330 M17N_OBJECT_UNREF (ic->produced);
4331 M17N_OBJECT_UNREF (ic->plist);
4336 if (im->driver.callback_list)
4338 minput__callback (ic, Minput_preedit_start);
4339 minput__callback (ic, Minput_status_start);
4340 minput__callback (ic, Minput_status_draw);
4343 MDEBUG_PRINT (" ok\n");
4350 @brief Destroy an input context.
4352 The minput_destroy_ic () function destroys the input context $IC,
4353 which must have been created by minput_create_ic (). It calls
4354 callback functions corresponding to #Minput_preedit_done,
4355 #Minput_status_done, and #Minput_candidates_done in this order. */
4358 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤òÇ˲õ¤¹¤ë.
4360 ´Ø¿ô minput_destroy_ic () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤òÇ˲õ¤¹¤ë¡£
4361 ¤³¤ÎÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Ï minput_create_ic ()
4362 ¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£¤³¤Î´Ø¿ô¤Ï
4363 #Minput_preedit_done, #Minput_status_done, #Minput_candidates_done
4364 ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¤³¤Î½ç¤Ë¸Æ¤Ö¡£
4368 minput_destroy_ic (MInputContext *ic)
4370 MDEBUG_PRINT2 (" [IM] destroying context (%s %s) ... ",
4371 msymbol_name (ic->im->name), msymbol_name (ic->im->language));
4372 if (ic->im->driver.callback_list)
4374 minput__callback (ic, Minput_preedit_done);
4375 minput__callback (ic, Minput_status_done);
4376 minput__callback (ic, Minput_candidates_done);
4378 (*ic->im->driver.destroy_ic) (ic);
4379 M17N_OBJECT_UNREF (ic->preedit);
4380 M17N_OBJECT_UNREF (ic->produced);
4381 M17N_OBJECT_UNREF (ic->plist);
4382 MDEBUG_PRINT (" done\n");
4389 @brief Filter an input key.
4391 The minput_filter () function filters input key $KEY according to
4392 input context $IC, and calls callback functions corresponding to
4393 #Minput_preedit_draw, #Minput_status_draw, and
4394 #Minput_candidates_draw if the preedit text, the status, and the
4395 current candidate are changed respectively.
4397 To make the input method commit the current preedit text (if any)
4398 and shift to the initial state, call this function with #Mnil as
4401 To inform the input method about the focus-out event, call this
4402 function with #Minput_focus_out as $KEY.
4404 To inform the input method about the focus-in event, call this
4405 function with #Minput_focus_in as $KEY.
4407 To inform the input method about the focus-move event (i.e. input
4408 spot change within the same input context), call this function
4409 with #Minput_focus_move as $KEY.
4412 If $KEY is filtered out, this function returns 1. In that case,
4413 the caller should discard the key. Otherwise, it returns 0, and
4414 the caller should handle the key, for instance, by calling the
4415 function minput_lookup () with the same key. */
4418 @brief ÆþÎÏ¥¡¼¤ò¥Õ¥£¥ë¥¿¤¹¤ë.
4420 ´Ø¿ô minput_filter () ¤ÏÆþÎÏ¥¡¼ $KEY ¤òÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4421 ¤Ë±þ¤¸¤Æ¥Õ¥£¥ë¥¿¤·¡¢preedit ¥Æ¥¥¹¥È¡¢¥¹¥Æ¡¼¥¿¥¹¡¢¸½»þÅÀ¤Ç¤Î¸õÊ䤬ÊѲ½¤·¤¿»þÅÀ¤Ç¡¢¤½¤ì¤¾¤ì
4422 #Minput_preedit_draw, #Minput_status_draw,
4423 #Minput_candidates_draw ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô¤ò¸Æ¤Ö¡£
4426 $KEY ¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 1 ¤òÊÖ¤¹¡£
4427 ¤³¤Î¾ì¹ç¸Æ¤Ó½Ð¤·Â¦¤Ï¤³¤Î¥¡¼¤ò¼Î¤Æ¤ë¤Ù¤¤Ç¤¢¤ë¡£
4428 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤·¡¢¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤¿¤È¤¨¤ÐƱ¤¸¥¡¼¤Ç´Ø¿ô minput_lookup ()
4429 ¤ò¸Æ¤Ö¤Ê¤É¤·¤Æ¡¢¤³¤Î¥¡¼¤ò½èÍý¤¹¤ë¡£
4431 @latexonly \IPAlabel{minput_filter} @endlatexonly
4435 minput_filter (MInputContext *ic, MSymbol key, void *arg)
4442 ret = (*ic->im->driver.filter) (ic, key, arg);
4444 if (ic->im->driver.callback_list)
4446 if (ic->preedit_changed)
4447 minput__callback (ic, Minput_preedit_draw);
4448 if (ic->status_changed)
4449 minput__callback (ic, Minput_status_draw);
4450 if (ic->candidates_changed)
4451 minput__callback (ic, Minput_candidates_draw);
4460 @brief Look up a text produced in the input context.
4462 The minput_lookup () function looks up a text in the input context
4463 $IC. $KEY must be identical to the one that was used in the previous call of
4466 If a text was produced by the input method, it is concatenated
4469 This function calls #MInputDriver::lookup .
4472 If $KEY was correctly handled by the input method, this function
4473 returns 0. Otherwise, it returns -1, even though some text
4474 might be produced in $MT. */
4477 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥ÈÃæ¤Î¥Æ¥¥¹¥È¤òõ¤¹.
4479 ´Ø¿ô minput_lookup () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC Ãæ¤Î¥Æ¥¥¹¥È¤òõ¤¹¡£
4480 $KEY ¤Ï´Ø¿ô minput_filter () ¤Ø¤ÎľÁ°¤Î¸Æ¤Ó½Ð¤·¤ËÍѤ¤¤é¤ì¤¿¤â¤Î¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4482 ¥Æ¥¥¹¥È¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ï M-text
4485 ¤³¤Î´Ø¿ô¤Ï¡¢#MInputDriver::lookup ¤ò¸Æ¤Ö¡£
4488 $KEY ¤¬ÆþÎϥ᥽¥Ã¥É¤Ë¤è¤Ã¤ÆŬÀڤ˽èÍý¤Ç¤¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£
4489 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤¹¡£
4490 ¤³¤Î¾ì¹ç¤Ç¤â $MT ¤Ë²¿¤é¤«¤Î¥Æ¥¥¹¥È¤¬À¸À®¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¡£
4492 @latexonly \IPAlabel{minput_lookup} @endlatexonly */
4495 minput_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
4497 return (ic ? (*ic->im->driver.lookup) (ic, key, arg, mt) : -1);
4502 @brief Set the spot of the input context.
4504 The minput_set_spot () function sets the spot of input context $IC
4505 to coordinate ($X, $Y ) with the height specified by $ASCENT and $DESCENT .
4506 The semantics of these values depends on the input method driver.
4508 For instance, a driver designed to work in a CUI environment may
4509 use $X and $Y as the column- and row numbers, and may ignore $ASCENT and
4510 $DESCENT . A driver designed to work in a window system may
4511 interpret $X and $Y as the pixel offsets relative to the origin of the
4512 client window, and may interpret $ASCENT and $DESCENT as the ascent- and
4513 descent pixels of the line at ($X . $Y ).
4515 $FONTSIZE specifies the fontsize of preedit text in 1/10 point.
4517 $MT and $POS are the M-text and the character position at the spot.
4518 $MT may be @c NULL, in which case, the input method cannot get
4519 information about the text around the spot. */
4522 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤Î¥¹¥Ý¥Ã¥È¤òÀßÄꤹ¤ë.
4524 ´Ø¿ô minput_set_spot () ¤Ï¡¢ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤Î¥¹¥Ý¥Ã¥È¤ò¡¢ºÂɸ ($X, $Y )
4525 ¤Î°ÌÃÖ¤Ë ¡¢¹â¤µ $ASCENT¡¢ $DESCENT
4526 ¤ÇÀßÄꤹ¤ë¡£ ¤³¤ì¤é¤ÎÃͤΰÕÌ£¤ÏÆþÎϥ᥽¥Ã¥É¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¡£
4528 ¤¿¤È¤¨¤Ð CUI ´Ä¶¤ÇÆ°ºî¤¹¤ë¥É¥é¥¤¥Ð¤Ï $X ¤È $Y
4529 ¤ò¤½¤ì¤¾¤ìÎó¤È¹Ô¤ÎÈÖ¹æ¤È¤·¤ÆÍѤ¤¡¢$ASCENT ¤È $DESCENT
4530 ¤ò̵»ë¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¡£ ¤Þ¤¿¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥àÍѤΥɥ饤¥Ð¤Ï
4531 $X ¤È $Y ¤ò¥¯¥é¥¤¥¢¥ó¥È¥¦¥£¥ó¥É¥¦¤Î¸¶ÅÀ¤«¤é¤Î¥ª¥Õ¥»¥Ã¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¤¡¢
4532 $ASCENT ¤È $DESCENT ¤ò ($X . $Y )
4533 ¤ÎÎó¤Î¥¢¥»¥ó¥È¤È¥Ç¥£¥»¥ó¥È¤ò¥Ô¥¯¥»¥ëñ°Ì¤Çɽ¤·¤¿¤â¤Î¤È¤·¤Æ°·¤¦¤«¤â¤·¤ì¤Ê¤¤¡£
4535 $FONTSIZE ¤Ë¤Ï preedit ¥Æ¥¥¹¥È¤Î¥Õ¥©¥ó¥È¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó¥Èñ°Ì¤Ç»ØÄꤹ¤ë¡£
4537 $MT ¤È $POS ¤Ï¤½¤Î¥¹¥Ý¥Ã¥È¤Î M-text ¤Èʸ»ú°ÌÃ֤Ǥ¢¤ë¡£$MT ¤Ï @c
4538 NULL ¤Ç¤â¤è¤¯¡¢¤½¤Î¾ì¹ç¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤Ï¥¹¥Ý¥Ã¥È¼þÊդΥƥ¥¹¥È¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤Ê¤¤¡£
4542 minput_set_spot (MInputContext *ic, int x, int y,
4543 int ascent, int descent, int fontsize,
4548 ic->spot.ascent = ascent;
4549 ic->spot.descent = descent;
4550 ic->spot.fontsize = fontsize;
4553 if (ic->im->driver.callback_list)
4554 minput__callback (ic, Minput_set_spot);
4559 @brief Toggle input method.
4561 The minput_toggle () function toggles the input method associated
4562 with input context $IC. */
4564 @brief ÆþÎϥ᥽¥Ã¥É¤òÀÚÂؤ¨¤ë.
4566 ´Ø¿ô minput_toggle () ¤ÏÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC
4567 ¤ËÂбþÉÕ¤±¤é¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ò¥È¥°¥ë¤¹¤ë¡£
4571 minput_toggle (MInputContext *ic)
4573 if (ic->im->driver.callback_list)
4574 minput__callback (ic, Minput_toggle);
4575 ic->active = ! ic->active;
4581 @brief Reset an input context.
4583 The minput_reset_ic () function resets input context $IC by
4584 calling a callback function corresponding to #Minput_reset. It
4585 resets the status of $IC to its initial one. As the
4586 current preedit text is deleted without commitment, if necessary,
4587 call minput_filter () with the arg @r key #Mnil to force the input
4588 method to commit the preedit in advance. */
4591 @brief ÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È¤ò¥ê¥»¥Ã¥È¤¹¤ë.
4593 ´Ø¿ô minput_reset_ic () ¤Ï #Minput_reset ¤ËÂбþ¤¹¤ë¥³¡¼¥ë¥Ð¥Ã¥¯´Ø¿ô
4594 ¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÆþÎÏ¥³¥ó¥Æ¥¯¥¹¥È $IC ¤ò¥ê¥»¥Ã¥È¤¹¤ë¡£¥ê¥»¥Ã¥È¤È¤Ï¡¢
4595 ¼ÂºÝ¤Ë¤ÏÆþÎϥ᥽¥Ã¥É¤ò½é´ü¾õÂ֤˰ܤ¹¤³¤È¤Ç¤¢¤ë¡£¸½ºßÆþÎÏÃæ¤Î¥Æ¥¥¹
4596 ¥È¤Ï¥³¥ß¥Ã¥È¤µ¤ì¤ë¤³¤È¤Ê¤¯ºï½ü¤µ¤ì¤ë¤Î¤Ç¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é
4597 ¥à¤Ï¡¢É¬Íפʤé¤Ðͽ¤á minput_filter () ¤ò°ú¿ô @r key #Mnil ¤Ç¸Æ¤ó¤Ç
4598 ¶¯À©Åª¤Ë¥×¥ê¥¨¥Ç¥£¥Ã¥È¥Æ¥¥¹¥È¤ò¥³¥ß¥Ã¥È¤µ¤»¤ë¤³¤È¡£ */
4601 minput_reset_ic (MInputContext *ic)
4603 if (ic->im->driver.callback_list)
4604 minput__callback (ic, Minput_reset);
4610 @brief Get title and icon filename of an input method.
4612 The minput_get_title_icon () function returns a plist containing a
4613 title and icon filename (if any) of an input method specified by
4614 $LANGUAGE and $NAME.
4616 The first element of the plist has key #Mtext and the value is an
4617 M-text of the title for identifying the input method. The second
4618 element (if any) has key #Mtext and the value is an M-text of the
4619 icon image (absolute) filename for the same purpose.
4622 If there exists a specified input method and it defines an title,
4623 a plist is returned. Otherwise, NULL is returned. The caller
4624 must free the plist by m17n_object_unref (). */
4626 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë.
4628 ´Ø¿ô minput_get_title_icon () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ë
4629 ÆþÎϥ᥽¥Ã¥É¤Î¥¿¥¤¥È¥ë¤È¡Ê¤¢¤ì¤Ð¡Ë¥¢¥¤¥³¥óÍÑ¥Õ¥¡¥¤¥ë¤ò´Þ¤à plist ¤ò
4632 plist ¤ÎÂè°ìÍ×ÁǤϡ¢#Mtext ¤ò¥¡¼¤Ë»ý¤Á¡¢ÃͤÏÆþÎϥ᥽¥Ã¥É¤ò¼±Ê̤¹¤ë
4633 ¥¿¥¤¥È¥ë¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£ÂèÆóÍ×ÁǤ¬¤¢¤ì¤Ð¡¢¥¡¼¤Ï #Mtext ¤Ç¤¢
4634 ¤ê¡¢Ãͤϼ±ÊÌÍÑ¥¢¥¤¥³¥ó²èÁü¤ÎÀäÂÐ¥Õ¥¡¥¤¥ë¥Í¡¼¥à¤òɽ¤¹ M-text ¤Ç¤¢¤ë¡£
4637 »ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¡¢¥¿¥¤¥È¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð
4638 plist ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð NULL ¤òÊÖ¤¹¡£¸Æ½Ð¦¤Ï
4639 ´Ø¿ô m17n_object_unref () ¤òÍѤ¤¤Æ plist ¤ò²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
4642 minput_get_title_icon (MSymbol language, MSymbol name)
4644 MInputMethodInfo *im_info;
4651 im_info = get_im_info (language, name, Mnil, Mtitle);
4652 if (! im_info || !im_info->title)
4654 mt = mtext_get_prop (im_info->title, 0, Mtext);
4656 file = mdatabase__find_file ((char *) MTEXT_DATA (mt));
4659 char *buf = alloca (MSYMBOL_NAMELEN (language) + MSYMBOL_NAMELEN (name)
4662 sprintf (buf, "icons/%s-%s.png", (char *) MSYMBOL_NAME (language),
4663 (char *) MSYMBOL_NAME (name));
4664 file = mdatabase__find_file (buf);
4665 if (! file && language == Mt)
4667 sprintf (buf, "icons/%s.png", (char *) MSYMBOL_NAME (name));
4668 file = mdatabase__find_file (buf);
4673 mplist_add (plist, Mtext, im_info->title);
4676 mt = mtext__from_data (file, strlen (file), MTEXT_FORMAT_UTF_8, 1);
4678 mplist_add (plist, Mtext, mt);
4679 M17N_OBJECT_UNREF (mt);
4687 @brief Get description text of an input method.
4689 The minput_get_description () function returns an M-text that
4690 describes the input method specified by $LANGUAGE and $NAME.
4693 If the specified input method has a description text, a pointer to
4694 #MText is returned. The caller has to free it by m17n_object_unref ().
4695 If the input method does not have a description text, @c NULL is
4698 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÀâÌÀ¥Æ¥¥¹¥È¤òÆÀ¤ë.
4700 ´Ø¿ô minput_get_description () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄê
4701 ¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤òÀâÌÀ¤¹¤ë M-text ¤òÊÖ¤¹¡£
4703 @return »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤¬ÀâÌÀ¤¹¤ë¥Æ¥¥¹¥È¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
4704 #MText ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¸Æ¤Ó½Ð¤·Â¦¤Ï¡¢¤½¤ì¤ò m17n_object_unref
4705 () ¤òÍѤ¤¤Æ²òÊü¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ÆþÎϥ᥽¥Ã¥É¤ËÀâÌÀ¥Æ¥¥¹¥È¤¬Ìµ¤±
4706 ¤ì¤Ð@c NULL ¤òÊÖ¤¹¡£ */
4709 minput_get_description (MSymbol language, MSymbol name)
4711 MInputMethodInfo *im_info;
4719 extra = language, language = Mt;
4721 im_info = get_im_info (language, name, extra, Mdescription);
4722 if (! im_info || ! im_info->description)
4724 M17N_OBJECT_REF (im_info->description);
4725 return im_info->description;
4731 @brief Get information about input method command(s).
4733 The minput_get_command () function returns information about
4734 the command $COMMAND of the input method specified by $LANGUAGE and
4735 $NAME. An input method command is a pseudo key event to which one
4736 or more actual input key sequences are assigned.
4738 There are two kinds of commands, global and local. A global
4739 command has a global definition, and the description and the key
4740 assignment may be inherited by a local command. Each input method
4741 defines a local command which has a local key assignment. It may
4742 also declare a local command that inherits the definition of a
4743 global command of the same name.
4745 If $LANGUAGE is #Mt and $NAME is #Mnil, this function returns
4746 information about a global command. Otherwise information about a
4747 local command is returned.
4749 If $COMMAND is #Mnil, information about all commands is returned.
4751 The return value is a @e well-formed plist (#m17nPlist) of this
4754 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4756 @c NAME is a symbol representing the command name.
4758 @c DESCRIPTION is an M-text describing the command, or #Mnil if the
4759 command has no description.
4761 @c STATUS is a symbol representing how the key assignment is decided.
4762 The value is #Mnil (the default key assignment), #Mcustomized (the
4763 key assignment is customized by per-user configuration file), or
4764 #Mconfigured (the key assignment is set by the call of
4765 minput_config_command ()). For a local command only, it may also
4766 be #Minherited (the key assignment is inherited from the
4767 corresponding global command).
4769 @c KEYSEQ is a plist of one or more symbols representing a key
4770 sequence assigned to the command. If there's no KEYSEQ, the
4771 command is currently disabled (i.e. no key sequence can trigger
4772 actions of the command).
4774 If $COMMAND is not #Mnil, the first element of the returned plist
4775 contains the information about $COMMAND.
4779 If the requested information was found, a pointer to a non-empty
4780 plist is returned. As the plist is kept in the library, the
4781 caller must not modify nor free it.
4783 Otherwise (the specified input method or the specified command
4784 does not exist), @c NULL is returned. */
4786 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
4788 ´Ø¿ô minput_get_command () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
4789 ¥á¥½¥Ã¥É¤Î¥³¥Þ¥ó¥É $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ
4790 ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢£±¤Ä°Ê¾å¤Î¼ÂºÝ¤ÎÆþÎÏ¥¡¼¥·¡¼¥¯¥¨
4791 ¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¡£
4793 ¥³¥Þ¥ó¥É¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É
4794 ¤Ï¥°¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤Ï¤½¤ÎÀâÌÀ¤È¥¡¼³ä¤êÅö¤Æ
4795 ¤ò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤ò»ý¤Ä¥í¡¼
4796 ¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÄêµÁ¤¹¤ë¡£¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥³¥Þ¥ó¥É¤ÎÄêµÁ¤ò·Ñ
4797 ¾µ¤¹¤ë¥í¡¼¥«¥ë¤Ê¥³¥Þ¥ó¥É¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
4799 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ë¥³
4800 ¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¤â
4803 $COMMAND ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
4805 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
4808 ((NAME DESCRIPTION STATUS [KEYSEQ ...]) ...)
4810 @c NAME ¤Ï¥³¥Þ¥ó¥É̾¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
4812 @c DESCRIPTION ¤Ï¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë
4815 @c STATUS ¤Ï¥¡¼³ä¤êÅö¤Æ¤¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢
4816 ¤ê¡¢¤½¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤Î³ä¤êÅö¤Æ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶
4817 Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿³ä¤êÅö¤Æ¡Ë, #Mconfigured
4818 ¡Êminput_config_command ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë³ä¤êÅö¤Æ¡Ë¤Î
4819 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë
4820 ¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤«¤é¤Î·Ñ¾µ¤Ë¤è¤ë³ä¤êÅö¤Æ¡Ë¤Ç¤â¤è¤¤¡£
4822 @c KEYSEQ ¤Ï£±¤Ä°Ê¾å¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ë plist ¤Ç¤¢¤ê¡¢³Æ¥·¥ó¥Ü¥ë¤Ï¥³¥Þ
4823 ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òɽ¤¹¡£KEYSEQ ¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢
4824 ¤½¤Î¥³¥Þ¥ó¥É¤Ï¸½¾õ¤Ç»ÈÍÑÉÔǽ¤Ç¤¢¤ë¡£¡Ê¤¹¤Ê¤ï¤Á¥³¥Þ¥ó¥É¤ÎÆ°ºî¤òµ¯
4825 Æ°¤Ç¤¤ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Ìµ¤¤¡£¡Ë
4827 $COMMAND ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤϡ¢
4828 $COMMAND ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
4832 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
4833 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
4836 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ä¥³¥Þ¥ó¥É¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
4841 get_im_command_description (MSymbol language, MSymbol name, MSymbol command)
4843 /* Return a description of the command COMMAND of the input method
4844 specified by LANGUAGE and NAME. */
4845 MPlist *cmd = minput_get_command (langauge, name, command);
4850 plist = mplist_value (cmds); /* (NAME DESCRIPTION KEY-SEQ ...) */
4851 plist = mplist_next (plist); /* (DESCRIPTION KEY-SEQ ...) */
4852 return (mplist_key (plist) == Mtext
4853 ? (MText *) mplist_value (plist)
4859 minput_get_command (MSymbol language, MSymbol name, MSymbol command)
4861 MInputMethodInfo *im_info;
4865 im_info = get_im_info (language, name, Mnil, Mcommand);
4867 || ! im_info->configured_cmds
4868 || MPLIST_TAIL_P (im_info->configured_cmds))
4870 if (command == Mnil)
4871 return im_info->configured_cmds;
4872 return mplist__assq (im_info->configured_cmds, command);
4878 @brief Configure the key sequence of an input method command.
4880 The minput_config_command () function assigns a list of key
4881 sequences $KEYSEQLIST to the command $COMMAND of the input method
4882 specified by $LANGUAGE and $NAME.
4884 If $KEYSEQLIST is a non-empty plist, it must be a list of key
4885 sequences, and each key sequence must be a plist of symbols.
4887 If $KEYSEQLIST is an empty plist, the command becomes unusable.
4889 If $KEYSEQLIST is NULL, the configuration of the command for the
4890 input method is canceled, and the default key sequences become
4891 effective. In such case, if $COMMAND is #Mnil, configurations for
4892 all commands of the input method are canceled.
4894 If $NAME is #Mnil, this function configures the key assignment of a
4895 global command, not that of a specific input method.
4897 The configuration takes effect for input methods opened or
4898 re-opened later in the current session. In order to make the
4899 configuration take effect for the future session, it must be saved
4900 in a per-user configuration file by the function
4901 minput_save_config ().
4905 If the operation was successful, this function returns 0,
4906 otherwise returns -1. The operation fails in these cases:
4908 <li>$KEYSEQLIST is not in a valid form.
4909 <li>$COMMAND is not available for the input method.
4910 <li>$LANGUAGE and $NAME do not specify an existing input method.
4914 minput_get_commands (), minput_save_config ().
4917 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤òÀßÄꤹ¤ë.
4919 ´Ø¿ô minput_config_command () ¤Ï¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È
4920 $KEYSEQLIST ¤ò¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤Î
4921 ¥³¥Þ¥ó¥É $COMMAND ¤Ë³ä¤êÅö¤Æ¤ë¡£
4923 $KEYSEQLIST ¤¬¶õ¥ê¥¹¥È¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Î¥ê¥¹¥È¤Ç¤¢¤ê¡¢
4924 ³Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥·¥ó¥Ü¥ë¤Î plist ¤Ç¤¢¤ë¡£
4926 $KEYSEQLIST ¤¬¶õ¤Î plist ¤Ê¤é¤Ð¡¢¥³¥Þ¥ó¥É¤Ï»ÈÍѤǤ¤Ê¤¯¤Ê¤ë¡£
4928 $KEYSEQLIST ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤ÎÀßÄê¤Ï
4929 ¥¥ã¥ó¥»¥ë¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬Í¸ú¤Ë¤Ê¤ë¡£¤³¤Î¾ì¹ç¡¢
4930 $COMMAND ¤¬ #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤Î¥³¥Þ¥ó¥É¤ÎÀßÄ꤬
4933 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
4934 ¥ë¤Ê¥³¥Þ¥ó¥É¤Î¥¡¼³ä¤êÅö¤Æ¤òÀßÄꤹ¤ë¡£
4936 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
4937 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
4938 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
4939 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
4943 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
4945 <li>$KEYSEQLIST ¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£
4946 <li>$COMMAND ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
4947 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
4951 minput_get_commands (), minput_save_config ().
4955 /* Add "C-x u" to the "start" command of Unicode input method. */
4957 MSymbol start_command = msymbol ("start");
4958 MSymbol unicode = msymbol ("unicode");
4959 MPlist *cmd, *plist, *key_seq_list, *key_seq;
4961 /* At first get the current key-sequence assignment. */
4962 cmd = mplist_get_command (Mt, unicode, start_command);
4965 /* The input method does not have the command "start". Here
4966 should come some error handling code. */
4968 /* Now CMD == ((start DESCRIPTION KEY-SEQUENCE ...) ...). Extract
4969 the part (KEY-SEQUENCE ...). */
4970 plist = mplist_next (mplist_next (mplist_value (cmd)));
4971 /* Copy it because we should not modify it directly. */
4972 key_seq_list = mplist_copy (plist);
4973 m17n_object_unref (cmds);
4975 key_seq = mplist ();
4976 mplist_add (key_seq, Msymbol, msymbol ("C-x"));
4977 mplist_add (key_seq, Msymbol, msymbol ("u"));
4978 mplist_add (key_seq_list, Mplist, key_seq);
4979 m17n_object_unref (key_seq);
4981 minput_config_command (Mt, unicode, start_command, key_seq_list);
4982 m17n_object_unref (key_seq_list);
4987 minput_config_command (MSymbol language, MSymbol name, MSymbol command,
4990 MInputMethodInfo *im_info, *config;
4997 if (command == Mnil)
4998 MERROR (MERROR_IM, -1);
4999 MPLIST_DO (plist, keyseqlist)
5000 if (! MPLIST_PLIST_P (plist)
5001 || ! check_command_keyseq (plist))
5002 MERROR (MERROR_IM, -1);
5005 im_info = get_im_info (language, name, Mnil, Mcommand);
5007 MERROR (MERROR_IM, -1);
5010 || ! mplist__assq (im_info->cmds, command)))
5011 MERROR (MERROR_IM, -1);
5013 config = get_config_info (im_info);
5016 if (! im_config_list)
5017 im_config_list = mplist ();
5018 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5019 config->cmds = mplist ();
5020 config->vars = mplist ();
5023 if (command == Mnil)
5025 MInputMethodInfo *custom = get_custom_info (im_info);
5027 mplist_set (config->cmds, Mnil, NULL);
5028 if (custom && custom->cmds)
5030 MPLIST_DO (plist, custom->cmds)
5032 command = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5034 mplist_add (plist, Msymbol, command);
5035 mplist_push (config->cmds, Mplist, plist);
5036 M17N_OBJECT_UNREF (plist);
5042 plist = mplist__assq (config->cmds, command);
5045 plist = MPLIST_PLIST (plist); /* (NAME [nil KEY-SEQUENCE ...]) */
5046 plist = MPLIST_NEXT (plist); /* ([nil ...]) */
5047 if (! MPLIST_TAIL_P (plist))
5048 mplist_set (plist, Mnil, NULL); /* () */
5053 mplist_add (config->cmds, Mplist, plist);
5054 M17N_OBJECT_UNREF (plist);
5055 plist = mplist_add (plist, Msymbol, command);
5056 plist = MPLIST_NEXT (plist);
5062 plist = mplist_add (plist, Msymbol, Mnil);
5063 MPLIST_DO (keyseqlist, keyseqlist)
5065 pl = mplist_copy (MPLIST_VAL (keyseqlist));
5066 plist = mplist_add (plist, Mplist, pl);
5067 M17N_OBJECT_UNREF (pl);
5071 config_all_commands (im_info);
5072 im_info->tick = time (NULL);
5079 @brief Get information about input method variable(s).
5081 The minput_get_variable () function returns information about
5082 the variable $VARIABLE of the input method specified by $LANGUAGE and $NAME.
5083 An input method variable controls behavior of an input method.
5085 There are two kinds of variables, global and local. A global
5086 variable has a global definition, and the description and the value
5087 may be inherited by a local variable. Each input method defines a
5088 local variable which has local value. It may also declare a
5089 local variable that inherits definition of a global variable of
5092 If $LANGUAGE is #Mt and $NAME is #Mnil, information about a global
5093 variable is returned. Otherwise information about a local variable
5096 If $VARIABLE is #Mnil, information about all variables is
5099 The return value is a @e well-formed plist (#m17nPlist) of this
5102 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5104 @c NAME is a symbol representing the variable name.
5106 @c DESCRIPTION is an M-text describing the variable, or #Mnil if the
5107 variable has no description.
5109 @c STATUS is a symbol representing how the value is decided. The
5110 value is #Mnil (the default value), #Mcustomized (the value is
5111 customized by per-user configuration file), or #Mconfigured (the
5112 value is set by the call of minput_config_variable ()). For a
5113 local variable only, it may also be #Minherited (the value is
5114 inherited from the corresponding global variable).
5116 @c VALUE is the initial value of the variable. If the key of this
5117 element is #Mt, the variable has no initial value. Otherwise, the
5118 key is #Minteger, #Msymbol, or #Mtext and the value is of the
5121 @c VALID-VALUEs (if any) specify which values the variable can have.
5122 They have the same type (i.e. having the same key) as @c VALUE except
5123 for the case that VALUE is an integer. In that case, @c VALID-VALUE
5124 may be a plist of two integers specifying the range of possible
5127 If there no @c VALID-VALUE, the variable can have any value as long
5128 as the type is the same as @c VALUE.
5130 If $VARIABLE is not #Mnil, the first element of the returned plist
5131 contains the information about $VARIABLE.
5135 If the requested information was found, a pointer to a non-empty
5136 plist is returned. As the plist is kept in the library, the
5137 caller must not modify nor free it.
5139 Otherwise (the specified input method or the specified variable
5140 does not exist), @c NULL is returned. */
5142 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5144 ´Ø¿ô minput_get_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎÏ
5145 ¥á¥½¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤È¤Ï¡¢
5146 ÆþÎϥ᥽¥Ã¥É¤Î¿¶Éñ¤òÀ©¸æ¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£
5148 ÊÑ¿ô¤Ë¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤Ï¥°
5149 ¥í¡¼¥Ð¥ë¤ËÄêµÁ¤µ¤ì¡¢¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤Ï¤½¤ÎÀâÌÀ¤ÈÃͤò·Ñ¾µ¤¹¤ë¤³¤È¤¬¤Ç
5150 ¤¤ë¡£³ÆÆþÎϥ᥽¥Ã¥É¤Ï¥í¡¼¥«¥ë¤ÊÃͤò»ý¤Ä¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÄêµÁ¤¹¤ë¡£
5151 ¤Þ¤¿Æ±Ì¾¤Î¥°¥í¡¼¥Ð¥ë¤ÊÊÑ¿ô¤ÎÄêµÁ¤ò·Ñ¾µ¤¹¤ë¥í¡¼¥«¥ë¤ÊÊÑ¿ô¤òÀë¸À¤¹¤ë
5154 $LANGUAGE ¤¬ #Mt ¤Ç $NAME ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥°¥í¡¼¥Ð¥ëÊÑ
5155 ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥í¡¼¥«¥ëÊÑ¿ô¤Ë´Ø¤¹¤ë¤â¤Î¤òÊÖ¤¹¡£
5157 $VARIABLE ¤¬ #Mnil ¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£
5159 Ìá¤êÃͤϰʲ¼¤Î·Á¼°¤Î @e well-formed plist (#m17nPlist) ¤Ç¤¢¤ë¡£
5161 ((NAME DESCRIPTION STATUS VALUE [VALID-VALUE ...]) ...)
5164 @c NAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5166 @c DESCRIPTION ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¤«¡¢ÀâÌÀ¤¬Ìµ¤¤¾ì¹ç¤Ë¤Ï
5169 @c STATUS ¤ÏÃͤ¬¤É¤Î¤è¤¦¤ËÄê¤á¤é¤ì¤ë¤«¤ò¤¢¤é¤ï¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
5170 @c STATUS ¤ÎÃÍ¤Ï #Mnil ¡Ê¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¡Ë, #Mcustomized ¡Ê¥æ¡¼¥¶Ëè¤ÎÀß
5171 Äê¥Õ¥¡¥¤¥ë¤Ë¤è¤Ã¤Æ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ÃÍ¡Ë, #Mconfigured
5172 ¡Êminput_config_variable ()¤ò¸Æ¤Ö¤³¤È¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ëÃ͡ˤΤ¤¤º¤ì
5173 ¤«¤Ç¤¢¤ë¡£¥í¡¼¥«¥ëÊÑ¿ô¤Î¾ì¹ç¤Ë¤Ï¡¢#Minherited ¡ÊÂбþ¤¹¤ë¥°¥í¡¼¥Ð¥ë
5174 ÊÑ¿ô¤«¤é·Ñ¾µ¤·¤¿Ã͡ˤǤâ¤è¤¤¡£
5176 @c VALUE ¤ÏÊÑ¿ô¤Î½é´üÃͤǤ¢¤ë¡£¤³¤ÎÍ×ÁǤΥ¡¼¤¬#Mt ¤Ç¤¢¤ì¤Ð½é´üÃͤò»ý
5177 ¤¿¤Ê¤¤¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¥¡¼¤Ï #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì
5178 ¤«¤Ç¤¢¤ê¡¢ÃͤϤ½¤ì¤¾¤ìÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5180 @c VALID-VALUE ¤Ï¤â¤·¤¢¤ì¤Ð¡¢ÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò»ØÄꤹ¤ë¡£¤³¤ì¤Ï @c VALUE
5181 ¤ÈƱ¤¸·¿(¤¹¤Ê¤ï¤ÁƱ¤¸¥¡¼¤ò»ý¤Ä) ¤Ç¤¢¤ë¤¬¡¢Îã³°¤È¤·¤Æ @c VALUE ¤¬
5182 integer ¤Î¾ì¹ç¤Ï @c VALID-VALUE ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹Æó¤Ä¤ÎÀ°¿ô¤«¤é
5183 ¤Ê¤ë plist ¤È¤Ê¤ë¤³¤È¤¬¤Ç¤¤ë¡£
5185 @c VALID-VALUE ¤¬¤Ê¤±¤ì¤Ð¡¢ÊÑ¿ô¤Ï @c VALUE ¤ÈƱ¤¸·¿¤Ç¤¢¤ë¸Â¤ê¤¤¤«¤Ê¤ëÃͤâ
5188 $VARIABLE ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë plist ¤ÎºÇ½é¤ÎÍ×ÁǤÏ
5189 $VARIABLE ¤Ë´Ø¤¹¤ë¾ðÊó¤ò´Þ¤à¡£
5193 µá¤á¤é¤ì¤¿¾ðÊ󤬸«¤Ä¤«¤ì¤Ð¡¢¶õ¤Ç¤Ê¤¤ plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹
5194 ¥È¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð¦¤¬Êѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë
5197 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¤¹¤Ê¤ï¤Á»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤äÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð
5201 minput_get_variable (MSymbol language, MSymbol name, MSymbol variable)
5203 MInputMethodInfo *im_info;
5207 im_info = get_im_info (language, name, Mnil, Mvariable);
5208 if (! im_info || ! im_info->configured_vars)
5210 if (variable == Mnil)
5211 return im_info->configured_vars;
5212 return mplist__assq (im_info->configured_vars, variable);
5218 @brief Configure the value of an input method variable.
5220 The minput_config_variable () function assigns $VALUE to the
5221 variable $VARIABLE of the input method specified by $LANGUAGE and
5224 If $VALUE is not NULL, it must be a plist of one element whose key
5225 is #Minteger, #Msymbol, or #Mtext, and the value is of the
5228 If $VALUE is NULL, a configuration for the variable for the input
5229 method is canceled, and the variable is initialized to the default
5230 value. In that case, if $VARIABLE is #Mnil, configurations for
5231 all variables of the input method are canceled.
5233 If $NAME is #Mnil, this function configure the value of global
5234 variable, not that of a specific input method.
5236 The configuration takes effect for input methods opened or
5237 re-opened later in the current session. To make the configuration
5238 take effect for the future session, it must be saved in a per-user
5239 configuration file by the function minput_save_config ().
5243 If the operation was successful, this function returns 0,
5244 otherwise returns -1. The operation fails in these cases:
5246 <li>$VALUE is not in a valid form, the type does not match the
5247 definition, or the value is our of range.
5248 <li>$VARIABLE is not available for the input method.
5249 <li>$LANGUAGE and $NAME do not specify an existing input method.
5253 minput_get_variable (), minput_save_config (). */
5255 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë.
5257 ´Ø¿ô minput_config_variable () ¤ÏÃÍ $VALUE ¤ò¡¢$LANGUAGE ¤È $NAME
5258 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô $VARIABLE ¤Ë³ä¤êÅö¤Æ¤ë¡£
5260 $VALUE ¤¬ NULL¤Ç¤Ê¤±¤ì¤Ð¡¢£±Í×ÁǤΠplist ¤Ç¤¢¤ê¡¢¤½¤Î¥¡¼¤Ï
5261 #Minteger, #Msymbol, #Mtext ¤Î¤¤¤º¤ì¤«¡¢ÃͤÏÂбþ¤¹¤ë·¿¤Î¤â¤Î¤Ç¤¢¤ë¡£
5263 $VALUE ¤¬ NULL ¤Ç¤¢¤ì¤Ð¡¢»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¤ÎÀßÄê¤Ï¥¥ã¥ó¥»¥ë
5264 ¤µ¤ì¡¢ÊÑ¿ô¤Ï¥Ç¥Õ¥©¥ë¥ÈÃͤ˽é´ü²½¤µ¤ì¤ë¡£¤³¤Î¾ì¹ç¡¢$VARIABLE ¤¬
5265 #Mnil ¤Ê¤é¤Ð»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÎÁ´¤Æ¤ÎÊÑ¿ô¤ÎÀßÄ꤬¥¥ã¥ó¥»¥ë¤µ¤ì¤ë¡£
5267 $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢¤³¤Î´Ø¿ô¤Ï¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¤Ê¤¯¥°¥í¡¼¥Ð
5268 ¥ë¤ÊÊÑ¿ô¤ÎÃͤòÀßÄꤹ¤ë¡£
5270 ¤³¤ì¤é¤ÎÀßÄê¤Ï¡¢¸½¹Ô¤Î¥»¥Ã¥·¥ç¥óÃæ¤ÇÆþÎϥ᥽¥Ã¥É¤¬¥ª¡¼¥×¥ó¡Ê¤Þ¤¿¤Ï
5271 ºÆ¥ª¡¼¥×¥ó¡Ë¤µ¤ì¤¿»þÅÀ¤Ç͸ú¤Ë¤Ê¤ë¡£¾Íè¤Î¥»¥Ã¥·¥ç¥óÃæ¤Ç¤â͸ú¤Ë¤¹
5272 ¤ë¤¿¤á¤Ë¤Ï¡¢´Ø¿ô minput_save_config () ¤òÍѤ¤¤Æ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤
5273 ¥ë¤ËÊݸ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5277 ¤³¤Î´Ø¿ô¤Ï¡¢½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤ò¡¢¼ºÇÔ¤¹¤ì¤Ð -1 ¤òÊÖ¤¹¡£¼ºÇԤȤϰʲ¼¤Î¾ì¹ç¤Ç¤¢¤ë¡£
5279 <li>$VALUE¤¬Í¸ú¤Ê·Á¼°¤Ç¤Ê¤¤¡£·¿¤¬ÄêµÁ¤Ë¹ç¤ï¤Ê¤¤¡¢¤Þ¤¿¤ÏÃͤ¬Èϰϳ°¤Ç¤¢¤ë¡£
5280 <li>$VARIABLE ¤¬»ØÄê¤ÎÆþÎϥ᥽¥Ã¥É¤ÇÍøÍѤǤ¤Ê¤¤¡£
5281 <li>$LANGUAGE ¤È $NAME ¤Ç»ØÄꤵ¤ì¤ëÆþÎϥ᥽¥Ã¥É¤¬Â¸ºß¤·¤Ê¤¤¡£
5285 minput_get_commands (), minput_save_config ().
5288 minput_config_variable (MSymbol language, MSymbol name, MSymbol variable,
5291 MInputMethodInfo *im_info, *config;
5296 im_info = get_im_info (language, name, Mnil, Mvariable);
5298 MERROR (MERROR_IM, -1);
5299 if (variable == Mnil)
5302 MERROR (MERROR_IM, -1);
5304 else if (! im_info->vars
5305 || ! (plist = mplist__assq (im_info->configured_vars, variable)))
5306 MERROR (MERROR_IM, -1);
5308 if (variable != Mnil && value)
5310 plist = MPLIST_PLIST (plist);
5311 plist = MPLIST_NEXT (plist); /* (DESC STATUS VALUE VALIDS ...) */
5312 plist = MPLIST_NEXT (plist); /* (STATUS VALUE VALIDS ...) */
5313 plist = MPLIST_NEXT (plist); /* (VALUE VALIDS ...) */
5314 if (MPLIST_KEY (plist) != Mt
5315 && ! check_variable_value (value, plist))
5316 MERROR (MERROR_IM, -1);
5319 config = get_config_info (im_info);
5322 if (! im_config_list)
5323 im_config_list = mplist ();
5324 config = new_im_info (NULL, language, name, Mnil, im_config_list);
5325 config->cmds = mplist ();
5326 config->vars = mplist ();
5329 if (variable == Mnil)
5331 MInputMethodInfo *custom = get_custom_info (im_info);
5333 mplist_set (config->vars, Mnil, NULL);
5334 if (custom && custom->cmds)
5336 MPLIST_DO (plist, custom->vars)
5338 variable = MPLIST_SYMBOL (MPLIST_PLIST (plist));
5340 mplist_add (plist, Msymbol, variable);
5341 mplist_push (config->vars, Mplist, plist);
5342 M17N_OBJECT_UNREF (plist);
5348 plist = mplist__assq (config->vars, variable);
5351 plist = MPLIST_PLIST (plist); /* (NAME nil VALUE) */
5352 plist = MPLIST_NEXT (plist); /* ([nil VALUE]) */
5353 if (! MPLIST_TAIL_P (plist))
5354 mplist_set (plist, Mnil ,NULL); /* () */
5359 mplist_add (config->vars, Mplist, plist);
5360 M17N_OBJECT_UNREF (plist);
5361 plist = mplist_add (plist, Msymbol, variable);
5362 plist = MPLIST_NEXT (plist);
5366 plist = mplist_add (plist, Msymbol, Mnil);
5367 mplist_add (plist, MPLIST_KEY (value), MPLIST_VAL (value));
5370 config_all_variables (im_info);
5371 im_info->tick = time (NULL);
5378 @brief Get the name of per-user configuration file.
5380 The minput_config_file () function returns the absolute path name
5381 of per-user configuration file into which minput_save_config ()
5382 save configurations. It is usually @c "config.mic" under the
5383 directory @c ".m17n.d" of user's home directory. It is not assured
5384 that the file of the returned name exists nor is
5385 readable/writable. If minput_save_config () fails and returns -1,
5386 an application program might check the file, make it
5387 writable (if possible), and try minput_save_config () again.
5391 This function returns a string. As the string is kept in the
5392 library, the caller must not modify nor free it.
5395 minput_save_config ()
5398 @brief ¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÆÀ¤ë.
5400 ´Ø¿ô minput_config_file () ¤Ï¡¢´Ø¿ô minput_save_config () ¤¬ÀßÄê¤ò
5401 Êݸ¤¹¤ë¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹Ì¾¤òÊÖ¤¹¡£Ä̾ï¤Ï¡¢¥æ¡¼¥¶
5402 ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê @c ".m17n.d" ¤Ë¤¢¤ë@c
5403 "config.mic" ¤È¤Ê¤ë¡£ÊÖ¤µ¤ì¤¿Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë¤«¡¢Æɤ߽ñ¤¤Ç
5404 ¤¤ë¤«¤ÏÊݾڤµ¤ì¤Ê¤¤¡£´Ø¿ôminput_save_config () ¤¬¼ºÇÔ¤·¤Æ -1 ¤òÊÖ
5405 ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò³Îǧ¤·¡¢
5406 ¡Ê¤Ç¤¤ì¤Ð¡Ë½ñ¤¹þ¤ß²Äǽ¤Ë¤·ºÆÅÙminput_save_config () ¤ò»î¤¹¤³¤È¤¬
5411 ¤³¤Î´Ø¿ô¤Ïʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¥é¥¤¥Ö¥é¥ê¤¬´ÉÍý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¸Æ½Ð
5412 ¦¤¬½¤Àµ¤·¤¿¤ê²òÊü¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤¤¡£
5415 minput_save_config ()
5419 minput_config_file ()
5423 return mdatabase__file (im_custom_mdb);
5429 @brief Save configurations in per-user configuration file.
5431 The minput_save_config () function saves the configurations done
5432 so far in the current session into the per-user configuration
5437 If the operation was successful, 1 is returned. If the per-user
5438 configuration file is currently locked, 0 is returned. In that
5439 case, the caller may wait for a while and try again. If the
5440 configuration file is not writable, -1 is returned. In that case,
5441 the caller may check the name of the file by calling
5442 minput_config_file (), make it writable if possible, and try
5446 minput_config_file () */
5448 @brief ÀßÄê¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë.
5450 ´Ø¿ô minput_save_config () ¤Ï¸½¹Ô¤Î¥»¥Ã¥·¥ç¥ó¤Ç¤³¤ì¤Þ¤Ç¤Ë¹Ô¤Ã¤¿ÀßÄê
5451 ¤ò¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¡£
5455 À®¸ù¤¹¤ì¤Ð 1 ¤òÊÖ¤¹¡£¥æ¡¼¥¶Ëè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤ì¤Ð 0
5456 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢¸Æ½Ð¦¤Ï¤·¤Ð¤é¤¯ÂԤäƺƻî¹Ô¤Ç¤¤ë¡£ÀßÄê¥Õ¥¡¥¤¥ë
5457 ¤¬½ñ¤¹þ¤ßÉԲĤξì¹ç¡¢-1 ¤òÊÖ¤¹¡£¤³¤Î¾ì¹ç¡¢minput_config_file () ¤ò
5458 ¸Æ¤ó¤Ç¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¡¢¤Ç¤¤ì¤Ð½ñ¤¹þ¤ß²Äǽ¤Ë¤·¡¢ºÆ»î¹Ô¤Ç¤
5462 minput_config_file () */
5465 minput_save_config (void)
5467 MPlist *data, *tail, *plist, *p, *elt;
5471 ret = mdatabase__lock (im_custom_mdb);
5474 if (! im_config_list)
5476 update_custom_info ();
5477 if (! im_custom_list)
5478 im_custom_list = mplist ();
5479 data = tail = mplist ();
5481 MPLIST_DO (plist, im_config_list)
5483 MPlist *pl = MPLIST_PLIST (plist);
5484 MSymbol language, name, extra, command, variable;
5485 MInputMethodInfo *custom, *config;
5487 language = MPLIST_SYMBOL (pl);
5488 pl = MPLIST_NEXT (pl);
5489 name = MPLIST_SYMBOL (pl);
5490 pl = MPLIST_NEXT (pl);
5491 extra = MPLIST_SYMBOL (pl);
5492 pl = MPLIST_NEXT (pl);
5493 config = MPLIST_VAL (pl);
5494 custom = get_custom_info (config);
5496 custom = new_im_info (NULL, language, name, extra, im_custom_list);
5498 MPLIST_DO (pl, config->cmds)
5500 elt = MPLIST_PLIST (pl);
5501 command = MPLIST_SYMBOL (elt);
5503 p = mplist__assq (custom->cmds, command);
5505 custom->cmds = mplist (), p = NULL;
5506 elt = MPLIST_NEXT (elt);
5507 if (MPLIST_TAIL_P (elt))
5510 mplist__pop_unref (p);
5514 elt = MPLIST_NEXT (elt);
5517 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5518 mplist_set (p, Mnil, NULL);
5519 mplist__conc (p, elt);
5523 p = MPLIST_PLIST (pl);
5524 mplist_add (custom->cmds, Mplist, p);
5529 MPLIST_DO (pl, config->vars)
5531 elt = MPLIST_PLIST (pl);
5532 variable = MPLIST_SYMBOL (elt);
5534 p = mplist__assq (custom->vars, variable);
5536 custom->vars = mplist (), p = NULL;
5537 elt = MPLIST_NEXT (elt);
5538 if (MPLIST_TAIL_P (elt))
5541 mplist__pop_unref (p);
5545 elt = MPLIST_NEXT (elt);
5548 p = MPLIST_NEXT (MPLIST_NEXT (MPLIST_PLIST (p)));
5549 mplist_set (p, Mnil, NULL);
5550 mplist__conc (p, elt);
5554 p = MPLIST_PLIST (pl);
5555 mplist_add (custom->vars, Mplist, p);
5560 M17N_OBJECT_UNREF (im_config_list);
5562 MPLIST_DO (plist, im_custom_list)
5564 MPlist *pl = MPLIST_PLIST (plist);
5565 MSymbol language, name, extra;
5566 MInputMethodInfo *custom, *im_info;
5568 language = MPLIST_SYMBOL (pl);
5569 pl = MPLIST_NEXT (pl);
5570 name = MPLIST_SYMBOL (pl);
5571 pl = MPLIST_NEXT (pl);
5572 extra = MPLIST_SYMBOL (pl);
5573 pl = MPLIST_NEXT (pl);
5574 custom = MPLIST_VAL (pl);
5575 im_info = lookup_im_info (im_info_list, language, name, extra);
5579 config_all_commands (im_info);
5581 config_all_variables (im_info);
5585 tail = mplist_add (tail, Mplist, elt);
5586 M17N_OBJECT_UNREF (elt);
5588 elt = mplist_add (elt, Mplist, pl);
5589 M17N_OBJECT_UNREF (pl);
5590 pl = mplist_add (pl, Msymbol, Minput_method);
5591 pl = mplist_add (pl, Msymbol, language);
5592 pl = mplist_add (pl, Msymbol, name);
5594 pl = mplist_add (pl, Msymbol, extra);
5595 if (custom->cmds && ! MPLIST_TAIL_P (custom->cmds))
5598 elt = mplist_add (elt, Mplist, pl);
5599 M17N_OBJECT_UNREF (pl);
5600 pl = mplist_add (pl, Msymbol, Mcommand);
5601 MPLIST_DO (p, custom->cmds)
5602 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5604 if (custom->vars && ! MPLIST_TAIL_P (custom->vars))
5607 elt = mplist_add (elt, Mplist, pl);
5608 M17N_OBJECT_UNREF (pl);
5609 pl = mplist_add (pl, Msymbol, Mvariable);
5610 MPLIST_DO (p, custom->vars)
5611 pl = mplist_add (pl, Mplist, MPLIST_PLIST (p));
5615 mplist_push (data, Mstring, ";; -*- mode:lisp; coding:utf-8 -*-");
5616 ret = mdatabase__save (im_custom_mdb, data);
5617 mdatabase__unlock (im_custom_mdb);
5618 M17N_OBJECT_UNREF (data);
5619 return (ret < 0 ? -1 : 1);
5626 @name Obsolete functions
5629 @name Obsolete ¤Ê´Ø¿ô
5635 @brief Get a list of variables of an input method (obsolete).
5637 This function is obsolete. Use minput_get_variable () instead.
5639 The minput_get_variables () function returns a plist (#MPlist) of
5640 variables used to control the behavior of the input method
5641 specified by $LANGUAGE and $NAME. The plist is @e well-formed
5642 (#m17nPlist) of the following format:
5645 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5646 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5650 @c VARNAME is a symbol representing the variable name.
5652 @c DOC-MTEXT is an M-text describing the variable.
5654 @c DEFAULT-VALUE is the default value of the variable. It is a
5655 symbol, integer, or M-text.
5657 @c VALUEs (if any) specifies the possible values of the variable.
5658 If @c DEFAULT-VALUE is an integer, @c VALUE may be a plist (@c FROM
5659 @c TO), where @c FROM and @c TO specifies a range of possible
5662 For instance, suppose an input method has the variables:
5664 @li name:intvar, description:"value is an integer",
5665 initial value:0, value-range:0..3,10,20
5667 @li name:symvar, description:"value is a symbol",
5668 initial value:nil, value-range:a, b, c, nil
5670 @li name:txtvar, description:"value is an M-text",
5671 initial value:empty text, no value-range (i.e. any text)
5673 Then, the returned plist is as follows.
5676 (intvar ("value is an integer" 0 (0 3) 10 20)
5677 symvar ("value is a symbol" nil a b c nil)
5678 txtvar ("value is an M-text" ""))
5682 If the input method uses any variables, a pointer to #MPlist is
5683 returned. As the plist is kept in the library, the caller must not
5684 modify nor free it. If the input method does not use any
5685 variable, @c NULL is returned. */
5687 @brief ÆþÎϥ᥽¥Ã¥É¤ÎÊÑ¿ô¥ê¥¹¥È¤òÆÀ¤ë.
5689 ´Ø¿ô minput_get_variables () ¤Ï¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5690 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤Î¿¶¤ëÉñ¤¤¤òÀ©¸æ¤¹¤ëÊÑ¿ô¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È
5691 (#MPlist) ¤òÊÖ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ï @e well-formed ¤Ç¤¢¤ê(#m17nPlist) °Ê
5695 (VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5696 VARNAME (DOC-MTEXT DEFAULT-VALUE [ VALUE ... ] )
5700 @c VARNAME ¤ÏÊÑ¿ô¤Î̾Á°¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5702 @c DOC-MTEXT ¤ÏÊÑ¿ô¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£
5704 @c DEFAULT-VALUE ¤ÏÊÑ¿ô¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ê¡¢¥·¥ó¥Ü¥ë¡¢À°¿ô¤â¤·¤¯¤Ï
5707 @c VALUE ¤Ï¡¢¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤ÐÊÑ¿ô¤Î¼è¤êÆÀ¤ëÃͤò¼¨¤¹¡£¤â¤·
5708 @c DEFAULT-VALUE ¤¬À°¿ô¤Ê¤é¡¢ @c VALUE ¤Ï (@c FROM @c TO) ¤È¤¤¤¦·Á
5709 ¤Î¥ê¥¹¥È¤Ç¤âÎɤ¤¡£¤³¤Î¾ì¹ç @c FROM ¤È @c TO ¤Ï²Äǽ¤ÊÃͤÎÈϰϤò¼¨¤¹¡£
5711 Îã¤È¤·¤Æ¡¢¤¢¤ëÆþÎϥ᥽¥Ã¥É¤¬¼¡¤Î¤è¤¦¤ÊÊÑ¿ô¤ò»ý¤Ä¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£
5713 @li name:intvar, ÀâÌÀ:"value is an integer",
5714 ½é´üÃÍ:0, ÃͤÎÈÏ°Ï:0..3,10,20
5716 @li name:symvar, ÀâÌÀ:"value is a symbol",
5717 ½é´üÃÍ:nil, ÃͤÎÈÏ°Ï:a, b, c, nil
5719 @li name:txtvar, ÀâÌÀ:"value is an M-text",
5720 ½é´üÃÍ:empty text, ÃͤÎÈϰϤʤ·(¤É¤ó¤Ê M-text ¤Ç¤â²Ä)
5722 ¤³¤Î¾ì¹ç¡¢ÊÖ¤µ¤ì¤ë¥ê¥¹¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡£
5725 (intvar ("value is an integer" 0 (0 3) 10 20)
5726 symvar ("value is a symbol" nil a b c nil)
5727 txtvar ("value is an M-text" ""))
5731 ÆþÎϥ᥽¥Ã¥É¤¬²¿¤é¤«¤ÎÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤ì¤Ð #MPlist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
5732 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5733 ÆþÎϥ᥽¥Ã¥É¤¬ÊÑ¿ô¤ò°ìÀÚ»ÈÍѤ·¤Æ¤Ê¤±¤ì¤Ð¡¢@c NULL ¤òÊÖ¤¹¡£ */
5736 minput_get_variables (MSymbol language, MSymbol name)
5738 MInputMethodInfo *im_info;
5743 im_info = get_im_info (language, name, Mnil, Mvariable);
5744 if (! im_info || ! im_info->configured_vars)
5747 M17N_OBJECT_UNREF (im_info->bc_vars);
5748 im_info->bc_vars = mplist ();
5749 MPLIST_DO (vars, im_info->configured_vars)
5751 MPlist *plist = MPLIST_PLIST (vars);
5752 MPlist *elt = mplist ();
5754 mplist_push (im_info->bc_vars, Mplist, elt);
5755 mplist_add (elt, Msymbol, MPLIST_SYMBOL (plist));
5756 elt = MPLIST_NEXT (elt);
5757 mplist_set (elt, Mplist, mplist_copy (MPLIST_NEXT (plist)));
5758 M17N_OBJECT_UNREF (elt);
5760 return im_info->bc_vars;
5766 @brief Set the initial value of an input method variable.
5768 The minput_set_variable () function sets the initial value of
5769 input method variable $VARIABLE to $VALUE for the input method
5770 specified by $LANGUAGE and $NAME.
5772 By default, the initial value is 0.
5774 This setting gets effective in a newly opened input method.
5777 If the operation was successful, 0 is returned. Otherwise -1 is
5778 returned, and #merror_code is set to #MERROR_IM. */
5780 @brief ÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô¤Î½é´üÃͤòÀßÄꤹ¤ë.
5782 ´Ø¿ô minput_set_variable () ¤Ï¡¢$LANGUAGE ¤È $NAME
5783 ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥ÉÊÑ¿ô $VARIABLE
5784 ¤Î½é´üÃͤò¡¢ $VALUE ¤ËÀßÄꤹ¤ë¡£
5786 ¥Ç¥Õ¥©¥ë¥È¤Î½é´üÃÍ¤Ï 0 ¤Ç¤¢¤ë¡£
5788 ¤³¤ÎÀßÄê¤Ï¡¢¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤é͸ú¤È¤Ê¤ë¡£
5791 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5792 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5795 minput_set_variable (MSymbol language, MSymbol name,
5796 MSymbol variable, void *value)
5799 MInputMethodInfo *im_info;
5804 if (variable == Mnil)
5805 MERROR (MERROR_IM, -1);
5806 plist = minput_get_variable (language, name, variable);
5807 plist = MPLIST_PLIST (plist);
5808 plist = MPLIST_NEXT (plist);
5810 mplist_add (pl, MPLIST_KEY (plist), value);
5811 ret = minput_config_variable (language, name, variable, pl);
5812 M17N_OBJECT_UNREF (pl);
5815 im_info = get_im_info (language, name, Mnil, Mvariable);
5824 @brief Get information about input method commands.
5826 The minput_get_commands () function returns information about
5827 input method commands of the input method specified by $LANGUAGE
5828 and $NAME. An input method command is a pseudo key event to which
5829 one or more actual input key sequences are assigned.
5831 There are two kinds of commands, global and local. Global
5832 commands are used by multiple input methods for the same purpose,
5833 and have global key assignments. Local commands are used only by
5834 a specific input method, and have only local key assignments.
5836 Each input method may locally change key assignments for global
5837 commands. The global key assignment for a global command is
5838 effective only when the current input method does not have local
5839 key assignments for that command.
5841 If $NAME is #Mnil, information about global commands is returned.
5842 In this case $LANGUAGE is ignored.
5844 If $NAME is not #Mnil, information about those commands that have
5845 local key assignments in the input method specified by $LANGUAGE
5846 and $NAME is returned.
5849 If no input method commands are found, this function returns @c NULL.
5851 Otherwise, a pointer to a plist is returned. The key of each
5852 element in the plist is a symbol representing a command, and the
5853 value is a plist of the form COMMAND-INFO described below.
5855 The first element of COMMAND-INFO has the key #Mtext, and the
5856 value is an M-text describing the command.
5858 If there are no more elements, that means no key sequences are
5859 assigned to the command. Otherwise, each of the remaining
5860 elements has the key #Mplist, and the value is a plist whose keys are
5861 #Msymbol and values are symbols representing input keys, which are
5862 currently assigned to the command.
5864 As the returned plist is kept in the library, the caller must not
5865 modify nor free it. */
5867 @brief ÆþÎϥ᥽¥Ã¥É¤Î¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÆÀ¤ë.
5869 ´Ø¿ô minput_get_commands () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ
5870 ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤ÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£ÆþÎϥ᥽¥Ã
5871 ¥É¥³¥Þ¥ó¥É¤È¤Ï¡¢µ¿»÷¥¡¼¥¤¥Ù¥ó¥È¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì¤Ë£±¤Ä°Ê¾å¤Î¼ÂºÝ¤Î
5872 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤â¤Î¤ò»Ø¤¹¡£
5874 ¥³¥Þ¥ó¥É¤Ë¤Ï¥°¥í¡¼¥Ð¥ë¤È¥í¡¼¥«¥ë¤Î£²¼ïÎब¤¢¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É
5875 ¤ÏÊ£¿ô¤ÎÆþÎϥ᥽¥Ã¥É¤Ë¤ª¤¤¤Æ¡¢Æ±¤¸ÌÜŪ¤Ç¡¢¥°¥í¡¼¥Ð¥ë¤Ê¥¡¼³ä¤êÅö¤Æ
5876 ¤ÇÍѤ¤¤é¤ì¤ë¡£¥í¡¼¥«¥ë¥³¥Þ¥ó¥É¤ÏÆÃÄê¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Î¤ß¡¢¥í¡¼¥«¥ë
5877 ¤Ê¥¡¼³äÅö¤Ç»ÈÍѤµ¤ì¤ë¡£
5879 ¸Ä¡¹¤ÎÆþÎϥ᥽¥Ã¥É¤Ï¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Î¥¡¼³äÅö¤òÊѹ¹¤¹¤ë¤³¤È¤â¤Ç
5880 ¤¤ë¡£¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥ÉÍѤΥ°¥í¡¼¥Ð¥ë¥¡¼³ä¤êÅö¤Æ¤Ï¡¢»ÈÍѤ¹¤ëÆþÎÏ
5881 ¥á¥½¥Ã¥É¤Ë¤ª¤¤¤Æ¤½¤Î¥³¥Þ¥ó¥ÉÍÑ¤Î¥í¡¼¥«¥ë¤Ê¥¡¼³äÅö¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç
5884 $NAME ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¥°¥í¡¼¥Ð¥ë¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÖ¤¹¡£¤³¤Î
5885 ¾ì¹ç¡¢$LANGUAGE ¤Ï̵»ë¤µ¤ì¤ë¡£
5887 $NAME ¤¬ #Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëÆþ
5888 Îϥ᥽¥Ã¥É¤ËÃÖ¤±¤ë¥í¡¼¥«¥ë¤Ê¥¡¼³ä¤êÅö¤Æ¤ò»ý¤Ä¥³¥Þ¥ó¥É¤Ë´Ø¤¹¤ë¾ðÊó
5892 ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï @c NULL ¤òÊÖ¤¹¡£
5894 ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¥ê¥¹¥È¤Î³ÆÍ×ÁǤÎ
5895 ¥¡¼¤Ï¸Ä¡¹¤Î¥³¥Þ¥ó¥É¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤϲ¼µ¤Î COMMAND-INFO
5896 ¤Î·Á¼°¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ç¤¢¤ë¡£
5898 COMMAND-INFO ¤ÎÂè°ìÍ×ÁǤΥ¡¼¤Ï #Mtext ¤Þ¤¿¤Ï #Msymbol ¤Ç¤¢¤ë¡£¥¡¼
5899 ¤¬ #Mtext ¤Ê¤é¡¢ÃͤϤ½¤Î¥³¥Þ¥ó¥É¤òÀâÌÀ¤¹¤ë M-text ¤Ç¤¢¤ë¡£¥¡¼¤¬
5900 #Msymbol ¤Ê¤éÃÍ¤Ï #Mnil ¤Ç¤¢¤ê¡¢¤³¤Î¥³¥Þ¥ó¥É¤ÏÀâÌÀ¥Æ¥¥¹¥È¤ò»ý¤¿¤Ê
5903 ¤½¤ì°Ê³°¤ÎÍ×ÁǤ¬Ìµ¤±¤ì¤Ð¡¢¤³¤Î¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤¬³ä
5904 ¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢»Ä¤ê¤Î³ÆÍ×ÁǤϥ
5905 ¡¼¤È¤·¤Æ#Mplist ¤ò¡¢ÃͤȤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò»ý¤Ä¡£¤³¤Î¥×¥í¥Ñ¥Æ¥£
5906 ¥ê¥¹¥È¤Î¥¡¼¤Ï #Msymbol ¤Ç¤¢¤ê¡¢Ãͤϸ½ºß¤½¤Î¥³¥Þ¥ó¥É¤Ë³ä¤êÅö¤Æ¤é¤ì
5907 ¤Æ¤¤¤ëÆþÎÏ¥¡¼¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
5909 ÊÖ¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ï¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤ª¤ê¡¢¸Æ¤Ó½Ð
5910 ¤·Â¦¤ÇÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
5913 minput_get_commands (MSymbol language, MSymbol name)
5915 MInputMethodInfo *im_info;
5920 im_info = get_im_info (language, name, Mnil, Mcommand);
5921 if (! im_info || ! im_info->configured_vars)
5923 M17N_OBJECT_UNREF (im_info->bc_cmds);
5924 im_info->bc_cmds = mplist ();
5925 MPLIST_DO (cmds, im_info->configured_cmds)
5927 MPlist *plist = MPLIST_PLIST (cmds);
5928 MPlist *elt = mplist ();
5930 mplist_push (im_info->bc_cmds, Mplist, elt);
5931 mplist_add (elt, MPLIST_SYMBOL (plist),
5932 mplist_copy (MPLIST_NEXT (plist)));
5933 M17N_OBJECT_UNREF (elt);
5935 return im_info->bc_cmds;
5941 @brief Assign a key sequence to an input method command (obsolete).
5943 This function is obsolete. Use minput_config_command () instead.
5945 The minput_assign_command_keys () function assigns input key
5946 sequence $KEYSEQ to input method command $COMMAND for the input
5947 method specified by $LANGUAGE and $NAME. If $NAME is #Mnil, the
5948 key sequence is assigned globally no matter what $LANGUAGE is.
5949 Otherwise the key sequence is assigned locally.
5951 Each element of $KEYSEQ must have the key $Msymbol and the value
5952 must be a symbol representing an input key.
5954 $KEYSEQ may be @c NULL, in which case, all assignments are deleted
5955 globally or locally.
5957 This assignment gets effective in a newly opened input method.
5960 If the operation was successful, 0 is returned. Otherwise -1 is
5961 returned, and #merror_code is set to #MERROR_IM. */
5963 @brief ÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É¤Ë¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤ò³ä¤êÅö¤Æ¤ë.
5965 ´Ø¿ô minput_assign_command_keys () ¤Ï¡¢ $LANGUAGE ¤È $NAME ¤Ë¤è¤Ã¤Æ
5966 »ØÄꤵ¤ì¤¿ÆþÎϥ᥽¥Ã¥ÉÍѤÎÆþÎϥ᥽¥Ã¥É¥³¥Þ¥ó¥É $COMMAND ¤ËÂФ·¤Æ¡¢
5967 ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹ $KEYSEQ ¤ò³ä¤êÅö¤Æ¤ë¡£ $NAME ¤¬ #Mnil ¤Ê¤é¤Ð¡¢
5968 $LANGUAGE ¤Ë´Ø·¸¤Ê¤¯¡¢ÆþÎÏ¥¡¼¥·¡¼¥¯¥¨¥ó¥¹¤Ï¥°¥í¡¼¥Ð¥ë¤Ë³ä¤êÅö¤Æ¤é
5969 ¤ì¤ë¡£¤½¤¦¤Ç¤Ê¤ì¤Ð¡¢³ä¤êÅö¤Æ¤Ï¥í¡¼¥«¥ë¤Ç¤¢¤ë¡£
5971 $KEYSEQ ¤Î³ÆÍ×ÁǤϥ¡¼¤È¤·¤Æ $Msymbol ¤ò¡¢ÃͤȤ·¤ÆÆþÎÏ¥¡¼¤òɽ¤¹¥·
5972 ¥ó¥Ü¥ë¤ò»ý¤¿¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
5974 $KEYSEQ ¤Ï @c NULL ¤Ç¤â¤è¤¤¡£¤³¤Î¾ì¹ç¡¢¥°¥í¡¼¥Ð¥ë¤â¤·¤¯¤Ï¥í¡¼¥«¥ë¤Ê
5975 ¤¹¤Ù¤Æ¤Î³ä¤êÅö¤Æ¤¬¾Ãµî¤µ¤ì¤ë¡£
5977 ¤³¤Î³ä¤êÅö¤Æ¤Ï¡¢³ä¤êÅö¤Æ°Ê¹ß¿·¤·¤¯¥ª¡¼¥×¥ó¤µ¤ì¤¿ÆþÎϥ᥽¥Ã¥É¤«¤éÍ
5980 @return ½èÍý¤¬À®¸ù¤¹¤ì¤Ð 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢
5981 #merror_code ¤ò #MERROR_IM ¤ËÀßÄꤹ¤ë¡£ */
5984 minput_assign_command_keys (MSymbol language, MSymbol name,
5985 MSymbol command, MPlist *keyseq)
5991 if (command == Mnil)
5992 MERROR (MERROR_IM, -1);
5997 if (! check_command_keyseq (keyseq))
5998 MERROR (MERROR_IM, -1);
6000 mplist_add (plist, Mplist, keyseq);
6005 ret = minput_config_command (language, name, command, keyseq);
6006 M17N_OBJECT_UNREF (keyseq);
6013 /*** @addtogroup m17nDebug */
6019 @brief Dump an input method.
6021 The mdebug_dump_im () function prints the input method $IM in a
6022 human readable way to the stderr. $INDENT specifies how many
6023 columns to indent the lines but the first one.
6026 This function returns $IM. */
6028 @brief ÆþÎϥ᥽¥Ã¥É¤ò¥À¥ó¥×¤¹¤ë.
6030 ´Ø¿ô mdebug_dump_im () ¤ÏÆþÎϥ᥽¥Ã¥É $IM ¤ò stderr
6031 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£$INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
6034 ¤³¤Î´Ø¿ô¤Ï $IM ¤òÊÖ¤¹¡£ */
6037 mdebug_dump_im (MInputMethod *im, int indent)
6039 MInputMethodInfo *im_info = (MInputMethodInfo *) im->info;
6042 prefix = (char *) alloca (indent + 1);
6043 memset (prefix, 32, indent);
6044 prefix[indent] = '\0';
6046 fprintf (stderr, "(input-method %s %s ", msymbol_name (im->language),
6047 msymbol_name (im->name));
6048 mdebug_dump_mtext (im_info->title, 0, 0);
6049 if (im->name != Mnil)
6053 MPLIST_DO (state, im_info->states)
6055 fprintf (stderr, "\n%s ", prefix);
6056 dump_im_state (MPLIST_VAL (state), indent + 2);
6059 fprintf (stderr, ")");