gen-inp.c
来自「linux 下的 oxim 输入法,简单易用.」· C语言 代码 · 共 1,468 行 · 第 1/3 页
C
1,468 行
{ have_word = True; unsigned int ret_len; char *ret_word = get_word(cf, cf->ichar[idx], &ret_len); if (ret_word) { unsigned int ucs4; int nbytes; char *p = ret_word; unsigned int utf8_len = 0; while (ret_len && (nbytes = oxim_utf8_to_ucs4(p, &ucs4, ret_len)) > 0) { utf8_len ++; if (utf8_len > 1) { mcch_size ++; iccf->mcch_list = oxim_realloc(iccf->mcch_list, mcch_size*sizeof(uch_t)); } iccf->mcch_list[i].uch = 0; memcpy((char *)iccf->mcch_list[i].s, p, nbytes); i ++; p += nbytes; ret_len -= nbytes; } iccf->mcch_list_grouping[n_igrp].n_word = utf8_len; n_igrp ++; free(ret_word); } } else if (ccode_to_char(cf->ichar[idx], (char *)iccf->mcch_list[i].s)) { iccf->mkey_list[n_igrp] = idx; iccf->mcch_list_grouping[n_igrp].n_word = 1; i ++; n_igrp ++; } *head = idx; } else { r = 1; } } } free(ks); iccf->n_mkey_list = n_igrp; iccf->n_mcch_list = n_igrp; *n_mcch = i; if (i) { inpinfo->n_mcch = n_igrp; inpinfo->mcch = iccf->mcch_list; for (i=0 ; i < n_igrp ; i++) { inpinfo->mcch_grouping[i+1] = iccf->mcch_list_grouping[i].n_word; } inpinfo->mcch_grouping[0] = have_word ? n_igrp : 0; } else { inpinfo->n_mcch = 0; inpinfo->mcch_grouping[0] = 0; free(iccf->mcch_list); free(iccf->mcch_list_grouping); free(iccf->mkey_list); *head = 0; } return r;}static intmatch_keystroke_wild(gen_inp_conf_t *cf, inpinfo_t *inpinfo, gen_inp_iccf_t *iccf){ icode_t icode[2]; unsigned int md, n_mcch; int idx; char *s1, *s2, *s, tmpch; md = (cf->header.icode_mode == ICODE_MODE2) ? 1 : 0; icode[0] = icode[1] = 0; /* * Search for the first char. */ s1 = strchr(iccf->keystroke, '*'); s2 = strchr(iccf->keystroke, '?'); if (s1 && s2) s = (s1 < s2) ? s1 : s2; else if (s1) s = s1; else s = s2; tmpch = *s; *s = '\0'; oxim_keys2codes(icode, 2, iccf->keystroke); idx = bsearch_char(cf->ic1, cf->ic2, icode[0], icode[1], cf->header.n_icode, md, 1, NULL); *s = tmpch; iccf->mcch_hidx = idx; /* refer to head index of cf->icidx */ /* * Pick up the remaining chars; */ if (pick_cch_wild(cf, iccf, &idx, 1, inpinfo, &n_mcch) == 0) { inpinfo->mcch_pgstate = MCCH_ONEPG; } else { inpinfo->mcch_pgstate = MCCH_BEGIN; } iccf->mcch_eidx = idx; /* refer to end index of cf->icidx */ return (n_mcch) ? 1 : 0;}static intmatch_keystroke_normal(gen_inp_conf_t *cf, inpinfo_t *inpinfo, gen_inp_iccf_t *iccf){ icode_t icode[2]; unsigned int size, md, n_ich=0, n_igrp=0, mcch_size; int idx, end_idx; uch_t *mcch = NULL; word_group_t *mcch_grouping = NULL; size = cf->header.n_icode; md = (cf->header.icode_mode == ICODE_MODE2) ? 1 : 0; icode[0] = icode[1] = 0; /* * Search for the first char. */ oxim_keys2codes(icode, 2, iccf->keystroke); if ((idx = bsearch_char(cf->ic1, cf->ic2, icode[0], icode[1], size, md, 0, &end_idx)) == -1) return 0; /* * Search for all the chars with the same keystroke. */ mcch_size = end_idx - idx + 1; /* 總共幾筆紀錄 */ /* 預先配置記憶體 */ mcch = oxim_malloc(mcch_size*sizeof(uch_t), False); mcch_grouping = oxim_malloc(mcch_size*sizeof(word_group_t), False); while(idx <= end_idx) { mcch_grouping[n_igrp].n_idx = n_ich; if (cf->ichar[idx] & WORD_MASK) { unsigned int ret_len; char *ret_word = get_word(cf, cf->ichar[idx], &ret_len); if (ret_word) { unsigned int ucs4; int nbytes; char *p = ret_word; unsigned int utf8_len = 0; while (ret_len && (nbytes = oxim_utf8_to_ucs4(p, &ucs4, ret_len)) > 0) { utf8_len ++; if (utf8_len > 1) { mcch_size ++; mcch = oxim_realloc(mcch, mcch_size*sizeof(uch_t)); } mcch[n_ich].uch = 0; memcpy((char *)mcch[n_ich].s, p, nbytes); n_ich ++; p += nbytes; ret_len -= nbytes; } mcch_grouping[n_igrp].n_word = utf8_len; n_igrp ++; free(ret_word); } } else if (ccode_to_char(cf->ichar[idx], (char *)mcch[n_ich].s)) { mcch_grouping[n_igrp].n_word = 1; n_ich ++; n_igrp ++; } idx ++; } if (iccf->n_mcch_list) { free(iccf->mcch_list); free(iccf->mcch_list_grouping); } iccf->mcch_list = mcch; iccf->mcch_list_grouping = mcch_grouping; iccf->n_mcch_list = n_igrp; iccf->mcch_hidx = 0; /* refer to index of iccf->mcch_list */ fillpage(cf, inpinfo, iccf, 0); return 1;}static int match_keystroke(gen_inp_conf_t *cf, inpinfo_t *inpinfo, gen_inp_iccf_t *iccf)/* return: 1: success, 0: false */{ int ret; inpinfo->n_mcch = 0; if (! (iccf->mode & INPINFO_MODE_INWILD)) ret = match_keystroke_normal(cf, inpinfo, iccf); else ret = match_keystroke_wild(cf, inpinfo, iccf); if (inpinfo->n_mcch > 1 && (iccf->mode & INPINFO_MODE_SPACE)) iccf->mode &= ~(INPINFO_MODE_SPACE); return ret;}/*------------------------------------------------------------------------*/static voidget_correct_skeystroke(gen_inp_conf_t *cf, inpinfo_t *inpinfo, gen_inp_iccf_t *iccf, int idx, uch_t *cch){ unsigned int i=0, j, klist[2]; int n_klist, ks_size, keycode; char *ks; if (idx < iccf->n_mkey_list) { i = iccf->mkey_list[idx]; } else { inpinfo->suggest_skeystroke[0].uch = 0; return; } ks_size = cf->header.n_max_keystroke + 1; ks = oxim_malloc(ks_size, 0); n_klist = (cf->header.icode_mode == ICODE_MODE1) ? 1 : 2; klist[0] = cf->ic1[i]; if (cf->header.icode_mode == ICODE_MODE2) klist[1] = cf->ic2[i]; oxim_codes2keys(klist, n_klist, ks, ks_size); if (strcmp_wild(iccf->keystroke, ks) == 0) { for (j=0; ks[j] != '\0'; j++) { keycode = oxim_key2code(ks[j]); inpinfo->suggest_skeystroke[j].uch = cf->header.keyname[keycode].uch; } inpinfo->suggest_skeystroke[j].uch = 0; } else inpinfo->suggest_skeystroke[0].uch = 0; free(ks);}static voidcommit_char(gen_inp_conf_t *cf, inpinfo_t *inpinfo, gen_inp_iccf_t *iccf, int idx){ static char cch_s[1024]; char *s=NULL; int i; unsigned int grp_idx = (iccf->mode & INPINFO_MODE_INWILD) ? idx : iccf->mcch_hidx + idx; word_group_t wg = iccf->mcch_list_grouping[grp_idx]; uch_t *mcch = iccf->mcch_list + wg.n_idx; uch_t *cch = mcch; ushort_t cch_len = wg.n_word; cch_s[0] = '\0'; while (cch_len--) { strcat(cch_s, (char *)mcch->s); mcch ++; } inpinfo->cch = cch_s; /* 只有單一字元才需要提示字根 */ if (wg.n_word == 1) { if (! (s = strchr(iccf->keystroke,'*')) && ! (s = strchr(iccf->keystroke,'?'))) { for (i=0; i<=inpinfo->keystroke_len; i++) inpinfo->suggest_skeystroke[i].uch = inpinfo->s_keystroke[i].uch; } else { get_correct_skeystroke(cf, inpinfo, iccf, idx, cch); } } else { inpinfo->suggest_skeystroke[0].uch = 0; } inpinfo->keystroke_len = 0; inpinfo->s_keystroke[0].uch = 0; inpinfo->n_mcch = 0; inpinfo->cch_publish.uch = cch->uch; inpinfo->mcch_pgstate = MCCH_ONEPG; iccf->mode &= ~(INPINFO_MODE_MCCH); iccf->mode &= ~(INPINFO_MODE_INWILD); inpinfo->guimode &= ~(GUIMOD_SELKEYSPOT);}static unsigned intcommit_keystroke(gen_inp_conf_t *cf, inpinfo_t *inpinfo, gen_inp_iccf_t *iccf)/* return: the IMKEY state */{ if (match_keystroke(cf, inpinfo, iccf)) { if (inpinfo->n_mcch == 1) { commit_char(cf, inpinfo, iccf, 0); return IMKEY_COMMIT; } else { iccf->mode |= INPINFO_MODE_MCCH; inpinfo->guimode |= GUIMOD_SELKEYSPOT; return return_correct(cf); } } else { if ((cf->mode & INP_MODE_AUTORESET)) { reset_keystroke(inpinfo, iccf); } else { iccf->mode |= INPINFO_MODE_WRONG; } return return_wrong(cf); }}/*------------------------------------------------------------------------*/static intmcch_choosech(gen_inp_conf_t *cf, inpinfo_t *inpinfo, gen_inp_iccf_t *iccf, int idx){ int min; if (inpinfo->n_mcch == 0 && ! match_keystroke(cf, inpinfo, iccf)) { return 0; } if (idx < 0) /* Always select the first. */ { idx = 0; } else { if ((cf->mode & INP_MODE_SELKEYSHIFT)) { idx ++; } min = (inpinfo->n_selkey > inpinfo->n_mcch) ? inpinfo->n_mcch : inpinfo->n_selkey; if (idx >= min) { return 0; } } commit_char(cf, inpinfo, iccf, idx); reset_keystroke(inpinfo, iccf); return 1;}static intfillpage(gen_inp_conf_t *cf, inpinfo_t *inpinfo, gen_inp_iccf_t *iccf, byte_t dir){ int i, j, n_pg=inpinfo->n_selkey; if (! (iccf->mode & INPINFO_MODE_INWILD)) { int total = iccf->n_mcch_list; switch (dir) { case 0: iccf->mcch_hidx = 0; break; case 1: if (iccf->mcch_hidx + n_pg < total) iccf->mcch_hidx += n_pg; else return 0; break; case -1: if (iccf->mcch_hidx - n_pg >= 0) iccf->mcch_hidx -= n_pg; else return 0; break; } /* */ uch_t *mcch = iccf->mcch_list + iccf->mcch_list_grouping[iccf->mcch_hidx].n_idx; j = total - iccf->mcch_hidx; i = (j >= n_pg) ? n_pg : j; inpinfo->mcch_grouping[0] = 0; for (j=0; j < i ; j++) { inpinfo->mcch_grouping[j+1] = iccf->mcch_list_grouping[iccf->mcch_hidx+j].n_word; if (iccf->mcch_list_grouping[iccf->mcch_hidx+j].n_word > 1) { inpinfo->mcch_grouping[0] = i; } } inpinfo->mcch = mcch; if (iccf->mcch_hidx == 0) inpinfo->mcch_pgstate = (i < total) ? MCCH_BEGIN : MCCH_ONEPG; else if (total - iccf->mcch_hidx > n_pg) inpinfo->mcch_pgstate = MCCH_MIDDLE; else inpinfo->mcch_pgstate = MCCH_END; inpinfo->n_mcch = i; } else { int r=0, n_mcch, hidx, eidx; switch (dir) { case 0: return 0; case 1: if (inpinfo->mcch_pgstate == MCCH_BEGIN || inpinfo->mcch_pgstate == MCCH_MIDDLE) { hidx = eidx = iccf->mcch_eidx + 1; r = pick_cch_wild(cf, iccf, &eidx, 1, inpinfo, (unsigned int *)&n_mcch); } else return 0; break; case -1: if (inpinfo->mcch_pgstate == MCCH_END || inpinfo->mcch_pgstate == MCCH_MIDDLE) { hidx = eidx = iccf->mcch_hidx - 1; r = pick_cch_wild(cf, iccf, &hidx, -1, inpinfo, (unsigned int *)&n_mcch); } else { return 0; } break; } if (r == 0) { if (dir == 1) inpinfo->mcch_pgstate = MCCH_END; else inpinfo->mcch_pgstate = MCCH_BEGIN; } else { inpinfo->mcch_pgstate = MCCH_MIDDLE; } iccf->mcch_hidx = hidx; iccf->mcch_eidx = eidx; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?