1 /* mimx-anthy.c -- Anthy input method external module. -*- coding: euc-jp; -*-
2 Copyright (C) 2003, 2004
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 @enpage mimx-anthy external module for the input method <ja, anthy>
26 @section mimx-anthy-description DESCRIPTION
28 The shared library mimx-anthy.so is an external module used by the
29 input method <ja, anthy>. It exports these functions.
34 Initialize this module.
42 Convert the current preedit text (Hiragana sequence) into
43 Kana-Kanji mixed text.
47 Record the change of candidate of the current segment.
51 Enlarge or shorten the length of the current segment.
55 Commit the lastly selected candidates of all the segments.
59 @section mimx-anthy-seealso See also
63 @japage mimx-anthy ÆþÎϥ᥽¥Ã¥É <ja, anthy> Íѳ°Éô¥â¥¸¥å¡¼¥ë.
65 @section mimx-anthy-description DESCRIPTION
67 ¶¦Í¥é¥¤¥Ö¥é¥ê mimx-anthy.so ¤ÏÆþÎϥ᥽¥Ã¥É<ja, anthy> ¤ËÍѤ¤¤é¤ì
68 ¤ë³°Éô¥â¥¸¥å¡¼¥ë¤Ç¤¢¤ê¡¢°Ê²¼¤Î´Ø¿ô¤ò export ¤·¤Æ¤¤¤ë¡£
81 ¸½ºß¤Î preedit ¥Æ¥¥¹¥È (¤Ò¤é¤¬¤ÊÎó) ¤ò¤«¤Ê´Á»ú¥Æ¥¥¹¥È¤ËÊÑ´¹¤¹¤ë¡£
85 ¸½ºß¤Î¥»¥°¥á¥ó¥È¤Î¸õÊä¤ÎÊÑÁ«¤òµÏ¿¤¹¤ë¡£
89 ¸½ºß¤Î¥»¥°¥á¥ó¥È¤ÎŤµ¤òÊѹ¹¤¹¤ë¡£
93 Á´¥»¥°¥á¥ó¥È¤ÎºÇ¿·¤Î¸õÊä¤ò¥³¥ß¥Ã¥È¤¹¤ë¡£
97 @section mimx-anthy-seealso »²¾È
110 #include <anthy/anthy.h>
112 static int initialized;
113 static MSymbol Manthy, Msegment;
115 /* A structure to record in MInputContext->plist with key Manthy. */
120 /* Which candidate is selected in each segment. */
121 int *candidate_numbers;
122 /* Size of the above array. */
124 /* Converter for this context. */
125 MConverter *converter;
128 static AnthyContext *
129 new_context (MInputContext *ic)
131 AnthyContext *context;
133 MSymbol euc_jp = msymbol ("euc-jp");
134 /* Rebound to an actual buffer just before being used. */
135 MConverter *converter = mconv_buffer_converter (euc_jp, NULL, 0);
139 ac = anthy_create_context ();
142 context = calloc (1, sizeof (AnthyContext));
145 context->num_segments = 0;
146 context->candidate_numbers = NULL;
147 context->converter = converter;
151 static AnthyContext *
152 get_context (MInputContext *ic)
154 MPlist *plist = ic->plist;
155 AnthyContext *context;
157 for (; plist && mplist_key (plist) != Mnil; plist = mplist_next (plist))
159 if (mplist_key (plist) != Manthy)
161 context = mplist_value (plist);
162 if (context->ic == ic)
170 free_context (AnthyContext *context)
172 anthy_release_context (context->ac);
173 if (context->candidate_numbers)
174 free (context->candidate_numbers);
175 mconv_free_converter (context->converter);
180 allocate_candidate_numbers (AnthyContext *context, int num)
182 if (context->num_segments < num)
184 if (context->num_segments == 0)
185 context->candidate_numbers = malloc (sizeof (int) * num);
187 context->candidate_numbers = realloc (context->candidate_numbers,
189 context->num_segments = num;
194 add_action (MPlist *actions, MSymbol name, MSymbol key, void *val)
196 MPlist *action = mplist ();
198 mplist_add (action, Msymbol, name);
199 mplist_add (action, key, val);
200 mplist_add (actions, Mplist, action);
201 m17n_object_unref (action);
204 /* Return a list of all candidates of the Nth segment. The return
205 value is a plist whose elements are plists who contains at most 5
209 make_candidate_list (AnthyContext *context, int n)
211 MPlist *plist = mplist (), *pl;
214 struct anthy_segment_stat ss;
217 anthy_get_segment_stat (context->ac, n, &ss);
218 for (i = 0, pl = mplist (); i < ss.nr_candidate; i++)
220 anthy_get_segment (context->ac, n, i, buf, sizeof (buf));
221 mconv_rebind_buffer (context->converter,
222 (unsigned char *) buf, strlen (buf));
223 mt = mconv_decode (context->converter, mtext ());
224 mtext_put_prop (mt, 0, mtext_len (mt), Msegment, (void *) (n + 1));
225 mplist_add (pl, Mtext, mt);
226 m17n_object_unref (mt);
229 mplist_add (plist, Mplist, pl);
230 m17n_object_unref (pl);
234 if (mplist_key (pl) != Mnil)
235 mplist_add (plist, Mplist, pl);
236 m17n_object_unref (pl);
243 MInputContext *ic = mplist_value (args);
244 AnthyContext *context;
249 Manthy = msymbol (" anthy");
250 Msegment = msymbol (" segment");
252 context = new_context (ic);
254 mplist_push (ic->plist, Manthy, context);
261 MInputContext *ic = mplist_value (args);
262 AnthyContext *context = get_context (ic);
265 free_context (context);
270 convert (MPlist *args)
272 MInputContext *ic = mplist_value (args);
273 AnthyContext *context = get_context (ic);
274 struct anthy_conv_stat cs;
275 MPlist *action, *actions;
277 unsigned char buf[1024];
282 mconv_rebind_buffer (context->converter, buf, sizeof (buf));
283 mconv_encode (context->converter, ic->preedit);
284 buf[context->converter->nbytes] = '\0';
285 anthy_set_string (context->ac, (char *) buf);
286 anthy_get_stat (context->ac, &cs);
287 allocate_candidate_numbers (context, cs.nr_segment);
290 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@<"));
291 add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@>"));
292 for (i = 0; i < cs.nr_segment; i++)
294 context->candidate_numbers[i] = 0;
296 add_action (actions, msymbol ("mark"), Msymbol, msymbol ("@anthy"));
297 action = make_candidate_list (context, i);
298 mplist_add (actions, Mplist, action);
299 m17n_object_unref (action);
301 if (cs.nr_segment > 1)
302 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@anthy"));
308 change (MPlist *args)
310 MInputContext *ic = mplist_value (args);
311 AnthyContext *context = get_context (ic);
316 if (! ic->candidate_list || ic->cursor_pos == 0)
318 segment = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1, Msegment);
322 context->candidate_numbers[segment] = ic->candidate_index;
327 resize (MPlist *args)
329 MInputContext *ic = mplist_value (args);
330 AnthyContext *context = get_context (ic);
331 struct anthy_conv_stat cs;
334 MPlist *actions, *action;
339 if (! ic->candidate_list || ic->cursor_pos == 0)
341 segment = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1, Msegment);
345 args = mplist_next (args);
346 shorten = mplist_value (args);
347 anthy_resize_segment (context->ac, segment, shorten == Mt ? -1 : 1);
348 anthy_get_stat (context->ac, &cs);
349 allocate_candidate_numbers (context, cs.nr_segment);
353 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@<"));
355 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@["));
356 add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@>"));
357 for (i = segment; i < cs.nr_segment; i++)
359 context->candidate_numbers[i] = 0;
360 if (i == segment + 1)
361 add_action (actions, msymbol ("mark"), Msymbol, msymbol ("@anthy"));
362 action = make_candidate_list (context, i);
363 mplist_add (actions, Mplist, action);
364 m17n_object_unref (action);
366 if (segment + 1 < cs.nr_segment)
367 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@anthy"));
372 commit (MPlist *args)
374 MInputContext *ic = mplist_value (args);
375 AnthyContext *context = get_context (ic);
376 struct anthy_conv_stat cs;
381 anthy_get_stat (context->ac, &cs);
382 for (i = 0; i < cs.nr_segment; i++)
383 anthy_commit_segment (context->ac, i, context->candidate_numbers[i]);
387 #else /* not HAVE_ANTHY */
389 MPlist *convert (MPlist *args) { return NULL; }
390 MPlist *change (MPlist *args) { return NULL; }
391 MPlist *resize (MPlist *args) { return NULL; }
392 MPlist *commit (MPlist *args) { return NULL; }
394 #endif /* not HAVE_ANTHY */
395 #endif /* not FOR_DOXYGEN */