clutter中的GSource

来源:互联网 发布:nba2k17低配优化补丁 编辑:程序博客网 时间:2024/05/21 22:28

转载时请注明出处和作者联系方式
文章出处:
http://blog.csdn.net/jack0106 
作者联系方式:冯牮 
fengjian0106@yahoo.com.cn

 

clutter是一个GUI库,使用opengl作为底层的绘图引擎。整个库使用c语言开发,基于glib和gobject对象系统。通常情况,main函数的形式如下:

 

 

熟悉gtk的朋友可以看出,main函数中的这种代码结构,和gtk程序中的main函数结构很类似,这是因为clutter和gtk中的主事件循环,都是基于GMainLoop以及GSource,而且他们的设计上,本身就有某种相似性。

 

最近把clutter-0.2,clutter-0.4和clutter-1.0版本的源代码翻出来看了看,主要是看其中事件循环这一部分的代码,学习一下其中的代码实现方法。

 

gui程序,从原理上来说,就是接收用户的输入(比如键盘输入,鼠标输入等),然后针对这些不同的输入事件,做出不同的处理。在GMainLoop这个框架中,就需要继承GSource,并且重新实现prepare/check/dispatch这三个虚函数,然后把这个子类GSource添加到主事件循环中。clutter-0.2的代码量最小,所以以此作为分析学习的切入点。下面是从clutter-0.2中取出的代码片段,我们重点看一下clutter中实现的一个GSource子类--ClutterXEventSource

 

 

这个版本的clutter,是运行在X11环境上的。Xserver管理了所有的输入设备,将所有的输入事件转换成Xevent,然后分发给对应的Xclient。Xclietn和Xserver之间,则是通过一个socket进行协议通信。所以ClutterXEventSource中,定义了一个GPollFD  event_poll_fd,这个变量中,保存的就是cultter和Xserver建立的socket连接的文件描述符。

 

prepare/check/dispatch这三个函数的代码,也比较简单,原理上看,就是等待XServer发送过来的用户输入事件,然后就进入dispatch函数,在dispatch函数,获取Xserver发送过来的XEvent,紧接着就调用clutter_dispatch_x_event()。

 

到这一步为止,用户通过键盘或鼠标的输入,就已经传递到了clutter内部,ClutterXEventSource的工作,就算是完成了。剩下的操作,是clutter对这个XEvent的转换(数据类型转换等等),以及在内部的分发,传递和处理(将event分发到对应的ClutterActor,然后对应的ClutterActor处理这个event),这个分发过程的细节,不在此次的讨论范围内。当分发和处理结束后,就将进入GMainLoop的下一次循环调度,当用户再次输入的时候,dispatch函数,将被再次调用。这样的话,整个GUI图形环境就运行起来了,ClutterXEventSource接收用户的输入,然后clutter处理这个输入事件,使用opengl重新绘制图形,然后这一次事件处理结束,clutter等待下一次用户输入。

 

clutter这个库的一个优势,就是可以方便的制作出动画效果。动画的原理,就是在固定的时间间隔上,重新绘制视图,只要这个时间间隔选取的合适,就可以产生动画效果。要在GMainLoop中实现动画,就需要用到另外一个GSource的子类--GTimeoutSource(GTimeoutSource是一个内部对象,作为使用者,我们只需要使用g_timeout_*这一簇函数就行了),设置好合适的时间间隔后,类似的,在GTimeoutSource的dispatch函数中,调用clutter的绘图引擎重新渲染视图,就可以产生动画的效果。

 

clutter中事件循环的基本原理就是这样,因为参考的是clutter-0.2版本的代码,代码量比较小,所以分析起来也比较容易。熟悉了这个版本的代码后,就可以看更高版本的代码实现细节了,我选的是0.4和1.0版本的源代码,看完这两版代码后发现,从0.4版本开始,event相关的代码部分,就已经成型并且基本稳定,考虑到1.0才是clutter的正式版,因此选取clutter-1.0来进行说明。

 

