chewing.0.3.2.c

来自「linux 下的 oxim 输入法,简单易用.」· C语言 代码 · 共 553 行

C
553
字号
/* * Bridge interface between libchewing and oxim */#ifdef HAVE_CONFIG_H#  include <config.h>#endif#include <chewing/chewing.h>#include <string.h>#include <X11/Xlib.h>#include <X11/keysym.h>#include "oximtool.h"#include "module.h"#include "chewing.0.3.2.h"/* the following keystate masks are defined by oxim */#define CAPS_MASK (2)#define CTRL_MASK (4)static int KeyMap = 0; /* 0:標準注音鍵盤 */static int CapsLockMode  = 0; /* 0:小寫, 1:大寫 */static int selKey_define[4][10] = 	{{'1','2','3','4','5','6','7','8','9','0'},	 {'q','w','e','r','t','y','u','i','o','p'},	 {'a','s','d','f','g','h','j','k','l',';'},	 {'z','x','c','v','b','n','m',',','.','/'}};static int selKey = 0;static uch_t etymon_list[N_KEYCODE];int MakeInpinfo(inpinfo_t *inpinfo);int CallSetConfig(inpinfo_t *inpinfo, ChewingContext *ctx){    chewing_set_candPerPage(ctx, 0xffff);    chewing_set_maxChiSymbolLen(ctx, 20);    chewing_set_spaceAsSelection(ctx, True);    chewing_set_selKey(ctx, (int *)selKey_define[selKey], 10);    return 0;}static intChewingInit(void *context, char *objname){    ChewingContext *ctx = (ChewingContext *)context ;    settings_t *im_settings = oxim_get_im_settings(objname);    if (!im_settings)    {        printf("沒有 %s 的設定!\n", objname);        return False;    }    int SelectionKeys;    if (oxim_setting_GetInteger(im_settings, "SelectionKeys", &SelectionKeys))    {	selKey = SelectionKeys;    }    if (!oxim_setting_GetInteger(im_settings, "CapsLockMode", &CapsLockMode))    {	CapsLockMode = 0;    }    if (oxim_setting_GetInteger(im_settings, "KeyMap", &KeyMap))    {	if (KeyMap < chewing_KBStr2Num("KB_DEFAULT") && KeyMap > chewing_KBStr2Num("KB_HANYU_PINYIN"))	{	    KeyMap = chewing_KBStr2Num("KB_DEFAULT");	}    }    char *pho_key = "1qaz2wsxedcrfv5tgbyhnujm8ik,9ol.0p;/-7634";    char *pho_name[41] = {"ㄅ","ㄆ","ㄇ","ㄈ","ㄉ","ㄊ","ㄋ","ㄌ","ㄍ","ㄎ","ㄏ","ㄐ","ㄑ","ㄒ","ㄓ","ㄔ","ㄕ","ㄖ","ㄗ","ㄘ","ㄙ","ㄧ","ㄨ","ㄩ","ㄚ","ㄛ","ㄜ","ㄝ","ㄞ","ㄟ","ㄠ","ㄡ","ㄢ","ㄣ","ㄤ","ㄥ","ㄦ","˙","ˊ","ˇ","ˋ"};    int keylen = strlen(pho_key), i, idx;     for (i = 0 ; i < keylen ; i++)    {	idx = oxim_key2code(pho_key[i]);	strcpy((char *)etymon_list[idx].s, pho_name[i]);    }    /* Initialize Chewing */    chewing_Init(CHEWING_DATA_DIR, NULL);    oxim_settings_destroy(im_settings);    return True;}static int ChewingXimInit(void *conf, inpinfo_t *inpinfo){    static char cchBuffer[MAX_PHONE_SEQ_LEN * MAX_UTF8_SIZE + 1];    ChewingContext *ctx = (ChewingContext *) conf;    int i;    inpinfo->iccf = chewing_new();    CallSetConfig(inpinfo, (ChewingContext *) inpinfo->iccf);    chewing_set_KBType( inpinfo->iccf, KeyMap );    inpinfo->etymon_list = (KeyMap == chewing_KBStr2Num("KB_HANYU_PINYIN")) ? NULL : etymon_list;    inpinfo->lcch = (uch_t *) calloc(MAX_PHONE_SEQ_LEN, sizeof(uch_t));    inpinfo->lcch_grouping = (ubyte_t *) calloc(MAX_PHONE_SEQ_LEN, sizeof(ubyte_t));    inpinfo->cch = cchBuffer;    inpinfo->guimode = GUIMOD_LISTCHAR | GUIMOD_SELKEYSPOT;    inpinfo->keystroke_len = 0;    inpinfo->s_keystroke = (uch_t *) calloc(3 + MAX_PHRASE_LEN, sizeof(uch_t));    inpinfo->mcch = (uch_t *) calloc(MAX_CHOICE_BUF, sizeof(uch_t));    inpinfo->mcch_grouping = calloc( MAX_SELKEY, sizeof(uint_t));    inpinfo->n_mcch = 0;    inpinfo->n_lcch = 0;    inpinfo->edit_pos = 0;    inpinfo->cch_publish.uch = (uchar_t) 0;    inpinfo->n_selkey = 10;    inpinfo->s_selkey = (uch_t *) calloc(MAX_SELKEY, sizeof(uch_t));    for (i = 0; i < 10; i++)    {	inpinfo->s_selkey[i].uch = (uchar_t) 0;	inpinfo->s_selkey[i].s[0] = selKey_define[selKey][i];    }    return True;}void CommitString(inpinfo_t *inpinfo){    int i ;    ChewingContext *ctx = inpinfo->iccf;    char *cch = chewing_commit_String(ctx);    inpinfo->cch[0] = '\0';    strcat(inpinfo->cch, (const char*) cch);    free(cch);    cch = NULL;}static unsigned int ChewingXimEnd(void *conf, inpinfo_t *inpinfo){    int rtn ;    /* if preedit exists, commit the string */    chewing_handle_Enter(inpinfo->iccf);    rtn = MakeInpinfo(inpinfo);    chewing_free((ChewingContext*) inpinfo->iccf);    free(inpinfo->s_keystroke);    free(inpinfo->lcch);    free(inpinfo->mcch);    free(inpinfo->mcch_grouping);    free(inpinfo->s_selkey);    inpinfo->iccf = NULL;    inpinfo->s_keystroke = NULL;    inpinfo->lcch = NULL;    inpinfo->mcch = NULL;    inpinfo->mcch_grouping = NULL;    inpinfo->s_selkey = NULL;    return rtn ;}void ShowChoose(inpinfo_t *inpinfo){    int i,no,len;    char *output = NULL;    ChewingContext *ctx = inpinfo->iccf;    int nPage = chewing_cand_TotalPage(ctx);    int pageNo = chewing_cand_CurrentPage(ctx);    int nChoicePerPage = chewing_cand_ChoicePerPage(ctx);    int nTotalChoice = chewing_cand_TotalChoice(ctx);    // for new oxim, there is no need to modify the lcch buffer    // instead, we put phrase to choose in mcch    no = pageNo * nChoicePerPage;    len = 0;    inpinfo->mcch_grouping[0] = 0;    chewing_cand_Enumerate(ctx);    for (i = 0;i < nChoicePerPage; no++,i++)    {        // in the last page, no will exceed nTotalChoice        if( no >= nTotalChoice )             break;	output = chewing_cand_String(ctx);	unsigned int ucs4, olen = strlen(output);	int nbytes, nchars = 0;        /* for each char in the phrase, copy to mcch */	while (olen && (nbytes = oxim_utf8_to_ucs4(output, &ucs4, olen)) > 0)	{	    inpinfo->mcch[len].uch = (uchar_t)0;	    memcpy(inpinfo->mcch[len++].s, output, nbytes);	    nchars ++;	    output += nbytes;	    olen -= nbytes;	}        /* set grouping to the length of the phrase */        inpinfo->mcch_grouping[i+1] = nchars;	if (nchars > 1)	    inpinfo->mcch_grouping[0] ++;     }    // set pgstate according to pci->pageNo & pci->nPage    if( nPage == 1) {        inpinfo->mcch_pgstate = MCCH_ONEPG;    }    else {        if( pageNo == 0 )            inpinfo->mcch_pgstate = MCCH_BEGIN;        else if( pageNo == nPage - 1)            inpinfo->mcch_pgstate = MCCH_END;        else            inpinfo->mcch_pgstate = MCCH_MIDDLE;    }    inpinfo->n_mcch = len ;}void ShowText(inpinfo_t *inpinfo){    int i;    ChewingContext *ctx = inpinfo->iccf;    int chiSymbolBufLen = chewing_buffer_Len(ctx);    bzero(inpinfo->lcch, sizeof(uch_t)*MAX_PHONE_SEQ_LEN) ;    char *bufferStr = chewing_buffer_String(ctx);        unsigned int ucs4, olen = strlen(bufferStr);        int nbytes, nchars = 0, len = 0;        /* for each char in the phrase, copy to mcch */        while (olen && (nbytes = oxim_utf8_to_ucs4(bufferStr, &ucs4, olen)) > 0)        {            inpinfo->lcch[len].uch = (uchar_t)0;            memcpy(inpinfo->lcch[len++].s, bufferStr, nbytes);            nchars ++;            bufferStr += nbytes;            olen -= nbytes;        }    inpinfo->n_lcch = chiSymbolBufLen ;}void ShowInterval(inpinfo_t *inpinfo){    int i, k, begin, len, count, nGroup ;    int label[MAX_PHONE_SEQ_LEN] ;    ChewingContext *ctx = inpinfo->iccf;    int chiSymbolBufLen = chewing_buffer_Len(ctx);    if( 0 == chiSymbolBufLen )    {        inpinfo->lcch_grouping[0] = 0 ;        return ;    }    // set label    for(count=0; count<chiSymbolBufLen; count++)    {        label[count] = count;    }    chewing_interval_Enumerate(ctx);    while(chewing_interval_hasNext(ctx))    {	IntervalType it;	chewing_interval_Get(ctx, &it);	len = it.to - it.from;	if( len > 1 )	{	    for(k=it.from; k<it.to; k++)	    {		label[k] = count;	    }	    count++;	}    }        // begin to set lcch_grouping by the label        nGroup = 0 ;        begin = 0 ;        for(i=1; i<chiSymbolBufLen; i++) {                if( label[i] != label[begin] ) {                        inpinfo->lcch_grouping[++nGroup] = ( i - begin ) ;                        begin = i ;                }        }        inpinfo->lcch_grouping[++nGroup] = ( i - begin ) ;        inpinfo->lcch_grouping[0] = nGroup ;}void ShowStateAndZuin(inpinfo_t *inpinfo){    int i, a , len = 0;    bzero( inpinfo->s_keystroke, sizeof(uch_t)*(3 + MAX_PHRASE_LEN));    ChewingContext *iccf = inpinfo->iccf;	    if(chewing_aux_Check(iccf))    {	char *auxStr = chewing_aux_String(iccf);        unsigned int ucs4, olen = strlen(auxStr);        int nbytes, nchars = 0;        /* for each char in the phrase, copy to mcch */        while (olen && (nbytes = oxim_utf8_to_ucs4(auxStr, &ucs4, olen)) > 0)        {            inpinfo->s_keystroke[len].uch = (uchar_t)0;            memcpy(inpinfo->s_keystroke[len++].s, auxStr, nbytes);            nchars ++;            auxStr += nbytes;            olen -= nbytes;        }	inpinfo->keystroke_len = chewing_aux_Length(iccf) ;    }    else    {	// 漢語拼音/*	if ( 0 == strcasecmp(chewing_kbtype_String(iccf), "KB_HANYU_PINYIN"))	{	}	else*/	{	char *zuinBuf = chewing_zuin_String(iccf, &len);        unsigned int ucs4, olen = strlen(zuinBuf);	len = 0;        int nbytes, nchars = 0;        /* for each char in the phrase, copy to mcch */        while (olen && (nbytes = oxim_utf8_to_ucs4(zuinBuf, &ucs4, olen)) > 0)        {            inpinfo->s_keystroke[len].uch = (uchar_t)0;            memcpy(inpinfo->s_keystroke[len++].s, zuinBuf, nbytes);            nchars ++;            zuinBuf += nbytes;            olen -= nbytes;        }	inpinfo->keystroke_len = len;	}    }}void SetCursor(inpinfo_t *inpinfo){    ChewingContext *ctx = inpinfo->iccf;    inpinfo->edit_pos = chewing_cursor_Current(ctx);}int MakeInpinfo(inpinfo_t *inpinfo){    ChewingContext *ctx = inpinfo->iccf;    int rtnValue = 0 ;    if(chewing_keystroke_CheckAbsorb(ctx))        rtnValue |= IMKEY_ABSORB;    if(chewing_keystroke_CheckIgnore(ctx))        rtnValue |= IMKEY_IGNORE;    if(chewing_commit_Check(ctx))    {        rtnValue |= IMKEY_COMMIT;        CommitString(inpinfo);    }    if(chewing_cand_TotalPage(ctx) != 0) { // in selection mode        ShowChoose(inpinfo);        inpinfo->guimode &= ~GUIMOD_LISTCHAR;     }    else { // not in selection mode        ShowText(inpinfo);        ShowInterval(inpinfo);        inpinfo->guimode |= GUIMOD_LISTCHAR;    }    ShowStateAndZuin(inpinfo);    SetCursor(inpinfo);    return rtnValue;}static unsigned intChewingKeystroke(void *conf, inpinfo_t *inpinfo, keyinfo_t *keyinfo){    KeySym keysym = keyinfo->keysym;    int rtn ;    /*     * CapsLock 時,輸出小寫,加上 Shift 才輸出大寫。     */    if (CapsLockMode == 0 && keyinfo->keystate & LockMask)    {	if (keyinfo->keystate & ShiftMask)	{	    keysym = toupper(keysym);	}	else	{	    keysym = tolower(keysym);	}    }    // set Chinese / English mode by keystate    if( keyinfo->keystate & CAPS_MASK )    {            chewing_set_ChiEngMode( inpinfo->iccf, SYMBOL_MODE);    }    else    {             chewing_set_ChiEngMode( inpinfo->iccf, CHINESE_MODE);    }    // check no ctrl key was pressed    if(keyinfo->keystate >= 0 && !(keyinfo->keystate & CTRL_MASK ) && !(keyinfo->keystate & ShiftMask) ) {        switch(keysym) {            case XK_Escape:                chewing_handle_Esc(inpinfo->iccf) ;                inpinfo->n_mcch = 0;                break ;            case XK_Return:                chewing_handle_Enter(inpinfo->iccf) ;                inpinfo->n_mcch = 0;                break ;            case XK_Delete:                chewing_handle_Del(inpinfo->iccf) ;		break ;            case XK_BackSpace:                chewing_handle_Backspace(inpinfo->iccf) ;                break ;            case XK_Up:                chewing_handle_Up(inpinfo->iccf);                break ;            case XK_Down:                chewing_handle_Down(inpinfo->iccf) ;                break ;            case XK_Left:                chewing_handle_Left(inpinfo->iccf) ;                break ;            case XK_Right:                chewing_handle_Right(inpinfo->iccf) ;                break ;            case XK_Home:                chewing_handle_Home(inpinfo->iccf);		break;	    case XK_End:                chewing_handle_End(inpinfo->iccf);                break;            case XK_Tab:                chewing_handle_Tab(inpinfo->iccf);                break;            case XK_Caps_Lock:                chewing_handle_Capslock(inpinfo->iccf);                break;            case ' ': /* Space */                chewing_handle_Space(inpinfo->iccf);                break;	    case XK_Insert:	    case XK_Page_Up:	    case XK_Page_Down:		return IMKEY_IGNORE;            default:                chewing_handle_Default(inpinfo->iccf, (char) keysym );                inpinfo->n_mcch = 0;                break;        }    }    else if (keyinfo->keystate & ShiftMask) {	switch ( keysym ) {	    case XK_Left:		chewing_handle_ShiftLeft(inpinfo->iccf) ;                break ;            case XK_Right:                chewing_handle_ShiftRight(inpinfo->iccf) ;                break;            case ' ':                chewing_handle_ShiftSpace(inpinfo->iccf) ;                chewing_set_ShapeMode( inpinfo->iccf, !chewing_get_ShapeMode( inpinfo->iccf ) );                break;	    case XK_Insert:	    case XK_Delete:	    case XK_Home:	    case XK_End:	    case XK_Page_Up:	    case XK_Page_Down:	    case XK_Up:	    case XK_Down:		return IMKEY_IGNORE;            default:		chewing_handle_Default(inpinfo->iccf, (char) keysym);		inpinfo->n_mcch = 0;		break;	}    }    else if (keyinfo->keystate & CTRL_MASK) {  // Ctrl-key Mask	    if (keysym <= '9' && keysym >= '0') 	    {		chewing_handle_CtrlNum(inpinfo->iccf, (char) keysym);	    }	    else	    {		return IMKEY_IGNORE;	    }    }    rtn = MakeInpinfo(inpinfo);    return rtn ;}static int ChewingShowKeystroke(void *conf, simdinfo_t *simdinfo){    simdinfo->s_keystroke = NULL;    return False;}                              static int ChewingTerminate(void *conf){    chewing_Terminate();    return True;}static char zh_chewing_comments[] = N_(     "Chewing : a smart phonetic input method module for OXIM.\n"    "By Lu-chuan Kung <lckung@iis.sinica.edu.tw>,\n"    "Kang-pen Chen <kpchen@iis.sinica.edu.tw>, and others.\n");static char *zh_chewing_valid_objname[] = { "chewing", NULL };module_t module_ptr = {    {         MTYPE_IM,        "chewing",			/* name */        MODULE_VERSION,			/* version */        zh_chewing_comments     },					/* comments */    zh_chewing_valid_objname,		/* valid_objname */    sizeof(ChewingConfigData),		/* conf_size */    ChewingInit,			/* init */    ChewingXimInit,			/* xim_init */    ChewingXimEnd,			/* xim_end */    ChewingKeystroke,			/* keystroke */    ChewingShowKeystroke,		/* show_keystroke */    ChewingTerminate			/* terminate */};

⌨️ 快捷键说明

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