gen-inp.c

来自「linux 下的 oxim 输入法,简单易用.」· C语言 代码 · 共 1,468 行 · 第 1/3 页

C
1,468 行
字号
    return 1;}static intmcch_nextpage(gen_inp_conf_t *cf, 	      inpinfo_t *inpinfo, gen_inp_iccf_t *iccf, char key){    int ret=0;    switch (inpinfo->mcch_pgstate) {    case MCCH_ONEPG:	switch (key) {	case ' ':	    if ((cf->mode & INP_MODE_AUTOUPCHAR))                ret = (mcch_choosech(cf, inpinfo, iccf, -1)) ?                	IMKEY_COMMIT : return_wrong(cf);            else                ret = return_correct(cf);	    break;	case '<':	case '>':	    ret = return_correct(cf);	    break;	default:	    ret = return_wrong(cf);	    break;	}	break;    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 = oxim_key2code(keystr[0]);	uch.uch = cf->header.keyname[(int)keycode].uch;	selkey_idx = ((s = strchr(cf->header.selkey, keystr[0]))) ? 		(int)(s - cf->header.selkey) : -1;	if (cf->header.n_endkey && 	    strchr(cf->header.endkey, 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 && 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 = get_bopomofo_index(uch);	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 ((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.endkey, 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){#if 0    gen_inp_conf_t *cf = (gen_inp_conf_t *)conf;    int i, idx;    uchar_t tmp;    char *k, keystroke[INP_CODE_LENGTH+1];    static uch_t keystroke_list[INP_CODE_LENGTH+1];    if (cf->header.icode_mode == ICODE_MODE1)	oxim_codes2keys(&(cf->ic1[idx]), 1, keystroke, SELECT_KEY_LENGTH+1);    else if (cf->header.icode_mode == ICODE_MODE2) {        unsigned int klist[2];	klist[0] = cf->ic1[idx];	klist[1] = cf->ic2[idx];	oxim_codes2keys(klist, 2, keystroke, SELECT_KEY_LENGTH+1);    }    for (i=0, k=keystroke; i<INP_CODE_LENGTH && *k; i++, k++) {	idx = oxim_key2code(*k);	if ((tmp = cf->header.keyname[idx].uch))	    keystroke_list[i].uch = tmp;	else {	    keystroke_list[i].uch = (uchar_t)0;	    keystroke_list[i].s[0] = '?';	}    }    keystroke_list[i].uch = (uchar_t)0;    simdinfo->s_keystroke = keystroke_list;    return (i) ? True : False;#else    simdinfo->s_keystroke = NULL;    return False;#endif}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->ic1)    {	free(cf->ic1);	cf->ic1 = NULL;    }    if (cf->ic2)    {	free(cf->ic2);	cf->ic2 = NULL;    }    if (cf->ichar)    {	free(cf->ichar);	cf->ichar = 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. It is the most generic\n"	"module which can read the IM table (\".tab\" file) and perform\n"	"the correct operations of the specific IM. It also can accept a\n"	"lot of options from the \"oximrc\" file to detailly control the\n"	"behavior of the IM. We hope that this module could match most of\n"	"your Chinese input requirements.\n\n"	"This module is free software, as part of oxim system.\n");module_t module_ptr = {    { MTYPE_IM,					/* module_type */      "gen_inp",				/* 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 + -
显示快捷键?