SCIM输入法架构分析(下)
转载时请注明出处:http://blog.csdn.net/absurd/
1. 概述
SCIM是Smart Common Input Method的简称,它是一个输入法框架,由苏哲领导开发的。作为新一代输入法框架,其架构设计精良,具有很好的扩充性和灵性性,代码质量也非常高,称得上是国内经典的开源项目了。本文试图对SCIM的架构进行分析,了解它的架构,也许并不能帮助你更好的使用它,但对于添加新的输入法引擎,或者把它移植到其它平台,会有一些帮助。不过,即使单从学习的角度出发,了解它的架构,对于提高设计能力也是有很大好处的。
2. SCIM的组成部件
2.1. 配置模块(Config)
2.2. 输入法前端模块(FrontEnd)
2.3. 输入法引擎模块(IMEngine)
2.4. 进程间通信模块
2.5. 输入法Panel
2.6. 输入法Helper
(续)
2.7. 模块动态加载机制(Module)
SCIM只是一个框架,具体的输入法是通过动态库的方式加载进来的,而不是在编译时静态的绑起来的。SCIM实现了一个Module类,封装了操作系统底层函数,提供面向对象的接口。另外,在此基础之上,还实现了其它几个类对Module进行包装,提供更具体的服务。
ConfigModule 用于动态加载配置模块。
FilterModule用于动态加载过滤器模块。
FrontEndModule用于动态加载前端模块。
IMEngineModule用于动态加载引擎模块。
HelperModule用于动态加载辅助功能模块。
2.8. 其它组件
2.8.1. 过滤器(Filter)模块:提供动态的转换或过滤功能,可以实现诸如在中文繁体和简体之间进行转换的功能。
2.8.2. 异常处理:SCIM完全采用OOP编程,使用了C++的异常处理机制,大部分模块都有自己的异常处理类。
2.8.3. 类工厂:为解耦使用者与实现者之间的耦合,SCIM采用了类工厂的机制来封装对象的创建。
2.8.4. Signal/Slot:为解耦软件各层间的耦合,SCIM采用了Signal/Slot机制。
3. SCIM的动态行为(GTK+中)
3.1. 传统输入法
PanelClient/ SocketInstance/SocketConfig是在应用程序进程中运行的,但为了降低与应用程序的耦合,它们往往被封装在一个独立的模块里,比如在GTK+中就是这样做的。
Panel是作为一个单独的进程运行的,它通过PanelAgent与外界交互。
输入法服务进程也是一个单独进程,它通过SocketFrontEnd与外界交互。尽管它也可以是另外一个输入法服务进程的代理,不过那样做似乎没有什么意义。
3.2. 手写输入法
手写输入法不是作为一个普通的引擎来实现的。它往往是一个单独的进程,带有GUI界面。它通过HelperAgent把识别的字符串提交给Panel,或者转发一些事件给Panel,它与应用程序之间并无直接通信。
Panel在此时除了具体传统的功能外,同时还作为手写输入法与应用程序的中介者。
这里的应用程序和普通的应用程序没有差别,它根本不会觉察到手写输入法的存在,这可能也体现出SCIM设计的精妙之处吧。
4. SCIM框架与具体输入法的关联
具体的输入法要挂到SCIM中,那是一件非常简单的事情,只要实现IMEngineInstanceBase接口,编译成一个动态库,放到指定的目录即可。输入法的实现者不必花费时间去考虑如何与应用程序关联起来,专心的去实现输入法本身就行了。
5. SCIM与GTK+的关联
GTK+是GNOME的一套GUI,实现得也很精致。把输入法挂到GTK+中来很简单,和SCIM类似,它对输入法也作了抽象,它要求实现GtkIMContextClass接口,并编译成一个动态库,放到指定的目录即可。
关于GtkIMContextClass的描述,可能参考文档http://developer.gnome.org/doc/API/2.0/gtk/GtkIMContext.html。
6. SCIM的配置文件
6.1. SCIM的配置文件放在/usr/local/etc/scim中(与安装位置有关):
Config文件放置的是与输入法有关的配置信息,包括输入法前端、输入法引擎、Panel、快捷键等的参数。
Global文件放置的是与输入法无关的配置信息,但这些信息对SCIM的环境来说,是必不可少的,如socket地址、panel应用程序名、socket超时时间等。
6.2. 数据文件和资源文件放在/usr/local/share/scim/中(与安装位置有关):
icons 中是放置的图片文件。
Pinyin之类的目录放的是具体输入法需要的数据文件。
~~end~~