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., 51 Franklin Street, Fifth Floor,
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 »²¾È
109 #include <anthy/anthy.h>
111 static int initialized;
112 static MSymbol Manthy, Msegment;
114 /* A structure to record in MInputContext->plist with key Manthy. */
119 /* Which candidate is selected in each segment. */
120 int *candidate_numbers;
121 /* Size of the above array. */
123 /* Converter for this context. */
124 MConverter *converter;
127 static AnthyContext *
128 new_context (MInputContext *ic)
130 AnthyContext *context;
132 MSymbol euc_jp = msymbol ("euc-jp");
133 /* Rebound to an actual buffer just before being used. */
134 MConverter *converter = mconv_buffer_converter (euc_jp, NULL, 0);
138 ac = anthy_create_context ();
141 context = calloc (1, sizeof (AnthyContext));
144 context->num_segments = 0;
145 context->candidate_numbers = NULL;
146 context->converter = converter;
150 static AnthyContext *
151 get_context (MInputContext *ic)
153 MPlist *plist = ic->plist;
154 AnthyContext *context;
156 for (; plist && mplist_key (plist) != Mnil; plist = mplist_next (plist))
158 if (mplist_key (plist) != Manthy)
160 context = mplist_value (plist);
161 if (context->ic == ic)
169 free_context (AnthyContext *context)
171 anthy_release_context (context->ac);
172 if (context->candidate_numbers)
173 free (context->candidate_numbers);
174 mconv_free_converter (context->converter);
179 allocate_candidate_numbers (AnthyContext *context, int num)
181 if (context->num_segments < num)
183 if (context->num_segments == 0)
184 context->candidate_numbers = malloc (sizeof (int) * num);
186 context->candidate_numbers = realloc (context->candidate_numbers,
188 context->num_segments = num;
193 add_action (MPlist *actions, MSymbol name, MSymbol key, void *val)
195 MPlist *action = mplist ();
197 mplist_add (action, Msymbol, name);
198 mplist_add (action, key, val);
199 mplist_add (actions, Mplist, action);
200 m17n_object_unref (action);
203 /* Return a list of all candidates of the Nth segment. The return
204 value is a plist whose elements are plists who contains at most 5
208 make_candidate_list (AnthyContext *context, int n)
210 MPlist *plist = mplist (), *pl;
213 struct anthy_segment_stat ss;
216 anthy_get_segment_stat (context->ac, n, &ss);
217 for (i = 0, pl = mplist (); i < ss.nr_candidate; i++)
219 anthy_get_segment (context->ac, n, i, buf, sizeof (buf));
220 mconv_rebind_buffer (context->converter,
221 (unsigned char *) buf, strlen (buf));
222 mt = mconv_decode (context->converter, mtext ());
223 mtext_put_prop (mt, 0, mtext_len (mt), Msegment, (void *) (n + 1));
224 mplist_add (pl, Mtext, mt);
225 m17n_object_unref (mt);
228 mplist_add (plist, Mplist, pl);
229 m17n_object_unref (pl);
233 if (mplist_key (pl) != Mnil)
234 mplist_add (plist, Mplist, pl);
235 m17n_object_unref (pl);
242 MInputContext *ic = mplist_value (args);
243 AnthyContext *context;
248 Manthy = msymbol (" anthy");
249 Msegment = msymbol (" segment");
251 context = new_context (ic);
253 mplist_push (ic->plist, Manthy, context);
260 MInputContext *ic = mplist_value (args);
261 AnthyContext *context = get_context (ic);
264 free_context (context);
269 convert (MPlist *args)
271 MInputContext *ic = mplist_value (args);
272 AnthyContext *context = get_context (ic);
273 struct anthy_conv_stat cs;
274 MPlist *action, *actions;
276 unsigned char buf[1024];
281 mconv_rebind_buffer (context->converter, buf, sizeof (buf));
282 mconv_encode (context->converter, ic->preedit);
283 buf[context->converter->nbytes] = '\0';
284 anthy_set_string (context->ac, (char *) buf);
285 anthy_get_stat (context->ac, &cs);
286 allocate_candidate_numbers (context, cs.nr_segment);
289 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@<"));
290 add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@>"));
291 for (i = 0; i < cs.nr_segment; i++)
293 context->candidate_numbers[i] = 0;
295 add_action (actions, msymbol ("mark"), Msymbol, msymbol ("@anthy"));
296 action = make_candidate_list (context, i);
297 mplist_add (actions, Mplist, action);
298 m17n_object_unref (action);
300 if (cs.nr_segment > 1)
301 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@anthy"));
307 change (MPlist *args)
309 MInputContext *ic = mplist_value (args);
310 AnthyContext *context = get_context (ic);
315 if (! ic->candidate_list || ic->cursor_pos == 0)
317 segment = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1, Msegment);
321 context->candidate_numbers[segment] = ic->candidate_index;
326 resize (MPlist *args)
328 MInputContext *ic = mplist_value (args);
329 AnthyContext *context = get_context (ic);
330 struct anthy_conv_stat cs;
333 MPlist *actions, *action;
338 if (! ic->candidate_list || ic->cursor_pos == 0)
340 segment = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1, Msegment);
344 args = mplist_next (args);
345 shorten = mplist_value (args);
346 anthy_resize_segment (context->ac, segment, shorten == Mt ? -1 : 1);
347 anthy_get_stat (context->ac, &cs);
348 allocate_candidate_numbers (context, cs.nr_segment);
352 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@<"));
354 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@["));
355 add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@>"));
356 for (i = segment; i < cs.nr_segment; i++)
358 context->candidate_numbers[i] = 0;
359 if (i == segment + 1)
360 add_action (actions, msymbol ("mark"), Msymbol, msymbol ("@anthy"));
361 action = make_candidate_list (context, i);
362 mplist_add (actions, Mplist, action);
363 m17n_object_unref (action);
365 if (segment + 1 < cs.nr_segment)
366 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@anthy"));
371 commit (MPlist *args)
373 MInputContext *ic = mplist_value (args);
374 AnthyContext *context = get_context (ic);
375 struct anthy_conv_stat cs;
380 anthy_get_stat (context->ac, &cs);
381 for (i = 0; i < cs.nr_segment; i++)
382 anthy_commit_segment (context->ac, i, context->candidate_numbers[i]);
386 #else /* not HAVE_ANTHY */
388 MPlist *convert (MPlist *args) { return NULL; }
389 MPlist *change (MPlist *args) { return NULL; }
390 MPlist *resize (MPlist *args) { return NULL; }
391 MPlist *commit (MPlist *args) { return NULL; }
393 #endif /* not HAVE_ANTHY */
394 #endif /* not FOR_DOXYGEN */