xim.c#1.53

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

53
1,365
字号
	imc->s_imodp = OXIM_IMGet(xccore->default_im_sinmd);	imc->sinp_num = xccore->default_im_sinmd;    }    return True;}static voidcircular_change_IM(IC *ic, int direction){    int i, j;    inp_state_t inpnum;    int NumberOfIM = oxim_get_NumberOfIM();    inpnum = ((ic->imc->inp_state & IM_CINPUT)) ? 			ic->imc->inp_num : NumberOfIM;    for (i=0, j=inpnum+direction; i<NumberOfIM+1; i++, j+=direction) {	if (j > NumberOfIM || j < 0)	    j += ( (j < 0) ? (NumberOfIM+1) : -(NumberOfIM+1) );	if (oxim_IMisCircular(j))	{	    if (change_IM(ic, j))		return;	}    }}static voidcall_simd(IC *ic){    static uchar_t prev_uch;    simdinfo_t simdinfo;    uch_t *skey = NULL;    int skey_len;    IM_Context_t *imc = ic->imc;    if (imc->inpinfo.cch_publish.uch) {	if (imc->inpinfo.cch_publish.uch != prev_uch) {	    prev_uch = imc->inpinfo.cch_publish.uch;	}	if (imc->inp_num == imc->sinp_num && 	    imc->inpinfo.suggest_skeystroke &&	    imc->inpinfo.suggest_skeystroke[0].uch)	    skey = imc->inpinfo.suggest_skeystroke;	else {	    simdinfo.imid = ic->imc->id;	    simdinfo.guimode = imc->inpinfo.guimode;	    simdinfo.cch_publish.uch = imc->inpinfo.cch_publish.uch;		    if (imc->s_imodp->show_keystroke(imc->s_imodp->conf, &simdinfo))		skey = simdinfo.s_keystroke;	}    }    if (! skey) {	imc->sinmd_keystroke[0].uch = (uchar_t)0;	return;    }/*    skey_len = uchs_len(skey);*/    for (skey_len=0; skey[skey_len].uch != (uchar_t)0; skey_len++);    if (imc->skey_size < skey_len+1) {	imc->skey_size = skey_len+1;	imc->sinmd_keystroke = oxim_realloc(		imc->sinmd_keystroke, imc->skey_size * sizeof(uch_t));    }    memcpy(imc->sinmd_keystroke, skey, (skey_len+1)*sizeof(uch_t));}static voidchange_simd(IC *ic){    int idx;    imodule_t *imodp;    IM_Context_t *imc = ic->imc;    if (imc->inpinfo.cch_publish.uch)    {	printf(N_("query->%s\n"), (char *)(imc->inpinfo.cch_publish.s));    }    return;    /* TODO : 記得刪掉 call_simd() */    do {	if ((imodp = OXIM_IMGetNext(imc->sinp_num+1, &idx)))	    break;    } while (idx != imc->sinp_num);    if (idx != imc->sinp_num) {        imc->sinp_num = idx;        imc->s_imodp = imodp;        xccore->default_im_sinmd = (inp_state_t)idx;        xccore->oxim_mode &= ~OXIM_SHOW_CINPUT;	call_simd(ic);    }}/*----------------------------------------------------------------------------	IM Protocol Handler.----------------------------------------------------------------------------*/static int xim_open_handler(XIMS ims, IMOpenStruct *call_data){    DebugLog(2, ("XIM_OPEN\n"));    //-----------------------------    //char buf[1024];    //sprintf(buf, "echo XIM_OPEN %d - %s >> /tmp/lang", call_data->connect_id, call_data->lang.name);    //system(buf);    //-----------------------------    if (call_data->connect_id > nencodings)    {	if (nencodings == 0)	    im_enc = oxim_malloc((sizeof(int *) * call_data->connect_id)+1, True);	else	    im_enc = oxim_realloc(im_enc, (sizeof(int *) * call_data->connect_id)+1);	nencodings = call_data->connect_id;    }    int i;    for (i=0 ; i < xim_support_locales.nlocale ; i++)    {        if (strcasecmp(call_data->lang.name, xim_support_locales.locale[i])==0)        {	    im_enc[call_data->connect_id] = i;            return True;        }    }    return True;}static int xim_close_handler(XIMS ims, IMCloseStruct *call_data){    DebugLog(2, ("XIM_CLOSE\n"));    if (! (xccore->oxim_mode & OXIM_RUN_EXIT)) {	ic_clean_all(call_data->connect_id, xccore);    }    return True;}static intxim_create_ic_handler(XIMS ims, IMChangeICStruct *call_data, int *icid){    int ret;    if ((xccore->oxim_mode & OXIM_RUN_EXIT))	return True;    ret = ic_create(ims, call_data, xccore);    *icid = (ret == True) ? call_data->icid : -1;    DebugLog(2, ("XIM_CREATE_IC: icid=%d\n", *icid));    return ret;}static intxim_destroy_ic_handler(XIMS ims, IMDestroyICStruct *call_data, int *icid){    *icid = call_data->icid;    DebugLog(2, ("XIM_DESTORY_IC: icid=%d\n", *icid));    if (! (xccore->oxim_mode & OXIM_RUN_EXIT))	ic_destroy(*icid, xccore);    return True;}static int xim_set_focus_handler(XIMS ims, IMChangeFocusStruct *call_data, int *icid) {    IC *ic;    *icid = call_data->icid;    DebugLog(2, ("XIM_SET_IC_FOCUS: icid=%d\n", *icid));    if ((xccore->oxim_mode & OXIM_RUN_EXIT))	return True;    if (! (ic = ic_find(call_data->icid)))	return False;    if ((ic->ic_state & IC_FOCUS))	return True;/* *  This is special handler for OXIM_SINGLE_IMC mode. In this mode, all ICs *  share a single IMC. When the ICs change their focus status, it will have *  racing condition: for example: IC A focus out, and IC B focus in. It may *  by that IC B receive the focus-in event first, and then IC A receive the *  focus-out. This will lead to the un-correct ic->ic_state value. So here *  we only allow the focus-in IC to set its id to IMC, and IMC's focus state *  will change only when its icid is the same as the id of the current IC. * *  But for OXIM_SINGLE_IMC mode off, there will not have this problem. But *  this technique is still valid, since each IMC in each IC will have the *  same icid value as their corresponding IC's id. */    ic->imc->icid = ic->id;    if ((ic->imc->inp_state & IM_CINPUT)) {	ic->imc->inp_state |= IM_XIMFOCUS;    }    if ((ic->imc->inp_state & IM_2BYTES)) {	ic->imc->inp_state |= IM_2BFOCUS;    }    ic->ic_state |= IC_FOCUS;    xccore->ic = ic;    if ((ic->ic_state & IC_NEWIC)) {	if ((xccore->oxim_mode & OXIM_RUN_IM_FOCUS) ||	    (xccore->oxim_mode & OXIM_RUN_2B_FOCUS)) {	    if (xim_connect(ic) == True) {		if ((xccore->oxim_mode & OXIM_RUN_IM_FOCUS))		    change_IM(ic, xccore->im_focus);		if ((xccore->oxim_mode & OXIM_RUN_2B_FOCUS))		    ic->imc->inp_state |= (IM_2BYTES | IM_2BFOCUS);	    }	}        ic->ic_state &= ~(IC_NEWIC);    }    if ((xccore->oxim_mode & OXIM_SINGLE_IMC)) {	if ((ic->imc->inp_state & IM_CINPUT) ||	    (ic->imc->inp_state & IM_2BYTES))	    xim_connect(ic);	else	    xim_disconnect(ic);	ic->imc->ic_rec = &(ic->ic_rec);    }    int enc_id = im_enc[call_data->connect_id];    setlocale(LC_ALL, xim_support_locales.locale[enc_id]);    return True;}static int xim_unset_focus_handler(XIMS ims, IMChangeFocusStruct *call_data, int *icid){    IC *ic;    *icid = call_data->icid;    DebugLog(2, ("XIM_UNSET_IC_FOCUS: icid=%d\n", *icid));    if ((xccore->oxim_mode & OXIM_RUN_EXIT))	return True;    if (! (ic = ic_find(call_data->icid)))	return False;    if (! (ic->ic_state & IC_FOCUS))	return True;    xccore->icp = ic;    ic->ic_state &= ~(IC_FOCUS);    setlocale(LC_ALL, xccore->lc_ctype);    return True;}static int xim_trigger_handler(XIMS ims, IMTriggerNotifyStruct *call_data, int *icid){    int major_code, minor_code;    char *str;    IC *ic;    *icid = call_data->icid;    DebugLog(2, ("XIM_TRIGGER_NOTIFY: icid=%d\n", *icid));    if ((xccore->oxim_mode & OXIM_RUN_EXIT))	return True;    if (! (ic = ic_find(call_data->icid)))	return False;    xccore->icp = xccore->ic;    xccore->ic = ic;    xccore->ic->ic_state |= IC_FOCUS;    ic->imc->icid = ic->id;    if (call_data->flag == 0) { 		/* on key */        /* 	 *  Here, the start of preediting is notified from         *  IMlibrary, which is the only way to start preediting         *  in case of Dynamic Event Flow, because ON key is         *  mandatary for Dynamic Event Flow. 	 */	ic->ic_state |= IC_CONNECT;	get_trigger_key(call_data->key_index/3, &major_code, &minor_code);	switch (major_code) {	case FKEY_ZHEN:				/* ctrl+space: default IM */	    if (change_IM(ic, ic->imc->inp_num) == False)	        xim_disconnect(ic);	    break;	case FKEY_2BSB:				/* shift+space: sb/2b */	    ic->imc->inp_state |= (IM_2BYTES | IM_2BFOCUS);	    if ((xccore->oxim_mode & OXIM_IM_FOCUS))	        xccore->oxim_mode |= OXIM_RUN_2B_FOCUS;	    break;	case FKEY_CIRIM:			/* ctrl+shift: circuler + */	    circular_change_IM(ic, 1);	    if (! (ic->imc->inp_state & IM_CINPUT))		xim_disconnect(ic);	    break;	case FKEY_CIRRIM:			/* shift+ctrl: circuler - */	    circular_change_IM(ic, -1);	    if (! (ic->imc->inp_state & IM_CINPUT))		xim_disconnect(ic);	    break;	case FKEY_IMN:				/* ctrl+alt+?: select IM */	    if (change_IM(ic, oxim_get_IMIdxByKey(minor_code)) == False)	        xim_disconnect(ic);	    break;	case FKEY_QPHRASE:	    if ((str = oxim_qphrase_str(minor_code)))	    {		xim_commit_string(ic, str);	    }	    xim_disconnect(ic);	    break;	case FKEY_SYMBOL:	    gui_switch_symbol();	    break;	case FKEY_KEYBOARD:	    gui_switch_keyboard();	    break;	}        return True;    }     else 					/* never happens */        return False;}#ifndef AltGrMask#define AltGrMask (1L<<13)#endifstatic intforward_keys_handler(IC *ic, keyinfo_t *keyinfo){    unsigned int ret;    int major_code, minor_code;    IM_Context_t *imc;    imc = ic->imc;/* *  Keycode translation for different layout of keyboards. * *  In most places of the world, we use the "qwerty" layout of the keyboard. *  But in other places, e.g., France, they use the "azerty" layout of the *  keyboard. There are many differences between them. For example, the *  number keys KP_1 .... KP_9 for "qwerty" keyboard do not have the Shift *  ON, but for "azerty" they do. So we have to do the keyboard translation *  here, if necessary. The translation is just from other layout to the *  "standard" "qwerty" layout. * *  This translation code is provided by dupre <dupre@lifo.univ-orleans.fr>. *  He commented that to do the correct translation, we have to turn off *  the non-necessary Shift mask for some keys, and turn on Shift mask for *  the others. Sometimes the keycode of the "azerty" keyboard will come *  with the "AltGr" mask on. It should always be turned off. Note that the *  translation is performed only when Shift and AltGr are NOT ON at the *  same moment. */    if ((xccore->oxim_mode & OXIM_KEYBOARD_TRANS)) {	if (! (keyinfo->keystate & ShiftMask &&	       keyinfo->keystate & AltGrMask) &&	    keyinfo->keysym > 32 && keyinfo->keysym < 127 &&	    keyinfo->keystr_len) {	    if (strstr("',-./0123456789;=[\\]`abcdefghijklmnopqrstuvwxyz",			keyinfo->keystr) != NULL) {		keyinfo->keystate &= ~ShiftMask;		keyinfo->keystate &= ~AltGrMask;	    }	    else {		keyinfo->keystate |=  ShiftMask;		keyinfo->keystate &= ~AltGrMask;	    }	}    }/* *  Process the special key binding. */    if (search_funckey(keyinfo->keysym, keyinfo->keystate,		&major_code, &minor_code)) {	char *str;	switch (major_code) {	case FKEY_ZHEN:            if ((imc->inp_state & IM_CINPUT))                change_IM(ic, -1);            else                change_IM(ic, imc->inp_num);	    break;	case FKEY_SYMBOL:	    gui_switch_symbol();	    break;	case FKEY_KEYBOARD:	    gui_switch_keyboard();	    break;	case FKEY_OUTSIMP:	    if (!strcasecmp("UTF-8", nl_langinfo(CODESET)))	    {		if (!(imc->inp_state & IM_OUTSIMP))		{		    imc->inp_state &= 0x0f;		    imc->inp_state |= IM_OUTSIMP;		}		else		    imc->inp_state &= 0x0f;	    }	    break;	case FKEY_OUTTRAD:	    if (!strcasecmp("UTF-8", nl_langinfo(CODESET)))	    {		if (!(imc->inp_state & IM_OUTTRAD))		{		    imc->inp_state &= 0x0f;		    imc->inp_state |= IM_OUTTRAD;		}		else		    imc->inp_state &= 0x0f;	    }	    break;	case FKEY_2BSB:            if ((imc->inp_state & IM_2BYTES)) {                imc->inp_state &= ~(IM_2BYTES | IM_2BFOCUS);	        if ((xccore->oxim_mode & OXIM_IM_FOCUS))	            xccore->oxim_mode &= ~OXIM_RUN_2B_FOCUS;	    }            else {                imc->inp_state |= (IM_2BYTES | IM_2BFOCUS);	        if ((xccore->oxim_mode & OXIM_IM_FOCUS))	            xccore->oxim_mode |= OXIM_RUN_2B_FOCUS;	    }	    break;	case FKEY_CIRIM:            circular_change_IM(ic, 1);	    break;	case FKEY_CIRRIM:            circular_change_IM(ic, -1);	    break;	case FKEY_IMN:            change_IM(ic, oxim_get_IMIdxByKey(minor_code));	    break;	case FKEY_CHREP:	    xim_commit_string(ic, NULL);	    break;	case FKEY_SIMD: /* 查字根 */            change_simd(ic);	    break;	case FKEY_IMFOCUS:	    if ((xccore->oxim_mode & OXIM_IM_FOCUS)) {		xccore->oxim_mode &= ~OXIM_IM_FOCUS;		xccore->oxim_mode &= ~OXIM_RUN_IM_FOCUS;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?