/* * Copyright (C) 1994,1995 Edward Der-Hua Liu, Hsin-Chu, Taiwan */ /* * modified for Big5Con by Hung-Chi Chu */ #include "big5con.h" int cursor_x = 0; static u_char cur_att = NormalColor; extern u_char *cin_textBuff, *cin_attrBuff, *cin_flagBuff; extern struct dispInfo dInfo; void p_err(char *fmt,...) { va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); fprintf(stderr, "\n"); exit(-1); } void bell() { fputc(007, stderr); } static void ostr(int x, char *str, int len, u_char attr) { memcpy(cin_textBuff + x, str, len); memset(cin_attrBuff + x, attr, len); memset(cin_flagBuff + x, 0, len); } static void costr(int x, char *str, int len, u_char attr) { u_char *dst, *end; memcpy(cin_textBuff + x, str, len); memset(cin_attrBuff + x, attr, len); for (dst = cin_flagBuff + x, end = dst + len; dst < end; dst += 2) { *dst = DF_BIG5_1 | LATCH_1; *(dst + 1) = DF_BIG5_1 | LATCH_2; } } static xputs(int x, u_char * s) { u_char ch; int len = strlen(s); int cl = 0; u_char *cp, *endp, *strp; char ctyp; u_char hb, lb; strp = cp = s; endp = s + len; cl = 0; ctyp = 0; while (cp < endp) { hb = *cp; if ((hb >= 0x81 && hb <= 0xfe) && cp + 1 < endp) { lb = *(cp + 1); if (lb >= 0x40 && lb <= 0x7e || lb >= 0xa1 && lb <= 0xfe) { if (ctyp == 1) { ostr(strp - s + x, strp, cl, cur_att); cl = 0; strp = cp; } cl += 2; cp += 2; ctyp = 2; continue; } } if (ctyp == 2) { costr(strp - s + x, strp, cl, cur_att); cl = 0; strp = cp; } cl++; cp++; ctyp = 1; } if (ctyp == 1) ostr(strp - s + x, strp, cl, cur_att); if (ctyp == 2) costr(strp - s + x, strp, cl, cur_att); } void xprintf(char *fmt,...) { va_list args; char tmp[100]; va_start(args, fmt); vsprintf(tmp, fmt, args); va_end(args); xputs(cursor_x, tmp); cursor_x += strlen(tmp); } void gotox(int x) { cursor_x = x; } void set_att(u_char att) { cur_att = att; } u_char fullchar[] = " !”#$%&’()*+,-./0123456789:;<=>?" "@ABCDEFGHIJKLMNOPQRSTUVWXYZ〔\〕︿ˍ" "‘abcdefghijklmnopqrstuvwxyz{|}∼ "; u_char *hfstr[] = {"[半形]", "[全形]"}; static u_char statstr[] = " 【英數】"; static int targe_inmd_key = 1; int show_keys[9] = {10}; int show_keys_n = 1; static int cur_show_keys = 0; u_char cur_input_ch[2]; char *tabfname[14] = {(char *)1, "cj.tab", "simplex.tab", (char *)1, "dayi3.tab", 0, 0, 0, "array30.tab", "liu.tab", 0, 0, 0, 0}; char TabDir[40] = XCIN_DIR; void show_target(u_char * s) { u_char kk[200]; memset(kk, ' ', sizeof(kk)); switch (targe_inmd_key) { case 10: { sprintf(kk, "%2X%2X ", (u_int) s[0], (u_int) s[1]); break; } case 11: case 3: case 6: kk[0] = 0; break; default: b52key(targe_inmd_key, s, kk); } kk[29] = 0; gotox(70); if (kk[0]) xprintf("%s", kk); else xprintf(" "); } static int replied = 0; void putkey_b5(u_char * s) { write(masterPty, s, 2); replied = 1; } void sendkey_b5(u_char * s) { cur_input_ch[0] = s[0]; cur_input_ch[1] = s[1]; show_target(cur_input_ch); putkey_b5(s); } void putstr(u_char * s) { write(masterPty, s, strlen(s)); replied = 1; } void putfchr(char ch) { char tt[3]; int ii = (int)(ch - ' ') << 1; tt[0] = fullchar[ii]; tt[1] = fullchar[ii + 1]; tt[2] = 0; putstr(tt); } void puthchr(char ch) { char tt[2]; tt[0] = ch; tt[1] = 0; putstr(tt); } InmdState inmdstate = {0, /* inp state */ 3 /* current in-method */ }; void SwitchCurInMethod(int usenow) { switch (CurInMethod) { case 3: init_tab_pho(usenow); break; case 6: init_tab_pp(usenow); break; case 10: init_inter_code(usenow); break; case 11: if (tabfname[11]) InitVocBox(usenow); else { CurInMethod = 3; init_tab_pho(usenow); } break; default: if (tabfname[CurInMethod]) init_tab(CurInMethod, usenow); else { CurInMethod = 3; init_tab_pho(usenow); } } } void show_halffull() { gotox(9); xprintf("%s", hfstr[HalfFull]); } void next_inp() { int i; for (i = CurInMethod + 1; i != CurInMethod; i = (i + 1) % 14) if (tabfname[i]) { if (i) { CurInMethod = i; inmdstate.kb_state |= EngChiMask; SwitchCurInMethod(1); } else if (EngChi) { inmdstate.kb_state &= ~EngChiMask; gotox(0); xprintf("%s", statstr); gotox(16); /* clear prev inp */ xprintf(" "); } else continue; break; } if (i == CurInMethod) { CurInMethod = i; inmdstate.kb_state |= EngChiMask; SwitchCurInMethod(1); } } void toggle_halffull() { inmdstate.kb_state ^= HalfFullMask; show_halffull(); } int trans_key2(int ch, int state) { int count; int res = 0; replied = 0; if ((state & KEY_ALT_MASK) && (state & KEY_SHIFT_MASK)) { res = lookup_key(tolower(ch)); } else if (ch == ' ' && (state & KEY_CTRL_MASK)) { inmdstate.kb_state ^= EngChiMask; if (!EngChi) { gotox(0); xprintf("%s", statstr); gotox(16); /* clear prev inp */ xprintf(" "); ClrSelArea(); } else { SwitchCurInMethod(1); } TextRefresh(); return (1); } else if (ch == ' ' && (state & KEY_SHIFT_MASK)) { toggle_halffull(); TextRefresh(); return (1); } else if ((state & KEY_CTRL_MASK) && (state & KEY_ALT_MASK)) { switch (ch) { int ttt; case '1': case '2': case '4': case '5': case '7': case '8': case '9': case '=': if (ch == '=') ttt = 12; else ttt = ch - '0'; if (!tabfname[ttt]) break; inmdstate.kb_state |= EngChiMask; CurInMethod = ttt; init_tab(CurInMethod, 1); TextRefresh(); return (1); case '3': CurInMethod = 3; inmdstate.kb_state |= EngChiMask; init_tab_pho(1); TextRefresh(); return (1); case '6': CurInMethod = 6; inmdstate.kb_state |= EngChiMask; init_tab_pp(); TextRefresh(); return (1); case '0': CurInMethod = 10; inmdstate.kb_state |= EngChiMask; init_inter_code(); TextRefresh(); return (1); case '-': if (!tabfname[11]) break; CurInMethod = 11; inmdstate.kb_state |= EngChiMask; InitVocBox(); TextRefresh(); return (1); case 'i': case 'I': cur_show_keys = (cur_show_keys + 1) % show_keys_n; targe_inmd_key = show_keys[cur_show_keys]; if (cur_input_ch[0]) { show_target(cur_input_ch); } TextRefresh(); return (1); case 'R': case 'r': sendkey_b5(cur_input_ch); TextRefresh(); return (1); } } else if (EngChi && !(state & (KEY_CTRL_MASK | KEY_ALT_MASK)) && ch != VK_Control_L) { int shiftm = state & KEY_SHIFT_MASK; res = 0; if (shiftm && ch != '<' && ch > ' ' && ch < 127 && CurInMethod != 6 && ch != '*' && ch != '?') { char tt[2]; if (state & KEY_CAPS_MASK && islower(ch)) ch -= 0x20; else if (!(state & KEY_CAPS_MASK) && isupper(ch)) ch += 0x20; if (HalfFull) putfchr(ch); else puthchr(ch); TextRefresh(); return (1); } switch (CurInMethod) { case 3: res = feedkey_pho(ch); break; case 6: res = feedkey_pp(ch, state); break; case 10: if (!shiftm) res = feedkey_intcode(ch); break; case 11: res = feedkey_vocbox(ch); break; default: res = feedkey(ch); break; } } else if ((ch == VK_Control_L && state & KEY_SHIFT_MASK) || (ch == VK_Shift_L && state & KEY_CTRL_MASK)) { next_inp(); TextRefresh(); return (1); } if ((!EngChi || !res) && !(state & (KEY_CTRL_MASK | KEY_ALT_MASK))) { u_char tt[3]; if (HalfFull && ch >= ' ' && ch <= 0x7e) { putfchr(ch); } } if (!replied && !res) return (0); else { TextRefresh(); return (1); } } typedef struct { char *argv; void *res; int type; /* 1:char* 4:int */ char *help; } ARG; extern char *phokbm_name; char display_name[16]; extern char tsfname[]; extern char *phrfname; extern int going_key; extern int altmeta; static ARG arg[] = { {"tabdir", TabDir, 21, "table directory name"}, {"tsfname", tsfname, 21, "TsIn file name"}, {"inmd", &CurInMethod, 11, "Input method: 1-11"}, {"phokbm", &phokbm_name, 1, "phonetic kbd zo:01 et:eten et26:et26 hsu:hsu's"}, {"in1", &tabfname[1], 1, "in method 1 (eg) cj.tab"}, {"in2", &tabfname[2], 1, "in method 2"}, {"in4", &tabfname[4], 1, "in method 4"}, {"in5", &tabfname[5], 1, "in method 5"}, {"in6", &tabfname[6], 1, "in method 6"}, {"in7", &tabfname[7], 1, "in method 7"}, {"in8", &tabfname[8], 1, "in method 8 (eg) ar30.tab"}, {"in9", &tabfname[9], 1, "in method 9"}, {"vocbox", &tabfname[11], 1, "vocabulary box file name"}, {"in12", &tabfname[12], 1, "in method 12"}, {"going", &going_key, 14, "going: 0,1"}, {"phrase", &phrfname, 1, "phrase name"}, {"altmeta", &altmeta, 14, "altmeta: 0,1"}, }; void get_arg(int argc, char **argv) { int num = sizeof(arg) / sizeof(ARG); char *pp; int i, j; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { for (j = 0; j < num; j++) if (!strcmp(&argv[i][1], arg[j].argv) && i < argc - 1) { pp = argv[i + 1]; switch (arg[j].type) { case 1: *(char **)arg[j].res = pp; break; case 11: *(char *)arg[j].res = atoi(pp); break; case 14: *(int *)arg[j].res = atoi(pp); break; case 21: strcpy(arg[j].res, pp); } i++; break; } #if 0 if (j == num) { char tt[128]; error("Unknown arg %s", argv[i]); error("Valid args are :"); error("\t\tSee README for details"); for (j = 0; j < num; j++) fprintf(stderr, "\t-%s %s\n", arg[j].argv, arg[j].help); exit(-1); } #endif } } } void cin_init(int argc, char **argv) { int i; char str[10]; char *pp; get_arg(argc, argv); if (TabDir[strlen(TabDir) - 1] != '/') strcat(TabDir, "/"); if (CurInMethod <= 0 || CurInMethod > 11 || (!tabfname[CurInMethod] && CurInMethod != 6)) CurInMethod = 3; targe_inmd_key = CurInMethod; SwitchCurInMethod(0); gotox(0); xprintf("%s", statstr); show_halffull(); init_phrase(); }