使用XCB编写X Window程序(06):XCB官方教程中缺少什么

  这将是我所写的关于XCB的最后一篇随笔。

  在XCB的官方教程中,还有三篇内容,一篇是将Colormap和Pixelmap的,一篇是讲如何更改窗口的鼠标指针的,还有一篇,则是讲如何将Xlib程序转换成xcb程序的。很显然,以上内容都不是我所想要的,所以我就不再一一依葫芦画瓢将它们再写成中文的了(其实理解Colormap和Pixelmap对理解OpenGL很有用)。我曾经多次吐槽XCB文档语焉不详,我说它语焉不详是指它对它自己的一些设计理念都没有讲清楚。比如在XCB的示例代码中,大量出现*_iterator_t,虽然明眼人一看就知道这是一个iterator模式,但是它的文档确实没有讲怎么构建一个*_iterator_t,也没有详细描述该模式。这给我的某些任务带来了很多困惑,比如我前面某篇中提到的枚举系统中的所有窗口,比如我还没有提到的怎么枚举glx中的fbconfig。

  XCB的文档实在是不行,按照我在《Linux江湖01:玩转Linux系统的方法论》中所列举的方法,那就只能阅读源代码了。这里需要强调一下,我这里所说的XCB,是指X C binding,其最高版本目前还是1.10。在Ubuntu中,它的包是libxcb1,一定不能省略前面的lib,否则将会找到另外一个XCB软件包。这样获取它的源代码:

  吐槽完毕!前面的吐槽是针对XCB的文档对它自身的说明不够详细。另外,在GUI编程领域,以及在X Window领域,还有一些重要的概念,当然,这本身不是XCB的范畴,我们不能对XCB团队要求太多。下面开始讲一讲我对GUI编程的一些理解(这些都是XCB教程中没有提到的。)

一、X协议

  在X.org的官网,可以找到所有的和X  Window相关的协议,但GLX除外。我这个共享一个PDF版的X核心协议:x11protocol.pdf 。X协议的设计应该还是很简明易懂的,虽然是英文版,用点心,一两天看完不是问题。

二、多线程

  在GUI编程中使用多线程也是一个比较复杂的问题。但是这个复杂的问题经过N多前辈的失败经验后,最终也有前辈总结:目前市面上可见的所有的GUI界面库都是单线程的。(请参考《Java并发编程实战》)在多个线程中操作同一个GUI对象会产生问题,比如使用MFC编写Windows程序时,如果将CWindow对象传递到另外一个线程中进行操作,程序会崩溃,再比如在Eclipse RCP中,如果在另外一个线程中操作View、Canvas等GUI对象,会产生异常。那么在XCB中,能否在一个线程中创建GUI对象,如window,然后在另外一个线程中操作这个window呢?XCB教程没有讲。大家感兴趣的可以自己试一下。

  GUI编程如果涉及多线程的话,我绝对最适合的模式应该是生产者-消费者模式,所有其它需要操作GUI对象的线程,最好是生成一个事件(生产者),然后将该事件发送到GUI线程(消费者)。这个事件的发送,可以使用一个BlockingQeue,也可以使用系统自身的SendEvent。

  XCB设计时,使用了另外一个异步模型,在《C#本质论》中,该模型被简写为APM。其实就是调用一个函数后,不用等待结果,函数不阻塞,直接返回。等想要结果的时候再调用另外一个函数获取结果。这是一个很普遍的模式,在我前面几篇XCB的讲解中可以看到。该模式用在这里主要是为了和X Server通讯的。而不是用来协调GUI线程和Worker线程的。

三、向窗口发送消息

  在XCB的教程中,教会了我们怎么处理X Server发送给我们的事件。事实上,我们有时不想仅仅只处理事件,有时还想向某一个窗口发送事件。这个XCB的教程没有讲,但是这个确实可以有。查看X协议可以看到SendEvent请求,xcb中也有send_event函数。

四、怎么拦截请求

  在我刚接触X Window的时候,我就常常想窗口管理器究竟是一个服务器端的程序,还是一个客户端的程序?现在我可以给出一个明确的回答:窗口管理器确实是一个客户端的程序,虽然它干的事有点像X Server应该干的事(给窗口加边框、图标,管理窗口大小、位置等)。之所以能够让一个客户端的程序做到这些事情,是因为程序发送给X Server的请求可以被拦截(其实是X Server转发)。不清楚这一点就永远写不了自己的窗口管理器。这一点,XCB的教程没有讲。

五、关于OpenGL

  虽然我总是探讨GUI,但是我更喜欢探讨计算机图形学,所以OpenGL不得不提。但是在XCB的官网中,没有讲怎么结合XCB和OpenGL的内容。(通过搜素引擎,可以搜到一个很过时的教程,要结合xcb、Xlib和Glx才能编写OpenGL程序。)而事实上,通过观察XCB的函数,我觉得1.10版的XCB本身可以直接用来写OpenGL程序,但是文档很稀烂。

  OpenGL是一个和平台无关的库,它的渲染流程整个都是在内存中进行的,只是最后需要把它的渲染的结果显示到一个窗口中而已(当然,也可以不显示到窗口中而保存到内存中或保存到文件中)。OpenGL只负责渲染,和GUI程序交互那是本地系统的事,在Windows中,是WGL,在X Window中,是GLX。这里再给大家共享一个GLX的PDF文档:glx1.4.pdf

  想象一下,有没有什么程序是X Window和OpenGL之间的桥梁,从而能让我们学习它的源代码呢?大家肯定会想到GLUT。因此,我决定看一看freeglut的源代码来一探究竟。使用下面的方法可以获得freeglut的源代码:

  不过很遗憾,最新版的freeglut里面也没有半点XCB的影子,它用的依然是Xlib,如下图:

  看来XCB的路还很长。(库开发者都不用,我这样的用户怎么用得好?)

  这一篇写得有点凌乱,但是信息量应该是不算小。欢迎大家探讨。

