(linenum→info "unix/slp.c:2238")

anthy/9100e/src-util/agent.c

    1: /* 
    2:  * 標準入出力でコマンドを受けたり,変換結果を送るなどの通信を
    3:  * アプリケーション(おもにEmacs)と行うことにより,アプリケーションに
    4:  * Anthyによる入力機能を容易かつ安全に追加できる.
    5:  *
    6:  * Funded by IPA未踏ソフトウェア創造事業 2002 2/26
    7:  * Copyright (C) 2001-2002 UGAWA Tomoharu
    8:  * Copyright (C) 2002-2004 TABATA Yusuke,
    9:  */
   10: /*
   11:  * *マルチコンテキストの扱いを決めかねている
   12:  * *入出力にstdioを使うかfdを使うか決めかねている
   13:  */
   14: 
   15: #include <sys/time.h>
   16: #include <sys/types.h>
   17: #include <unistd.h>
   18: #include <string.h>
   19: #include <stdio.h>
   20: #include <stdlib.h>
   21: #include <ctype.h>
   22: #include <assert.h>
   23: 
   24: #include <anthy/anthy.h>
   25: #include <anthy/input.h>
   26: 
   27: #include "rkconv.h"
   28: 
   29: #include <config.h>
   30: 
   31: extern void egg_main(void);
   32: 
   33: /* 何回次候補を押すと候補の列挙を一覧モードに切替えるか? */
   34: #define DEFAULT_ENUM_CAND_LIMIT 3
   35: 
   36: 
   37: /* キーに対応する定数 */
   38: #define KEY_SHIFT   0x00010000
   39: #define KEY_CTRL    0x00020000
   40: #define KEY_ALT     0x00040000
   41: 
   42: #define KEY_SPACE   ' '
   43: #define KEY_OPAR    '('
   44: #define KEY_CPAR    ')'
   45: 
   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
   54: 
   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)
   63: 
   64: #define BUF_GROW_SIZE 4096
   65: 
   66: #define MAX(a,b) ((a) > (b) ? (a) : (b))
   67: 
   68: 
   69: /*
   70:  * コマンドにはキーが押されたことを示す普通のコマンドと
   71:  * 高水準な命令のハイレベルコマンドがある.
   72:  */
   73: enum {
   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,
   80: 
   81:   /* キーコマンド */
   82:   CMD_SPACE = 1000,
   83:   CMD_ENTER,
   84:   CMD_BACKSPACE, 
   85:   CMD_DELETE,
   86:   CMD_UP,
   87:   CMD_ESC,
   88:   CMD_SHIFTARROW,
   89:   CMD_ARROW,
   90:   CMD_KEY,
   91:   CMD_GOBOL,
   92:   CMD_GOEOL,
   93:   CMD_CUT
   94: };
   95: 
   96: struct high_level_command_type {
   97:   const char* name;
   98:   int cmd;
   99:   int n_arg;
  100:   int opt_arg;
  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},
  116:   /**/
  117:   {"SET_PREEDIT_MODE", CMDH_SET_PREEDIT_MODE, 1, 0},
  118:   /**/
  119:   {NULL, -1, 0, 0}
  120: };
Permalink to this note guest: anthy/9100e/src-util/agent.c:96-120 on Fri Feb 29 19:14:21 +0900 2008

ハイレベルコマンドの文字列定義