clutter-0.2只能运行在X11环境中,因此在构造ClutterXEventSource的时候,代码没有设计更多的层次,在初始化代码中,直接就初始化了ClutterXEventSource。到了clutter-1.0中,采用面向对象思想进行了更好的设计,并且匹配了多种后端,包括X11/win32/sdl/egl等等。在clutter的初始化阶段,直接调用后端的初始化代码,然后再由每个后端各自初始化自己的事件循环。因此,在clutter中定义了一个纯虚类,ClutterBackend,这个纯虚类有如下的一系列函数接口,不同的后端,只要继承这个ClutterBackend并且实现如下的函数就可以了。

 

 

ClutterBackendX11结构体,就是ClutterBackend的一个子类,clutter_backend_x11_init_events函数,就是这个子类重新实现的init_events虚函数。

 

ClutterEventSource以及它的prepare/check/dispatch这3个函数,和clutter-0.2版本中的区别不大,结构都是一致的,clutter_event_dispatch函数,是用户输入事件对应的代码的入口点,在这个函数中,clutter获取Xevent,然后转换event并且分发处理,事件处理结束后,函数返回,进入poll下一次循环调度。

 

需要特别说明的一点是,从结构上来看,由于事件循环的初始化,是包含在后端的初始化过程中的,所以ClutterEventSource可以设计成ClutterBackendX11的一个成员变量,ClutterBackendX11中的event_source指针,就是指向这个成员变量。但是,从代码中可以看到,在ClutterEventSource中,也有一个指针backend,指向包含该source的ClutterBackend,这是因为clutter_event_dispatch这个函数的第一个参数是GSource,在dispatch函数中,如果要使用backend,就只能通过ClutterEventSource->backend这个指针来获取。

 

写到这里,还想起一件事,顺便一起记录下来,clutter整体的框架,和qt中的Graphics View Framework很类似。clutter中的ClutterStage,相当于qt中的QGraphicsScene,clutter中的ClutterActor,相当于qt中的QGraphicsItem。这两套框架的接口设计,差不多都是一样的,如果熟悉其中的一套框架,那么另外一套框架上手起来也是比较容易的。

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 用夜神模拟器玩第五人格太卡怎么办 雷电模拟器玩刺激战场太卡了怎么办 绝地求生刺激战场模拟器太卡怎么办 ddj sb2打碟功能没了怎么办 驼背怎么办 要能快速矫正的方法 苹果7中间的home键坏了怎么办 苹果6p的home键不管用怎么办 华为获取数据失败请检查网络怎么办 三星手机未解锁刷机变砖怎么办 手机显示充电但是充不进去怎么办 手机拔出显示无法连接移动网怎么办 手机上的音乐老是显示网络忙怎么办 华为手机账号换手机忘记密码怎么办 墨墨背单词的注册邮箱忘了怎么办 华为手机华为账号密码忘记了怎么办 手机玩游戏降频特别厉害怎么办 苹果应用商店id登录老卡怎么办 苹果id忘记了自动续费怎么办 红米手机小米账号密码忘了怎么办 小米5splus没系统卡米怎么办 注册谷歌账号输入手机好怎么办 谷歌注册电话号码用了太多次怎么办 内存卡用了深度清理的软件怎么办 华为畅享5s密码忘了怎么办 小米5s进水了一直开机关机怎么办 手机菜单键功能键返回键失灵怎么办 小米5s更新系统发热严重怎么办 小米手机4G网速不好怎么办力 红米5 plus开不开机怎么办 小米3s手机触屏部分失灵怎么办 魅族手机屏幕锁密码忘了怎么办 手机没设置魅族账号密码忘了怎么办 魅族手机格式化密码忘了怎么办 魅族手机忘记密码了怎么解锁怎么办 手机设置的应用加密忘记密码怎么办 手机上设置应用加密忘记密码怎么办 魅蓝flyme密码忘了怎么办图片 魅族手机经常自动账号锁屏怎么办 魅族锁定后又不知道密码怎么办 魅族手机锁屏锁定了怎么办 魅族手机已锁定怎么办密码忘了