gen-inp-v1.c
来自「linux 下的 oxim 输入法,简单易用.」· C语言 代码 · 共 1,570 行 · 第 1/3 页
C
1,570 行
/* Copyright (C) 2006 by OXIM TEAM This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/ #ifdef HAVE_CONFIG_H# include "config.h"#endif#include <string.h>#include <X11/Xlib.h>#include <X11/keysym.h>#include "oximtool.h"#include "module.h"#include "gen-inp-v1.h"static char *bopomofo[] = {"ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙ", /* 聲母 */ "ㄧㄨㄩ", "ㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦ" /* 韻母 */};static int fillpage(gen_inp_conf_t *cf, inpinfo_t *inpinfo, gen_inp_iccf_t *iccf, byte_t dir);static void gen_inp_resource(gen_inp_conf_t *cf, settings_t *im_settings);/*---------------------------------------------------------------------------- gen_inp_init()----------------------------------------------------------------------------*/static intloadtab(gen_inp_conf_t *cf, char *objname){ table_prefix_t tp; unsigned int size = MODULE_ID_SIZE; cf->memory_usage = sizeof(gen_inp_conf_t); if (gzread(cf->zfp , &tp, size) != size || strcmp(tp.prefix, "gencin") || tp.version != 1) { oxim_perr(OXIMMSG_WARNING, N_("gen_inp: %s: invalid tab file.\n"),cf->tabfn); return False; } size = sizeof(cintab_head_v1_t); cf->memory_usage += size; if (gzread(cf->zfp, &(cf->header), size) != size) { oxim_perr(OXIMMSG_WARNING, N_("gen_inp: %s: reading error.\n"), cf->tabfn); return False; } unsigned int checksum = crc32(0L, (char *)&cf->header, sizeof(cintab_head_v1_t) - sizeof(unsigned int)); if (cf->header.chksum != checksum) { oxim_perr(OXIMMSG_WARNING, N_("gen_inp: %s: checksum error.\n"), cf->tabfn); return False; } settings_t *im_settings; /* 讀取輸入法表格預設的定義 */ im_settings = oxim_get_default_settings(objname, True); if (im_settings) { gen_inp_resource(cf, im_settings); oxim_settings_destroy(im_settings); } /* 讀取使用者的定義 */ im_settings = oxim_get_im_settings(objname); if (im_settings) { gen_inp_resource(cf, im_settings); oxim_settings_destroy(im_settings); } return True;}static voidsetup_kremap(gen_inp_conf_t *cf, char *value){ int i=0; unsigned int num; char *s = value, *sp; while (*s) { if (*s == ';') { i++; } s++; } if (!i) return; cf->n_kremap = i; cf->kremap = oxim_malloc(sizeof(kremap_t) * i, True); s = sp = value; for (i=0; i<cf->n_kremap; i++) { while (*s != ':') { s++; } *s = '\0'; cf->kremap[i].keystroke = strdup(sp); s++; sp = s; while (*s != ';') s++; *s = '\0'; strncpy((char *)cf->kremap[i].uch.s, sp, UCH_SIZE); s++; sp = s; }}static voidgen_inp_resource(gen_inp_conf_t *cf, settings_t *im_settings){ int boolean; if (oxim_setting_GetBoolean(im_settings, "AutoCompose", &boolean)) oxim_setflag(&cf->mode, INP_MODE_AUTOCOMPOSE, boolean); if (oxim_setting_GetBoolean(im_settings, "AutoUpChar", &boolean)) oxim_setflag(&cf->mode, INP_MODE_AUTOUPCHAR, boolean); if (oxim_setting_GetBoolean(im_settings, "AutoFullUp", &boolean)) oxim_setflag(&cf->mode, INP_MODE_AUTOFULLUP, boolean); if (oxim_setting_GetBoolean(im_settings, "SpaceAutoUp", &boolean)) oxim_setflag(&cf->mode, INP_MODE_SPACEAUTOUP, boolean); if (oxim_setting_GetBoolean(im_settings, "SelectKeyShift", &boolean)) oxim_setflag(&cf->mode, INP_MODE_SELKEYSHIFT, boolean); if (oxim_setting_GetBoolean(im_settings, "SpaceIgnore", &boolean)) oxim_setflag(&cf->mode, INP_MODE_SPACEIGNOR, boolean); if (oxim_setting_GetBoolean(im_settings, "SpaceReset", &boolean)) oxim_setflag(&cf->mode, INP_MODE_SPACERESET, boolean); if (oxim_setting_GetBoolean(im_settings, "AutoReset", &boolean)) oxim_setflag(&cf->mode, INP_MODE_AUTORESET, boolean); if (oxim_setting_GetBoolean(im_settings, "WildEnable", &boolean)) oxim_setflag(&cf->mode, INP_MODE_WILDON, boolean); if (oxim_setting_GetBoolean(im_settings, "EndKey", &boolean)) oxim_setflag(&cf->mode, INP_MODE_ENDKEY, boolean); /* 使用注音符號字根排列規則 */ if (oxim_setting_GetBoolean(im_settings, "BoPoMoFoCheck", &boolean)) oxim_setflag(&cf->mode, INP_MODE_BOPOMOFOCHK, boolean); char *string; bzero(cf->disable_sel_list, N_KEYS); if (oxim_setting_GetString(im_settings, "DisableSelectList", &string)) { if (strlen(string) && strcasecmp("NONE", string) != 0) { strcpy(cf->disable_sel_list, string); } } if (oxim_setting_GetString(im_settings, "Remap", &string)) { 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; } if (strlen(string) && strcasecmp(string, "NONE") != 0) { setup_kremap(cf, string); } } /* 有結束鍵設定,就自動設定按結束鍵自動上字 */ if (cf->header.n_end_key) { cf->mode |= INP_MODE_ENDKEY; }}static int gen_inp_init(void *conf, char *objname){ gen_inp_conf_t *cf = (gen_inp_conf_t *)conf; char *s, value[128], truefn[256]; unsigned int size;/* * Read the IM tab file. */ sprintf(value, "%s.tab", objname); if (oxim_check_datafile(value, "tables", truefn, 256) == True) { if ((cf->zfp = gzopen(truefn, "rb")) == NULL) { return False; } cf->tabfn = (char *)strdup(truefn); if (!loadtab(cf, objname)) { free(cf->tabfn); gzclose(cf->zfp); cf->zfp = NULL; return False; } /* 決定檔案讀取模式 */ /* 使用基本的檔案操作函數判斷此檔是否為未壓縮格式 */ table_prefix_t tp; FILE *fp; /* 不必判斷 fopen 是否成功!因為 gzopen 若通過,fopen() 沒有理由不行 */ fp = fopen(truefn, "rb"); fread(&tp, 1, MODULE_ID_SIZE, fp); fclose(fp); cf->direct_mode = (memcmp(tp.prefix, "gencin", 6) == 0) ? True : False; } else { return False; } /*------------------------------------------------------ 如果是壓縮型態的輸入法參考檔,就把 offset table 與 input content 統統讀進記憶體。 ------------------------------------------------------*/ if (!cf->direct_mode) { if (gzseek(cf->zfp, cf->header.offset_table_offset, SEEK_SET) < 0) { return False; } size = (cf->header.n_input_content+1) * sizeof(unsigned int); cf->offset_tbl = oxim_malloc(size, False); if (gzread(cf->zfp, cf->offset_tbl, size) != size) { free(cf->offset_tbl); oxim_perr(OXIMMSG_WARNING, N_("gen_inp: %s: reading offset table error.\n"), cf->tabfn); return False; } cf->offset_size = size; cf->memory_usage += size; /* 把輸入資料也讀進記憶體 */ if (gzseek(cf->zfp, cf->header.input_content_offset, SEEK_SET) < 0) { free(cf->offset_tbl); cf->offset_tbl = NULL; return False; } size = cf->offset_tbl[cf->header.n_input_content] - cf->offset_tbl[0]; cf->input_content = oxim_malloc(size, False); if(gzread(cf->zfp, cf->input_content, size) != size) { free(cf->offset_tbl); cf->offset_tbl = NULL; free(cf->input_content); cf->input_content = NULL; return False; } cf->input_content_size = size; cf->memory_usage += size; } /*------------------------------------------------------*/ /* 產生給螢幕小鍵盤用的字根表 */ int i; for (i = 0 ; i < N_KEYS ; i++) { if (cf->header.keyname[i].uch) { int idx = oxim_key2code(i); if (idx) { cf->etymon_list[idx].uch = cf->header.keyname[i].uch; } } } return True;}/*---------------------------------------------------------------------------- gen_inp_xim_init()----------------------------------------------------------------------------*/static intgen_inp_xim_init(void *conf, inpinfo_t *inpinfo){ gen_inp_conf_t *cf = (gen_inp_conf_t *)conf; int i; unsigned int size; inpinfo->iccf = oxim_malloc(sizeof(gen_inp_iccf_t), True); inpinfo->etymon_list = cf->etymon_list; inpinfo->guimode = 0; inpinfo->keystroke_len = 0; inpinfo->s_keystroke = oxim_malloc((N_NAME_LENGTH)*sizeof(uch_t), True); inpinfo->suggest_skeystroke = oxim_malloc((cf->header.n_max_keystroke+1)*sizeof(uch_t), True); if (! (cf->mode & INP_MODE_SELKEYSHIFT)) { inpinfo->n_selkey = cf->header.n_selection_key; inpinfo->s_selkey = oxim_malloc(inpinfo->n_selkey*sizeof(uch_t), True); for (i=0; i<SELECT_KEY_LENGTH && i<cf->header.n_selection_key; i++) inpinfo->s_selkey[i].s[0] = cf->header.selection_keys[i]; } else { inpinfo->n_selkey = cf->header.n_selection_key+1; inpinfo->s_selkey = oxim_malloc(inpinfo->n_selkey*sizeof(uch_t), True); for (i=0; i<SELECT_KEY_LENGTH && i<cf->header.n_selection_key; i++) inpinfo->s_selkey[i+1].s[0] = cf->header.selection_keys[i]; } i = inpinfo->n_selkey; inpinfo->n_mcch = 0; inpinfo->mcch = NULL; inpinfo->mcch_grouping = oxim_malloc((i+1) * sizeof(uint_t), True); inpinfo->mcch_pgstate = MCCH_ONEPG; inpinfo->n_lcch = 0; inpinfo->lcch = NULL; inpinfo->lcch_grouping = NULL; inpinfo->cch_publish.uch = 0; return True;}static unsigned intgen_inp_xim_end(void *conf, inpinfo_t *inpinfo){ gen_inp_conf_t *cf = (gen_inp_conf_t *)conf; gen_inp_iccf_t *iccf = (gen_inp_iccf_t *)inpinfo->iccf; if (iccf->mkey_list) { free(iccf->mkey_list); iccf->mkey_list = NULL; } free(inpinfo->iccf); inpinfo->iccf = NULL; if (inpinfo->mcch) { free(inpinfo->mcch); inpinfo->mcch = NULL; } free(inpinfo->s_keystroke); inpinfo->s_keystroke = NULL; free(inpinfo->suggest_skeystroke); inpinfo->suggest_skeystroke = NULL; free(inpinfo->s_selkey); inpinfo->s_selkey = NULL; free(inpinfo->mcch_grouping); inpinfo->mcch_grouping = NULL; return IMKEY_ABSORB;}/*---------------------------------------------------------------------------- gen_inp_keystroke()----------------------------------------------------------------------------*/static unsigned intreturn_wrong(gen_inp_conf_t *cf){ return IMKEY_ABSORB;}static unsigned intreturn_correct(gen_inp_conf_t *cf){ return IMKEY_ABSORB;}static voidreset_keystroke(inpinfo_t *inpinfo, gen_inp_iccf_t *iccf){ inpinfo->s_keystroke[0].uch = 0; inpinfo->keystroke_len = 0; inpinfo->n_mcch = 0; iccf->keystroke[0] = '\0'; iccf->mode = 0; inpinfo->mcch_pgstate = MCCH_ONEPG; if (iccf->mkey_list) { free(iccf->mkey_list); iccf->mkey_list = NULL; }}/*------------------------------------------------------------------------*/static void *get_input_content(gen_inp_conf_t *cf, unsigned int idx){ if (idx >= cf->header.n_input_content) { return NULL; } unsigned int offset, offset_len; /* 完全使用磁碟 I/O */ if (cf->direct_mode) { unsigned int ofs[2]; /* 表格起始位置 + (索引值 x 4) */ unsigned int idx_offset = cf->header.offset_table_offset + (idx << 2); unsigned int offsetsize = sizeof(unsigned int) << 1; /* 移動讀取指標 */ if (gzseek(cf->zfp, idx_offset, SEEK_SET) < 0) { return NULL; } /* 讀入輸入資料偏移位置 */ if (gzread(cf->zfp, &ofs, offsetsize) != offsetsize) { return NULL; } offset = ofs[0]; offset_len = ofs[1] - offset; if (gzseek(cf->zfp, offset, SEEK_SET) < 0) { return NULL; } } else /* Offset Table 已經讀入記憶體內 */ { offset = cf->offset_tbl[idx] - cf->offset_tbl[0]; offset_len = cf->offset_tbl[idx+1] - offset - cf->offset_tbl[0]; } /* 配置記憶體 */ /* 讀入真正的輸入資料 */ void *icr = oxim_malloc(offset_len, False); if (cf->direct_mode) { if (gzread(cf->zfp, icr, offset_len) != offset_len) { free(icr); icr = NULL; } } else { memcpy(icr, cf->input_content+offset, offset_len); } return icr;}static intcmp_icvalue(gen_inp_conf_t *cf, char *keystroke, unsigned int idx, int wildcmp){ static char buf[256]; unsigned char keystroke_len = strlen(keystroke); void *icr = get_input_content(cf, idx); unsigned char key_len; int cmp; if (!icr) { return -1; } memcpy(&key_len, icr, 1); strncpy(buf, icr+2, key_len); buf[key_len] = '\0'; if (wildcmp) { cmp = strcmp_wild(keystroke, buf); } else { cmp = strcmp(buf, keystroke); } free(icr); if (cmp > 0) cmp = 1; else if (cmp < 0) cmp = -1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?