121: 122: struct command { 123: int cmd; 124: char** arg; 125: int n_arg; 126: struct command* next; 127: }; 128: 129: struct connection { 130: char* rbuf; 131: int n_rbuf; 132: int s_rbuf; 133: int rfd; 134: 135: char* wbuf; 136: int n_wbuf; 137: int s_wbuf; 138: int wfd; 139: }; 140: 141: static void send_error(void); 142: 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; 148: static int egg; 149: static char *personality; 150: int use_utf8; 151: 152: static char * 153: encode_command_arg(char *a) 154: { 155: int i, j, len; 156: char *s; 157: 158: len = strlen(a); 159: s = malloc(len + 1); 160: for(i = 0,j = 0; i < len; i++) { 161: if (a[i] != '\\') { 162: s[j] = a[i]; 163: j++; 164: continue; 165: } 166: /* バックスラッシュ */ 167: i++; 168: switch (a[i]) { 169: case 0: 170: case '\\': 171: s[j] = '\\'; 172: j++; 173: break; 174: case '\"': 175: s[j] = '\"'; 176: j++; 177: break; 178: case 'X': 179: { 180: char buf[5]; 181: unsigned char *p; 182: int num; 183: /* ToBeDone エラーチェック */ 184: strncpy(buf, &a[i+1], 4); 185: i+= 5; 186: sscanf(buf, "%x", (unsigned int *)&num); 187: p = (unsigned char *)buf; 188: p[0] = num & 255; 189: p[1] = num >> 8; 190: j += sprintf(&s[j], "%c%c", buf[1] , buf[0]); 191: } 192: break; 193: } 194: } 195: s[j] = 0; 196: 197: return s; 198: } 199: 200: static int 201: ensure_buffer(char** buf, int* size, int to_size) 202: { 203: if (*size < to_size) { 204: *buf = (char*) realloc(*buf, to_size); 205: if (*buf == NULL) { 206: return -1; 207: } 208: *size = to_size; 209: } 210: return 0; 211: } 212: 213: static void 214: kill_connection(struct connection* conn) 215: { 216: (void) conn; 217: exit(0); 218: } 219: 220: static struct command * 221: make_command0(int no) 222: { 223: struct command* cmd; 224: 225: cmd = (struct command*) malloc(sizeof(struct command)); 226: cmd->cmd = no; 227: cmd->n_arg = 0; 228: cmd->arg = NULL; 229: cmd->next = NULL; 230: 231: return cmd; 232: } 233: 234: static struct command * 235: make_command1(int no, const char* arg1) 236: { 237: struct command* cmd; 238: 239: cmd = (struct command*) malloc(sizeof(struct command)); 240: cmd->cmd = no; 241: cmd->n_arg = 1; 242: cmd->arg = (char**) malloc(sizeof(char*) * 1); 243: cmd->arg[0] = strdup(arg1); 244: cmd->next = NULL; 245: 246: return cmd; 247: } 248: 249: static struct key_name_table { 250: const char* name; 251: int code; 252: int is_modifier; 253: } key_name_table[] = { 254: {"shift", KEY_SHIFT, 1}, 255: {"ctrl", KEY_CTRL, 1}, 256: {"alt", KEY_ALT, 1}, 257: 258: {"space", KEY_SPACE, 0}, 259: {"opar", KEY_OPAR, 0}, 260: {"cpar", KEY_CPAR, 0}, 261: {"enter", KEY_ENTER, 0}, 262: {"esc", KEY_ESC, 0}, 263: {"backspace", KEY_BACKSPACE, 0}, 264: {"delete", KEY_DELETE, 0}, 265: {"left", KEY_LEFT, 0}, 266: {"right", KEY_RIGHT, 0}, 267: {"up", KEY_UP, 0}, 268: 269: {NULL, 0, 0} 270: }; 271: 272: /* 273: * エンコードされたキーの情報を取得する 274: */ 275: static int 276: read_encoded_key(char** buf) 277: { 278: char* p; 279: char* str; 280: 281: int key = 0; 282: 283: /* 閉じ括弧を探す */ 284: for (p = *buf + 1; *p; p++) { 285: if (*p == ')') { 286: break; 287: } 288: } 289: 290: if (*p == '\0') { 291: *buf = p; 292: return '\0'; 293: } 294: 295: str = *buf + 1; 296: *p = '\0'; 297: *buf = p + 1; 298: 299: p = strtok(str, " \t\r"); 300: if (!p) { 301: return '\0'; 302: } 303: 304: do { 305: if (p[1] == '\0') { 306: return key | *p; 307: } else { 308: struct key_name_table* e; 309: 310: for (e = key_name_table; e->name; e++) { 311: if (strcmp(e->name, p) == 0) { 312: key |= e->code; 313: if (e->is_modifier == 0) { 314: return key; 315: } 316: } 317: } 318: } 319: } while((p = strtok(NULL, " \t\r"))); 320: 321: return '\0'; 322: } 323: 324: static struct high_level_command_type * 325: find_command_type(char *str) 326: { 327: struct high_level_command_type* cmdn; 328: for (cmdn = high_level_command_type; cmdn->name; cmdn++) { 329: if (!strcmp(str, cmdn->name)) { 330: return cmdn; 331: } 332: } 333: return NULL; 334: } 335: 336: /* ハイレベルコマンドをパースする */ 337: static struct command * 338: make_hl_command(char *buf) 339: { 340: /* high-level command */ 341: struct high_level_command_type* cmdn; 342: struct command* cmd = NULL; 343: char* p; 344: int i; 345: 346: /* コマンドの種類を調べる */ 347: p = strtok(buf, " \t\r"); 348: if (!p) { 349: return NULL; 350: } 351: cmdn = find_command_type(p); 352: if (!cmdn) { 353: return NULL; 354: } 355: 356: /* コマンドを作る */ 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); 362: } else { 363: cmd->arg = NULL; 364: } 365: for (i = 0; i < cmd->n_arg; i++) { 366: p = strtok(NULL, " \t\r"); 367: if (!p) { 368: while (i-- > 0) 369: free(cmd->arg[i]); 370: free(cmd->arg); 371: free(cmd); 372: return NULL; 373: } 374: cmd->arg[i] = encode_command_arg(p); 375: } 376: while ((p = strtok(NULL, " \t\r"))) { 377: if (!p) { 378: break; 379: } 380: cmd->n_arg++; 381: cmd->arg = (char**) realloc(cmd->arg, sizeof(char*) * cmd->n_arg); 382: cmd->arg[cmd->n_arg - 1] = encode_command_arg(p); 383: } 384: cmd->next = NULL; 385: return cmd; 386: } 387: 388: /* 普通のコマンドをパースする */ 389: static struct command * 390: make_ll_command(char *buf) 391: { 392: struct command* cmd_head = NULL; 393: struct command* cmd = NULL; 394: char* p; 395: 396: for (p = buf; *p; ) { 397: struct command* cmd0 = NULL; 398: int c; 399: 400: if (isspace((int)(unsigned char) *p)) { 401: p++; 402: continue; 403: } else if (*p == '(') { 404: c = read_encoded_key(&p); 405: } else { 406: c = *p++; 407: } 408: 409: switch (c) { 410: case '\0': 411: break; 412: case KEY_SPACE: 413: cmd0 = make_command0(CMD_SPACE); 414: break; 415: case KEY_CTRL_J: 416: case KEY_ENTER: 417: case KEY_DOWN: 418: cmd0 = make_command0(CMD_ENTER); 419: break; 420: case KEY_BACKSPACE: 421: case KEY_CTRL_H: 422: cmd0 = make_command0(CMD_BACKSPACE); 423: break; 424: case KEY_DELETE: 425: case KEY_CTRL_D: 426: cmd0 = make_command0(CMD_DELETE); 427: break; 428: case KEY_SHIFT_LEFT: 429: cmd0 = make_command1(CMD_SHIFTARROW, "-1"); 430: break; 431: case KEY_SHIFT_RIGHT: 432: cmd0 = make_command1(CMD_SHIFTARROW, "1"); 433: break; 434: case KEY_LEFT: 435: cmd0 = make_command1(CMD_ARROW, "-1"); 436: break; 437: case KEY_RIGHT: 438: cmd0 = make_command1(CMD_ARROW, "1"); 439: break; 440: case KEY_UP: 441: cmd0 = make_command0(CMD_UP); 442: break; 443: case KEY_ESC: 444: cmd0 = make_command0(CMD_ESC); 445: break; 446: case KEY_CTRL_A: 447: cmd0 = make_command0(CMD_GOBOL); 448: break; 449: case KEY_CTRL_E: 450: cmd0 = make_command0(CMD_GOEOL); 451: break; 452: case KEY_CTRL_K: 453: cmd0 = make_command0(CMD_CUT); 454: break; 455: default: 456: if ((c & 0xffffff80) == 0) { 457: /* ASCII文字 */ 458: char str[2]; 459: 460: str[0] = (char)c; 461: str[1] = '\0'; 462: /* cmd_key */ 463: cmd0 = make_command1(CMD_KEY, str); 464: } 465: break; 466: } 467: 468: if (cmd0) { 469: if (cmd) { 470: cmd->next = cmd0; 471: } else { 472: cmd_head = cmd0; 473: } 474: cmd = cmd0; 475: } 476: } /* for (p) */ 477: 478: if (cmd) { 479: cmd->next = make_command0(CMDH_GETPREEDIT); 480: } else { 481: cmd_head = make_command0(CMDH_GETPREEDIT); 482: } 483: 484: return cmd_head; 485: } 486: 487: static struct command* 488: make_command(char* buf) 489: { 490: 491: if (*buf == ' ') { 492: /* ハイレベルコマンド */ 493: struct command *cmd; 494: cmd = make_hl_command(buf); 495: if (!cmd) { 496: send_error(); 497: } 498: return cmd; 499: } 500: return make_ll_command(buf); 501: } 502: 503: static int 504: proc_connection(void)
Permalink to this note guest: anthy/9100e/src-util/agent.c:503-504 on Fri Feb 29 18:44:11 +0900 2008

