以下讨论的具体实现是利用IMdkit开发的XIM服务器。
1.初始化输入法服务1
2
3
4
| ims = IMOpenIM(display,IMModifiers,”Xi18n”,IMServerWindow,window,
IMServerName,imname,IMLocale,DEFAULT_LOCALE,
IMServerTransport,transport,IMInputStyles,input_styles,
IMProtocolHandler,MyProtoHandler,IMEncodingList,encodings,NULL);
|
函数IMOpenIM初始化输入法服务的连接,并设置一个或多个由变长的参数列表指定的IM的属性。
下面简介上面函数中的参数:
Display是当前的屏幕显示。
IMModifiers定义XIM的协议模型,有两种:
“Xi18n”指定R6标准的IM协议模型。
“XIMP”指定R5标准的Ximp模型。 IMServerWindow指定IM服务器的窗口以便于与XIM客户程序进行通讯。
IMServerName指定IM服务器的名字。
IMLocale指定IM服务器支持的locale列表。
IMServerTransport指定IM服务器用来与客户程序间的通讯技术。
IMIputStyles指定IM服务器支持的输入风格列表。如:XIMPeeditPosition|XIMStatusNothing为光标跟随,不需要状态显示风格。下面的具体协议处理就是根据这种风格来介绍的。
IMProtocolHandler指定当IM主循环接收到客户程序的协议时的时间处理函数。
IMEncodingList指定IM服务器支持的传输编码列表。
2.协议处理函数 下面函数用于处理整个客户协议,由于篇幅原因,本文只列出了相应的协议,而没有具体的处理函数,实际应用中,每一个分支都由一个相应的函数来处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| MyProtoHandler(XIMS ims,IMProtocol *call_data)
{
switch(call_data->major_code){
case XIM_OPEN:
case XIM_CLOSE:
case XIM_CREATE_IC:
case XIM_DESTROY_IC:
case XIM_SET_IC_VALUES:
case XIM_GET_IC_VALUES:
case XIM_FORWARD_EVENT:
case XIM_SET_IC_FOCUS:
case XIM_UNSET_IC_FOCUS:
case XIM_RESET_IC:
case XIM_TRIGGER_NOTIFY:
}
}
|
函数MyProtoHandler是由IMOpenIM登记的处理客户程序发送到IM服务器的协议的函数,在参数call_data中有相应的协议。上面列出了一些主要的协议,对于不同的情况(主要是根据不同的输入法风格),有一些协议不必处理,或根本不会发生。下面简介一些主要的协议处理过程。
XIM_OPEN:XIM客户程序启动时,要在IM库和IM服务器之间建立逻辑连接。
XIM_CLOSE:关闭在IM库和IM服务器之间建立 的逻辑连接。
XIM_CREATE_IC:当客户程序创建了一个输入法上下文(IC)时,发送此协议到IM服务器,这时在IM服务器中为此IC申请了一个相应的结构,用于记录一些必要的信息,包括字体、位置、前背景色等等。
XIM_DESTROY_IC:当客户程序退出时,删除相应的IC,释放一些与IC相关的存储空间。
XIM_SET_IC_VALUES:设置当前连接IM服务器的IC的属性。实际XIM服务器定期发送此协议来修改IC的属性值。
XIM_GET_IC_VALUES:取得当前连接IM服务器的IC的属性。
XIM_FORWARD_EVENT:当有按键发生时,客户程序发送此协议到IM服务器,此按键事件放在call_data的event结构中。在相应的处理函数中,读出相应的键值,如果是一些控制键,就作相应的操作,如输入法的开启,不同输入法之间的切换等;如果是输入法不需要处理的键,就直接送回客户程序,如一些功能键,组合键等;否则调用输入法的处理程序,输入法处理程序对这个字符进行处理,此时在预编辑区和选择区会有相应的变化,如果有结果字符串生成,输入法服务器会按照开始时确定的编码方式把这个字符串发送到客户程序,这样就完成了一次输入过程。
XIM_SET_IC_FOCUS:当在不同的应用程序间进行切换时,当前的IC会发生变化,此时新的应用程序会发送此协议到IM服务器,输入法服务器会改变当前的焦点,当前的一些与IC有关的属性和全局变量也要有相应的变化。
XIM_UNSET_IC_FOCUS:当前IC失去焦点。在此处可以释放一些与当前IC相关的资源。
XIM_RESET_IC:重置在IM服务器中的IC的状态。
XIM_TRIGGER_NOTIFY:IM库通知IM服务器匹配启动(on-keys)和关闭(off-keys)的事件发生了。
3.主事件循环 在主程序中要用XselectInput选择输入法窗口要处理的所有X事件,
1
2
| XSelectInput(display,window,ExposureMask|ButtonPressMask|ButtonReleaseMask|
ButtonMotionMask|VisibilityChangeMask);
|
然后在主循环中要处理所有这些事件,如下由函数MyXEventHandler完成。
1
2
3
4
5
6
| for(:{
XNext event;
XNextEvent(display,&event);
if (XFilterEvent(&event,NULL)= =True) continue;
MyXEventHandler(&event);
}
|
函数MyEventHandler要处理输入法窗口的事件。包括在屏幕上的显示,窗口的改变,拖动窗口,及与其他窗口进行通讯等消息。通过此函数,可以使程序达到对用户友好的目的。
以上三点是一个XIM服务器的必须要处理的,我们还需要包含以下头文件:X11/Xlib.h、IMdkit.h和Xi18n.h,后面两个头文件是IMdkit提供的面向R6标准的一些结构定义。另外连接的时候要连接IMdkit的libXimd.so。 |