gen-inp-v1.c
来自「linux 下的 oxim 输入法,简单易用.」· C语言 代码 · 共 1,570 行 · 第 1/3 页
C
1,570 行
case MCCH_END: switch (key) { case ' ': case '>': ret = (fillpage(cf, inpinfo, iccf, 0)) ? IMKEY_ABSORB : return_wrong(cf); break; case '<': ret = (fillpage(cf, inpinfo, iccf, -1)) ? IMKEY_ABSORB : return_wrong(cf); break; default: ret = return_wrong(cf); break; } break; case MCCH_BEGIN: switch (key) { case ' ': case '>': ret = (fillpage(cf, inpinfo, iccf, 1)) ? IMKEY_ABSORB : return_wrong(cf); break; case '<': ret = return_correct(cf); break; default: ret = return_wrong(cf); break; } break; default: switch (key) { case ' ': case '>': ret = (fillpage(cf, inpinfo, iccf, 1)) ? IMKEY_ABSORB : return_wrong(cf); break; case '<': ret = (fillpage(cf, inpinfo, iccf, -1)) ? IMKEY_ABSORB : return_wrong(cf); break; default: ret = return_wrong(cf); break; } break; } return ret;}/*------------------------------------------------------------------------*/static unsigned intmodifier_escape(gen_inp_conf_t *cf, int class){ unsigned int ret=0; switch (class) { case QPHR_SHIFT: if ((cf->modesc & QPHR_SHIFT)) ret |= IMKEY_SHIFTPHR; ret |= IMKEY_SHIFTESC; break; case QPHR_CTRL: if ((cf->modesc & QPHR_CTRL)) ret |= IMKEY_CTRLPHR; break; case QPHR_ALT: if ((cf->modesc & QPHR_ALT)) ret |= IMKEY_ALTPHR; break; case QPHR_FALLBACK: if ((cf->modesc & QPHR_FALLBACK)) ret |= IMKEY_FALLBACKPHR; break; } return ret;}static intget_bopomofo_index(uch_t uch){ int idx; int uch_len = strlen((char *)uch.s); int isbopomofo = False; for (idx = 0; idx < 3 && uch_len; idx++) { if (strstr(bopomofo[idx], (char *)uch.s)) return idx; } return -1;}static unsigned intgen_inp_keystroke(void *conf, inpinfo_t *inpinfo, keyinfo_t *keyinfo){ gen_inp_conf_t *cf = (gen_inp_conf_t *)conf; gen_inp_iccf_t *iccf = (gen_inp_iccf_t *)inpinfo->iccf; KeySym keysym = keyinfo->keysym; char *keystr = keyinfo->keystr; int len, max_len; char sp_ignore=0, inp_wrong=0; len = inpinfo->keystroke_len; max_len = cf->header.n_max_keystroke; if ((iccf->mode & INPINFO_MODE_SPACE)) { sp_ignore = 1; iccf->mode &= ~(INPINFO_MODE_SPACE); } if ((iccf->mode & INPINFO_MODE_WRONG)) { inp_wrong = 1; iccf->mode &= ~(INPINFO_MODE_WRONG); } if ((keysym == XK_BackSpace || keysym == XK_Delete) && len) { iccf->keystroke[len-1] = '\0'; inpinfo->s_keystroke[len-1].uch = (uchar_t)0; inpinfo->keystroke_len --; inpinfo->n_mcch = 0; inpinfo->cch_publish.uch = (uchar_t)0; inpinfo->mcch_pgstate = MCCH_ONEPG; inpinfo->guimode &= ~(GUIMOD_SELKEYSPOT); iccf->mode = 0; if ((cf->mode & INP_MODE_WILDON) && (strchr(iccf->keystroke, '*') || strchr(iccf->keystroke, '?'))) { iccf->mode |= INPINFO_MODE_INWILD; } if (len-1 > 0 && (cf->mode & INP_MODE_AUTOCOMPOSE)) { match_keystroke(cf, inpinfo, iccf); } return IMKEY_ABSORB; } else if (keysym == XK_Escape && len) { reset_keystroke(inpinfo, iccf); inpinfo->cch_publish.uch = (uchar_t)0; inpinfo->mcch_pgstate = MCCH_ONEPG; inpinfo->guimode &= ~(GUIMOD_SELKEYSPOT); return IMKEY_ABSORB; } else if (keysym == XK_space) { inpinfo->cch_publish.uch = (uchar_t)0; if ((cf->mode & INP_MODE_SPACEAUTOUP) && /* avoid wild mode auto up */ (! (iccf->mode & INPINFO_MODE_INWILD) || (iccf->mode & INPINFO_MODE_MCCH)) &&/* end of wild mod */ (inpinfo->n_mcch > 1 || inpinfo->mcch_pgstate != MCCH_ONEPG)) { if ((mcch_choosech(cf, inpinfo, iccf, -1))) { return IMKEY_COMMIT; } else { if ((cf->mode & INP_MODE_AUTORESET)) { reset_keystroke(inpinfo, iccf); } else { iccf->mode |= INPINFO_MODE_WRONG; } return return_wrong(cf); } } else if ((iccf->mode & INPINFO_MODE_MCCH)) { return mcch_nextpage(cf, inpinfo, iccf, ' '); } else if ((cf->mode & INP_MODE_SPACERESET) && inp_wrong) { reset_keystroke(inpinfo, iccf); return IMKEY_ABSORB; } else if (sp_ignore) { return IMKEY_ABSORB; } else if (inpinfo->keystroke_len) { return commit_keystroke(cf, inpinfo, iccf); } } else if ((keysym >= XK_KP_0 && keysym <= XK_KP_9) || (keysym >= XK_KP_Multiply && keysym <= XK_KP_Divide)) { return IMKEY_IGNORE; } else if ((keysym == XK_Left || keysym == XK_Right) && (inpinfo->guimode & GUIMOD_SELKEYSPOT)) { char pg_key = (keysym == XK_Left) ? '<' : '>'; return mcch_nextpage(cf, inpinfo, iccf, pg_key); } else if (keyinfo->keystr_len == 1) { unsigned int ret=IMKEY_ABSORB, ret1=0; int selkey_idx, endkey_pressed=0; char keycode, *s; uch_t uch; inpinfo->cch_publish.uch = (uchar_t)0; keycode = keystr[0]; /* 不區分按鍵大小寫 */ if (!cf->header.keep_key_case) { /* 沒有按下 Shift 的話,統統轉換為小寫 */ if (!(keyinfo->keystate & ShiftMask)) { keycode = tolower(keycode); } else /* 否則轉換為大寫 */ { keycode = toupper(keycode); } keystr[0] = keycode; } uch.uch = cf->header.keyname[(int)keycode].uch; selkey_idx = ((s = strchr(cf->header.selection_keys, keystr[0]))) ? (int)(s - cf->header.selection_keys) : -1; if (cf->header.n_end_key && strchr(cf->header.end_keys, iccf->keystroke[len-1])) { endkey_pressed = 1; } if (len && selkey_idx != -1 && (endkey_pressed || ! uch.uch)) { /* Don't enter the multi-cch selection, but selkey pressed. */ if (len==1 && strlen(cf->disable_sel_list) && strchr(cf->disable_sel_list, iccf->keystroke[len-1])) { uch.s[0] = keystr[0]; } else { return (mcch_choosech(cf, inpinfo, iccf, selkey_idx)) ? IMKEY_COMMIT : return_wrong(cf); } } else if ((keystr[0]=='<' || keystr[0]=='>') && (inpinfo->guimode & GUIMOD_SELKEYSPOT)) { return mcch_nextpage(cf, inpinfo, iccf, keystr[0]); } else if ((iccf->mode & INPINFO_MODE_MCCH)) { /* Enter the multi-cch selection. */ if (selkey_idx != -1) { return (mcch_choosech(cf, inpinfo, iccf, selkey_idx)) ? IMKEY_COMMIT : return_wrong(cf); } else if ((cf->mode & INP_MODE_AUTOUPCHAR)) { if (! mcch_choosech(cf, inpinfo, iccf, -1)) { return return_wrong(cf); } ret |= IMKEY_COMMIT; } else { return return_wrong(cf); } } /* 檢查所輸入的字根是否為注音符號 */ int bopomofo_idx = (cf->mode & INP_MODE_BOPOMOFOCHK) ? get_bopomofo_index(uch) : -1; int isappend = True; int stroke_idx; /* 注音符號要特別處理 */ if (bopomofo_idx >= 0) { for (stroke_idx=0 ;stroke_idx < inpinfo->keystroke_len;stroke_idx++) { /* 首先,注音符號不可能有重複 */ if (strcmp((char *)uch.s, (char *)inpinfo->s_keystroke[stroke_idx].s) == 0) return IMKEY_ABSORB; /* 字根性質相同嗎?是的話,直接取代 */ if (get_bopomofo_index(inpinfo->s_keystroke[stroke_idx]) == bopomofo_idx) { isappend = False; break; } } } /* The previous cch might be committed, so len might be 0 */ len = inpinfo->keystroke_len; if (!uch.uch && (keyinfo->keystate & ShiftMask)) { if (! (cf->mode & INP_MODE_WILDON) || (keystr[0] != '*' && keystr[0] != '?')) { return (ret | modifier_escape(cf, QPHR_SHIFT)); } else { iccf->mode |= INPINFO_MODE_INWILD; } } else if ((keyinfo->keystate & ControlMask) && (ret1 = modifier_escape(cf, QPHR_CTRL))) { return (ret | ret1); } else if ((keyinfo->keystate & Mod1Mask) && (ret1 = modifier_escape(cf, QPHR_ALT))) { return (ret | ret1); } else if (!uch.uch) { return (ret | IMKEY_IGNORE); } else if (len >= max_len) { return return_wrong(cf); } if (isappend) { iccf->keystroke[len] = keystr[0]; iccf->keystroke[len+1] = '\0'; if (keystr[0] == '*' || keystr[0] == '?') { inpinfo->s_keystroke[len].s[0] = keystr[0]; inpinfo->s_keystroke[len].s[1] = ' '; } else { inpinfo->s_keystroke[len].uch = uch.uch; } inpinfo->s_keystroke[len+1].uch = (uchar_t)0; inpinfo->keystroke_len ++; len ++; } else { iccf->keystroke[stroke_idx] = keystr[0]; inpinfo->s_keystroke[stroke_idx].uch = uch.uch; } /* 如果是注音輸入法的話,要依據注音符號規則排列 */ if (bopomofo_idx >= 0) { int idx; int keystroke_len = inpinfo->keystroke_len; int sort_tbl[4] = {-1, -1, -1, -1}; /* 兩個字根以上才需要檢查 */ if (keystroke_len > 1) { /* 取得每個注音符號的性質位置*/ for (idx=0 ; idx < keystroke_len ; idx++) { int b_idx = get_bopomofo_index(inpinfo->s_keystroke[idx]); sort_tbl[idx] = b_idx < 0 ? 9 : b_idx; } for (idx=0 ; idx < keystroke_len-1 ; idx++) { int x; for (x=idx+1 ; x < keystroke_len ; x++) { if (sort_tbl[idx] > sort_tbl[x]) { int tmp = sort_tbl[idx]; sort_tbl[idx] = sort_tbl[x]; sort_tbl[x] = tmp; uch_t tmp_uch = inpinfo->s_keystroke[idx]; inpinfo->s_keystroke[idx] = inpinfo->s_keystroke[x]; inpinfo->s_keystroke[x] = tmp_uch; char tmp_ch = iccf->keystroke[idx]; iccf->keystroke[idx] = iccf->keystroke[x]; iccf->keystroke[x] = tmp_ch; } } } } } if ((cf->mode & INP_MODE_SPACEIGNOR) && len == max_len) { iccf->mode |= INPINFO_MODE_SPACE; } if ((cf->mode & INP_MODE_ENDKEY) && len>1 && (s=strchr(cf->header.end_keys, keystr[0]))) { return commit_keystroke(cf, inpinfo, iccf); } else if ((cf->mode & INP_MODE_AUTOFULLUP) && len == max_len) { return commit_keystroke(cf, inpinfo, iccf); } else if ((cf->mode & INP_MODE_AUTOCOMPOSE)) { match_keystroke(cf, inpinfo, iccf); } return ret; } return IMKEY_IGNORE;}/*---------------------------------------------------------------------------- gen_inp_show_keystroke()----------------------------------------------------------------------------*/static int gen_inp_show_keystroke(void *conf, simdinfo_t *simdinfo){ simdinfo->s_keystroke = NULL; return False;}static intgen_inp_terminate(void *conf){ gen_inp_conf_t *cf = (gen_inp_conf_t *)conf; if (cf->tabfn) { free(cf->tabfn); cf->tabfn = NULL; } if (cf->offset_tbl) { free(cf->offset_tbl); cf->offset_tbl = NULL; cf->memory_usage -= cf->offset_size; } if (cf->input_content) { free(cf->input_content); cf->input_content = NULL; cf->memory_usage -= cf->input_content_size; } if (cf->kremap) { int i; for (i=0; i < cf->n_kremap; i++) { free(cf->kremap[i].keystroke); } free(cf->kremap); cf->n_kremap = 0; cf->kremap = NULL; } /* 釋放 cache 記憶體 */ if (cf->n_cache) { int i; for (i=0 ; i < cf->n_cache ; i++) { free(cf->cache[i].keystroke); } free(cf->cache); cf->n_cache = 0; cf->cache = NULL; } if (cf->zfp) { gzclose(cf->zfp); cf->zfp = NULL; } return True;}/*---------------------------------------------------------------------------- Definition of general input method module (template).----------------------------------------------------------------------------*/static char *gen_inp_valid_objname[] = { "*", NULL };static char gen_inp_comments[] = N_( "This is the general input method module.\n");module_t module_ptr = { { MTYPE_IM, /* module_type */ "gen_inp_v1", /* name */ MODULE_VERSION, /* version */ gen_inp_comments }, /* comments */ gen_inp_valid_objname, /* valid_objname */ sizeof(gen_inp_conf_t), /* conf_size */ gen_inp_init, /* init */ gen_inp_xim_init, /* xim_init */ gen_inp_xim_end, /* xim_end */ gen_inp_keystroke, /* keystroke */ gen_inp_show_keystroke, /* show_keystroke */ gen_inp_terminate /* terminate */};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?