李先静的专栏

欢迎大家加入Linux Mobile Research,本圈子主要致力于基于linux的嵌入式系统的学习和研究,包括内核、驱动、GUI、MMI、软件设计方法和软件优化等方面,欢迎大家加入,无论是高手还是新手,一起学习共同进步。个人网站上线:http://www.limodev.cn

用户操作
[即时聊天] [发私信] [加为好友]
李先静ID:absurd
1017358次访问,排名26好友231人,关注者236
Only those who attempt the absurd can achieve the impossible.
absurd的文章
原创 384 篇
翻译 1 篇
转载 57 篇
评论 1513 篇
李先静的公告
个人网站上线: http://www.limodev.cn,以后BLOG将在CSDN和limodev上同时更新,欢迎交流,评论和交换友情链接。
最近评论
securitydoor:加油哦
SuperKris:应该把rootfs里的/var/tmp改成是指向/tmp的连接,
别的程序也可能用/var/tmp保存临时文件,好像pppd这个拨号程序就是
creative55:牛人,佩服。
Nick518:即将实现MTK方案动态加载,到时候可以无限扩展手机功能. 哈哈
AntiSoul:不错,这些是什么方面的开发?
文章分类
收藏
相册
1.个人相册
2.设计备忘录用图
3.设计本质论用图
4.scim架构用图
6.临时文件
7.其它文件
8.研究笔记用图
marvell-linux
1.友情链接
aimself@CSDN(RSS)
directfb中文网站(RSS)
Eric's Little Hut
eye_of_back的专栏(RSS)
Linux Mobile Research
Phoenix@上海(RSS)
segments的专栏(RSS)
study's Blog(RSS)
tracestudio
伐木丁丁鸟鸣嘤嘤(RSS)
会飞的鱼的专栏(RSS)
创系的技术博客
小四的BLOG(RSS)
小马哥的博客(RSS)
开源电信(RSS)
御风剑客
新奇的BLOG
易军军的网络家
李吉群的专栏(RSS)
2.亲情链接
凤凰的幸福蓄水池(RSS)
我的相册
3.软界高手
Donald E. Knuth (RSS)
孟岩(RSS)
透明(RSS)
4.LinuxMobile
celinuxforum(RSS)
GPE(RSS)
maemo.org(RSS)
opensource.motorola
palowireless
5.XWindow
Jserv's blog(RSS)
Keith Packard(RSS)
6.技术资源
7.开源项目
freedesktop(RSS)
GNU(RSS)
GTK+(RSS)
matchbox(RSS)
pxa27x-linux/
8.我的BLOG镜像
absurd@chinaunix
absurd@msn
My English BLOG(RSS)
存档
订阅我的博客
XML聚合  FeedSky

原创 SCIM输入法架构分析(上)收藏

新一篇: SCIM输入法架构分析(下) | 旧一篇: Linux下文件关联的实现原理

SCIM输入法架构分析(上)

 

转载时请注明出处:http://blog.csdn.net/absurd/

 

文档格式与术语说明

 

 

1.      概述

SCIM是Smart Common Input Method的简称,它是一个输入法框架,由苏哲领导开发的。作为新一代输入法框架,其架构设计精良,具有很好的扩充性和灵性性,代码质量也非常高,称得上是国内经典的开源项目了。本文试图对SCIM的架构进行分析,了解它的架构,也许并不能帮助你更好的使用它,但对于添加新的输入法引擎,或者把它移植到其它平台,会有一些帮助。不过,即使单从学习的角度出发,了解它的架构,对于提高设计能力也是有很大好处的。

 

SCIM具有如下特点:

1.       完全面向对象的设计,并用C++实现。

2.       高度模块化。

3.       非常灵活的设计,支持动态加载不同的输入法,支持C/S模型运行。

4.       简单的编程接口。

5.       UNICODE提供全面支持。

6.       提供了一些非常好用的工具函数,可以大大加快开发进度。

7.       提供了功能丰富的GUI panel。

8.       提供了统一的配置框架。

9.       很方便的集成现存的输入法。

10.    不但支持传统的键盘输入法,也支持手写识别等新式输入法。

 

2.      SCIM的组成部件

l         配置模块(Config)

l         输入法前端模块(FrontEnd)

l         输入法引擎模块(IMEngine)

l         进程间通信模块(IPC)

l         输入法Panel

l         输入法Helper

 

