2 * ɸ½àÆþ½ÐÎϤǥ³¥Þ¥ó¥É¤ò¼õ¤±¤¿¤ê¡¤ÊÑ´¹·ë²Ì¤òÁ÷¤ë¤Ê¤É¤ÎÄÌ¿®¤ò
3 * ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó(¤ª¤â¤ËEmacs)¤È¹Ô¤¦¤³¤È¤Ë¤è¤ê¡¤¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë
4 * Anthy¤Ë¤è¤ëÆþÎϵ¡Ç½¤òÍưפ«¤Ä°ÂÁ´¤ËÄɲäǤ¤ë¡¥
6 * Funded by IPA̤Ƨ¥½¥Õ¥È¥¦¥§¥¢ÁϤ»ö¶È 2002 2/26
7 * Copyright (C) 2001-2002 UGAWA Tomoharu
8 * Copyright (C) 2002-2004 TABATA Yusuke,
11 * *¥Þ¥ë¥Á¥³¥ó¥Æ¥¥¹¥È¤Î°·¤¤¤ò·è¤á¤«¤Í¤Æ¤¤¤ë
12 * *Æþ½ÐÎϤËstdio¤ò»È¤¦¤«fd¤ò»È¤¦¤«·è¤á¤«¤Í¤Æ¤¤¤ë
16 #include <sys/types.h>
24 #include <anthy/anthy.h>
25 #include <anthy/input.h>
31 extern void egg_main(void);
33 /* ²¿²ó¼¡¸õÊä¤ò²¡¤¹¤È¸õÊä¤ÎÎóµó¤ò°ìÍ÷¥â¡¼¥É¤ËÀÚÂؤ¨¤ë¤«¡© */
34 #define DEFAULT_ENUM_CAND_LIMIT 3
37 /* ¥¡¼¤ËÂбþ¤¹¤ëÄê¿ô */
38 #define KEY_SHIFT 0x00010000
39 #define KEY_CTRL 0x00020000
40 #define KEY_ALT 0x00040000
46 #define KEY_ENTER 0x00000100
47 #define KEY_DELETE 0x00000200
48 #define KEY_LEFT 0x00000300
49 #define KEY_RIGHT 0x00000400
50 #define KEY_ESC 0x00000500
51 #define KEY_BACKSPACE 0x00000600
52 #define KEY_UP 0x00000700
53 #define KEY_DOWN 0x00000800
55 #define KEY_CTRL_A (KEY_CTRL | 'A')
56 #define KEY_CTRL_E (KEY_CTRL | 'E')
57 #define KEY_CTRL_J (KEY_CTRL | 'J')
58 #define KEY_CTRL_K (KEY_CTRL | 'K')
59 #define KEY_CTRL_H (KEY_CTRL | 'H')
60 #define KEY_CTRL_D (KEY_CTRL | 'D')
61 #define KEY_SHIFT_LEFT (KEY_SHIFT | KEY_LEFT)
62 #define KEY_SHIFT_RIGHT (KEY_SHIFT | KEY_RIGHT)
64 #define BUF_GROW_SIZE 4096
66 #define MAX(a,b) ((a) > (b) ? (a) : (b))
70 * ¥³¥Þ¥ó¥É¤Ë¤Ï¥¡¼¤¬²¡¤µ¤ì¤¿¤³¤È¤ò¼¨¤¹ÉáÄ̤Υ³¥Þ¥ó¥É¤È
71 * ¹â¿å½à¤ÊÌ¿Îá¤Î¥Ï¥¤¥ì¥Ù¥ë¥³¥Þ¥ó¥É¤¬¤¢¤ë¡¥
74 /* ¥Ï¥¤¥ì¥Ù¥ë¥³¥Þ¥ó¥É */
75 CMDH_IGNORE_ICTXT, CMDH_GETPREEDIT, CMDH_SELECT_CONTEXT,
76 CMDH_RELEASE_CONTEXT, CMDH_MAP_EDIT, CMDH_MAP_SELECT,
77 CMDH_GET_CANDIDATE, CMDH_SELECT_CANDIDATE, CMDH_CHANGE_TOGGLE,
78 CMDH_MAP_CLEAR, CMDH_SET_BREAK_INTO_ROMAN,
79 CMDH_SET_PREEDIT_MODE, CMDH_PRINT_CONTEXT,
96 struct high_level_command_type {
101 } high_level_command_type[] = {
102 /* ¥³¥ó¥Æ¥¥¹¥È¤Î¾ðÊó¤òɽ¼¨¤¹¤ë */
103 {"PRINT_CONTEXT", CMDH_PRINT_CONTEXT, 0, 0},
104 /* ¥È¥°¥ë¤Ë»È¤¦¥¡¼¤òÊѹ¹¤¹¤ë */
105 {"CHANGE_TOGGLE", CMDH_CHANGE_TOGGLE, 1, 0},
106 /* ¥³¥ó¥Æ¥¥¹¥È¤òÁªÂò¤¹¤ë */
107 {"SELECT_CONTEXT", CMDH_SELECT_CONTEXT, 1, 0},
108 {"RELEASE_CONTEXT", CMDH_RELEASE_CONTEXT, 0, 0},
109 {"MAP_CLEAR", CMDH_MAP_CLEAR, 1, 0},
110 {"MAP_EDIT", CMDH_MAP_EDIT, 3, 0},
111 {"MAP_SELECT", CMDH_MAP_SELECT, 1, 0},
112 {"GET_CANDIDATE", CMDH_GET_CANDIDATE, 1, 0},
113 {"SELECT_CANDIDATE", CMDH_SELECT_CANDIDATE, 1, 0},
114 /* ¥Ð¥Ã¥¯¥¹¥Ú¡¼¥¹¤Ç¥í¡¼¥Þ»ú¤ËÌá¤ë */
115 {"BREAK_INTO_ROMAN", CMDH_SET_BREAK_INTO_ROMAN, 1, 0},
117 {"SET_PREEDIT_MODE", CMDH_SET_PREEDIT_MODE, 1, 0},
126 struct command* next;
141 static void send_error(void);
143 static struct connection* conn;
144 static struct anthy_input_config* config;
145 static struct command* command_queue;
146 static int daemon_sock = -1;
147 static int anonymous;
149 static char *personality;
153 encode_command_arg(char *a)
160 for(i = 0,j = 0; i < len; i++) {
166 /* ¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å */
183 /* ToBeDone ¥¨¥é¡¼¥Á¥§¥Ã¥¯ */
184 strncpy(buf, &a[i+1], 4);
186 sscanf(buf, "%x", (unsigned int *)&num);
187 p = (unsigned char *)buf;
190 j += sprintf(&s[j], "%c%c", buf[1] , buf[0]);
201 ensure_buffer(char** buf, int* size, int to_size)
203 if (*size < to_size) {
204 *buf = (char*) realloc(*buf, to_size);
214 kill_connection(struct connection* conn)
220 static struct command *
221 make_command0(int no)
225 cmd = (struct command*) malloc(sizeof(struct command));
234 static struct command *
235 make_command1(int no, const char* arg1)
239 cmd = (struct command*) malloc(sizeof(struct command));
242 cmd->arg = (char**) malloc(sizeof(char*) * 1);
243 cmd->arg[0] = strdup(arg1);
249 static struct key_name_table {
253 } key_name_table[] = {
254 {"shift", KEY_SHIFT, 1},
255 {"ctrl", KEY_CTRL, 1},
258 {"space", KEY_SPACE, 0},
259 {"opar", KEY_OPAR, 0},
260 {"cpar", KEY_CPAR, 0},
261 {"enter", KEY_ENTER, 0},
263 {"backspace", KEY_BACKSPACE, 0},
264 {"delete", KEY_DELETE, 0},
265 {"left", KEY_LEFT, 0},
266 {"right", KEY_RIGHT, 0},
273 * ¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿¥¡¼¤Î¾ðÊó¤ò¼èÆÀ¤¹¤ë
276 read_encoded_key(char** buf)
284 for (p = *buf + 1; *p; p++) {
299 p = strtok(str, " \t\r");
308 struct key_name_table* e;
310 for (e = key_name_table; e->name; e++) {
311 if (strcmp(e->name, p) == 0) {
313 if (e->is_modifier == 0) {
319 } while((p = strtok(NULL, " \t\r")));
324 static struct high_level_command_type *
325 find_command_type(char *str)
327 struct high_level_command_type* cmdn;
328 for (cmdn = high_level_command_type; cmdn->name; cmdn++) {
329 if (!strcmp(str, cmdn->name)) {
336 /* ¥Ï¥¤¥ì¥Ù¥ë¥³¥Þ¥ó¥É¤ò¥Ñ¡¼¥¹¤¹¤ë */
337 static struct command *
338 make_hl_command(char *buf)
340 /* high-level command */
341 struct high_level_command_type* cmdn;
342 struct command* cmd = NULL;
346 /* ¥³¥Þ¥ó¥É¤Î¼ïÎà¤òÄ´¤Ù¤ë */
347 p = strtok(buf, " \t\r");
351 cmdn = find_command_type(p);
357 cmd = (struct command*) malloc(sizeof(struct command));
358 cmd->cmd = cmdn->cmd;
359 cmd->n_arg = cmdn->n_arg;
360 if (cmd->n_arg > 0) {
361 cmd->arg = (char**) malloc(sizeof(char*) * cmd->n_arg);
365 for (i = 0; i < cmd->n_arg; i++) {
366 p = strtok(NULL, " \t\r");
374 cmd->arg[i] = encode_command_arg(p);
376 while ((p = strtok(NULL, " \t\r"))) {
381 cmd->arg = (char**) realloc(cmd->arg, sizeof(char*) * cmd->n_arg);
382 cmd->arg[cmd->n_arg - 1] = encode_command_arg(p);
388 /* ÉáÄ̤Υ³¥Þ¥ó¥É¤ò¥Ñ¡¼¥¹¤¹¤ë */
389 static struct command *
390 make_ll_command(char *buf)
392 struct command* cmd_head = NULL;
393 struct command* cmd = NULL;
396 for (p = buf; *p; ) {
397 struct command* cmd0 = NULL;
400 if (isspace((int)(unsigned char) *p)) {
403 } else if (*p == '(') {
404 c = read_encoded_key(&p);
413 cmd0 = make_command0(CMD_SPACE);
418 cmd0 = make_command0(CMD_ENTER);
422 cmd0 = make_command0(CMD_BACKSPACE);
426 cmd0 = make_command0(CMD_DELETE);
429 cmd0 = make_command1(CMD_SHIFTARROW, "-1");
431 case KEY_SHIFT_RIGHT:
432 cmd0 = make_command1(CMD_SHIFTARROW, "1");
435 cmd0 = make_command1(CMD_ARROW, "-1");
438 cmd0 = make_command1(CMD_ARROW, "1");
441 cmd0 = make_command0(CMD_UP);
444 cmd0 = make_command0(CMD_ESC);
447 cmd0 = make_command0(CMD_GOBOL);
450 cmd0 = make_command0(CMD_GOEOL);
453 cmd0 = make_command0(CMD_CUT);
456 if ((c & 0xffffff80) == 0) {
463 cmd0 = make_command1(CMD_KEY, str);
479 cmd->next = make_command0(CMDH_GETPREEDIT);
481 cmd_head = make_command0(CMDH_GETPREEDIT);
487 static struct command*
488 make_command(char* buf)
492 /* ¥Ï¥¤¥ì¥Ù¥ë¥³¥Þ¥ó¥É */
494 cmd = make_hl_command(buf);
500 return make_ll_command(buf);
504 proc_connection(void)
514 if (daemon_sock >= 0) {
515 max_fd = daemon_sock;
516 FD_SET(daemon_sock, &rfds);
518 max_fd = MAX(conn->rfd, max_fd);
519 FD_SET(conn->rfd, &rfds);
520 if (conn->n_wbuf > 0) {
521 max_fd = MAX(conn->wfd, max_fd);
522 FD_SET(conn->wfd, &wfds);
528 ret = select(max_fd + 1, &rfds, &wfds, NULL, NULL);
533 if (conn->n_wbuf > 0 && FD_ISSET(conn->wfd, &wfds)) {
534 ret = write(conn->wfd, conn->wbuf, conn->n_wbuf);
536 kill_connection (conn);
539 if (conn->n_wbuf > 0) {
540 memmove(conn->wbuf, conn->wbuf + ret, conn->n_wbuf);
545 if (FD_ISSET(conn->rfd, &rfds)) {
546 ensure_buffer(&conn->rbuf, &conn->s_rbuf,
547 conn->n_rbuf + BUF_GROW_SIZE);
548 ret = read(conn->rfd,
549 conn->rbuf + conn->n_rbuf, conn->s_rbuf - conn->n_rbuf);
551 kill_connection (conn);
559 static struct command *
565 if (command_queue != NULL) {
567 command_queue = cmd->next;
574 for (p = conn->rbuf; p < conn->rbuf + conn->n_rbuf; p++) {
577 cmd = make_command(conn->rbuf);
578 conn->n_rbuf -= p + 1 - conn->rbuf;
579 memmove(conn->rbuf, p + 1, conn->n_rbuf);
587 if (proc_connection() == -1) {
595 write_reply(const char* buf)
603 write_reply("ERR\r\n");
609 write_reply("OK\r\n");
613 send_number10(int num)
617 sprintf(buf, "%d", num);
622 send_string(const char* str)
628 send_quote_string(const char* str)
630 char buf[20]; /* ¤³¤Î¤°¤é¤¤¤¢¤ì¤ÐÂçÄñÂç¾æÉ× */
634 end = buf + sizeof(buf) - 2;
635 for (q = buf, p = str; *p;) {
658 send_preedit(struct anthy_input_preedit* pedit)
661 send_number10(pedit->state);
663 if (pedit->commit != NULL) {
664 send_string(" ((COMMIT) \"");
665 send_quote_string(pedit->commit);
669 if (pedit->cut_buf != NULL) {
670 send_string(" ((CUTBUF) \"");
671 send_quote_string(pedit->cut_buf);
675 switch (pedit->state) {
676 case ANTHY_INPUT_ST_OFF:
677 case ANTHY_INPUT_ST_NONE:
679 case ANTHY_INPUT_ST_EDIT:
680 case ANTHY_INPUT_ST_CONV:
681 case ANTHY_INPUT_ST_CSEG:
683 struct anthy_input_segment* seg;
685 for (seg = pedit->segment; seg; seg = seg->next) {
686 if (seg->str == NULL) {
687 if (seg->flag & ANTHY_INPUT_SF_CURSOR)
688 send_string(" cursor");
690 if (seg->flag & ANTHY_INPUT_SF_CURSOR) {
691 if (seg->flag & ANTHY_INPUT_SF_ENUM)
692 send_string(" ((UL RV ENUM) \"");
693 else if (seg->flag & ANTHY_INPUT_SF_ENUM_REVERSE)
694 send_string(" ((UL RV ENUMR) \"");
696 send_string(" ((UL RV) \"");
698 send_string(" ((UL) \"");
700 send_quote_string(seg->str);
702 send_number10(seg->cand_no);
704 send_number10(seg->nr_cand);
712 send_string(")\r\n");
716 send_single_candidate(struct anthy_input_segment* seg)
719 send_quote_string(seg->str);
721 send_number10(seg->cand_no);
723 send_number10(seg->nr_cand);
724 send_string(")\r\n");
728 free_command(struct command* cmd)
732 for (i = 0; i < cmd->n_arg; i++)
738 struct input_context_list {
740 struct anthy_input_context* ictx;
741 struct input_context_list* next;
744 static struct input_context_list* ictx_list = NULL;
747 new_input_context(int id)
749 struct input_context_list* ictxl;
752 (struct input_context_list*) malloc(sizeof (struct input_context_list));
754 ictxl->ictx = anthy_input_create_context(config);
755 ictxl->next = ictx_list;
759 static struct anthy_input_context*
760 get_current_input_context(void)
762 if (ictx_list == NULL)
763 new_input_context(0);
765 return ictx_list->ictx;
769 cmdh_get_preedit(struct anthy_input_context* ictx)
771 struct anthy_input_preedit* pedit;
773 pedit = anthy_input_get_preedit(ictx);
775 anthy_input_free_preedit(pedit);
779 cmdh_select_input_context(struct command* cmd)
782 struct input_context_list** p;
784 id = atoi(cmd->arg[0]);
785 for (p = &ictx_list; *p; p = &(*p)->next) {
786 if ((*p)->id == id) {
787 struct input_context_list* sel;
790 sel->next = ictx_list;
797 new_input_context(id);
802 cmdh_release_input_context(struct command* cmd)
804 struct input_context_list* sel;
811 ictx_list = ictx_list->next;
812 anthy_input_free_context(sel->ictx);
818 cmdh_change_toggle(struct command *cmd)
820 int toggle = cmd->arg[0][0];
823 ret = anthy_input_edit_toggle_config(config, toggle);
829 anthy_input_change_config(config);
834 cmdh_map_clear(struct command *cmd)
836 anthy_input_clear_rk_config(config, atoi(cmd->arg[0]));
837 anthy_input_change_config(config);
842 cmdh_set_break_into_roman(struct command *cmd)
844 anthy_input_break_into_roman_config(config, atoi(cmd->arg[0]));
845 anthy_input_change_config(config);
850 cmdh_set_preedit_mode(struct command *cmd)
852 anthy_input_preedit_mode_config(config, atoi(cmd->arg[0]));
853 anthy_input_change_config(config);
858 cmdh_map_edit(struct command* cmd)
861 int map_no = atoi(cmd->arg[0]);
864 ret = anthy_input_edit_rk_config(config, map_no,
865 cmd->arg[1], cmd->arg[2], NULL);
871 anthy_input_change_config(config);
876 cmdh_map_select(struct anthy_input_context* ictx,
882 map_name = cmd->arg[0];
883 if (strcmp(map_name, "alphabet") == 0)
884 map_no = ANTHY_INPUT_MAP_ALPHABET;
885 else if (strcmp(map_name, "hiragana") == 0)
886 map_no = ANTHY_INPUT_MAP_HIRAGANA;
887 else if (strcmp(map_name, "katakana") == 0)
888 map_no = ANTHY_INPUT_MAP_KATAKANA;
889 else if (strcmp(map_name, "walphabet") == 0)
890 map_no = ANTHY_INPUT_MAP_WALPHABET;
891 else if (strcmp(map_name, "hankaku_kana") == 0)
892 map_no = ANTHY_INPUT_MAP_HANKAKU_KANA;
898 anthy_input_map_select(ictx, map_no);
903 cmdh_get_candidate(struct anthy_input_context* ictx,
906 struct anthy_input_segment* seg;
909 cand_no = atoi(cmd->arg[0]);
911 seg = anthy_input_get_candidate(ictx, cand_no);
915 send_single_candidate(seg);
916 anthy_input_free_segment(seg);
921 cmdh_select_candidate(struct anthy_input_context* ictx,
927 cand_no = atoi(cmd->arg[0]);
928 ret = anthy_input_select_candidate(ictx, cand_no);
932 cmdh_get_preedit(ictx);
937 cmd_shift_arrow(struct anthy_input_context* ictx,
940 int lr = atoi(cmd->arg[0]);
941 anthy_input_resize(ictx, lr);
945 cmd_arrow(struct anthy_input_context* ictx, struct command* cmd)
947 int lr = atoi(cmd->arg[0]);
948 anthy_input_move(ictx, lr);
952 cmd_key(struct anthy_input_context* ictx, struct command* cmd)
954 anthy_input_str(ictx, cmd->arg[0]);
958 * ¥³¥Þ¥ó¥É¤ò¥Ç¥£¥¹¥Ñ¥Ã¥Á¤¹¤ë
961 dispatch_command(struct anthy_input_context* ictx,
965 case CMDH_IGNORE_ICTXT:
968 case CMDH_PRINT_CONTEXT:
969 /* Dirty implementation, would cause corrpution.*/
971 anthy_context_t ac = anthy_input_get_anthy_context(ictx);
973 anthy_print_context(ac);
977 case CMDH_GETPREEDIT:
978 cmdh_get_preedit(ictx);
980 case CMDH_SELECT_CONTEXT:
981 cmdh_select_input_context(cmd);
983 case CMDH_RELEASE_CONTEXT:
984 cmdh_release_input_context(cmd);
989 case CMDH_CHANGE_TOGGLE:
990 cmdh_change_toggle(cmd);
995 case CMDH_MAP_SELECT:
996 cmdh_map_select(ictx, cmd);
998 case CMDH_GET_CANDIDATE:
999 cmdh_get_candidate(ictx, cmd);
1001 case CMDH_SELECT_CANDIDATE:
1002 cmdh_select_candidate(ictx, cmd);
1004 case CMDH_SET_BREAK_INTO_ROMAN:
1005 cmdh_set_break_into_roman(cmd);
1007 case CMDH_SET_PREEDIT_MODE:
1008 cmdh_set_preedit_mode(cmd);
1010 /* key commands follows */
1013 anthy_input_space(ictx);
1016 anthy_input_commit(ictx);
1019 anthy_input_erase_prev(ictx);
1022 anthy_input_erase_next(ictx);
1025 anthy_input_prev_candidate(ictx);
1028 anthy_input_quit(ictx);
1030 case CMD_SHIFTARROW:
1031 cmd_shift_arrow(ictx, cmd);
1034 cmd_arrow(ictx, cmd);
1040 anthy_input_beginning_of_line(ictx);
1043 anthy_input_end_of_line(ictx);
1046 anthy_input_cut(ictx);
1054 struct anthy_input_context* ictx;
1055 struct command* cmd;
1058 cmd = read_command();
1061 ictx = get_current_input_context();
1063 dispatch_command(ictx, cmd);
1073 printf(PACKAGE "-agent "VERSION "\n");
1078 parse_args(int argc, char **argv)
1081 char *conffile = NULL, *dir = NULL, *dic = NULL;
1084 for (i = 1; i < argc; i++) {
1085 char *str = argv[i];
1086 if (!strcmp("--version", str)) {
1088 } else if (!strcmp("--anonymous", str)) {
1090 } else if (!strcmp("--egg", str)) {
1092 } else if (!strncmp("--personality=", str, 14)) {
1093 personality = &str[14];
1094 } else if (!strcmp("--utf8", str)) {
1096 } else if (i < argc - 1) {
1097 char *arg = argv[i+1];
1098 if (!strcmp("--dir", str)) {
1101 } else if (!strcmp("--dic", str)) {
1104 } else if (!strcmp("--conffile", str)) {
1111 anthy_conf_override("CONFFILE", conffile);
1114 anthy_conf_override("ANTHYDIR", dir);
1117 anthy_conf_override("SDIC", dic);
1122 main(int argc, char **argv)
1124 parse_args(argc, argv);
1125 if (anthy_input_init()) {
1126 printf("Failed to init anthy\n");
1130 anthy_input_set_personality("");
1131 } else if (personality) {
1132 anthy_input_set_personality(personality);
1139 config = anthy_input_create_config();
1140 conn = (struct connection*) malloc(sizeof(struct connection));