第一个基于XServer的程序
2009-12-21 21:37
169 查看
看了fcitx源码很长时间,里面的结构也大概明白了,但是按键消息怎么给输入法的总是不明白,前几天看到一个Linux下输入法的说明文章,才一下子解开了这个迷,原来有一个XIM(X Input Method),在Linux下弄输入法,就是对这个库编程。网址在这里:
http://www.ibm.com/developerworks/cn/linux/i18n/xim/xim-2/index.html
有了这个文章的帮助,很容易就把fcitx的整体结构看清楚了。主要用的是xlib的库,每一个输入法的相关函数封装到了一个结构中,这个结构包括了有关输入法的所有操作函数,然后在切换输入法的时候,把这个结构换一下就可以。所有的输入法结构的初始化在SetIM函数中,可以清楚的看到,用RegisterNewIM函数来注册,在这个函数里,就可以看到,把每个输入法相关的函数都放到了IM结构中,IM的定义如下
在程序中,定义了一个IM *im变量,用来保存现在的输入法。在SetIM中会给这个im分配内存, im = (IM *) malloc (sizeof (IM) * iIMCount);
这样,处理完成后,就等待客户端程序的事件了。原来这这么一个过程
现在fcitx的结构要比以前的结构清楚多了。
程序结构清楚了,下一步就是学习了。首先从最简单的做起,一个XServer的客户端,显示一个小窗口,因为要给用户一个界面来看到现在的输入法状态。
代码如下
编译此代码:gcc -lX11 -o firstxlib firstxlib.o
最后附一个Xlib Manual的网址:http://tronche.com/gui/x/xlib/
http://www.ibm.com/developerworks/cn/linux/i18n/xim/xim-2/index.html
有了这个文章的帮助,很容易就把fcitx的整体结构看清楚了。主要用的是xlib的库,每一个输入法的相关函数封装到了一个结构中,这个结构包括了有关输入法的所有操作函数,然后在切换输入法的时候,把这个结构换一下就可以。所有的输入法结构的初始化在SetIM函数中,可以清楚的看到,用RegisterNewIM函数来注册,在这个函数里,就可以看到,把每个输入法相关的函数都放到了IM结构中,IM的定义如下
typedef struct { char strName[MAX_IM_NAME + 1]; void (*ResetIM) (void); INPUT_RETURN_VALUE (*DoInput) (int); INPUT_RETURN_VALUE (*GetCandWords) (SEARCH_MODE); char *(*GetCandWord) (int); char *(*GetLegendCandWord) (int); Bool (*PhraseTips) (void); void (*Init) (void); void (*Destroy) (void); } IM;
在程序中,定义了一个IM *im变量,用来保存现在的输入法。在SetIM中会给这个im分配内存, im = (IM *) malloc (sizeof (IM) * iIMCount);
这样,处理完成后,就等待客户端程序的事件了。原来这这么一个过程
现在fcitx的结构要比以前的结构清楚多了。
程序结构清楚了,下一步就是学习了。首先从最简单的做起,一个XServer的客户端,显示一个小窗口,因为要给用户一个界面来看到现在的输入法状态。
代码如下
#include <stdlib.h> #include <stdio.h> #include <X11/Xlib.h> #include <X11/Xlocale.h> #include <X11/Xutil.h> #include <iconv.h> typedef struct { GC gc; XColor color; }WINDOW_COLOR; int WIDTH = 150; int HEIGHT = 60; Display *dpy; // 这就是和XServer通信的一个标识 int iScreen; GC dimGC; GC lightGC; WINDOW_COLOR mainWindowColor = { NULL, {0, 240 << 8, 255 << 8, 240 << 8} }; Window mainWindow; int iMainWindowX = 20; int iMainWindowY = 40; void InitWindowColor( void ); Bool InitX(void); Bool InitX( void ) { if ( ( dpy = XOpenDisplay( (char *)NULL)) == NULL ) { fprintf ( stderr, "Error: this programe can't open display/n" ); return False; } iScreen = DefaultScreen ( dpy ); return True; } void InitWindowColor( void ) { XGCValues values; int iPixel; int i = 0; mainWindowColor.gc = XCreateGC( dpy, mainWindow, 0, &values ); if ( XAllocColor ( dpy, DefaultColormap( dpy, DefaultScreen ( dpy ) ), &(mainWindowColor.color))) iPixel = mainWindowColor.color.pixel; else iPixel = WhitePixel ( dpy, DefaultScreen ( dpy ) ); XSetForeground ( dpy, mainWindowColor.gc, iPixel ); } void CloseX(void) { XCloseDisplay( dpy ); } Bool CreateWindow(void) { XSetWindowAttributes attrib; unsigned long attribmask; int iBackPixel; attrib.override_redirect = True; attribmask = CWOverrideRedirect; // sprintf ( str mainWindow = XCreateSimpleWindow ( dpy, DefaultRootWindow( dpy ), iMainWindowX, iMainWindowY, WIDTH, HEIGHT, 0, WhitePixel ( dpy, DefaultScreen(dpy)), iBackPixel ); if ( mainWindow == ( Window ) NULL ) { return False; } XChangeWindowAttributes ( dpy, mainWindow, attribmask, &attrib ); XSelectInput ( dpy, mainWindow, ExposureMask | KeyPressMask | ButtonPress | ButtonReleaseMask | StructureNotifyMask | EnterWindowMask | PointerMotionMask | LeaveWindowMask | VisibilityChangeMask ); InitWindowColor(); return True; } void DisplayWindow(void) { XMapRaised ( dpy, mainWindow ); } void DrawMainWindow( void ) { XDrawRectangle ( dpy, mainWindow, mainWindowColor.gc, 1, 1, WIDTH-2, HEIGHT - 2 ); } void MyXEventHandler ( XEvent *event ) { unsigned char iPos; switch ( event->type ) { case ClientMessage: //if ( ( event->xclient.message_type == about_protocol_atom ) && ( ( Atom )event->xclient.data.l[0] == about_kill_atom )) { DrawMainWindow(); } break; case Expose: fprintf ( stderr, "XEvent--Expose/n"); if ( event->xexpose.count > 0 ) { break; } if ( event->xexpose.window == mainWindow ) { DrawMainWindow(); } break; case DestroyNotify: break; case ButtonPress: switch ( event->xbutton.button ) { case Button1: { // 这里是移动窗口的代码 int x = event->xbutton.x; int y = event->xbutton.y; XEvent evtGrabbed; Bool bMoved = False; while ( 1 ) { XMaskEvent ( dpy, PointerMotionMask | ButtonReleaseMask | ButtonPressMask, &evtGrabbed ); if ( ButtonRelease == evtGrabbed.xany.type ) { if ( Button1 == evtGrabbed.xbutton.button ) break; } else if ( MotionNotify == evtGrabbed.xany.type ) { static Time LastTime; if ( evtGrabbed.xmotion.time - LastTime < 20 ) { continue; } XMoveWindow ( dpy, mainWindow, evtGrabbed.xmotion.x_root - x, evtGrabbed.xmotion.y_root - y ); XRaiseWindow ( dpy, mainWindow ); bMoved = True; LastTime = evtGrabbed.xmotion.time; } } printf ( "Left Mouse Button Press/n" ); } break; case Button2: printf ( "Middle Mouse Button Press/n" ); break; case Button3: printf ( "Right Mouse Button Press/n" ); break; } break; case KeyPressMask: printf ( "Key Down/n" ); } } int main ( int argc, char *argv[] ) { XEvent event; if ( !InitX() ) { return 1; } printf ( "OK, Create OK/n" ); if ( CreateWindow() ) { printf ( "OK, Create Window OK/n" ); } DisplayWindow(); DrawMainWindow(); // 和Windows下的消息循环相同 for ( ;; ) { XNextEvent ( dpy, &event ); if ( XFilterEvent ( &event, None ) == True ) { continue; } // 自己定义的消息处理函数 MyXEventHandler( &event ); } CloseX(); return 0; }
编译此代码:gcc -lX11 -o firstxlib firstxlib.o
最后附一个Xlib Manual的网址:http://tronche.com/gui/x/xlib/
相关文章推荐
- 基于Xcode4开发第一个iPhone程序:“Hello World”(转)
- java开发第一个JNI示例程序(基于linux操作系统)--java调用native方法
- Directx3D9学习之一:环境搭建与运行第一个程序环境配置(基于VS2012与win7)
- 我的第一个基于MyEclipse下的Struts2运用程序
- Android深入探究笔记之一 -- 我的第一个 Android 程序,基于 Intent 的组件交互机制
- mahout入门之编写第一个基于用户的推荐程序
- 基于Xcode4开发第一个iPhone程序:“Hello World” [转自:宝玉]
- 第一个基于winpcap编程的程序
- 在Android程序上,创建你的第一个基于AIR的Flex
- Windows8开发指南(16)开发基于Windows8的第一个metro界面C++程序
- 机器学习第一个练手程序 基于决策树的iris数据预测
- 第一个爬虫程序,基于requests和BeautifulSoup
- Servlet简介以及web配置以及第一个基于Servlet的HelloWorld程序
- [IOS]从零开始搭建基于Xcode7的IOS开发环境和免开发者帐号真机调试运行第一个IOS程序HelloWorld
- 在Android程序上,创建你的第一个基于AIR的Flex
- 微软全球最具价值专家Windows8 讲坛---------开发基于Windows8的第一个C#程序,hello,yincheng,mvp
- Windows8开发指南(16)开发基于Windows8的第一个metro界面C++程序
- 全面接触TDD - 1. 第一个基于TDD的程序
- VC菜菜鸟:建立第一个基于Visual C++的Windows窗口程序
- [IOS]从零开始搭建基于Xcode7的IOS开发环境和免开发者帐号真机调试运行第一个IOS程序HelloWorld