首页 > 代码库 > 使用XCB编写X Window程序(06):XCB官方教程中缺少什么

使用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发布于博客园,转载请注明出处。)

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