SCIM是高度模块化的,每个模块都非常独立。为了做到这一点,一方面需要从设计出发,让各个模块完成单一的功能,使模块本身是高内聚的。而另一方面,SCIM也采用了几种高级的技术:

l         针对接口编程。对于一些具有不同实现的模块,为了减少与调用者的耦合,提供一个抽象的接口是有必要的。配合下文所介绍的动态加载机制,模块的调用者根本不关心采用的哪种实现,接口与实现是分开的,它使用的是模块的抽象接口,模块的实现变化时,对模块的使用者几乎没有影响。

l         模块动态加载机制。SCIM的整个设计干净利落,框架就是框架,其它任何附加的功能都是通过插件来实现的,在运行时才动态的加载进来。不同的平台对于动态库的处理方式有些不一样,SCIM实现了一个module类,对操作系统的底层函数进行了封装,同时提供面向对象的接口,使用更加方便。

l         signal/slot机制。多个不同的对象协作起来完成一项任务,是面向对象设计的特点之一。消息在这些对象之间来回传递,特别是对于异步调用、事件/状态触发等情况,底层模块需要调用上层模块中的函数。这样,模块之间的层次关系不再像面向过程中那样明显。凡事有利必有弊,如果设计得不好,可能会造成上层与下层之间紧密的耦合,层次关系混乱。为了避免这个问题,SCIM里采用了signal/slot机制,上层向下层注册signal的处理器(slot)。当某个signal触发时,下层模块回调signal的处理器(slot)。

 

下面我们一一分析各个模块。

2.1.     配置模块(Config)

 

所谓众口难调,再好的软件也无法满足不同用户,不同的环境下的需求。采用配置文件来定制软件,是惯用的手法。SCIM也不例外,但是作为输入法,也有其特殊性,多个应用程序(如Panel、输入法服务进程、手写、输入设置界面等)往往要共享一些配置信息。

 

如果这些应用程序都直接去操作配置文件,不但可能会发生访问冲突,导致配置文件被破坏。也可能出现配置不同步的情况,一个应用程序修改了配置信息,而其它应用程序毫不知情,无法让配置信息在所有相关进程中即时生效。

 

最好的办法是,所有的配置信息由一个应用程序负责统一管理。只有它能够直接存取配置文件,其它应用程序,都需要通过向它发送请求来存取配置信息。这样,以上几个问题都迎刃而解了。

 

无论直接存取配置文件,还是从其它进程中存取配置信息,对使用者来说,并不需要关心。也就是说,使用者关心的是接口提供的功能,而不关心具体的实现,实现改变后,也不应该影响使用者。为了让各个应用程序采用统一的方式存取配置信息,SCIM中定义了一个ConfigBase接口,使用者通过它存取配置信息。

 

由此可见,SCIM中的配置模块有不同的实现,这些实现都要求遵循ConfigBase接口规范。SCIM提供了两个默认的实现,它们都是作为动态可加载模块形式出现的。一个称为SimpleConfig,它是用来直接存取配置文件的,另一个称为SocketConfig,它是用来从输入法服务进程存取配置信息的。

 

2.2.     输入法前端模块(FrontEnd)

 

个人认为,输入法的前端(FrontEnd)这种说法容易让人误解。按常识讲,相对后端而言,用户直接打交道的才称为前端,我开始以为前端就是Panel。其实不然,输入法是作为一个服务进程来实现的,这里的前端是指输入法服务进程中接收请求的模块。它负责接收来自客户端应用程序的请求,把请求转发给具体的输入法引擎或者配置模块,最后把处理的结果返回给客户端应用程序。

 

SCIM中的前端也有不同的实现,这些实现都遵循FrontEndBase接口规范。SCIM提供了两个默认的实现,它们都是作为动态可加载模块形式出现的。一个称为SocketFrontEnd,它定义了一套自己的通信协议,当然这协议是属于应用层的,它下层协议通常采用本地socket,但它并不限于某种特定的承载层。客户端应用程序必须遵循这个协议,把请求按这个格式发上来,它就可以使用SCIM提供的服务。另外一个是基于XIM实现的,这是一种X Window提供的老式输入方式,似乎一般很少使用。

 

2.3.     输入法引擎模块(IMEngine)

 

输入法引擎就是输入法的具体实现,比如拼音输入法,五笔输入法等等。不过在这里,输入法引擎其实是一个抽象的概念,可以是一种输入法,也可以是多种输入法,甚至只是一个输入法的代理。前面说过,SCIM只是一个输入法框架,其它输入法要挂到SCIM里来,就需要实现一个输入法引擎。

 

