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 + -
显示快捷键?