1 /* mimx-anthy.c -- Input method external module for Anthy.
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 @page 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
72 #include <anthy/anthy.h>
74 static int initialized;
75 static MSymbol Manthy, Msegment;
77 /* A structure to record in MInputContext->plist with key Manthy. */
81 /* Which candidate is selected in each segment. */
82 int *candidate_numbers;
83 /* Size of the above array. */
85 /* Converter for this context. */
86 MConverter *converter;
90 new_context (MInputContext *ic)
92 AnthyContext *context = NULL;
93 MSymbol euc_jp = msymbol ("euc-jp");
94 /* Rebound to an actual buffer just before being used. */
95 MConverter *converter = mconv_buffer_converter (euc_jp, NULL, 0);
99 context = calloc (1, sizeof (AnthyContext));
100 context->ac = anthy_create_context ();
101 context->num_segments = 0;
102 context->candidate_numbers = NULL;
103 context->converter = converter;
109 free_context (AnthyContext *context)
111 anthy_release_context (context->ac);
112 if (context->candidate_numbers)
113 free (context->candidate_numbers);
114 mconv_free_converter (context->converter);
119 allocate_candidate_numbers (AnthyContext *context, int num)
121 if (context->num_segments < num)
123 if (context->num_segments == 0)
124 context->candidate_numbers = malloc (sizeof (int) * num);
126 context->candidate_numbers = realloc (context->candidate_numbers,
128 context->num_segments = num;
133 add_action (MPlist *actions, MSymbol name, MSymbol key, void *val)
135 MPlist *action = mplist ();
137 mplist_add (action, Msymbol, name);
138 mplist_add (action, key, val);
139 mplist_add (actions, Mplist, action);
140 m17n_object_unref (action);
143 /* Return a list of all candidates of the Nth segment. The return
144 value is a plist whose elements are plists who contains at most 5
148 make_candidate_list (AnthyContext *context, int n)
150 MPlist *plist = mplist (), *pl;
153 struct anthy_segment_stat ss;
156 anthy_get_segment_stat (context->ac, n, &ss);
157 for (i = 0, pl = mplist (); i < ss.nr_candidate; i++)
159 anthy_get_segment (context->ac, n, i, buf, sizeof (buf));
160 mconv_rebind_buffer (context->converter,
161 (unsigned char *) buf, strlen (buf));
162 mt = mconv_decode (context->converter, mtext ());
163 mtext_put_prop (mt, 0, mtext_len (mt), Msegment, (void *) (n + 1));
164 mplist_add (pl, Mtext, mt);
165 m17n_object_unref (mt);
168 mplist_add (plist, Mplist, pl);
169 m17n_object_unref (pl);
173 if (mplist_key (pl) != Mnil)
174 mplist_add (plist, Mplist, pl);
175 m17n_object_unref (pl);
182 MInputContext *ic = mplist_value (args);
187 Manthy = msymbol (" anthy");
188 Msegment = msymbol (" segment");
191 mplist_push (ic->plist, Manthy, new_context (ic));
198 MInputContext *ic = mplist_value (args);
199 AnthyContext *context = mplist_get (ic->plist, Manthy);
202 free_context (context);
207 convert (MPlist *args)
209 MInputContext *ic = mplist_value (args);
210 AnthyContext *context = mplist_get (ic->plist, Manthy);
211 struct anthy_conv_stat cs;
212 MPlist *action, *actions;
214 unsigned char buf[1024];
219 mconv_rebind_buffer (context->converter, buf, sizeof (buf));
220 mconv_encode (context->converter, ic->preedit);
221 buf[context->converter->nbytes] = '\0';
222 anthy_set_string (context->ac, (char *) buf);
223 anthy_get_stat (context->ac, &cs);
224 allocate_candidate_numbers (context, cs.nr_segment);
227 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@<"));
228 add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@>"));
229 for (i = 0; i < cs.nr_segment; i++)
231 context->candidate_numbers[i] = 0;
233 add_action (actions, msymbol ("mark"), Msymbol, msymbol ("@anthy"));
234 action = make_candidate_list (context, i);
235 mplist_add (actions, Mplist, action);
236 m17n_object_unref (action);
238 if (cs.nr_segment > 1)
239 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@anthy"));
245 change (MPlist *args)
247 MInputContext *ic = mplist_value (args);
248 AnthyContext *context = mplist_get (ic->plist, Manthy);
253 if (! ic->candidate_list || ic->cursor_pos == 0)
255 segment = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1, Msegment);
259 context->candidate_numbers[segment] = ic->candidate_index;
264 resize (MPlist *args)
266 MInputContext *ic = mplist_value (args);
267 AnthyContext *context = mplist_get (ic->plist, Manthy);
268 struct anthy_conv_stat cs;
271 MPlist *actions, *action;
276 if (! ic->candidate_list || ic->cursor_pos == 0)
278 segment = (int) mtext_get_prop (ic->preedit, ic->cursor_pos - 1, Msegment);
282 args = mplist_next (args);
283 shorten = mplist_value (args);
284 anthy_resize_segment (context->ac, segment, shorten == Mt ? -1 : 1);
285 anthy_get_stat (context->ac, &cs);
286 allocate_candidate_numbers (context, cs.nr_segment);
290 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@<"));
292 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@["));
293 add_action (actions, msymbol ("delete"), Msymbol, msymbol ("@>"));
294 for (i = segment; i < cs.nr_segment; i++)
296 context->candidate_numbers[i] = 0;
297 if (i == segment + 1)
298 add_action (actions, msymbol ("mark"), Msymbol, msymbol ("@anthy"));
299 action = make_candidate_list (context, i);
300 mplist_add (actions, Mplist, action);
301 m17n_object_unref (action);
303 if (segment + 1 < cs.nr_segment)
304 add_action (actions, msymbol ("move"), Msymbol, msymbol ("@anthy"));
309 commit (MPlist *args)
311 MInputContext *ic = mplist_value (args);
312 AnthyContext *context = mplist_get (ic->plist, Manthy);
313 struct anthy_conv_stat cs;
316 anthy_get_stat (context->ac, &cs);
317 for (i = 0; i < cs.nr_segment; i++)
318 anthy_commit_segment (context->ac, i, context->candidate_numbers[i]);
322 #else /* not HAVE_ANTHY */
324 MPlist *convert (MPlist *args) { return NULL; }
325 MPlist *change (MPlist *args) { return NULL; }
326 MPlist *resize (MPlist *args) { return NULL; }
327 MPlist *commit (MPlist *args) { return NULL; }
329 #endif /* not HAVE_ANTHY */
330 #endif /* not FOR_DOXYGEN */