/* Copyright (C) 1994,1995 Edward Der-Hua Liu, Hsin-Chu, Taiwan */ #include "gcin.h" #include "pho.h" #include #include extern PHO_ITEM *ch_pho; int ityp3_pho; static int cpg, maxi; int start_idx, stop_idx; PHOKBM phkbm; u_char typ_pho[4]; char inph[8]; extern int text_pho_N; gboolean b_hsu_kbm; extern PIN_JUYIN *pin_juyin; int pin_juyinN; #define MAX_HASH_PHO 27 u_short hash_pho[MAX_HASH_PHO+1]; static char typ_pho_len[]={5, 2, 4, 3}; gboolean same_query_show_pho_win(); gboolean pho_has_input() { return typ_pho[0] || typ_pho[1] || typ_pho[2] || typ_pho[3] || same_query_show_pho_win(); } phokey_t pho2key(char typ_pho[]) { phokey_t key=typ_pho[0]; int i; for(i=1; i < 4; i++) { key = typ_pho[i] | (key << typ_pho_len[i]) ; } return key; } void key_typ_pho(phokey_t phokey, u_char rtyp_pho[]) { rtyp_pho[3] = phokey & 7; phokey >>= 3; rtyp_pho[2] = phokey & 0xf; phokey >>=4; rtyp_pho[1] = phokey & 0x3; phokey >>=2; rtyp_pho[0] = phokey; } void mask_key_typ_pho(phokey_t *key) { if (!typ_pho[0]) *key &= ~(31<<9); if (!typ_pho[1]) *key &= ~(3<<7); if (!typ_pho[2]) *key &= ~(15<<3); if (!typ_pho[3]) *key &= ~(7); } #define TKBM 0 #define MIN_M_PHO 5 static void find_match_phos(u_char mtyp_pho[4], int *mcount, int newkey) { int vv; phokey_t key = pho2key(typ_pho); mask_key_typ_pho(&key); #if TKBM dbg("-------------------- %d --", typ_pho[3]); prph(key); dbg("\n"); #endif for (vv = hash_pho[typ_pho[0]]; vv < hash_pho[typ_pho[0]+1]; vv++) { phokey_t ttt=idx_pho[vv].key; if (newkey!=' ' && !typ_pho[3]) mask_key_typ_pho(&ttt); if (ttt > key) break; int count = 0; int i; for(i=idx_pho[vv].start; i < idx_pho[vv+1].start; i++) { if (utf8_sz(ch_pho[i].ch) > 1) { #if 0 utf8_putchar(ch_pho[i].ch); dbg(" "); #endif count++; } } if (*mcount < count) { *mcount = count; memcpy(mtyp_pho, typ_pho, sizeof(typ_pho)); #if TKBM dbg("count %d\n", count); #endif if (*mcount > MIN_M_PHO) break; } } } gboolean inph_typ_pho_pinyin(int newkey); gboolean inph_typ_pho(int newkey) { int i; int insert = -1; if (pin_juyin) { return inph_typ_pho_pinyin(newkey); } int max_in_idx; for(max_in_idx=3; max_in_idx>=0 && !typ_pho[max_in_idx]; max_in_idx--); // try insert mode first if (insert < 0) for(i=0; i < 3; i++) { char num = phkbm.phokbm[(int)newkey][i].num; int typ = phkbm.phokbm[(int)newkey][i].typ; if (num && !inph[typ] && typ>max_in_idx) { inph[typ] = newkey; typ_pho[typ] = num; #if TKBM dbg("insert typ %d\n", typ); #endif insert = typ; break; } } if (insert < 0) { // then overwrite mode for(i=0; i < 3; i++) { char num = phkbm.phokbm[newkey][i].num; int typ = phkbm.phokbm[newkey][i].typ; if (num) { inph[typ] = newkey; typ_pho[typ] = num; insert = typ; break; } } } // dbg("newkey %c\n", newkey); int mcount = 0; u_char mtyp_pho[4]; int a; for(a=0; a < 3; a++) { char num = phkbm.phokbm[(int)inph[0]][a].num; char typ = phkbm.phokbm[(int)inph[0]][a].typ; if (typ == 3) continue; if (num) { if (typ==2 && typ_pho[0] && !typ_pho[2]) typ_pho[0] = 0; typ_pho[(int)typ] = num; #if TKBM dbg("%d num %d\n",a, num); #endif find_match_phos(mtyp_pho, &mcount, newkey); } for(i=0; i < 3; i++) { char num = phkbm.phokbm[(int)inph[2]][i].num; char typ = phkbm.phokbm[(int)inph[2]][i].typ; if (!num) break; if (typ!=2) continue; typ_pho[(int)typ] = num; find_match_phos(mtyp_pho, &mcount, newkey); if (mcount > MIN_M_PHO) { return TRUE; } } find_match_phos(mtyp_pho, &mcount, newkey); if (mcount > MIN_M_PHO) { return TRUE; } } if (mcount) { memcpy(typ_pho, mtyp_pho, sizeof(typ_pho)); return TRUE; } return FALSE; } void clrin_pho() { bzero(typ_pho,sizeof(typ_pho)); bzero(inph,sizeof(inph)); maxi=ityp3_pho=0; cpg=0; if (gcin_pop_up_win && !same_query_show_pho_win()) hide_win_pho(); } void disp_pho(int index, char *phochar); void clr_in_area_pho() { int i; clrin_pho(); for(i=0; i < 4; i++) disp_pho(i, " "); } static void disp_in_area_pho() { int i; if (pin_juyin) { for(i=0;i<6;i++) { disp_pho(i, &inph[i]); } } else { for(i=0;i<4;i++) disp_pho(i, &pho_chars[i][typ_pho[i]*3]); } } static int qcmp_count(const void *aa, const void *bb) { PHO_ITEM *a = (PHO_ITEM *)aa; PHO_ITEM *b = (PHO_ITEM *)bb; return b->count - a->count; } void disp_pho_sel(char *s); void minimize_win_pho(); static void ClrSelArea() { disp_pho_sel(" "); minimize_win_pho(); } extern char *TableDir; extern char phofname[128]; gboolean get_start_stop_idx(phokey_t key, int *start_i, int *stop_i) { int typ_pho0 = key >> 9; int vv=hash_pho[typ_pho0]; while (vv=key) break; else vv++; } if (vv >= idxnum_pho || idx_pho[vv].key != key) return FALSE; *start_i=idx_pho[vv].start; *stop_i=idx_pho[vv+1].start; return TRUE; } // given the pho key & the big5 char, return the idx in ch_pho int ch_key_to_ch_pho_idx(phokey_t phkey, char *utf8) { int start_i, stop_i; get_start_stop_idx(phkey, &start_i, &stop_i); int i; for(i=start_i; i> 9 == i) hash_pho[i]=ttt; else { continue; } while (ttt < idxnum_pho && idx_pho[ttt].key >> 9 == i) ttt++; } for(i=MAX_HASH_PHO; !hash_pho[i]; i--) hash_pho[i]=idxnum_pho; char kbmfname[MAX_GCIN_STR]; FILE *fr; char phokbm_name[MAX_GCIN_STR]; #if 1 get_gcin_conf_fstr(PHONETIC_KEYBOARD, phokbm_name, "zo-asdf"); #else strcpy(phokbm_name, "pinyin-asdf"); #endif free(pin_juyin); pin_juyin = NULL; if (!strstr(phokbm_name, "pinyin")) { text_pho_N = 3; } else { load_pin_juyin(); } if (strcmp(phokbm_name, "hsu")) b_hsu_kbm = FALSE; else b_hsu_kbm = TRUE; strcat(phokbm_name, ".kbm"); dbg("phokbm_name:%s\n", phokbm_name); get_sys_table_file_name(phokbm_name, kbmfname); if ((fr=fopen(kbmfname,"r"))==NULL) p_err("Cannot open %s", kbmfname); fread(&phkbm,sizeof(phkbm),1,fr); fclose (fr); } void show_win_pho(); void init_tab_pho() { if (!ch_pho) { load_tab_pho_file(); } show_win_pho(); clr_in_area_pho(); } gboolean shift_char_proc(KeySym key, int kbstate); int feedkey_pho(KeySym xkey, int kbstate) { int ctyp = 0; static unsigned int vv, ii; static phokey_t key; char *pp=NULL; char kno; int i,j,jj=0,kk=0; char out_buffer[(CH_SZ+2) * 10 + 4]; int out_bufferN; if ((kbstate & ShiftMask)) { return shift_char_proc(xkey, kbstate); } if (xkey >= 'A' && xkey <='Z') xkey+=0x20; switch (xkey) { case XK_Escape: if (!typ_pho[0] &&!typ_pho[1] &&!typ_pho[2] &&!typ_pho[3]) return 0; ClrSelArea(); clr_in_area_pho(); if (is_gtab_query_mode()) close_gtab_pho_win(); return 1; case XK_BackSpace: ityp3_pho=0; for(j=3;j>=0;j--) if (typ_pho[j]) { typ_pho[j]=0; if (!typ_pho[0]&&!typ_pho[1]&&!typ_pho[2]&&!typ_pho[3]) { ClrSelArea(); clr_in_area_pho(); return 1; } break; } if (j<0) return 0; goto llll3; case '<': if (!ityp3_pho) return 0; if (cpg >= phkbm.selkeyN) cpg -= phkbm.selkeyN; goto proc_state; case ' ': if (!typ_pho[0] && !typ_pho[1] && !typ_pho[2]) { if (current_CS->b_half_full_char) return full_char_proc(xkey); return 0; } if (!ityp3_pho && xkey==' ') { inph_typ_pho(xkey); ctyp=3; kno=0; jj=0; goto llll1; } ii = start_idx+ cpg + phkbm.selkeyN; if (ii < stop_idx) { cpg += phkbm.selkeyN; } else { if (cpg) { cpg=0; ii=start_idx; } else { putkey_pho(key, start_idx); /* maxi=ityp3_pho=0; */ return 1; } } i=0; ClrSelArea(); out_bufferN=0; while(i= 127 || xkey < ' ') return 0; if ((pp=strchr(phkbm.selkey, xkey)) && maxi && ityp3_pho) { int c=pp-phkbm.selkey; if (c=key) break; else vv++; } if (ttt > key || (ityp3_pho && idx_pho[vv].key != key) ) { while (jj<4) { while(kk<3) if (phkbm.phokbm[(int)inph[jj]][kk].num ) { if (kk) { ctyp=phkbm.phokbm[(int)inph[jj]][kk-1].typ; typ_pho[ctyp]=0; } kno=phkbm.phokbm[(int)inph[jj]][kk].num; ctyp=phkbm.phokbm[(int)inph[jj]][kk].typ; typ_pho[ctyp]=kno; kk++; goto llll2; } else kk++; jj++; kk=1; } bell(); ityp3_pho=typ_pho[3]=0; disp_in_area_pho(); return 1; } proc_state: disp_in_area_pho(); start_idx = ii = idx_pho[vv].start; stop_idx = idx_pho[vv+1].start; // dbg("start_idx: %d %d\n", start_idx, stop_idx); // ClrSelArea(); // gotoxy(0,MROW-2); ii+=cpg; if (ityp3_pho && stop_idx - start_idx==1) { putkey_pho(key, ii); maxi=ityp3_pho=0; return 1; } i=0; out_bufferN=0; if (ityp3_pho) { while(i< phkbm.selkeyN && ii < stop_idx) { out_buffer[out_bufferN++] = phkbm.selkey[i]; int len = u8cpy(&out_buffer[out_bufferN], ch_pho[ii].ch); out_bufferN+=len; out_buffer[out_bufferN++] = ' '; ii++; i=i+1; } out_buffer[out_bufferN++] = cpg ? '<' : ' '; if (ii < stop_idx) { out_buffer[out_bufferN++] = cpg ? '\\' : ' '; out_buffer[out_bufferN++] = '>'; } else { cpg=0; } maxi=i; } else { while(i