(京山游侠于2014-09-24发布于博客园,转载请注明出处。)

时间: 2024-08-13 10:21:31

使用XCB编写X Window程序(06):XCB官方教程中缺少什么的相关文章

使用XCB编写X Window程序(06):XCB取代Xlib的理由

我经常访问Xorg的官网,希望能找到一些对理解Linux和X Window有用的东西.结果也确实是偶有所得.比如,在Xorg的官网中就建议大家不用Xlib了,改用XCB.不可否认,Xlib确实是一个比较老的东西,老到最新的一本关于Xlib的书都已经是N多年前出版的了.有了Xorg官方的指导,我自然不用学Xlib了,直接上XCB. 经过这一段时间的学习,对XCB有了一定的了解.我的学习是根据XCB官方的教程来的,当然,如果有一点点在GUI编程领域的经验和悟性学习起来会更加事半功倍.在XCB的官方教

使用XCB编写X Window程序(01):快速起步

估计现在已经没有谁使用XCB这么底层的库写应用程序了,要用也是用经过精心封装的Motif, LessTiff, GTK, Qt, EWL,  ETK或者Cairo等高层次的库.我之所以这么费心地去折腾XCB,其实主要也是为了学习.毕竟,使用最接近底层的UI库写代码是学习X协议及GUI编程原理的最好方法. XCB的主要教程可以参考这里:http://xcb.freedesktop.org/tutorial/ 和X协议有关的文档,在这里:http://www.x.org/releases/X11R7

使用XCB编写X Window程序(02):在窗口中绘图

在上一篇中,我展示了怎么连接X服务器以及怎么创建一个窗口.创建窗口是编写GUI程序的根本.在GUI编程中还有另外两个重点,其一是事件处理,其二是在窗口中绘图.这一篇中,将展示如何使用XCB在窗口中进行绘图. 先看一个示例代码及其运行效果,代码如下: 1 #include <stdlib.h> 2 #include <stdio.h> 3 4 #include <xcb/xcb.h> 5 6 int 7 main () 8 { 9 /* geometric objects

使用XCB编写X Window程序(04):在窗口中绘制文字

在前面的几节中,我展示了使用XCB创建窗口.在窗口中画图以及捕获并处理事件.在这一篇中,我将展示在窗口中绘制文字.绘制文字当然离不开字体,所以我还会简单地探讨一下X Server的核心字体系统.老规矩,先上代码和运行效果图,代码如下: 1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <string.h> 4 #include <inttypes.h> 5 #include <xcb/xcb.h

使用XCB编写X Window程序(05):使用异步的方式和X Server通讯及获取和设置窗口的属性

在前面的例子中,我们从来没有关心过调用XCB函数时,该函数和X Server的通讯是同步的还是异步的.因为在前面的例子中,我们基本上不关心XCB函数的返回值,只有在上一篇中,由于某些操作需要关心它们是否成功(比如是否成功打开字体.是否成功创建GC等),才涉及到XCB函数的返回值. 在这一篇中会更进一步,因为是获取窗口的属性,所以肯定要关注从X Server获取的数据,这时,将会涉及到XCB函数同X Server的通讯是同步的还是异步的.什么是同步?就是说调用一个函数向X Server发出一个请求

用VS2010编写的C++程序,在其他电脑上无法运行,提示缺少mfc100.dll的解决办法

问题: 在自己电脑上用VS2010编写的VC++程序(使用MFC库),不能在其他电脑上运行.双击提示: "无法启动此程序,因为计算机中丢失mfc100.dll 尝试重新安装该程序以解决此问题." 解决方案: 方案一 采用静态编译使用VS2010编译的程序在windowsxp中运行时,经常会出现找不到相关的DLL文件,我们可以使用静态编译的方法把这些运行依赖文件打包到*.exe中来,以减少对环境的依赖. 一般可以配置以下两项: 项目 -< **属性 -< 配置属性-<

1014 编写完词法分析程序的感想

经过几个星期的努力,总算把词法分析的程序给完成了,总的来说这是一个坚苦而又漫长的过程.是啊,读了那么多年的书,编写词法分析程序可是第一次呀!看着劳动成果,很欣慰!虽然这不是我一个人做的,是大家的共同努力得来的. 几个星期前,当听到老师布置给我们的这个题目时,我们都蒙了,这么难的题目我们怎么会啊!毕竟我们对那个一无所知,对于老师上课的讲解还能听懂,不过理论与实践之间还是有鸿沟的.我们私下都表示不满,抗议,可是一切都是徒劳,所以我们只能尽我们自己最大的努力把程序给写出来. “也许完成不了!”两个星期

转:Qt编写串口通信程序全程图文讲解

转载:http://blog.csdn.net/yafeilinux/article/details/4717706  作者:yafeilinux (说明:我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自己改动.) 在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourceforge.net/projects/qextser

为编写的Windows程序提升权限

1.要求以管理员身份运行 在vs工程属性中,Linker ---> Manifest File---> UAC Execution Level,选择requireAdministrator (/level='requireAdministrator')选项 2.在main函数开始时运行以下函数代码: BOOL WINAPI EnablePrivileges() { HANDLE hToken; TOKEN_PRIVILEGES tkp; if (!OpenProcessToken(GetCur