毫无疑问,SCIM中的输入法引擎也有多种实现,这些实现都遵循IMEngineInstanceBase接口规范。SCIM提供了两个默认的实现,它们都是作为动态可加载模块形式出现的。一个称为SocketInstance,它是一个输入法代理,一般来说,应用程序直接使用的就是它。另外一个称为RawCodeInstance,顾名思意,就是将按键原封不动的输出。

 

其它输入法要挂到SCIM框架里来,需要实现IMEngineInstanceBase接口,并编译成一个动态库,放在指定的目录之中。所以SCIM并不与某种具体的输入法关联起来,而运行时动态加载进来的。其它输入法不在SCIM的核心之列,都是以单独的软件包发行的。

 

2.4.     进程间通信模块

 

输入法所服务的不是一个应用程序,而可能是系统中所有的应用程序。若把它作为应用程序的一部分来实现,会造成不必要的数据冗余,浪费硬件资源。作为一个单独的服务进程是合适的,用C/S模型来实现。所以进程间的通信机制必不可少,SCIM采用的本地socket方式,当然也可以用其它方式实现,但没有什么必要。

 

应用层协议封装在Transaction中,它负责把特定的请求或事件等打包成数据包,也负责从数据包中取出请求或事件等。至于数据的实际传输,由Socket实现。服务器端使用SocketServer,客户端使用SocketClient。Transaction使用的是Socket的抽象接口,并不关心是服务器端还是客户端。

 

2.5.     输入法Panel

 

对于输入法来说,Panel是必不可少,若没有它,再好的输入法也是没有点睛之笔的作品。Panel不但给用户一种直观的反馈,如候选字,联想词组等,也提供了一些辅助功能,如中英文切换、全角半角切换,查看帮助信息等。

 

但是Panel是有GUI界面的,也就是说,Panel必须要与特定的GUI绑定起来,SCIM是一个输入法框架,应该尽量不要依赖于特定的平台。这一点上,SCIM做得很好,尽管SCIM实现了一个基于GTK的Panel,但它并不属于核心之列,它是一个完全独立的工具。

 

不管用哪一个GUI实现Panel,有很大一部分代码都是相同或者相似的,SCIM把这些代码封装在两个类中,一个PanelAgent类供Panel的服务器端使用,Panel本身通过它接收请求。另一个PanelAgent类供Panel的客户端使用,用它来与Panel进行交互。

 

2.6.     输入法Helper

 

一些新的输入法方式,如手写输入法等,当作传统的IMEngine来实现,比较麻烦也不太优雅。SCIM把这些输入法作为特殊处理,通过Helper集成进来。

 

SCIM提供了一个HelperAgent类,手写输入法通过它把手写结果提交给应用程序。HelperAgent实际是Panel的一个客户端,它与PanelAgent交互,但是它的功能很简单,而且与PanelClient功能并没有太多相似之处,所以作为一个单独的类来实现。

 

~~待续~~

 

 

发表于 @ 2006年08月31日 20:51:00|评论(loading...)|编辑

新一篇: SCIM输入法架构分析(下) | 旧一篇: Linux下文件关联的实现原理

评论

#flyingxu 发表于2006-09-01 23:22:00  IP: 218.80.61.*
顶一下,uml图不是太专业
#dfar2008 发表于2006-09-02 15:05:00  IP: 222.64.145.*
顶一下,这个框架有前途
#dudu 发表于2006-09-02 16:08:00  IP: 202.113.4.*
SCIM到底是Simple Chinese Input Methods的缩写还是Smart Common Input Method的缩写呢?
#Bruce 发表于2006-09-03 02:42:00  IP: 222.71.42.*
小題大作
#microrain 发表于2006-09-03 18:44:00  IP: 221.217.127.*
我现在用的输入法就是这个,真的不错。
自带的五笔真的很好用,,不过如果能将极点的字库及拼音方式加进来就更好了。
#Shutra 发表于2006-09-03 15:38:00  IP: 222.70.110.*
To dudu:
应该是“智能通用输入法平台”。如果你用过的话就知道了。
#absurd 发表于2006-09-04 21:54:00  IP: 211.161.63.*
to Bruce: 呵,不明白你指什么,何不说详细一点。
Csdn Blog version 3.1a
Copyright © 李先静