Update license in the spec file
[platform/core/uifw/anthy.git] / src-util / input.c
1 /*
2  * Anthy¤Î¥­¡¼¤Î¼õ¤±ÉÕ¤±¤ä¥×¥ê¥¨¥Ç¥£¥Ã¥È¤ÎÀ©¸æ¤ò¹Ô¤¦¥ì¥¤¥ä¡¼
3  *
4  * º£¤«¤é¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò½ñ¤¯¾ì¹ç¤Ë¤Ïuim¤ÎÍøÍѤò¤ªÁ¦¤á¤·¤Þ¤¹¡£
5  *
6  * Funded by IPA̤Ƨ¥½¥Õ¥È¥¦¥§¥¢ÁϤ»ö¶È 2002 1/23
7  * Copyright (C) 2001-2002 UGAWA Tomoharu
8  *
9  * $Id: input.c,v 1.25 2002/11/16 03:35:21 yusuke Exp $
10  *
11  */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <ctype.h>
16 #include <sys/time.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <string.h>
20 #include <assert.h>
21
22 #include <anthy/anthy.h>
23 #include <anthy/input.h>
24
25 #include "rkconv.h"
26 #include "rkhelper.h"
27
28 struct anthy_input_context {
29   /* ANTHY_INPUT_ST_* */
30   int state;
31
32   /* always allocated */
33   struct rk_conv_context* rkctx;
34   int map_no;  /* RKMAP_* */
35   /* ÊÑ´¹¤¹¤ëʸ»úÎó¤Î¥Ð¥Ã¥Õ¥¡*/
36   char* hbuf;
37   int n_hbuf;
38   int s_hbuf;
39   char* hbuf_follow;
40   int n_hbuf_follow;
41   int s_hbuf_follow;
42
43   /* allocated only in conv state */
44   anthy_context_t actx;
45   struct a_segment* segment;
46   struct a_segment* cur_segment;
47   int enum_cand_count;
48   int enum_cand_limit;
49   int enum_reverse;
50   int last_gotten_cand;
51
52   /* always allocated by the library */
53   /* ¥³¥ß¥Ã¥È¥Ð¥Ã¥Õ¥¡ */
54   char* commit;
55   int n_commit;
56   int s_commit;
57
58   /* always allocated by the library */
59   /* ¥«¥Ã¥È¥Ð¥Ã¥Õ¥¡ */
60   char* cut;
61   int n_cut;
62   int s_cut;
63
64   struct anthy_input_config* cfg;
65   struct anthy_input_context* next_cfg_owner;
66 };
67
68 int anthy_input_errno;
69
70 #define DEFAULT_ENUM_CAND_LIMIT 3
71
72 #define MAX(a,b) ((a) > (b) ? (a) : (b))
73
74 #define is_eucchar(s)  (((s)[0] & 0x80) && ((s)[1] & 0x80))
75
76
77 struct anthy_input_config {
78   struct rk_option* rk_option;
79   /* 6¤Ïsrc-util/rkhelper.h ¤Î NR_RKMAP¤ËÁêÅö */
80   struct rk_map*   rk_map[6];
81   struct anthy_input_context* owners;
82   /**/
83   int break_into_roman;
84   int preedit_mode;
85 };
86
87 struct a_segment {
88   int index;
89   int pos;
90   struct anthy_segment_stat ass;
91   int cand;
92   struct a_segment* next, * prev;
93 };
94
95 static int
96 ensure_buffer(char** buf, int* size, int to_size)
97 {
98   if (*size < to_size) {
99     *buf = (char*) realloc(*buf, to_size);
100     if (*buf == NULL) {
101       anthy_input_errno = AIE_NOMEM;
102       return -1;
103     }
104     *size = to_size;
105   }
106   return 0;
107 }
108
109 static void
110 leave_edit_state(struct anthy_input_context* ictx)
111 {
112   /* do noting */
113   (void) ictx;
114 }
115
116
117 static void
118 enter_none_state(struct anthy_input_context* ictx)
119 {
120   ictx->state = ANTHY_INPUT_ST_NONE;
121 }
122
123 static void
124 enter_edit_state(struct anthy_input_context* ictx)
125 {
126   ictx->state = ANTHY_INPUT_ST_EDIT;
127   rk_flush(ictx->rkctx);
128   rk_select_registered_map(ictx->rkctx, ictx->map_no);
129   ictx->n_hbuf = 0;
130   ictx->n_hbuf_follow = 0;
131 }
132
133 static void
134 enter_edit_state_noinit(struct anthy_input_context* ictx)
135 {
136   ictx->state = ANTHY_INPUT_ST_EDIT;
137 }
138
139 static void
140 leave_conv_state(struct anthy_input_context* ictx)
141 {
142   struct a_segment* as, * next;
143   anthy_release_context(ictx->actx);
144   for (as = ictx->segment; as; as = next) {
145     next = as->next;
146     free(as);
147   }
148   anthy_reset_context(ictx->actx);
149 }
150
151 static void
152 reset_anthy_input_context(struct anthy_input_context* ictx)
153 {
154   switch (ictx->state) {
155   case ANTHY_INPUT_ST_NONE:
156     break;
157   case ANTHY_INPUT_ST_EDIT:
158     leave_edit_state(ictx);
159     break;
160   case ANTHY_INPUT_ST_CONV:
161     leave_conv_state(ictx);
162     break;
163   }
164   enter_none_state(ictx);
165 }
166
167 static void
168 read_rk_result(struct anthy_input_context* ictx)
169 {
170   int ret;
171
172   ret = rk_result(ictx->rkctx, ictx->hbuf + ictx->n_hbuf,
173                   ictx->s_hbuf - ictx->n_hbuf);
174   if (ret > 0) {
175     if (ictx->s_hbuf - ictx->n_hbuf > 0)
176       ictx->n_hbuf = ictx->s_hbuf - 1;
177     
178     ensure_buffer(&ictx->hbuf, &ictx->s_hbuf, ictx->n_hbuf + ret + 1);
179     
180     rk_result(ictx->rkctx, ictx->hbuf + ictx->n_hbuf, 
181               ictx->s_hbuf - ictx->n_hbuf);
182   }
183   if (ictx->hbuf)
184     ictx->n_hbuf += strlen(ictx->hbuf + ictx->n_hbuf);
185 }
186
187 static void
188 terminate_rk(struct anthy_input_context* ictx)
189 {
190   rk_terminate(ictx->rkctx);
191   read_rk_result(ictx);
192   rk_flush(ictx->rkctx);
193 }
194
195 static void
196 join_noconv_string(struct anthy_input_context* ictx)
197 {
198   if (ictx->n_hbuf_follow > 0) {
199     ensure_buffer(&ictx->hbuf, &ictx->s_hbuf, 
200                   ictx->n_hbuf + ictx->n_hbuf_follow);
201     memcpy(ictx->hbuf + ictx->n_hbuf, ictx->hbuf_follow, ictx->n_hbuf_follow);
202     ictx->n_hbuf += ictx->n_hbuf_follow;
203     ictx->n_hbuf_follow = 0;
204   }
205 }
206
207 static void
208 enter_conv_state(struct anthy_input_context* ictx)
209 {
210   int ret;
211   struct anthy_conv_stat acs;
212   struct a_segment* as_tail, ** as_tailp;
213   int i;
214   int last_pos;
215
216   ictx->state = ANTHY_INPUT_ST_CONV;
217
218   terminate_rk(ictx);
219
220   join_noconv_string(ictx);
221
222   if (ictx->n_hbuf == 0) {
223     ensure_buffer(&ictx->commit, &ictx->s_commit, ictx->n_commit + 1);
224     ictx->commit[ictx->n_commit++] = ' ';
225     enter_none_state(ictx);
226     return;
227   }
228
229   ensure_buffer(&ictx->hbuf, &ictx->s_hbuf, ictx->n_hbuf + 1);
230   ictx->hbuf[ictx->n_hbuf] = '\0';
231
232   ictx->enum_cand_count = 0;
233   ictx->actx = anthy_create_context();
234   anthy_context_set_encoding(ictx->actx, ANTHY_EUC_JP_ENCODING);
235   if (!ictx->actx) {
236     enter_none_state(ictx);
237     anthy_input_errno = AIE_NOMEM;
238     return;
239   }
240   anthy_reset_context(ictx->actx);
241   ret = anthy_set_string(ictx->actx, ictx->hbuf);
242   if (ret < 0) {
243     anthy_release_context(ictx->actx);
244     enter_none_state(ictx);
245     return;
246   }
247
248   anthy_get_stat(ictx->actx, &acs);
249   as_tail = NULL;
250   as_tailp = &ictx->segment;
251   last_pos = 0;
252   for (i = 0; i < acs.nr_segment; i++) {
253     struct a_segment* as;
254     as = (struct a_segment*) malloc(sizeof(struct a_segment));
255     as->index = i;
256     as->pos = last_pos;
257     anthy_get_segment_stat(ictx->actx, i, &as->ass);
258     last_pos += as->ass.seg_len;
259     as->cand = 0;
260     as->prev = as_tail;
261     *as_tailp = as;
262     as->next = NULL;
263     as_tailp = &as->next;
264     as_tail = as;
265   }
266   ictx->cur_segment = ictx->segment;
267   ictx->last_gotten_cand = 0;
268 }
269
270 static void
271 enter_conv_state_noinit(struct anthy_input_context* ictx)
272 {
273   ictx->state = ANTHY_INPUT_ST_CONV;
274 }
275
276 static void
277 enter_cseg_state(struct anthy_input_context* ictx)
278 {
279   ictx->state = ANTHY_INPUT_ST_CSEG;
280   ictx->enum_cand_count = 0;
281 }
282
283 static void
284 leave_cseg_state(struct anthy_input_context* ictx)
285 {
286   /* do nothing */
287   (void)ictx;
288 }
289
290 static int
291 cmdh_map_select(struct anthy_input_context* ictx, int map)
292 {
293   switch (map) {
294   case ANTHY_INPUT_MAP_ALPHABET:
295     ictx->map_no = RKMAP_ASCII;
296     break;
297   case ANTHY_INPUT_MAP_WALPHABET:
298     ictx->map_no = RKMAP_WASCII;
299     break;
300   case ANTHY_INPUT_MAP_HIRAGANA:
301     ictx->map_no = RKMAP_HIRAGANA;
302     break;
303   case ANTHY_INPUT_MAP_KATAKANA:
304     ictx->map_no = RKMAP_KATAKANA;
305     break;
306   case ANTHY_INPUT_MAP_HANKAKU_KANA:
307     ictx->map_no = RKMAP_HANKAKU_KANA;
308     break;
309   default:
310     anthy_input_errno = AIE_INVAL;
311     return -1;
312   }
313
314   rk_select_registered_map(ictx->rkctx, ictx->map_no);
315
316   return 0;
317 }
318
319 static struct anthy_input_segment* 
320 cmdh_get_candidate(struct anthy_input_context* ictx, int cand_no)
321 {
322   struct a_segment* cs;
323   struct anthy_input_segment* seg;
324   int len;
325
326   cs = ictx->cur_segment;
327   if (cand_no >= cs->ass.nr_candidate) {
328     anthy_input_errno = AIE_INVAL;
329     return NULL;
330   }
331   ictx->last_gotten_cand = cand_no;
332
333   seg = (struct anthy_input_segment*) 
334     malloc(sizeof(struct anthy_input_segment));
335   len = anthy_get_segment(ictx->actx, cs->index, cand_no, NULL, 0);
336   seg->str = (char*) malloc(len + 1);
337   anthy_get_segment(ictx->actx, cs->index, cand_no, seg->str, len + 1);
338   seg->cand_no = cand_no;
339   seg->noconv_len = anthy_get_segment(ictx->actx, cs->index, 
340                                       NTH_UNCONVERTED_CANDIDATE, NULL, 0);
341   seg->nr_cand = cs->ass.nr_candidate;
342   seg->flag = ANTHY_INPUT_SF_CURSOR;
343   if (ictx->enum_cand_count >= ictx->enum_cand_limit)
344           seg->flag |= (ictx->enum_reverse ?
345                         ANTHY_INPUT_SF_ENUM_REVERSE : ANTHY_INPUT_SF_ENUM);
346
347   return seg;
348 }
349
350 static void
351 do_cmd_commit(struct anthy_input_context* ictx)
352 {
353   struct a_segment* as;
354
355   for (as = ictx->segment; as; as = as->next) {
356     int len;
357     
358     len = anthy_get_segment(ictx->actx, as->index, as->cand, NULL, 0);
359     ensure_buffer(&ictx->commit, &ictx->s_commit, ictx->n_commit + len + 1);
360     anthy_get_segment(ictx->actx, as->index, as->cand, 
361                       ictx->commit + ictx->n_commit, len + 1);
362     ictx->n_commit += len;
363     anthy_commit_segment(ictx->actx, as->index, as->cand);
364   }
365 }
366
367 static int
368 cmdh_select_candidate(struct anthy_input_context* ictx, 
369                       int cand_no)
370 {
371   struct a_segment* cs;
372
373   cs = ictx->cur_segment;
374   if (cand_no >= cs->ass.nr_candidate) {
375     anthy_input_errno = AIE_INVAL;
376     return -1;
377   }
378   cs->cand = cand_no;
379   
380   if (cs->next) {
381     ictx->cur_segment = cs->next;
382     ictx->last_gotten_cand = ictx->cur_segment->cand;
383     ictx->enum_cand_count = 0;
384   } else {
385     ictx->last_gotten_cand = ictx->cur_segment->cand;
386     ictx->enum_cand_count = 0;
387   }
388
389   return 0;
390 }
391
392 static void
393 do_cmd_push_key(struct anthy_input_context* ictx, const char* str)
394 {
395   const char* p;
396
397   for (p = str; *p; p++) {
398     if (isspace((int)(unsigned char) *p) && *p != ' ')
399       continue;
400
401     rk_push_key(ictx->rkctx, *p);
402     read_rk_result(ictx);
403   }
404 }
405
406 static void
407 cmd_push_key(struct anthy_input_context* ictx, const char* str)
408 {
409   do_cmd_push_key(ictx, str);
410 }
411
412 static void
413 cmd_move_cursor(struct anthy_input_context* ictx, int d)
414 {
415   if (rk_get_pending_str(ictx->rkctx, NULL, 0) > 1) {
416     rk_flush(ictx->rkctx);
417     return;
418   }
419
420   if (d > 0) {
421     char* p;
422     int len;
423     if (ictx->n_hbuf_follow == 0)
424       return;
425     for (p = ictx->hbuf_follow; 
426          p < ictx->hbuf_follow + ictx->n_hbuf_follow && d > 0; p++, d--) {
427       if (p < ictx->hbuf_follow + ictx->n_hbuf_follow - 1 && is_eucchar(p))
428         p++;
429     }
430     len = p - ictx->hbuf_follow;
431     ensure_buffer(&ictx->hbuf, &ictx->s_hbuf, ictx->n_hbuf + len);
432     memcpy(ictx->hbuf + ictx->n_hbuf, ictx->hbuf_follow, len);
433     ictx->n_hbuf += len;
434     ictx->n_hbuf_follow -= len;
435     memmove(ictx->hbuf_follow, p, ictx->n_hbuf_follow);
436   } else {
437     char* p;
438     int len;
439     if (ictx->n_hbuf == 0)
440       return;
441     for (p = ictx->hbuf + ictx->n_hbuf; 
442          p > ictx->hbuf && d < 0; p--, d++) {
443       if (p - 1 > ictx->hbuf && is_eucchar(p - 2))
444         p--;
445     }
446     len = (ictx->hbuf + ictx->n_hbuf) - p;
447     ensure_buffer(&ictx->hbuf_follow, &ictx->s_hbuf_follow, 
448                   ictx->n_hbuf_follow + len);
449     if (ictx->n_hbuf_follow > 0)
450       memmove(ictx->hbuf_follow + len, ictx->hbuf_follow, ictx->n_hbuf_follow);
451     memcpy(ictx->hbuf_follow, p, len);
452     ictx->n_hbuf_follow += len;
453     ictx->n_hbuf -= len;
454   }
455 }
456
457 static void
458 cmd_backspace(struct anthy_input_context* ictx)
459 {
460   int len;
461
462   len = rk_get_pending_str(ictx->rkctx, NULL, 0);
463   if (len > 1) {
464     char* buf;
465     /* ³ÎÄꤵ¤ì¤Æ¤¤¤Ê¤¤¥í¡¼¥Þ»ú¤¬¤¢¤ë¤Î¤Ç¡¢ºÇ¸å¤Îʸ»ú¤ò¥«¥Ã¥È */
466     len--;
467
468     buf = (char*) malloc(len);
469     rk_get_pending_str(ictx->rkctx, buf, len);
470     rk_flush(ictx->rkctx);
471     do_cmd_push_key(ictx, buf);    
472     free(buf);
473   } else {
474     if (brk_roman_get_previous_pending(ictx->rkctx)) {
475       char *buf;
476       buf = strdup(brk_roman_get_previous_pending(ictx->rkctx));
477       ictx->n_hbuf -= brk_roman_get_decided_len(ictx->rkctx);
478
479       rk_flush(ictx->rkctx);
480       do_cmd_push_key(ictx,buf);
481       free(buf);
482     } else {
483       if (ictx->n_hbuf >= 2 && is_eucchar(ictx->hbuf + ictx->n_hbuf - 2)) {
484         ictx->n_hbuf -= 2;
485       } else if (ictx->n_hbuf >= 1) {
486         ictx->n_hbuf--;
487       }
488     }
489   }
490
491   if (ictx->n_hbuf + ictx->n_hbuf_follow <= 0 && len <= 1) {
492     leave_edit_state(ictx);
493     enter_none_state(ictx);
494   }
495 }
496
497 static void
498 cmd_delete(struct anthy_input_context* ictx)
499 {
500   int len;
501
502   if (rk_get_pending_str(ictx->rkctx, NULL, 0) > 1)
503     return;
504   if (ictx->n_hbuf_follow <= 0)
505     return;
506
507   len = ictx->n_hbuf_follow >= 2 && is_eucchar(ictx->hbuf_follow) ? 2 : 1;
508
509   if (ictx->n_hbuf_follow <= len)
510     ictx->n_hbuf_follow = 0;
511   else {
512     ictx->n_hbuf_follow -= len;
513     memmove(ictx->hbuf_follow, ictx->hbuf_follow + len, ictx->n_hbuf_follow);
514   }
515
516   if (ictx->n_hbuf + ictx->n_hbuf_follow <= 0) {
517     leave_edit_state(ictx);
518     enter_none_state(ictx);
519   }
520 }
521
522 static void
523 cmd_commit_unconv(struct anthy_input_context* ictx)
524 {
525   ensure_buffer(&ictx->commit, &ictx->s_commit, 
526                 ictx->n_commit + ictx->n_hbuf + ictx->n_hbuf_follow);
527   memcpy(ictx->commit + ictx->n_commit, ictx->hbuf, ictx->n_hbuf);
528   ictx->n_commit += ictx->n_hbuf;
529   if (ictx->n_hbuf_follow > 0)
530     memcpy(ictx->commit + ictx->n_commit, 
531            ictx->hbuf_follow, ictx->n_hbuf_follow);
532   ictx->n_commit += ictx->n_hbuf_follow;
533 }
534
535 static void
536 cmd_resize(struct anthy_input_context* ictx, int d)
537 {
538   int i;
539   struct anthy_conv_stat acs;
540   struct a_segment* as;
541   int last_pos;
542
543   anthy_resize_segment(ictx->actx, ictx->cur_segment->index, d);
544   anthy_get_stat(ictx->actx, &acs);
545
546   anthy_get_segment_stat(ictx->actx, 
547                          ictx->cur_segment->index, &ictx->cur_segment->ass);
548   ictx->cur_segment->cand = NTH_UNCONVERTED_CANDIDATE;
549   last_pos = ictx->cur_segment->ass.seg_len;
550   for (as = ictx->cur_segment, i = as->index + 1; i < acs.nr_segment; i++) {
551     if (as->next == NULL) {
552       struct a_segment* as2;
553       
554       as2 = (struct a_segment*) malloc(sizeof(struct a_segment));
555       as2->index = i;
556       as2->prev = as;
557       as->next = as2;
558       as2->next = NULL;
559       as = as2;
560     } else 
561       as = as->next;
562     as->pos = last_pos;
563     anthy_get_segment_stat(ictx->actx, i, &as->ass);
564     last_pos += as->ass.seg_len;
565     as->cand = NTH_UNCONVERTED_CANDIDATE;
566   }
567   ictx->last_gotten_cand = NTH_UNCONVERTED_CANDIDATE;
568
569   as = as->next;            /* ÉÔÀµ¤Ê¥á¥â¥ê¥¢¥¯¥»¥¹¤Î½¤Àµ */
570   if (as) {
571     as->prev->next = NULL;
572     for (; as; ) {
573       struct a_segment* const next = as->next;
574       free(as);
575       as = next;
576     }
577   }
578 }
579
580 static void
581 commit_noconv_string(struct anthy_input_context* ictx)
582 {
583   join_noconv_string(ictx);
584   ensure_buffer(&ictx->commit, &ictx->s_commit, 
585                 ictx->n_commit + ictx->n_hbuf + 1);
586         /* +1 is just for an optimization */
587   memcpy(ictx->commit + ictx->n_commit, 
588          ictx->hbuf, ictx->n_hbuf);
589   ictx->n_commit += ictx->n_hbuf;
590   ictx->n_hbuf = 0;
591 }
592
593 static void
594 cmd_commit(struct anthy_input_context* ictx)
595 {
596   do_cmd_commit(ictx);
597 }
598
599 static void
600 cmd_next_candidate(struct anthy_input_context* ictx)
601 {
602   struct a_segment* as;
603
604   ictx->enum_cand_count++;
605
606   as = ictx->cur_segment;
607
608   if (!ictx->enum_reverse)
609     as->cand = ictx->last_gotten_cand;
610   else
611     ictx->enum_reverse = 0;
612
613   if (as->cand == NTH_UNCONVERTED_CANDIDATE) {
614     while (as) {
615       if (as->cand == NTH_UNCONVERTED_CANDIDATE) {
616         as->cand = 0;
617       }
618       as = as->next;
619     }
620     ictx->last_gotten_cand = 0;
621   } else {
622     if (++as->cand >= as->ass.nr_candidate)
623       as->cand = 0;
624     ictx->last_gotten_cand = as->cand;
625   }
626 }
627
628 static void
629 cmd_prev_candidate(struct anthy_input_context* ictx)
630 {
631   struct a_segment* as;
632
633   ictx->enum_cand_count++;
634
635   as = ictx->cur_segment;
636
637   if (ictx->enum_reverse)
638     as->cand = ictx->last_gotten_cand;
639   else
640     ictx->enum_reverse = 1;
641
642   if (as->cand == NTH_UNCONVERTED_CANDIDATE) {
643     while (as) {
644       if (as->cand == NTH_UNCONVERTED_CANDIDATE) {
645         as->cand = 0;
646       }
647       as = as->next;
648     }
649     ictx->last_gotten_cand = 0;
650   } else {
651     if (--as->cand < 0) 
652       as->cand = as->ass.nr_candidate - 1;
653     ictx->last_gotten_cand = as->cand;
654   }
655 }
656
657 static void
658 cmd_move_selection(struct anthy_input_context* ictx, int d)
659 {
660   if (d > 0) 
661     while (d-- > 0 && ictx->cur_segment->next) {
662       ictx->enum_cand_count = 0;
663       ictx->cur_segment = ictx->cur_segment->next;
664       ictx->last_gotten_cand = ictx->cur_segment->cand;
665     }
666   else
667     while (d++ < 0 && ictx->cur_segment->prev) {
668       ictx->enum_cand_count = 0;
669       ictx->cur_segment = ictx->cur_segment->prev;
670       ictx->last_gotten_cand = ictx->cur_segment->cand;
671     }
672 }
673
674 static void
675 cmd_move_to_bol_seg(struct anthy_input_context* ictx)
676 {
677   ictx->cur_segment = ictx->segment;
678   ictx->enum_cand_count = 0;  
679   ictx->last_gotten_cand = ictx->cur_segment->cand;
680 }
681
682 static void
683 cmd_move_to_eol_seg(struct anthy_input_context* ictx)
684 {
685   while (ictx->cur_segment->next)
686     ictx->cur_segment = ictx->cur_segment->next;
687   ictx->enum_cand_count = 0;  
688   ictx->last_gotten_cand = ictx->cur_segment->cand;
689 }
690
691 static void
692 cmd_unhiragana_candidate(struct anthy_input_context* ictx)
693 {
694   struct a_segment* as;
695
696   for (as = ictx->cur_segment->next; as; as = as->next)
697     as->cand = 0;
698 }
699
700 static void
701 cmd_move_to_bol(struct anthy_input_context* ictx)
702 {
703   terminate_rk(ictx);
704
705   if (ictx->hbuf_follow == NULL) { /* ºÇŬ²½ */
706     ictx->hbuf_follow = ictx->hbuf;
707     ictx->n_hbuf_follow = ictx->n_hbuf;
708     ictx->s_hbuf_follow = ictx->s_hbuf;
709     ictx->hbuf = NULL;
710     ictx->n_hbuf = 0;
711     ictx->s_hbuf = 0;
712     return;
713   }
714
715   ensure_buffer(&ictx->hbuf_follow, &ictx->s_hbuf_follow,
716                 ictx->n_hbuf + ictx->n_hbuf_follow);
717   memmove(ictx->hbuf_follow + ictx->n_hbuf, 
718           ictx->hbuf_follow, ictx->n_hbuf_follow);
719   memcpy(ictx->hbuf_follow, ictx->hbuf, ictx->n_hbuf);
720   ictx->n_hbuf_follow += ictx->n_hbuf;
721   ictx->n_hbuf = 0;
722 }
723
724 static void
725 cmd_move_to_eol(struct anthy_input_context* ictx)
726 {
727   terminate_rk(ictx);
728
729   if (ictx->hbuf == NULL) { /* ºÇŬ²½ */
730     ictx->hbuf = ictx->hbuf_follow;
731     ictx->n_hbuf = ictx->n_hbuf_follow;
732     ictx->s_hbuf = ictx->s_hbuf_follow;
733     ictx->hbuf_follow = NULL;
734     ictx->n_hbuf_follow = 0;
735     ictx->s_hbuf_follow = 0;
736     return;
737   }
738
739   ensure_buffer(&ictx->hbuf, &ictx->s_hbuf, 
740                 ictx->n_hbuf + ictx->n_hbuf_follow);
741   memcpy(ictx->hbuf + ictx->n_hbuf, ictx->hbuf_follow, ictx->n_hbuf_follow);
742   ictx->n_hbuf += ictx->n_hbuf_follow;
743   ictx->n_hbuf_follow = 0;
744 }
745
746 static void
747 cmd_cut(struct anthy_input_context* ictx)
748 {
749   char* tmp_str;
750   int   tmp_int;
751
752   terminate_rk(ictx);
753
754   /* ¥Ð¥Ã¥Õ¥¡¤ÎÆþ¤ì´¹¤¨¤ÇºÑ¤Þ¤»¤ë */
755   tmp_str = ictx->cut;
756   tmp_int = ictx->s_cut;
757   ictx->cut = ictx->hbuf_follow;
758   ictx->n_cut = ictx->n_hbuf_follow;
759   ictx->s_cut = ictx->s_hbuf_follow;
760   ictx->hbuf_follow = tmp_str;
761   ictx->n_hbuf_follow = 0;
762   ictx->s_hbuf_follow = tmp_int;
763 }
764                 
765 /*****************************************************************/
766
767 /* pure function */
768 struct anthy_input_context* 
769 anthy_input_create_context(struct anthy_input_config* cfg)
770 {
771   struct anthy_input_context* ictx;
772   int i;
773
774   ictx = 
775     (struct anthy_input_context*) malloc(sizeof(struct anthy_input_context));
776   ictx->state = ANTHY_INPUT_ST_NONE;
777   ictx->rkctx = rk_context_create(cfg->break_into_roman);
778   for (i = 0; i < NR_RKMAP; i++)
779     rk_register_map(ictx->rkctx, i, cfg->rk_map[i]);
780   ictx->map_no = RKMAP_HIRAGANA;
781   rk_select_registered_map(ictx->rkctx, ictx->map_no);
782   ictx->hbuf = NULL;
783   ictx->n_hbuf = 0;
784   ictx->s_hbuf = 0;
785   ictx->hbuf_follow = NULL;
786   ictx->n_hbuf_follow = 0;
787   ictx->s_hbuf_follow = 0;
788   ictx->enum_cand_limit = DEFAULT_ENUM_CAND_LIMIT;
789   ictx->enum_cand_count = 0;
790   ictx->actx = NULL;
791   ictx->segment = NULL;
792   ictx->cur_segment = NULL;
793   ictx->enum_reverse = 0;       /* ½é´ü²½Ëº¤ì¤Î½¤Àµ */
794   ictx->last_gotten_cand = 0;   /* ½é´ü²½Ëº¤ì¤Î½¤Àµ */
795   ictx->commit = NULL;
796   ictx->n_commit = 0;
797   ictx->s_commit = 0;
798   ictx->cut = NULL;
799   ictx->n_cut = 0;
800   ictx->s_cut = 0;
801   ictx->cfg = cfg;
802   ictx->next_cfg_owner = cfg->owners;
803   cfg->owners = ictx;
804   return ictx;
805 }
806
807 void
808 anthy_input_free_context(struct anthy_input_context* ictx)
809 {
810   struct anthy_input_context **p;
811
812   reset_anthy_input_context(ictx);
813   rk_context_free(ictx->rkctx);
814
815   for (p = &ictx->cfg->owners; *p; p = &(*p)->next_cfg_owner)
816     if (*p == ictx) {
817       *p = ictx->next_cfg_owner;
818       break;
819     }
820
821   free(ictx->hbuf);
822   free(ictx->hbuf_follow);
823   free(ictx->commit);
824   free(ictx->cut);
825   free(ictx);
826 }
827
828 void
829 anthy_input_free_preedit(struct anthy_input_preedit* pedit)
830 {
831   struct anthy_input_segment* p, * q;
832
833   free(pedit->commit);
834   free(pedit->cut_buf);
835   for (p = pedit->segment; p; p = q) {
836     q = p->next;
837     anthy_input_free_segment(p);
838   }
839   free(pedit);
840 }
841
842 void
843 anthy_input_free_segment(struct anthy_input_segment* seg)
844 {
845   free(seg->str);
846   free(seg);
847 }
848
849 void
850 anthy_input_str(struct anthy_input_context* ictx, const char* str)
851 {
852   switch (ictx->state) {
853   case ANTHY_INPUT_ST_OFF:
854     break;
855   case ANTHY_INPUT_ST_NONE:
856     enter_edit_state(ictx);
857     cmd_push_key(ictx, str);
858     if (ictx->map_no == RKMAP_ASCII ||
859         ictx->map_no == RKMAP_WASCII) {
860       commit_noconv_string(ictx);
861       leave_edit_state(ictx);
862       enter_none_state(ictx);
863     }
864     break;
865   case ANTHY_INPUT_ST_EDIT:
866     cmd_push_key(ictx, str);
867     break;
868   case ANTHY_INPUT_ST_CONV:
869     cmd_commit(ictx);
870     leave_conv_state(ictx);
871     enter_edit_state(ictx);
872     cmd_push_key(ictx, str);
873     break;
874   case ANTHY_INPUT_ST_CSEG:
875     cmd_commit(ictx);
876     leave_cseg_state(ictx);
877     enter_conv_state_noinit(ictx);
878     leave_conv_state(ictx);
879     enter_edit_state(ictx);
880     cmd_push_key(ictx, str);
881     break;
882   }
883 }
884
885 void
886 anthy_input_next_candidate(struct anthy_input_context* ictx)
887 {
888   switch (ictx->state) {
889   case ANTHY_INPUT_ST_OFF:
890     break;
891   case ANTHY_INPUT_ST_NONE:
892     break;
893   case ANTHY_INPUT_ST_EDIT:
894     enter_conv_state(ictx);
895     break;
896   case ANTHY_INPUT_ST_CONV:
897     cmd_next_candidate(ictx);
898     break;
899   case ANTHY_INPUT_ST_CSEG:
900     cmd_unhiragana_candidate(ictx);
901     leave_cseg_state(ictx);
902     enter_conv_state_noinit(ictx);
903     cmd_next_candidate(ictx);
904     break;
905   }
906 }
907
908
909 void
910 anthy_input_prev_candidate(struct anthy_input_context* ictx)
911 {
912   switch (ictx->state) {
913   case ANTHY_INPUT_ST_OFF:
914     break;
915   case ANTHY_INPUT_ST_NONE:
916     break;
917   case ANTHY_INPUT_ST_EDIT:
918     enter_conv_state(ictx);
919     break;
920   case ANTHY_INPUT_ST_CONV:
921     cmd_prev_candidate(ictx);
922     break;
923   case ANTHY_INPUT_ST_CSEG:
924     leave_cseg_state(ictx);
925     enter_conv_state_noinit(ictx);
926     cmd_prev_candidate(ictx);
927     break;
928   }
929 }
930
931 void
932 anthy_input_quit(struct anthy_input_context* ictx)
933 {
934   switch (ictx->state) {
935   case ANTHY_INPUT_ST_OFF:
936     break;
937   case ANTHY_INPUT_ST_NONE:  
938     break;
939   case ANTHY_INPUT_ST_EDIT:
940     leave_edit_state(ictx);
941     enter_none_state(ictx);
942     break;
943   case ANTHY_INPUT_ST_CONV:
944     leave_conv_state(ictx);
945     enter_edit_state_noinit(ictx);
946     break;
947   case ANTHY_INPUT_ST_CSEG:
948     leave_cseg_state(ictx);
949     enter_conv_state_noinit(ictx);
950     leave_conv_state(ictx);
951     enter_edit_state_noinit(ictx);
952     break;
953   }
954 }
955
956 void
957 anthy_input_erase_prev(struct anthy_input_context* ictx)
958 {
959   switch (ictx->state) {
960   case ANTHY_INPUT_ST_OFF:
961     break;
962   case ANTHY_INPUT_ST_NONE:  
963     break;
964   case ANTHY_INPUT_ST_EDIT:
965     cmd_backspace(ictx);
966     break;
967   case ANTHY_INPUT_ST_CONV:
968     leave_conv_state(ictx);
969     enter_edit_state_noinit(ictx);
970     break;
971   case ANTHY_INPUT_ST_CSEG:
972     leave_cseg_state(ictx);
973     enter_conv_state_noinit(ictx);
974     leave_conv_state(ictx);
975     enter_edit_state_noinit(ictx);
976     break;
977   }
978 }
979
980 void
981 anthy_input_erase_next(struct anthy_input_context* ictx)
982 {
983   switch (ictx->state) {
984   case ANTHY_INPUT_ST_OFF:
985     break;
986   case ANTHY_INPUT_ST_NONE:  
987     break;
988   case ANTHY_INPUT_ST_EDIT:
989     cmd_delete(ictx);
990     break;
991   case ANTHY_INPUT_ST_CONV:
992     break;
993   case ANTHY_INPUT_ST_CSEG:
994     break;
995   }
996 }
997
998 void
999 anthy_input_commit(struct anthy_input_context* ictx)
1000 {
1001   switch (ictx->state) {
1002   case ANTHY_INPUT_ST_OFF:
1003     break;
1004   case ANTHY_INPUT_ST_NONE:  
1005     break;
1006   case ANTHY_INPUT_ST_EDIT:
1007     terminate_rk(ictx);
1008     cmd_commit_unconv(ictx);
1009     leave_edit_state(ictx);
1010     enter_none_state(ictx);
1011     break;
1012   case ANTHY_INPUT_ST_CONV:
1013     cmd_commit(ictx);
1014     leave_conv_state(ictx);
1015     enter_none_state(ictx);
1016     break;
1017   case ANTHY_INPUT_ST_CSEG:
1018     cmd_commit(ictx);
1019     leave_cseg_state(ictx);
1020     enter_conv_state_noinit(ictx);
1021     leave_conv_state(ictx);
1022     enter_none_state(ictx);
1023     break;
1024   }
1025 }
1026
1027 void
1028 anthy_input_move(struct anthy_input_context* ictx, int lr)
1029 {
1030   switch (ictx->state) {
1031   case ANTHY_INPUT_ST_OFF:
1032     break;
1033   case ANTHY_INPUT_ST_NONE:  
1034     break;
1035   case ANTHY_INPUT_ST_EDIT:
1036     cmd_move_cursor(ictx, lr);
1037     break;
1038   case ANTHY_INPUT_ST_CONV:
1039     cmd_move_selection(ictx, lr);
1040     break;
1041   case ANTHY_INPUT_ST_CSEG:
1042     cmd_unhiragana_candidate(ictx);
1043     leave_cseg_state(ictx);
1044     enter_conv_state_noinit(ictx);
1045     cmd_move_selection(ictx, lr);
1046     break;
1047   }
1048 }
1049
1050 void
1051 anthy_input_resize(struct anthy_input_context* ictx, int lr)
1052 {
1053   switch (ictx->state) {
1054   case ANTHY_INPUT_ST_OFF:
1055     break;
1056   case ANTHY_INPUT_ST_NONE:  
1057     break;
1058   case ANTHY_INPUT_ST_EDIT:
1059     break;
1060   case ANTHY_INPUT_ST_CONV:
1061     enter_cseg_state(ictx);
1062     cmd_resize(ictx, lr);
1063     break;
1064   case ANTHY_INPUT_ST_CSEG:
1065     cmd_resize(ictx, lr);
1066     break;
1067   }
1068 }
1069
1070 void
1071 anthy_input_beginning_of_line(struct anthy_input_context* ictx)
1072 {
1073   switch (ictx->state) {
1074   case ANTHY_INPUT_ST_OFF:
1075     break;
1076   case ANTHY_INPUT_ST_NONE:  
1077     break;
1078   case ANTHY_INPUT_ST_EDIT:
1079     cmd_move_to_bol(ictx);
1080     break;
1081   case ANTHY_INPUT_ST_CONV:
1082     cmd_move_to_bol_seg(ictx);
1083     break;
1084   case ANTHY_INPUT_ST_CSEG:
1085     break;
1086   }
1087 }  
1088
1089 void
1090 anthy_input_end_of_line(struct anthy_input_context* ictx)
1091 {
1092   switch (ictx->state) {
1093   case ANTHY_INPUT_ST_OFF:
1094     break;
1095   case ANTHY_INPUT_ST_NONE:  
1096     break;
1097   case ANTHY_INPUT_ST_EDIT:
1098     cmd_move_to_eol(ictx);
1099     break;
1100   case ANTHY_INPUT_ST_CONV:
1101     cmd_move_to_eol_seg(ictx);
1102     break;
1103   case ANTHY_INPUT_ST_CSEG:
1104     break;
1105   }
1106 }  
1107
1108 void
1109 anthy_input_cut(struct anthy_input_context* ictx)
1110 {
1111   switch (ictx->state) {
1112   case ANTHY_INPUT_ST_OFF:
1113     break;
1114   case ANTHY_INPUT_ST_NONE:  
1115     break;
1116   case ANTHY_INPUT_ST_EDIT:
1117     cmd_cut(ictx);
1118     break;
1119   case ANTHY_INPUT_ST_CONV:
1120     break;
1121   case ANTHY_INPUT_ST_CSEG:
1122     break;
1123   }
1124 }
1125
1126 /* key oriented function */
1127 void
1128 anthy_input_key(struct anthy_input_context* ictx, int c)
1129 {
1130   char buf[2];
1131   
1132   buf[0] = (char) c;
1133   buf[1] = '\0';
1134   anthy_input_str(ictx, buf);
1135 }
1136
1137 void
1138 anthy_input_space(struct anthy_input_context* ictx)
1139 {
1140   switch (ictx->state) {
1141   case ANTHY_INPUT_ST_OFF:
1142     break;
1143   case ANTHY_INPUT_ST_NONE:
1144     enter_edit_state(ictx);
1145     do_cmd_push_key(ictx, " ");
1146     commit_noconv_string(ictx);
1147     leave_edit_state(ictx);
1148     enter_none_state(ictx);      
1149     break;
1150   case ANTHY_INPUT_ST_EDIT:
1151     terminate_rk(ictx);
1152     if (rk_selected_map(ictx->rkctx) == RKMAP_SHIFT_ASCII)
1153       do_cmd_push_key(ictx, " ");
1154     else
1155       enter_conv_state(ictx);
1156     break;
1157   case ANTHY_INPUT_ST_CONV:
1158     cmd_next_candidate(ictx);
1159     break;
1160   case ANTHY_INPUT_ST_CSEG:
1161     cmd_unhiragana_candidate(ictx);
1162     leave_cseg_state(ictx);
1163     enter_conv_state_noinit(ictx);
1164     cmd_next_candidate(ictx);
1165     break;
1166   }
1167 }
1168
1169 /* meta function command */
1170
1171 int
1172 anthy_input_get_state(struct anthy_input_context* ictx)
1173 {
1174   return ictx->state;
1175 }
1176
1177 static struct anthy_input_segment *
1178 alloc_segment(int flag, int len, int noconv_len)
1179 {
1180   struct anthy_input_segment *seg;
1181   seg = (struct anthy_input_segment*)
1182     malloc(sizeof(struct anthy_input_segment));
1183   seg->flag = flag;
1184   seg->cand_no = -1;
1185   seg->nr_cand = -1;
1186   seg->noconv_len = noconv_len;
1187   if (len) {
1188     seg->str = (char *)malloc(len);
1189   } else {
1190     seg->str = NULL;
1191   }
1192   seg->next = NULL;
1193   return seg;
1194 }
1195
1196 static void
1197 get_edit_mode_preedit(struct anthy_input_context* ictx,
1198                       struct anthy_input_preedit* pedit)
1199 {
1200   struct anthy_input_segment** p;
1201   int len;
1202   /* º¸¤Îʸ»úÎópending|¥«¡¼¥½¥ë|±¦¤Îʸ»úÎó */
1203
1204   p = &pedit->segment;
1205
1206   /* left */
1207   if (ictx->n_hbuf > 0) {
1208     *p = alloc_segment(ANTHY_INPUT_SF_EDITING, ictx->n_hbuf + 1,
1209                        ictx->n_hbuf);
1210
1211     memcpy((*p)->str, ictx->hbuf, ictx->n_hbuf);
1212     (*p)->str[ictx->n_hbuf] = '\0';
1213     p = &(*p)->next;
1214   }
1215
1216   if (ictx->cfg->preedit_mode) {
1217     len = rk_partial_result(ictx->rkctx, NULL, 0);
1218     if (len > 1) {
1219       *p = alloc_segment(ANTHY_INPUT_SF_PENDING, len, len - 1);
1220
1221       rk_partial_result(ictx->rkctx, (*p)->str, len);
1222       p = &(*p)->next;
1223     }
1224   } else {
1225     len = rk_get_pending_str(ictx->rkctx, NULL, 0);
1226     if (len > 1) {
1227       *p = alloc_segment(ANTHY_INPUT_SF_PENDING, len, len - 1);
1228       
1229       rk_get_pending_str(ictx->rkctx, (*p)->str, len);
1230       p = &(*p)->next;
1231     }
1232   }
1233
1234   /* cursor */
1235   *p = alloc_segment(ANTHY_INPUT_SF_CURSOR, 0, 0);
1236   pedit->cur_segment = *p;
1237   p = &(*p)->next;
1238
1239   /* right */
1240   if (ictx->n_hbuf_follow > 0) {
1241     *p = alloc_segment(ANTHY_INPUT_SF_EDITING,
1242                        ictx->n_hbuf_follow + 1,
1243                        ictx->n_hbuf_follow);
1244     memcpy((*p)->str, ictx->hbuf_follow, ictx->n_hbuf_follow);
1245     (*p)->str[ictx->n_hbuf_follow] = '\0';
1246   }
1247 }
1248
1249 struct anthy_input_preedit*
1250 anthy_input_get_preedit(struct anthy_input_context* ictx)
1251 {
1252   struct anthy_input_preedit* pedit;
1253
1254   pedit = (struct anthy_input_preedit*) 
1255     malloc(sizeof(struct anthy_input_preedit));
1256
1257   pedit->state = ictx->state;
1258
1259   /* Ì¤¥³¥ß¥Ã¥È¤Îʸ»úÎó */
1260   if (ictx->n_commit > 0) {
1261     pedit->commit = (char*) malloc(ictx->n_commit + 1);
1262     memcpy(pedit->commit, ictx->commit, ictx->n_commit);
1263     pedit->commit[ictx->n_commit] = '\0';
1264     ictx->n_commit = 0;
1265   } else {
1266     pedit->commit = NULL;
1267   }
1268
1269   /* ¥«¥Ã¥È¥Ð¥Ã¥Õ¥¡¤Îʸ»úÎó */
1270   if(ictx->n_cut > 0) {
1271     pedit->cut_buf = (char*) malloc(ictx->n_cut + 1);
1272     memcpy(pedit->cut_buf, ictx->cut, ictx->n_cut);
1273     pedit->cut_buf[ictx->n_cut] = '\0';
1274     ictx->n_cut = 0;
1275   } else {
1276     pedit->cut_buf = NULL;
1277   }
1278
1279   pedit->segment = NULL;
1280   pedit->cur_segment = NULL;
1281   switch (ictx->state) {
1282   case ANTHY_INPUT_ST_OFF:
1283   case ANTHY_INPUT_ST_NONE:
1284     break;
1285   case ANTHY_INPUT_ST_EDIT:
1286     get_edit_mode_preedit(ictx, pedit);
1287     break;
1288   case ANTHY_INPUT_ST_CONV:
1289   case ANTHY_INPUT_ST_CSEG:
1290     {
1291       struct anthy_input_segment** p;
1292       struct a_segment* as;
1293       
1294       for (as = ictx->segment, p = &pedit->segment; as; as = as->next) {
1295         /* ³ÆʸÀá¤ËÂФ·¤Æ */
1296         int len, noconv_len;
1297         
1298         noconv_len = anthy_get_segment(ictx->actx, as->index, 
1299                                        NTH_UNCONVERTED_CANDIDATE,
1300                                        NULL, 0);
1301         len = anthy_get_segment(ictx->actx, as->index, as->cand, NULL, 0);
1302         *p = alloc_segment(ANTHY_INPUT_SF_NONE, len + 1, noconv_len);
1303
1304         anthy_get_segment(ictx->actx, as->index, as->cand, (*p)->str, len + 1);
1305         (*p)->cand_no = as->cand;
1306         (*p)->nr_cand = as->ass.nr_candidate;
1307         (*p)->next = NULL;
1308         
1309         if (as == ictx->cur_segment) {
1310           pedit->cur_segment = *p;
1311           (*p)->flag |= ANTHY_INPUT_SF_CURSOR;
1312           if (ictx->enum_cand_count >= ictx->enum_cand_limit)
1313             (*p)->flag |= (ictx->enum_reverse ?
1314                            ANTHY_INPUT_SF_ENUM_REVERSE : ANTHY_INPUT_SF_ENUM);
1315
1316           if (ictx->state == ANTHY_INPUT_ST_CSEG) {
1317             struct a_segment* as1;
1318             
1319             for (as1 = as->next, len = 0; as1; as1 = as1->next)
1320               len += anthy_get_segment(ictx->actx, as1->index,
1321                                        NTH_UNCONVERTED_CANDIDATE, NULL, 0);
1322             if (len > 0) {
1323               char* s;
1324
1325               p = &(*p)->next;
1326               *p = alloc_segment(ANTHY_INPUT_SF_FOLLOWING, len + 1, len);
1327               for (as1 = as->next, s = (*p)->str; as1; as1 = as1->next) {
1328                 anthy_get_segment(ictx->actx, as1->index, 
1329                                   NTH_UNCONVERTED_CANDIDATE,
1330                                   s, len - (s - (*p)->str) + 1);
1331                 s += anthy_get_segment(ictx->actx, as1->index, 
1332                                        NTH_UNCONVERTED_CANDIDATE, NULL, 0);
1333               }
1334               (*p)->str[len] = '\0';
1335               (*p)->next = NULL;
1336             }
1337             break;
1338           }
1339         }
1340
1341         p = &(*p)->next;
1342       }
1343     }
1344     break;
1345   }
1346
1347   return pedit;
1348 }
1349
1350 int
1351 anthy_input_map_select(struct anthy_input_context* ictx, int map)
1352 {
1353   switch (ictx->state) {
1354   case ANTHY_INPUT_ST_OFF:
1355     break;
1356   case ANTHY_INPUT_ST_NONE:  
1357   case ANTHY_INPUT_ST_EDIT:
1358   case ANTHY_INPUT_ST_CONV:
1359   case ANTHY_INPUT_ST_CSEG:
1360     return cmdh_map_select(ictx, map);
1361     break;
1362   }
1363
1364   anthy_input_errno = AIE_INVAL;
1365   return -1;
1366 }
1367
1368 int
1369 anthy_input_get_selected_map(struct anthy_input_context* ictx)
1370 {
1371   return ictx->map_no;
1372 }
1373
1374 struct anthy_input_segment* 
1375 anthy_input_get_candidate(struct anthy_input_context* ictx, int cand_no)
1376 {
1377   switch (ictx->state) {
1378   case ANTHY_INPUT_ST_CONV:
1379     return cmdh_get_candidate(ictx, cand_no);
1380     break;
1381   case ANTHY_INPUT_ST_OFF:
1382   case ANTHY_INPUT_ST_NONE:  
1383   case ANTHY_INPUT_ST_EDIT:
1384   case ANTHY_INPUT_ST_CSEG:
1385     break;
1386   }
1387
1388   anthy_input_errno = AIE_INVAL;
1389   return NULL;
1390 }
1391
1392 int
1393 anthy_input_select_candidate(struct anthy_input_context* ictx, int cand)
1394 {
1395   switch (ictx->state) {
1396   case ANTHY_INPUT_ST_OFF:
1397   case ANTHY_INPUT_ST_NONE:  
1398   case ANTHY_INPUT_ST_EDIT:
1399     break;
1400   case ANTHY_INPUT_ST_CONV:
1401     return cmdh_select_candidate(ictx, cand);
1402     break;
1403   case ANTHY_INPUT_ST_CSEG:
1404     break;
1405   }
1406
1407   anthy_input_errno = AIE_INVAL;
1408   return -1;
1409 }
1410
1411 int
1412 anthy_input_edit_toggle_config(struct anthy_input_config *cfg, char tg)
1413 {
1414   return anthy_input_do_edit_toggle_option(cfg->rk_option, tg);
1415 }
1416
1417 int
1418 anthy_input_edit_rk_config(struct anthy_input_config *cfg, int map,
1419                            const char *from, const char *to, const char *follow)
1420 {
1421   return
1422     anthy_input_do_edit_rk_option(cfg->rk_option, map,
1423                                   from, to, follow);
1424 }
1425
1426 int
1427 anthy_input_clear_rk_config(struct anthy_input_config *cfg,
1428                             int use_default)
1429 {
1430   return
1431     anthy_input_do_clear_rk_option(cfg->rk_option, use_default);
1432 }
1433
1434 int
1435 anthy_input_break_into_roman_config(struct anthy_input_config *cfg,
1436                                     int brk)
1437 {
1438   int old_val;
1439   old_val = cfg->break_into_roman;
1440   cfg->break_into_roman = brk;
1441   return old_val;
1442 }
1443
1444 int
1445 anthy_input_preedit_mode_config(struct anthy_input_config *cfg,
1446                                 int val)
1447 {
1448   int old_val;
1449   old_val = cfg->preedit_mode;
1450   cfg->preedit_mode = val;
1451   return old_val;
1452 }
1453
1454 void
1455 anthy_input_change_config(struct anthy_input_config* cfg)
1456 {
1457   struct anthy_input_context* p;
1458
1459   struct rk_map* h_map = cfg->rk_map[RKMAP_HIRAGANA];
1460   struct rk_map* k_map = cfg->rk_map[RKMAP_KATAKANA];
1461   struct rk_map* s_map = cfg->rk_map[RKMAP_SHIFT_ASCII];
1462   struct rk_map* hk_map = cfg->rk_map[RKMAP_HANKAKU_KANA];
1463
1464   cfg->rk_map[RKMAP_HIRAGANA] = make_rkmap_hiragana(cfg->rk_option);
1465   cfg->rk_map[RKMAP_KATAKANA] = make_rkmap_katakana(cfg->rk_option);
1466   cfg->rk_map[RKMAP_SHIFT_ASCII] = make_rkmap_shiftascii(cfg->rk_option);
1467   cfg->rk_map[RKMAP_HANKAKU_KANA] = make_rkmap_hankaku_kana(cfg->rk_option);
1468
1469   /* ¤³¤Îconfig¤ò¶¦Í­¤¹¤ë¥³¥ó¥Æ¥­¥¹¥È¤¹¤Ù¤Æ¤ËÂФ·¤Æ */
1470   for (p = cfg->owners; p; p = p->next_cfg_owner) {
1471     reset_anthy_input_context(p);
1472     rk_register_map(p->rkctx, RKMAP_HIRAGANA, cfg->rk_map[RKMAP_HIRAGANA]);
1473     rk_register_map(p->rkctx, RKMAP_KATAKANA, cfg->rk_map[RKMAP_KATAKANA]);
1474     rk_register_map(p->rkctx, RKMAP_SHIFT_ASCII, 
1475                     cfg->rk_map[RKMAP_SHIFT_ASCII]);
1476     rk_register_map(p->rkctx, RKMAP_HANKAKU_KANA, 
1477                     cfg->rk_map[RKMAP_HANKAKU_KANA]);
1478     rk_select_registered_map(p->rkctx, RKMAP_HIRAGANA);
1479   }
1480
1481   rk_map_free(h_map);
1482   rk_map_free(k_map);
1483   rk_map_free(s_map);
1484   rk_map_free(hk_map);
1485 }
1486
1487 struct anthy_input_config*
1488 anthy_input_create_config(void)
1489 {
1490   struct anthy_input_config* cfg;
1491
1492   cfg = (struct anthy_input_config*) malloc(sizeof(struct anthy_input_config));
1493
1494   cfg->rk_option = anthy_input_create_rk_option();
1495   cfg->break_into_roman = 0;
1496   cfg->preedit_mode = 0;
1497   cfg->rk_map[RKMAP_ASCII] = make_rkmap_ascii(cfg->rk_option);
1498   cfg->rk_map[RKMAP_SHIFT_ASCII] = make_rkmap_shiftascii(cfg->rk_option);
1499   cfg->rk_map[RKMAP_HIRAGANA] = make_rkmap_hiragana(cfg->rk_option);
1500   cfg->rk_map[RKMAP_KATAKANA] = make_rkmap_katakana(cfg->rk_option);
1501   cfg->rk_map[RKMAP_WASCII] = make_rkmap_wascii(cfg->rk_option);
1502   cfg->rk_map[RKMAP_HANKAKU_KANA] = make_rkmap_hankaku_kana(cfg->rk_option);
1503   cfg->owners = NULL;
1504
1505   return cfg;
1506 }
1507
1508 void
1509 anthy_input_free_config(struct anthy_input_config* cfg)
1510 {
1511   int err;
1512
1513   /* ¤³¤Îconfig¤ò¶¦Í­¤¹¤ëÁ´¤Æ¤Îcontext¤ò»öÁ°¤Ë²òÊü¤¹¤ë»ö */
1514   assert(!cfg->owners);
1515
1516   rk_map_free(cfg->rk_map[RKMAP_ASCII]);
1517   rk_map_free(cfg->rk_map[RKMAP_SHIFT_ASCII]);
1518   rk_map_free(cfg->rk_map[RKMAP_HIRAGANA]);
1519   rk_map_free(cfg->rk_map[RKMAP_KATAKANA]);
1520   rk_map_free(cfg->rk_map[RKMAP_WASCII]);
1521   rk_map_free(cfg->rk_map[RKMAP_HANKAKU_KANA]);
1522
1523   err = anthy_input_free_rk_option(cfg->rk_option);
1524   free(cfg);
1525 }
1526
1527 int
1528 anthy_input_init(void)
1529 {
1530   return anthy_init();
1531 }
1532
1533 void
1534 anthy_input_set_personality(const char *personality)
1535 {
1536   anthy_set_personality(personality);
1537 }
1538
1539 anthy_context_t
1540 anthy_input_get_anthy_context(struct anthy_input_context *ictx)
1541 {
1542   return ictx->actx;
1543 }