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