注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

回首望星辰

See you in the next world

 
 
 

日志

 
 

GTK 输入法模块 GTK IMContext   

2010-02-04 10:17:44|  分类: 软件开发 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

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上实现字母和符号的输入,此外即使在非字母符号的输入状态下,某些特殊的键值如回车,删除等,在一些输入法实现中,也可能通过这个途径来发送。

  评论这张
 
阅读(1590)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017