fcitx输入法代码分析总结
fcitx输入法代码分析总结
- fcitx处理输入的方式
- fcitx的组织结构
- fcitx的启动流程
- im加载
- 用代码生成代码
- 继承
- 输入法开发接口
- 区位输入法详细分析
- 附注
fcitx处理输入的方式
首先,作为一个输入法,fcitx在linux下的工作方式是这样的:
fcitx的组织结构
Fcitx小企鹅输入法通过将各个模块抽象成不同的addon插件,来管理诸多功能。像frontend、im(输入法)、ui, 属于必备的特殊的addon,fcitx有专门的对应的代码来处理加载,其他像简繁体、dbus、标点等作为普通的modules,都使用通用的module模块对之加载。
在fcitx下,不管是一个ime、ui,或是其他普通module,都要首先在fcitx下进行addon注册,方法就是在 /usr/share/fcitx/addon目录下放入自己的 .config(作为插件的普通配置)文件,然后根据自己功能的不同在文件夹下放入对应功能的 .config(具体功能的配置) 文件,并编译自己的模块生成动态库 .so文件供fcitx动态使用。
fcitx的启动流程
Fcitx经过历次修改后,目前的架构视所有功能都为插件,这样可以很容易的扩充其功能,能够很容易的面对将来的变化。在启动一个instance时,fcitx框架下可能会有很多插件,instance启动的第一步,便是为各种类型的插件们先提供一个容器。C语言实现的fcitx使用utarray(ut列表类似于C++的array)和uthash作为容器。
FcitxInstance* instance = (FcitxInstance*) arg;FcitxAddonsInit(&instance->addons);FcitxInstanceInitIM(instance);FcitxInstanceInitNoPreeditApps(instance);FcitxFrontendsInit(&instance->frontends);InitFcitxModules(&instance->modules);InitFcitxModules(&instance->eventmodules);
为插件申请完成空间之后,便是加载所有的插件。这里的“加载”,只是将所有的插件配置信息pushback到addons列表里,与其说是加载,不如说是在fcitx里先注册,fcitx的加载采用的是lazy-load懒惰式加载,使用某个插件再加载之。
Fcitx的注册插件方式:通过遍历所有在 /usr/share/fcitx/addon 下的 .config 文件,完成所有addon的加载。这里的加载加载只是通用性的加载,不针对特殊功能的addon做特殊加载,下面还会根据不同的插件类型做进一步加载。
im加载
输入法addon的注册流程
输入法addon的加载流程:
目前的addon都是动态库文件方式dlopen()加载,lazyload方式,以输入法插件为例:当切换至某个输入法时才会加载该输入法的动态库,通过dlsym()函数导入动态库中接口变量,该变量都是通过宏定义FCITX_DEFINE_PLUGIN()定义的变量。
具体加载方式可参加下图。
用代码生成代码
用宏定义生成指定的函数、变量。
函数结构相同,需要的参数类型有一点差异的情况
看函数FcitxIMEntryConfigBind(),查看该函数的定义将跳转到带参宏CONFIG_BINDING_BEGIN(FcitxIMEntry),查看该宏定义才发现它定义了一个通用的配置绑定函数,只要指定参数类型,就会生成对应类型的函数配置绑定函数。
为什么要这样做——避免代码的重复一处改变多处修改。
fcitx有多种插件(addon),都会用到配置绑定函数,做相同的操作,但是他们传入的参数类型会有不同,所以不能使用同一个函数,所以使用这种方法。
继承
前面说fcitx的各类功能(输入法、前端、模块)都是作为插件addon加载的,所有功能都有作为addon的共同部分,(就可以理解为都继承自addon),用FcitxGenericConfig作为不同模块结构体的共用部分,放在模块结构体的最前面(这很重要,在强转类型的时候,会舍弃掉结构体后面的部分,而保留前面部分),当只要使用共同部分时,就可以使用类型强转,(将派生类转换为基类)就可以使用公共的基类函数了。唯一麻烦一点的是不同的结构体在函数参数上是不会进行尝试转换的,对于每一个结构体,需要自己定义这种类型的“向基类转换”函数,然后在使用公共的基类操作函数。here is an instance:
FcitxInstanceLoadAllIM()函数的作用,就是遍历所有输入法配置文件,将他们对应的输入法加入到instance->availimes 这个容器里面。(这只相当于注册到instance,并未真正的加载其二进制文件,.so 库文件要等使用时再加载)
过程:先遍历addon插件,在所有插件中寻找属于输入法的插件:
之后对每个输入法addon按其.config文件创建并写入FcitxIM结构体,(其中FcitxGenericConfig公共部分已在之前就配置好了)
真正的加载使用输入法是从FcitxInstanceSwitchIMByIndex()函数入口的:
从函数字面上看是切换输入法,无论是初始化加载默认输入法还是切换时转换输入法,实际上都是给该函数一个Index去调用的。
一步步往后,在函数FcitxInstanceLoadIM中,使用了linux库函数dlopen()去动态调用对应的动态库文件,一旦加载完成动态库,动态库里的全局变量在fcitx进程空间中就可见了,使用dlsym()函数,传入打开的动态库文件句柄和要搜索的全局变量名,返回的就是该变量。
每一个动态库的代码中,都有一个形如这样的变量定义宏定义语句:
FCITX_DEFINE_PLUGIN():
这样就形成了统一的命名风格,fcitx框架代码即使在不知道对应库的情况下,也能根据外界的.config文件调用到该变量
而dlsym()函数搜寻的正是这个变量,他就是整个.so文件的接口,所有的功能函数都是通过它调用的。
输入法开发接口
区位输入法详细分析
附注
Fcitx wiki:https://fcitx-im.org/wiki/Fcitx/zh-hans
Fcitx github:https://github.com/fcitx
Fcitx 开发者讨论社区(google):https://groups.google.com/group/fcitx-dev
Fcitx 作者博客:https://www.csslayer.info/wordpress/author/csslayer/
fcitx输入法代码分析总结相关推荐
- fcitx输入法在wps、wineqq中失灵问题的解决
最近由Mint转到了Open SUSE下,各种折腾. 眼看着已经折腾差不多了,今天又遇到个问题: 在Wineqq以及wps下,fcitx输入法打不开,没法输入中文. 这就非常坑了,这两个软件输入不了中 ...
- 20155320《网络对抗》Exp4 恶意代码分析
20155320<网络对抗>Exp4 恶意代码分析 [系统运行监控] 使用schtasks指令监控系统运行 首先在C盘目录下建立一个netstatlog.bat文件(由于是系统盘,所以从别 ...
- 《网络攻防》 恶意代码分析
20145224陈颢文 <网络攻防>恶意代码分析 基础问题回答 如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什 ...
- SCIM输入法架构分析(上)
SCIM输入法架构分析(上) 转载时请注明出处:http://blog.csdn.net/absurd/ 文档格式与术语说明 1. 概述 SCIM是Smart Common Input Me ...
- Linux fcitx用不了中文,关于fcitx输入法不能使用中文解决办法
cjxgm 说:Archnew 说:我按照你说的做了,輸入法只能在終端里切换,无法在终端以外的地方切换,不知道怎么回事 你做了什么?你说一遍我看看是否有错(把修改过的文件完整地都贴出来) 在 ~/. ...
- 20165310 NetSec2019 Week6 Exp4 恶意代码分析
20165310 NetSec2019 Week6 Exp4 恶意代码分析 一.实验要求 1.系统运行监控 使用如计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,连接的外部IP是哪里.运行一段时间 ...
- SCIM输入法架构分析 上
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! SCIM ...
- SCIM输入法架构分析 上)
SCIM输入法架构分析(上) 转载时请注明出处:http://blog.csdn.net/absurd/ 文档格式与术语说明 1. 概述 SCIM是Smart Common Input Me ...
- SCIM输入法架构分析 下
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! SCIM ...
最新文章
- 【OpenCV】读取csv文件
- python数组写入txt文档_Python打开文件,将list、numpy数组内容写入txt文件中的方法...
- waves服务器系统盘,Waves 新款小巧化 SoundGrid 服务器 Server One-C 和 Extreme Server-C 公开...
- html转换成keynote,keynote代码高亮【转】
- vb mysql ado_VB中的ADO数据对象编程详解
- python 小甲鱼 代码_Python小代码
- 微信小游戏踩坑记录(二)
- 【20090702-03】ArcEngine的类库介绍(转)
- Linux学习之linux下文件目录的了解及总结
- 科大讯飞2019机械核心部件寿命预测,亚军方案
- 压箱底的Android UI开源库(一)
- 方正电脑如何关闭网络启动计算机,方正电脑怎么进安全模式
- win10系统64位安装与配置java环境,安装使用citespace经验
- php爬虫框架使用案例QueryList,将数据爬到mysql数据库
- Android的一个登陆注册页面
- 从遗传力到肠菌力:概念及研究进展
- java mysql vo mybatis 分页_Mybatis Plus 使用VO分页查询
- java中average方法_Java中的IntStream average()方法
- 《迅雷链精品课》第八课:迅雷链多链结构
- 朗涛任命Juanita Zhang为中国大陆区总经理,Peggy Hon为中国香港区总经理