2 * Anthy¤Î¥¡¼¤Î¼õ¤±ÉÕ¤±¤ä¥×¥ê¥¨¥Ç¥£¥Ã¥È¤ÎÀ©¸æ¤ò¹Ô¤¦¥ì¥¤¥ä¡¼
4 * º£¤«¤é¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò½ñ¤¯¾ì¹ç¤Ë¤Ïuim¤ÎÍøÍѤò¤ªÁ¦¤á¤·¤Þ¤¹¡£
6 * Funded by IPA̤Ƨ¥½¥Õ¥È¥¦¥§¥¢ÁϤ»ö¶È 2002 1/23
7 * Copyright (C) 2001-2002 UGAWA Tomoharu
9 * $Id: input.c,v 1.25 2002/11/16 03:35:21 yusuke Exp $
17 #include <sys/types.h>
22 #include <anthy/anthy.h>
23 #include <anthy/input.h>
28 struct anthy_input_context {
29 /* ANTHY_INPUT_ST_* */
32 /* always allocated */
33 struct rk_conv_context* rkctx;
34 int map_no; /* RKMAP_* */
35 /* ÊÑ´¹¤¹¤ëʸ»úÎó¤Î¥Ð¥Ã¥Õ¥¡*/
43 /* allocated only in conv state */
45 struct a_segment* segment;
46 struct a_segment* cur_segment;
52 /* always allocated by the library */
53 /* ¥³¥ß¥Ã¥È¥Ð¥Ã¥Õ¥¡ */
58 /* always allocated by the library */
64 struct anthy_input_config* cfg;
65 struct anthy_input_context* next_cfg_owner;
68 int anthy_input_errno;
70 #define DEFAULT_ENUM_CAND_LIMIT 3
72 #define MAX(a,b) ((a) > (b) ? (a) : (b))
74 #define is_eucchar(s) (((s)[0] & 0x80) && ((s)[1] & 0x80))
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;
90 struct anthy_segment_stat ass;
92 struct a_segment* next, * prev;
96 ensure_buffer(char** buf, int* size, int to_size)
98 if (*size < to_size) {
99 *buf = (char*) realloc(*buf, to_size);
101 anthy_input_errno = AIE_NOMEM;
110 leave_edit_state(struct anthy_input_context* ictx)
118 enter_none_state(struct anthy_input_context* ictx)
120 ictx->state = ANTHY_INPUT_ST_NONE;
124 enter_edit_state(struct anthy_input_context* ictx)
126 ictx->state = ANTHY_INPUT_ST_EDIT;
127 rk_flush(ictx->rkctx);
128 rk_select_registered_map(ictx->rkctx, ictx->map_no);
130 ictx->n_hbuf_follow = 0;
134 enter_edit_state_noinit(struct anthy_input_context* ictx)
136 ictx->state = ANTHY_INPUT_ST_EDIT;
140 leave_conv_state(struct anthy_input_context* ictx)
142 struct a_segment* as, * next;
143 anthy_release_context(ictx->actx);
144 for (as = ictx->segment; as; as = next) {
148 anthy_reset_context(ictx->actx);
152 reset_anthy_input_context(struct anthy_input_context* ictx)
154 switch (ictx->state) {
155 case ANTHY_INPUT_ST_NONE:
157 case ANTHY_INPUT_ST_EDIT:
158 leave_edit_state(ictx);
160 case ANTHY_INPUT_ST_CONV:
161 leave_conv_state(ictx);
164 enter_none_state(ictx);
168 read_rk_result(struct anthy_input_context* ictx)
172 ret = rk_result(ictx->rkctx, ictx->hbuf + ictx->n_hbuf,
173 ictx->s_hbuf - ictx->n_hbuf);
175 if (ictx->s_hbuf - ictx->n_hbuf > 0)
176 ictx->n_hbuf = ictx->s_hbuf - 1;
178 ensure_buffer(&ictx->hbuf, &ictx->s_hbuf, ictx->n_hbuf + ret + 1);
180 rk_result(ictx->rkctx, ictx->hbuf + ictx->n_hbuf,
181 ictx->s_hbuf - ictx->n_hbuf);
184 ictx->n_hbuf += strlen(ictx->hbuf + ictx->n_hbuf);
188 terminate_rk(struct anthy_input_context* ictx)
190 rk_terminate(ictx->rkctx);
191 read_rk_result(ictx);
192 rk_flush(ictx->rkctx);
196 join_noconv_string(struct anthy_input_context* ictx)
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;
208 enter_conv_state(struct anthy_input_context* ictx)
211 struct anthy_conv_stat acs;
212 struct a_segment* as_tail, ** as_tailp;
216 ictx->state = ANTHY_INPUT_ST_CONV;
220 join_noconv_string(ictx);
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);
229 ensure_buffer(&ictx->hbuf, &ictx->s_hbuf, ictx->n_hbuf + 1);
230 ictx->hbuf[ictx->n_hbuf] = '\0';
232 ictx->enum_cand_count = 0;
233 ictx->actx = anthy_create_context();
234 anthy_context_set_encoding(ictx->actx, ANTHY_EUC_JP_ENCODING);
236 enter_none_state(ictx);
237 anthy_input_errno = AIE_NOMEM;
240 anthy_reset_context(ictx->actx);
241 ret = anthy_set_string(ictx->actx, ictx->hbuf);
243 anthy_release_context(ictx->actx);
244 enter_none_state(ictx);
248 anthy_get_stat(ictx->actx, &acs);
250 as_tailp = &ictx->segment;
252 for (i = 0; i < acs.nr_segment; i++) {
253 struct a_segment* as;
254 as = (struct a_segment*) malloc(sizeof(struct a_segment));
257 anthy_get_segment_stat(ictx->actx, i, &as->ass);
258 last_pos += as->ass.seg_len;
263 as_tailp = &as->next;
266 ictx->cur_segment = ictx->segment;
267 ictx->last_gotten_cand = 0;
271 enter_conv_state_noinit(struct anthy_input_context* ictx)
273 ictx->state = ANTHY_INPUT_ST_CONV;
277 enter_cseg_state(struct anthy_input_context* ictx)
279 ictx->state = ANTHY_INPUT_ST_CSEG;
280 ictx->enum_cand_count = 0;
284 leave_cseg_state(struct anthy_input_context* ictx)
291 cmdh_map_select(struct anthy_input_context* ictx, int map)
294 case ANTHY_INPUT_MAP_ALPHABET:
295 ictx->map_no = RKMAP_ASCII;
297 case ANTHY_INPUT_MAP_WALPHABET:
298 ictx->map_no = RKMAP_WASCII;
300 case ANTHY_INPUT_MAP_HIRAGANA:
301 ictx->map_no = RKMAP_HIRAGANA;
303 case ANTHY_INPUT_MAP_KATAKANA:
304 ictx->map_no = RKMAP_KATAKANA;
306 case ANTHY_INPUT_MAP_HANKAKU_KANA:
307 ictx->map_no = RKMAP_HANKAKU_KANA;
310 anthy_input_errno = AIE_INVAL;
314 rk_select_registered_map(ictx->rkctx, ictx->map_no);
319 static struct anthy_input_segment*
320 cmdh_get_candidate(struct anthy_input_context* ictx, int cand_no)
322 struct a_segment* cs;
323 struct anthy_input_segment* seg;
326 cs = ictx->cur_segment;
327 if (cand_no >= cs->ass.nr_candidate) {
328 anthy_input_errno = AIE_INVAL;
331 ictx->last_gotten_cand = cand_no;
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);
351 do_cmd_commit(struct anthy_input_context* ictx)
353 struct a_segment* as;
355 for (as = ictx->segment; as; as = as->next) {
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);
368 cmdh_select_candidate(struct anthy_input_context* ictx,
371 struct a_segment* cs;
373 cs = ictx->cur_segment;
374 if (cand_no >= cs->ass.nr_candidate) {
375 anthy_input_errno = AIE_INVAL;
381 ictx->cur_segment = cs->next;
382 ictx->last_gotten_cand = ictx->cur_segment->cand;
383 ictx->enum_cand_count = 0;
385 ictx->last_gotten_cand = ictx->cur_segment->cand;
386 ictx->enum_cand_count = 0;
393 do_cmd_push_key(struct anthy_input_context* ictx, const char* str)
397 for (p = str; *p; p++) {
398 if (isspace((int)(unsigned char) *p) && *p != ' ')
401 rk_push_key(ictx->rkctx, *p);
402 read_rk_result(ictx);
407 cmd_push_key(struct anthy_input_context* ictx, const char* str)
409 do_cmd_push_key(ictx, str);
413 cmd_move_cursor(struct anthy_input_context* ictx, int d)
415 if (rk_get_pending_str(ictx->rkctx, NULL, 0) > 1) {
416 rk_flush(ictx->rkctx);
423 if (ictx->n_hbuf_follow == 0)
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))
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);
434 ictx->n_hbuf_follow -= len;
435 memmove(ictx->hbuf_follow, p, ictx->n_hbuf_follow);
439 if (ictx->n_hbuf == 0)
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))
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;
458 cmd_backspace(struct anthy_input_context* ictx)
462 len = rk_get_pending_str(ictx->rkctx, NULL, 0);
465 /* ³ÎÄꤵ¤ì¤Æ¤¤¤Ê¤¤¥í¡¼¥Þ»ú¤¬¤¢¤ë¤Î¤Ç¡¢ºÇ¸å¤Îʸ»ú¤ò¥«¥Ã¥È */
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);
474 if (brk_roman_get_previous_pending(ictx->rkctx)) {
476 buf = strdup(brk_roman_get_previous_pending(ictx->rkctx));
477 ictx->n_hbuf -= brk_roman_get_decided_len(ictx->rkctx);
479 rk_flush(ictx->rkctx);
480 do_cmd_push_key(ictx,buf);
483 if (ictx->n_hbuf >= 2 && is_eucchar(ictx->hbuf + ictx->n_hbuf - 2)) {
485 } else if (ictx->n_hbuf >= 1) {
491 if (ictx->n_hbuf + ictx->n_hbuf_follow <= 0 && len <= 1) {
492 leave_edit_state(ictx);
493 enter_none_state(ictx);
498 cmd_delete(struct anthy_input_context* ictx)
502 if (rk_get_pending_str(ictx->rkctx, NULL, 0) > 1)
504 if (ictx->n_hbuf_follow <= 0)
507 len = ictx->n_hbuf_follow >= 2 && is_eucchar(ictx->hbuf_follow) ? 2 : 1;
509 if (ictx->n_hbuf_follow <= len)
510 ictx->n_hbuf_follow = 0;
512 ictx->n_hbuf_follow -= len;
513 memmove(ictx->hbuf_follow, ictx->hbuf_follow + len, ictx->n_hbuf_follow);
516 if (ictx->n_hbuf + ictx->n_hbuf_follow <= 0) {
517 leave_edit_state(ictx);
518 enter_none_state(ictx);
523 cmd_commit_unconv(struct anthy_input_context* ictx)
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;
536 cmd_resize(struct anthy_input_context* ictx, int d)
539 struct anthy_conv_stat acs;
540 struct a_segment* as;
543 anthy_resize_segment(ictx->actx, ictx->cur_segment->index, d);
544 anthy_get_stat(ictx->actx, &acs);
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;
554 as2 = (struct a_segment*) malloc(sizeof(struct a_segment));
563 anthy_get_segment_stat(ictx->actx, i, &as->ass);
564 last_pos += as->ass.seg_len;
565 as->cand = NTH_UNCONVERTED_CANDIDATE;
567 ictx->last_gotten_cand = NTH_UNCONVERTED_CANDIDATE;
569 as = as->next; /* ÉÔÀµ¤Ê¥á¥â¥ê¥¢¥¯¥»¥¹¤Î½¤Àµ */
571 as->prev->next = NULL;
573 struct a_segment* const next = as->next;
581 commit_noconv_string(struct anthy_input_context* ictx)
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;
594 cmd_commit(struct anthy_input_context* ictx)
600 cmd_next_candidate(struct anthy_input_context* ictx)
602 struct a_segment* as;
604 ictx->enum_cand_count++;
606 as = ictx->cur_segment;
608 if (!ictx->enum_reverse)
609 as->cand = ictx->last_gotten_cand;
611 ictx->enum_reverse = 0;
613 if (as->cand == NTH_UNCONVERTED_CANDIDATE) {
615 if (as->cand == NTH_UNCONVERTED_CANDIDATE) {
620 ictx->last_gotten_cand = 0;
622 if (++as->cand >= as->ass.nr_candidate)
624 ictx->last_gotten_cand = as->cand;
629 cmd_prev_candidate(struct anthy_input_context* ictx)
631 struct a_segment* as;
633 ictx->enum_cand_count++;
635 as = ictx->cur_segment;
637 if (ictx->enum_reverse)
638 as->cand = ictx->last_gotten_cand;
640 ictx->enum_reverse = 1;
642 if (as->cand == NTH_UNCONVERTED_CANDIDATE) {
644 if (as->cand == NTH_UNCONVERTED_CANDIDATE) {
649 ictx->last_gotten_cand = 0;
652 as->cand = as->ass.nr_candidate - 1;
653 ictx->last_gotten_cand = as->cand;
658 cmd_move_selection(struct anthy_input_context* ictx, int d)
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;
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;
675 cmd_move_to_bol_seg(struct anthy_input_context* ictx)
677 ictx->cur_segment = ictx->segment;
678 ictx->enum_cand_count = 0;
679 ictx->last_gotten_cand = ictx->cur_segment->cand;
683 cmd_move_to_eol_seg(struct anthy_input_context* ictx)
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;
692 cmd_unhiragana_candidate(struct anthy_input_context* ictx)
694 struct a_segment* as;
696 for (as = ictx->cur_segment->next; as; as = as->next)
701 cmd_move_to_bol(struct anthy_input_context* ictx)
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;
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;
725 cmd_move_to_eol(struct anthy_input_context* ictx)
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;
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;
747 cmd_cut(struct anthy_input_context* ictx)
754 /* ¥Ð¥Ã¥Õ¥¡¤ÎÆþ¤ì´¹¤¨¤ÇºÑ¤Þ¤»¤ë */
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;
765 /*****************************************************************/
768 struct anthy_input_context*
769 anthy_input_create_context(struct anthy_input_config* cfg)
771 struct anthy_input_context* 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);
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;
791 ictx->segment = NULL;
792 ictx->cur_segment = NULL;
793 ictx->enum_reverse = 0; /* ½é´ü²½Ëº¤ì¤Î½¤Àµ */
794 ictx->last_gotten_cand = 0; /* ½é´ü²½Ëº¤ì¤Î½¤Àµ */
802 ictx->next_cfg_owner = cfg->owners;
808 anthy_input_free_context(struct anthy_input_context* ictx)
810 struct anthy_input_context **p;
812 reset_anthy_input_context(ictx);
813 rk_context_free(ictx->rkctx);
815 for (p = &ictx->cfg->owners; *p; p = &(*p)->next_cfg_owner)
817 *p = ictx->next_cfg_owner;
822 free(ictx->hbuf_follow);
829 anthy_input_free_preedit(struct anthy_input_preedit* pedit)
831 struct anthy_input_segment* p, * q;
834 free(pedit->cut_buf);
835 for (p = pedit->segment; p; p = q) {
837 anthy_input_free_segment(p);
843 anthy_input_free_segment(struct anthy_input_segment* seg)
850 anthy_input_str(struct anthy_input_context* ictx, const char* str)
852 switch (ictx->state) {
853 case ANTHY_INPUT_ST_OFF:
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);
865 case ANTHY_INPUT_ST_EDIT:
866 cmd_push_key(ictx, str);
868 case ANTHY_INPUT_ST_CONV:
870 leave_conv_state(ictx);
871 enter_edit_state(ictx);
872 cmd_push_key(ictx, str);
874 case ANTHY_INPUT_ST_CSEG:
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);
886 anthy_input_next_candidate(struct anthy_input_context* ictx)
888 switch (ictx->state) {
889 case ANTHY_INPUT_ST_OFF:
891 case ANTHY_INPUT_ST_NONE:
893 case ANTHY_INPUT_ST_EDIT:
894 enter_conv_state(ictx);
896 case ANTHY_INPUT_ST_CONV:
897 cmd_next_candidate(ictx);
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);
910 anthy_input_prev_candidate(struct anthy_input_context* ictx)
912 switch (ictx->state) {
913 case ANTHY_INPUT_ST_OFF:
915 case ANTHY_INPUT_ST_NONE:
917 case ANTHY_INPUT_ST_EDIT:
918 enter_conv_state(ictx);
920 case ANTHY_INPUT_ST_CONV:
921 cmd_prev_candidate(ictx);
923 case ANTHY_INPUT_ST_CSEG:
924 leave_cseg_state(ictx);
925 enter_conv_state_noinit(ictx);
926 cmd_prev_candidate(ictx);
932 anthy_input_quit(struct anthy_input_context* ictx)
934 switch (ictx->state) {
935 case ANTHY_INPUT_ST_OFF:
937 case ANTHY_INPUT_ST_NONE:
939 case ANTHY_INPUT_ST_EDIT:
940 leave_edit_state(ictx);
941 enter_none_state(ictx);
943 case ANTHY_INPUT_ST_CONV:
944 leave_conv_state(ictx);
945 enter_edit_state_noinit(ictx);
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);
957 anthy_input_erase_prev(struct anthy_input_context* ictx)
959 switch (ictx->state) {
960 case ANTHY_INPUT_ST_OFF:
962 case ANTHY_INPUT_ST_NONE:
964 case ANTHY_INPUT_ST_EDIT:
967 case ANTHY_INPUT_ST_CONV:
968 leave_conv_state(ictx);
969 enter_edit_state_noinit(ictx);
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);
981 anthy_input_erase_next(struct anthy_input_context* ictx)
983 switch (ictx->state) {
984 case ANTHY_INPUT_ST_OFF:
986 case ANTHY_INPUT_ST_NONE:
988 case ANTHY_INPUT_ST_EDIT:
991 case ANTHY_INPUT_ST_CONV:
993 case ANTHY_INPUT_ST_CSEG:
999 anthy_input_commit(struct anthy_input_context* ictx)
1001 switch (ictx->state) {
1002 case ANTHY_INPUT_ST_OFF:
1004 case ANTHY_INPUT_ST_NONE:
1006 case ANTHY_INPUT_ST_EDIT:
1008 cmd_commit_unconv(ictx);
1009 leave_edit_state(ictx);
1010 enter_none_state(ictx);
1012 case ANTHY_INPUT_ST_CONV:
1014 leave_conv_state(ictx);
1015 enter_none_state(ictx);
1017 case ANTHY_INPUT_ST_CSEG:
1019 leave_cseg_state(ictx);
1020 enter_conv_state_noinit(ictx);
1021 leave_conv_state(ictx);
1022 enter_none_state(ictx);
1028 anthy_input_move(struct anthy_input_context* ictx, int lr)
1030 switch (ictx->state) {
1031 case ANTHY_INPUT_ST_OFF:
1033 case ANTHY_INPUT_ST_NONE:
1035 case ANTHY_INPUT_ST_EDIT:
1036 cmd_move_cursor(ictx, lr);
1038 case ANTHY_INPUT_ST_CONV:
1039 cmd_move_selection(ictx, lr);
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);
1051 anthy_input_resize(struct anthy_input_context* ictx, int lr)
1053 switch (ictx->state) {
1054 case ANTHY_INPUT_ST_OFF:
1056 case ANTHY_INPUT_ST_NONE:
1058 case ANTHY_INPUT_ST_EDIT:
1060 case ANTHY_INPUT_ST_CONV:
1061 enter_cseg_state(ictx);
1062 cmd_resize(ictx, lr);
1064 case ANTHY_INPUT_ST_CSEG:
1065 cmd_resize(ictx, lr);
1071 anthy_input_beginning_of_line(struct anthy_input_context* ictx)
1073 switch (ictx->state) {
1074 case ANTHY_INPUT_ST_OFF:
1076 case ANTHY_INPUT_ST_NONE:
1078 case ANTHY_INPUT_ST_EDIT:
1079 cmd_move_to_bol(ictx);
1081 case ANTHY_INPUT_ST_CONV:
1082 cmd_move_to_bol_seg(ictx);
1084 case ANTHY_INPUT_ST_CSEG:
1090 anthy_input_end_of_line(struct anthy_input_context* ictx)
1092 switch (ictx->state) {
1093 case ANTHY_INPUT_ST_OFF:
1095 case ANTHY_INPUT_ST_NONE:
1097 case ANTHY_INPUT_ST_EDIT:
1098 cmd_move_to_eol(ictx);
1100 case ANTHY_INPUT_ST_CONV:
1101 cmd_move_to_eol_seg(ictx);
1103 case ANTHY_INPUT_ST_CSEG:
1109 anthy_input_cut(struct anthy_input_context* ictx)
1111 switch (ictx->state) {
1112 case ANTHY_INPUT_ST_OFF:
1114 case ANTHY_INPUT_ST_NONE:
1116 case ANTHY_INPUT_ST_EDIT:
1119 case ANTHY_INPUT_ST_CONV:
1121 case ANTHY_INPUT_ST_CSEG:
1126 /* key oriented function */
1128 anthy_input_key(struct anthy_input_context* ictx, int c)
1134 anthy_input_str(ictx, buf);
1138 anthy_input_space(struct anthy_input_context* ictx)
1140 switch (ictx->state) {
1141 case ANTHY_INPUT_ST_OFF:
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);
1150 case ANTHY_INPUT_ST_EDIT:
1152 if (rk_selected_map(ictx->rkctx) == RKMAP_SHIFT_ASCII)
1153 do_cmd_push_key(ictx, " ");
1155 enter_conv_state(ictx);
1157 case ANTHY_INPUT_ST_CONV:
1158 cmd_next_candidate(ictx);
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);
1169 /* meta function command */
1172 anthy_input_get_state(struct anthy_input_context* ictx)
1177 static struct anthy_input_segment *
1178 alloc_segment(int flag, int len, int noconv_len)
1180 struct anthy_input_segment *seg;
1181 seg = (struct anthy_input_segment*)
1182 malloc(sizeof(struct anthy_input_segment));
1186 seg->noconv_len = noconv_len;
1188 seg->str = (char *)malloc(len);
1197 get_edit_mode_preedit(struct anthy_input_context* ictx,
1198 struct anthy_input_preedit* pedit)
1200 struct anthy_input_segment** p;
1202 /* º¸¤Îʸ»úÎópending|¥«¡¼¥½¥ë|±¦¤Îʸ»úÎó */
1204 p = &pedit->segment;
1207 if (ictx->n_hbuf > 0) {
1208 *p = alloc_segment(ANTHY_INPUT_SF_EDITING, ictx->n_hbuf + 1,
1211 memcpy((*p)->str, ictx->hbuf, ictx->n_hbuf);
1212 (*p)->str[ictx->n_hbuf] = '\0';
1216 if (ictx->cfg->preedit_mode) {
1217 len = rk_partial_result(ictx->rkctx, NULL, 0);
1219 *p = alloc_segment(ANTHY_INPUT_SF_PENDING, len, len - 1);
1221 rk_partial_result(ictx->rkctx, (*p)->str, len);
1225 len = rk_get_pending_str(ictx->rkctx, NULL, 0);
1227 *p = alloc_segment(ANTHY_INPUT_SF_PENDING, len, len - 1);
1229 rk_get_pending_str(ictx->rkctx, (*p)->str, len);
1235 *p = alloc_segment(ANTHY_INPUT_SF_CURSOR, 0, 0);
1236 pedit->cur_segment = *p;
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';
1249 struct anthy_input_preedit*
1250 anthy_input_get_preedit(struct anthy_input_context* ictx)
1252 struct anthy_input_preedit* pedit;
1254 pedit = (struct anthy_input_preedit*)
1255 malloc(sizeof(struct anthy_input_preedit));
1257 pedit->state = ictx->state;
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';
1266 pedit->commit = NULL;
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';
1276 pedit->cut_buf = NULL;
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:
1285 case ANTHY_INPUT_ST_EDIT:
1286 get_edit_mode_preedit(ictx, pedit);
1288 case ANTHY_INPUT_ST_CONV:
1289 case ANTHY_INPUT_ST_CSEG:
1291 struct anthy_input_segment** p;
1292 struct a_segment* as;
1294 for (as = ictx->segment, p = &pedit->segment; as; as = as->next) {
1295 /* ³ÆʸÀá¤ËÂФ·¤Æ */
1296 int len, noconv_len;
1298 noconv_len = anthy_get_segment(ictx->actx, as->index,
1299 NTH_UNCONVERTED_CANDIDATE,
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);
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;
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);
1316 if (ictx->state == ANTHY_INPUT_ST_CSEG) {
1317 struct a_segment* as1;
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);
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);
1334 (*p)->str[len] = '\0';
1351 anthy_input_map_select(struct anthy_input_context* ictx, int map)
1353 switch (ictx->state) {
1354 case ANTHY_INPUT_ST_OFF:
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);
1364 anthy_input_errno = AIE_INVAL;
1369 anthy_input_get_selected_map(struct anthy_input_context* ictx)
1371 return ictx->map_no;
1374 struct anthy_input_segment*
1375 anthy_input_get_candidate(struct anthy_input_context* ictx, int cand_no)
1377 switch (ictx->state) {
1378 case ANTHY_INPUT_ST_CONV:
1379 return cmdh_get_candidate(ictx, cand_no);
1381 case ANTHY_INPUT_ST_OFF:
1382 case ANTHY_INPUT_ST_NONE:
1383 case ANTHY_INPUT_ST_EDIT:
1384 case ANTHY_INPUT_ST_CSEG:
1388 anthy_input_errno = AIE_INVAL;
1393 anthy_input_select_candidate(struct anthy_input_context* ictx, int cand)
1395 switch (ictx->state) {
1396 case ANTHY_INPUT_ST_OFF:
1397 case ANTHY_INPUT_ST_NONE:
1398 case ANTHY_INPUT_ST_EDIT:
1400 case ANTHY_INPUT_ST_CONV:
1401 return cmdh_select_candidate(ictx, cand);
1403 case ANTHY_INPUT_ST_CSEG:
1407 anthy_input_errno = AIE_INVAL;
1412 anthy_input_edit_toggle_config(struct anthy_input_config *cfg, char tg)
1414 return anthy_input_do_edit_toggle_option(cfg->rk_option, tg);
1418 anthy_input_edit_rk_config(struct anthy_input_config *cfg, int map,
1419 const char *from, const char *to, const char *follow)
1422 anthy_input_do_edit_rk_option(cfg->rk_option, map,
1427 anthy_input_clear_rk_config(struct anthy_input_config *cfg,
1431 anthy_input_do_clear_rk_option(cfg->rk_option, use_default);
1435 anthy_input_break_into_roman_config(struct anthy_input_config *cfg,
1439 old_val = cfg->break_into_roman;
1440 cfg->break_into_roman = brk;
1445 anthy_input_preedit_mode_config(struct anthy_input_config *cfg,
1449 old_val = cfg->preedit_mode;
1450 cfg->preedit_mode = val;
1455 anthy_input_change_config(struct anthy_input_config* cfg)
1457 struct anthy_input_context* p;
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];
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);
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);
1484 rk_map_free(hk_map);
1487 struct anthy_input_config*
1488 anthy_input_create_config(void)
1490 struct anthy_input_config* cfg;
1492 cfg = (struct anthy_input_config*) malloc(sizeof(struct anthy_input_config));
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);
1509 anthy_input_free_config(struct anthy_input_config* cfg)
1513 /* ¤³¤Îconfig¤ò¶¦Í¤¹¤ëÁ´¤Æ¤Îcontext¤ò»öÁ°¤Ë²òÊü¤¹¤ë»ö */
1514 assert(!cfg->owners);
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]);
1523 err = anthy_input_free_rk_option(cfg->rk_option);
1528 anthy_input_init(void)
1530 return anthy_init();
1534 anthy_input_set_personality(const char *personality)
1536 anthy_set_personality(personality);
1540 anthy_input_get_anthy_context(struct anthy_input_context *ictx)