Chinaunix首页 | 论坛 | 博客
  • 博客访问: 544390
  • 博文数量: 84
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 2109
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-25 14:02
文章分类

全部博文(84)

文章存档

2011年(10)

2010年(22)

2009年(16)

2008年(36)

我的朋友

分类: LINUX

2010-09-28 17:16:28

作者:刘旭晖 Raymond转载请注明出处

Email

BLOGhttp://blog.csdn.net/colorant/

主页:

      

       这段时间因为需要移植一个输入法程序,所以学习研究了GTK下输入法实现的相关程序,这才发现输入法所涉及到的内容不光是输入法应用程序本身,GTKXWindow系统中,还必须要有相应的模块支持,这篇文档是我对于GTK的输入法支持模块GtkIMContext的一点粗浅的理解。

 

1         相关参考资料

http://library.gnome.org/devel/gtk/stable/GtkIMContext.html GtkIMContextAPI文档

http://www.ibm.com/developerworks/cn/linux/i18n/xim/xim-2/index.html XIM协议的原理及其实现,这篇文章和本文没有太大的关系,但是可以了解一下XWindow系统的输入法协议作为辅助的背景知识。

 

2         IM-Context模块框架

 

2.1        类层次结构

Ø       GtkIMContext:虚基类,定义了IMContext类支持的信号和接口函数。其主要用途是作为GtkIMMultiContext及其它子类的基类,并提供了一组的函数封装用于调用这些类函数。

Ø       GtkIMMultiContextGtkIMContext的子类,实现了一个可以动态加载不同的Slave IMContext模块的框架,自己并不真正处理输入法相关的任务,而是作为一个类似二传手的角色,在GTK Widget和具体的Slave IMContext之间传递数据,转发信号。

Ø       GtkIMContextSimpleGtkIMContext的子类,实现了一个基于查表实现文字检索的IMContext,主要用途:一是作为其它具体的基于查表实现文字检索的IMContext的父类(具体子类只需要添加自己的索引表格即可),二是作为GtkIMMultiContext的一个默认的Slave Context,当特定的Slave由于某些原因无法被创建时,SimpleContext将被创建并返回。

Ø       Build-in IMContext:除了上述IMContext相关类实现,GTK还自带了GtkIMContextTaiGtkIMContextXIM等基于GtkIMContext实现的具体的全功能IMContext,以及Am_et等基于GtkIMContextSimple的查表类的IMContext的具体实现。

Ø       Other IMContext:此外,不同的输入法可以根据自己的需要,实现自己的子类。如SCIM基于GtkIMContext实现的GTKIMContextSCIMMatchbox-keyboard基于GtkIMContextSimple实现的MbIMContext

 

3         工作机制

3.1        GTK WidgetIMContext的关系

GTKWidget中,涉及到IMContext的主要是和文字编辑相关的GTK Entry GTK TextView这两个Widget。这两个widget的类成员中都包含了一个指向GtkIMContext对象的指针,并在类实例的初始化函数中分配并将指针指向了一个GtkIMMultiContext的实例对象。

 

GtkIMMultiContext对象在初始化过程中,首先设置其Slave成员指针为空,而后在IMContext相关的后续操作中,再通过gtk_im_multicontext_set_slavegtk_im_multicontext_get_slave函数设置其具体的slave IMContext对象。

3.2        GtkIMContext成员函数和信号

GtkIMContext的类成员函数中:

 

Ø       set_client_window

Ø       focus_in

Ø       focus_out

这几个函数主要是由相关的GTK Widget在初始化,以及焦点,可视等状态变化的时候调用,用来通知IMContext相关信息的。具体的IMContext通常用这些函数来初始化事件通讯机制,显示消隐UI界面等。

 

Ø       reset

Ø       set_cursor_location

Ø       filter_keypress

这几个函数主要是在用户在执行输入等操作时,由相关的GTK Widget根据当前文本的状态进行调用,通知IMContext模块状态重置,光标位置变动(可以用来实现光标跟随)和键值输入的情况。

 

Ø       get_surrounding

Ø       delete_surrounding

Ø       get_preedit_string

Ø       set_use_preedit

Ø       set_surrounding

这几个函数的主要目的是用来实现Preeditauto correct或者其它前后文相关操作功能,前三个函数是由IM端发起调用,用于从相关GTK Widget读写数据。后两个函数则是由Widget端发起调用,用于通知IM是否使用preedit模式,和反馈surrounding数据。

 

GtkIMContext的信号包括:

Ø       "commit"

Ø       "delete-surrounding"

Ø       "preedit-changed"

Ø       "preedit-end"

Ø       "preedit-start"

Ø       "retrieve-surrounding"

这些信号用于IM模块通知相关的GTK Widget对应事件的发生,是IM模块向Widget发送信息的主要途径。

3.3        WidgetIMContext的交互

GtkEntry为例,GtkWidgetIMContext交互的流程大致如下:

Ø       GtkEntry对象初始化:创建GtkIMMultiContext成员对象,设置GtkIMMultiContextcommitpreedit等信号的处理函数。GtkIMMultiContext的初始化函数设置IM模块默认工作模式等。

Ø       GtkEntry对象实例化(realize):调用set_client_window设置IMContext对应的GDKWindow。通常这是GtkIMMultiContext第一次获取并创建它具体的slave IMContext对象的时刻,GtkIMMultiContext将自己实现的callback函数链接到slave IMContext的上述信号上,这些Callback函数通常再将这些信号通过自身的对象emit出去,从而让GtkEntry所注册的callback函数得到调用。

Ø       GtkEntry窗口获得、失去焦点:调用focus_in, focus_out函数通知IM模块焦点的变化情况

Ø       GtkEntry窗口获得按键事件:调用filter_keypress函数通知IM模块键值的输入,IM模块通常会根据当前的输入法状态,通过preedit-startpreedit-changed信号通知GtkEntry处于预编辑状态的文字内容发生变化,GtkEntry通过get_preedit_string函数获得实际的预编辑状态的文字内容并更新显示。用户选取文字完成输入后,IM模块通过preedit-end信号通知GtkEntry预编辑状态结束,并通过commit信号通知GtkEntry用户选择的文字内容。如果Preedit模式不适用,如英文输入状态等,则输入法模块可能直接通过commit信号通知GtkEntry文字内容。

3.4        IMContextIM的交互

需要注意的是GtkIMContext是作为相关GTK Widget的成员对象运行在用户程序的进程内,而不是输入法程序的进程内。所以IMContextIM之间还存在着通讯问题。

因为通过使用GtkIMMultiContext实现了IMContext模块的动态加载机制,所以具体的IMContext和对应的IM的通讯机制根据各自的实现而不同。从而实现了对各种不同通讯协议的兼容支持。

GtkIMContextXIM支持XWindow标准所定义的XIM协议,通过XIM协议规定的xeventXIM APPXIM Server之间发送相关信息。

SCIM所支持的GtkIMContextSCIM则通过socket通讯机制与SCIM进行通讯。

3.5        其它输入方式

对于字母或其它可由X11逻辑键值所对应的各种符号,除了通过GtkIMContext输入以外,有些程序如虚拟键盘(xvkbd, matchbox-keyboard)等,还可能通过发送fake key_event来模拟物理键盘的输入,通过X11的事件分发机制将键值传送到当前on focusGTK Widget上实现字母和符号的输入,此外即使在非字母符号的输入状态下,某些特殊的键值如回车,删除等,在一些输入法实现中,也可能通过这个途径来发送。

阅读(828) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-09-29 14:33:24

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com