標準入力を処理する

505: { 506: fd_set rfds; 507: fd_set wfds; 508: int max_fd; 509: int ret; 510: 511: max_fd = -1; 512: FD_ZERO(&rfds); 513: FD_ZERO(&wfds); 514: if (daemon_sock >= 0) { 515: max_fd = daemon_sock; 516: FD_SET(daemon_sock, &rfds); 517: } 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); 523: } 524: 525: if (max_fd == -1) 526: return -1; 527: 528: ret = select(max_fd + 1, &rfds, &wfds, NULL, NULL); 529: if (ret < 0) { 530: return -1; 531: } 532: 533: if (conn->n_wbuf > 0 && FD_ISSET(conn->wfd, &wfds)) { 534: ret = write(conn->wfd, conn->wbuf, conn->n_wbuf); 535: if (ret <= 0) { 536: kill_connection (conn); 537: } else { 538: conn->n_wbuf -= ret; 539: if (conn->n_wbuf > 0) { 540: memmove(conn->wbuf, conn->wbuf + ret, conn->n_wbuf); 541: } 542: } 543: } 544: 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); 550: if (ret <= 0) { 551: kill_connection (conn); 552: } else { 553: conn->n_rbuf += ret; 554: } 555: } 556: return 0; 557: } 558: 559: static struct command * 560: read_command(void) 561: { 562: struct command* cmd; 563: 564: AGAIN: 565: if (command_queue != NULL) { 566: cmd = command_queue; 567: command_queue = cmd->next; 568: return cmd; 569: } 570: 571: while (1) { 572: 573: char* p; 574: for (p = conn->rbuf; p < conn->rbuf + conn->n_rbuf; p++) { 575: if (*p == '\n') { 576: *p = '\0'; 577: cmd = make_command(conn->rbuf); 578: conn->n_rbuf -= p + 1 - conn->rbuf; 579: memmove(conn->rbuf, p + 1, conn->n_rbuf); 580: if (cmd) { 581: command_queue = cmd; 582: goto AGAIN; 583: } 584: } 585: } 586: 587: if (proc_connection() == -1) { 588: return NULL; 589: } 590: 591: } 592: } 593: 594: static void 595: write_reply(const char* buf) 596: { 597: printf("%s", buf); 598: } 599: 600: static void 601: send_error(void) 602: { 603: write_reply("ERR\r\n"); 604: } 605: 606: static void 607: send_ok(void) 608: { 609: write_reply("OK\r\n"); 610: } 611: 612: static void 613: send_number10(int num) 614: { 615: char buf[20]; 616: 617: sprintf(buf, "%d", num); 618: write_reply(buf); 619: } 620: 621: static void 622: send_string(const char* str) 623: { 624: write_reply(str); 625: } 626: 627: static void 628: send_quote_string(const char* str) 629: { 630: char buf[20]; /* このぐらいあれば大抵大丈夫 */ 631: const char *p; 632: char *q, *end; 633: 634: end = buf + sizeof(buf) - 2; 635: for (q = buf, p = str; *p;) { 636: if (q >= end) { 637: *q = '\0'; 638: write_reply(buf); 639: q = buf; 640: } 641: 642: switch (*p) { 643: case '\"': 644: case '\\': 645: *q++ = '\\'; 646: break; 647: default: 648: break; 649: } 650: 651: *q++ = *p++; 652: } 653: *q = '\0'; 654: write_reply(buf); 655: } 656: 657: static void 658: send_preedit(struct anthy_input_preedit* pedit) 659: { 660: send_string("("); 661: send_number10(pedit->state); 662: 663: if (pedit->commit != NULL) { 664: send_string(" ((COMMIT) \""); 665: send_quote_string(pedit->commit); 666: send_string("\")"); 667: } 668: 669: if (pedit->cut_buf != NULL) { 670: send_string(" ((CUTBUF) \""); 671: send_quote_string(pedit->cut_buf); 672: send_string("\")"); 673: } 674: 675: switch (pedit->state) { 676: case ANTHY_INPUT_ST_OFF: 677: case ANTHY_INPUT_ST_NONE: 678: break; 679: case ANTHY_INPUT_ST_EDIT: 680: case ANTHY_INPUT_ST_CONV: 681: case ANTHY_INPUT_ST_CSEG: 682: { 683: struct anthy_input_segment* seg; 684: 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"); 689: } else { 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) \""); 695: else 696: send_string(" ((UL RV) \""); 697: } else 698: send_string(" ((UL) \""); 699: 700: send_quote_string(seg->str); 701: send_string("\" "); 702: send_number10(seg->cand_no); 703: send_string(" "); 704: send_number10(seg->nr_cand); 705: send_string(")"); 706: } 707: } 708: } 709: break; 710: } 711: 712: send_string(")\r\n"); 713: } 714: 715: static void 716: send_single_candidate(struct anthy_input_segment* seg) 717: { 718: send_string("(\""); 719: send_quote_string(seg->str); 720: send_string("\" "); 721: send_number10(seg->cand_no); 722: send_string(" "); 723: send_number10(seg->nr_cand); 724: send_string(")\r\n"); 725: } 726: 727: static void 728: free_command(struct command* cmd) 729: { 730: int i; 731: 732: for (i = 0; i < cmd->n_arg; i++) 733: free(cmd->arg[i]); 734: free(cmd->arg); 735: free(cmd); 736: } 737: 738: struct input_context_list { 739: int id; 740: struct anthy_input_context* ictx; 741: struct input_context_list* next; 742: }; 743: 744: static struct input_context_list* ictx_list = NULL; 745: 746: static void 747: new_input_context(int id) 748: { 749: struct input_context_list* ictxl; 750: 751: ictxl = 752: (struct input_context_list*) malloc(sizeof (struct input_context_list)); 753: ictxl->id = id; 754: ictxl->ictx = anthy_input_create_context(config); 755: ictxl->next = ictx_list; 756: ictx_list = ictxl; 757: } 758: 759: static struct anthy_input_context* 760: get_current_input_context(void) 761: { 762: if (ictx_list == NULL) 763: new_input_context(0); 764: 765: return ictx_list->ictx; 766: } 767: 768: static void 769: cmdh_get_preedit(struct anthy_input_context* ictx) 770: { 771: struct anthy_input_preedit* pedit; 772: 773: pedit = anthy_input_get_preedit(ictx); 774: send_preedit(pedit); 775: anthy_input_free_preedit(pedit); 776: } 777: 778: static void 779: cmdh_select_input_context(struct command* cmd) 780: { 781: int id; 782: struct input_context_list** p; 783: 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; 788: sel = *p; 789: *p = sel->next; 790: sel->next = ictx_list; 791: ictx_list = sel; 792: send_ok(); 793: return; 794: } 795: } 796: 797: new_input_context(id); 798: send_ok(); 799: } 800: 801: static void 802: cmdh_release_input_context(struct command* cmd) 803: { 804: struct input_context_list* sel; 805: (void)cmd; 806: if (!ictx_list) { 807: send_ok(); 808: return ; 809: } 810: sel = ictx_list; 811: ictx_list = ictx_list->next; 812: anthy_input_free_context(sel->ictx); 813: free(sel); 814: send_ok(); 815: } 816: 817: static void 818: cmdh_change_toggle(struct command *cmd) 819: { 820: int toggle = cmd->arg[0][0]; 821: int ret; 822: 823: ret = anthy_input_edit_toggle_config(config, toggle); 824: 825: if (ret != 0) { 826: send_error(); 827: return; 828: } 829: anthy_input_change_config(config); 830: send_ok(); 831: } 832: 833: static void 834: cmdh_map_clear(struct command *cmd) 835: { 836: anthy_input_clear_rk_config(config, atoi(cmd->arg[0])); 837: anthy_input_change_config(config); 838: send_ok(); 839: } 840: 841: static void 842: cmdh_set_break_into_roman(struct command *cmd) 843: { 844: anthy_input_break_into_roman_config(config, atoi(cmd->arg[0])); 845: anthy_input_change_config(config); 846: send_ok(); 847: } 848: 849: static void 850: cmdh_set_preedit_mode(struct command *cmd) 851: { 852: anthy_input_preedit_mode_config(config, atoi(cmd->arg[0])); 853: anthy_input_change_config(config); 854: send_ok(); 855: } 856: 857: static void 858: cmdh_map_edit(struct command* cmd) 859: { 860: /* MAP,from,to */ 861: int map_no = atoi(cmd->arg[0]); 862: int ret; 863: 864: ret = anthy_input_edit_rk_config(config, map_no, 865: cmd->arg[1], cmd->arg[2], NULL); 866: 867: if (ret != 0) { 868: send_error(); 869: return; 870: } 871: anthy_input_change_config(config); 872: send_ok(); 873: } 874: 875: static void 876: cmdh_map_select(struct anthy_input_context* ictx, 877: struct command* cmd) 878: { 879: char* map_name; 880: int map_no; 881: 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; 893: else { 894: send_error(); 895: return; 896: } 897: 898: anthy_input_map_select(ictx, map_no); 899: send_ok(); 900: } 901: 902: static void 903: cmdh_get_candidate(struct anthy_input_context* ictx, 904: struct command* cmd) 905: { 906: struct anthy_input_segment* seg; 907: int cand_no; 908: 909: cand_no = atoi(cmd->arg[0]); 910: 911: seg = anthy_input_get_candidate(ictx, cand_no); 912: if (seg == NULL) 913: send_error(); 914: else { 915: send_single_candidate(seg); 916: anthy_input_free_segment(seg); 917: } 918: } 919: 920: static void 921: cmdh_select_candidate(struct anthy_input_context* ictx, 922: struct command* cmd) 923: { 924: int ret; 925: int cand_no; 926: 927: cand_no = atoi(cmd->arg[0]); 928: ret = anthy_input_select_candidate(ictx, cand_no); 929: if (ret < 0) { 930: send_error(); 931: } else { 932: cmdh_get_preedit(ictx); 933: } 934: } 935: 936: static void 937: cmd_shift_arrow(struct anthy_input_context* ictx, 938: struct command* cmd) 939: { 940: int lr = atoi(cmd->arg[0]); 941: anthy_input_resize(ictx, lr); 942: } 943: 944: static void 945: cmd_arrow(struct anthy_input_context* ictx, struct command* cmd) 946: { 947: int lr = atoi(cmd->arg[0]); 948: anthy_input_move(ictx, lr); 949: } 950: 951: static void 952: cmd_key(struct anthy_input_context* ictx, struct command* cmd) 953: { 954: anthy_input_str(ictx, cmd->arg[0]); 955: } 956: 957: /* 958: * コマンドをディスパッチする 959: */ 960: static void 961: dispatch_command(struct anthy_input_context* ictx, 962: struct command* cmd) 963: { 964: switch (cmd->cmd) { 965: case CMDH_IGNORE_ICTXT: 966: send_error(); 967: break; 968: case CMDH_PRINT_CONTEXT: 969: /* Dirty implementation, would cause corrpution.*/ 970: { 971: anthy_context_t ac = anthy_input_get_anthy_context(ictx); 972: if (ac) { 973: anthy_print_context(ac); 974: } 975: } 976: break; 977: case CMDH_GETPREEDIT: 978: cmdh_get_preedit(ictx); 979: break; 980: case CMDH_SELECT_CONTEXT: 981: cmdh_select_input_context(cmd); 982: break; 983: case CMDH_RELEASE_CONTEXT: 984: cmdh_release_input_context(cmd); 985: break; 986: case CMDH_MAP_EDIT: 987: cmdh_map_edit(cmd); 988: break; 989: case CMDH_CHANGE_TOGGLE: 990: cmdh_change_toggle(cmd); 991: break; 992: case CMDH_MAP_CLEAR: 993: cmdh_map_clear(cmd); 994: break; 995: case CMDH_MAP_SELECT: 996: cmdh_map_select(ictx, cmd); 997: break; 998: case CMDH_GET_CANDIDATE: 999: cmdh_get_candidate(ictx, cmd); 1000: break;
1 2
Syntax (Markdown)