6.我是输入法

本文深入讨论了现代输入法的设计理念,包括智能预测、快捷短语、语音输入等功能,以及它们如何提升用户在不同场景下的输入效率。同时,文章还分析了输入法在移动设备、桌面系统和特殊领域的应用现状与发展趋势。
// 告诉系统,我是输入法
Bool InitXIM (Window im_window)
{
    XIMStyles      *input_styles;
    XIMTriggerKeys *on_keys;
    XIMEncodings   *encodings;
    char           *p, *imname;

    // 获取环境变亮XMODIFIERS的值
    imname = getenv ("XMODIFIERS");
    if (imname) {
        if (strstr (imname, "@im="))
            imname += 4;
        else {
            fprintf (stderr, "XMODIFIERS Error...\n");
            imname = DEFAULT_IMNAME;
        }
    }
    else {
        fprintf (stderr, "Please set XMODIFIERS...\n");
        imname = DEFAULT_IMNAME;
    }
#ifdef _DEBUG
    strcpy (strXModifiers, imname);
#endif

    input_styles = (XIMStyles *) malloc (sizeof (XIMStyles));
    input_styles->count_styles = sizeof (Styles) / sizeof (XIMStyle) - 1;
    input_styles->supported_styles = Styles;

    on_keys = (XIMTriggerKeys *) malloc (sizeof (XIMTriggerKeys));
    on_keys->count_keys = iTriggerKeyCount + 1;
    on_keys->keylist = Trigger_Keys;// 设定输入法切换快捷键。在LoadConfig里面设置。

    encodings = (XIMEncodings *) malloc (sizeof (XIMEncodings));
    encodings->count_encodings = sizeof (zhEncodings) / sizeof (XIMEncoding) - 1;
    encodings->supported_encodings = zhEncodings;// 设定编码

    p = getenv ("LC_CTYPE");// 这个我们在前面看过了。见《main函数》中关于setlocale (LC_CTYPE, "");
    if (!p) {
    p = getenv ("LC_ALL");
    if (!p)
        p = getenv ("LANG");
    }
    if (p) {
#ifdef _DEBUG
    strcpy (strUserLocale, p);
#endif
    if (!strcasestr (strLocale, p)) {
        strcat (strLocale, ",");
        strcat (strLocale, p);
    }
    }

    // 告诉系统,我是输入法。并设定相关属性
    // 其中,最重要的就是告诉输入法有事调用MyProtoHandler。
    ims = IMOpenIM (dpy, IMModifiers, "Xi18n", IMServerWindow, im_window, IMServerName, imname,
            IMLocale, strLocale, IMServerTransport, "X/", IMInputStyles, input_styles, IMEncodingList, encodings, IMProtocolHandler, MyProtoHandler, IMFilterEventMask, KeyPressMask | KeyReleaseMask, NULL);

    if (ims == (XIMS) NULL) {
        fprintf (stderr, "Start FCITX error. Another XIM daemon named %s is running?\n", imname);
        return False;
    }

    // 这儿实际上的构造一个链表,并调用ims的methods->setIMValues进行处理
    if (!bStaticXIM)
        IMSetIMValues (ims, IMOnKeysList, on_keys, NULL);

    return True;
}
// 该函数主要的构造一个链表
char *IMSetIMValues (XIMS ims, ...)
{
    va_list var;
    int total_count;
    XIMArg *args;
    char *ret;  

    // 计算参数的个数
    Va_start (var, ims);
    _IMCountVaList (var, &total_count);
    va_end (var);

    // 构建一个list,其中没有Item的是
    //typedef struct
    //{
    //    char    *name;
    //    XPointer    value;
    //} XIMArg;
    // 它这儿构造list的方式是比较巧妙的。它是以类似于sprintf的方式进行构建的。
    // 比如我们调用sprintfx(dest, "name", "NameVal", "age", AgeVal)
    // 就可以构建一个链表形式为:
    //_______________________________
    //|        name ==> NameVal        |
    //|        age  ==> AgeVal            |
    //───────────────────
    Va_start (var, ims);
    _IMVaToNestedList (var, total_count, &args);
    va_end (var);
    // 链表构造完成,调用本函数调用者指定的方法对构造好的链表进行进一步处理
    ret = (*ims->methods->setIMValues) (ims, args);

    if (args)
        XFree ((char *) args);
    /*endif*/
    return ret;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值