XWindow研究笔记(1)转载时请注明出处和作者联系方式作者联系方式:李先静xianjimliathotmaildotcom有不少朋友发邮件给我,询问关于TinyX的一些问题,最常见的是编译错误和字体显示问题。因为我们后来改用DirectFB作为显示后端了,所以很久没有再玩XWindow了,我这里没有调试环境,也没有时间去帮大家调试。希望大家原谅。虽然XWindow是一个非常复杂的系统,但只要静下心来分析,通常遇到的问题也是很容易解决的,前年我花了一段时间去研究XWindow的实现,我发现了解它的实现后,很多问题都迎刃而解了。最近我会整理一下当时的笔记,放到这里供有兴趣的朋友参考。缩略语清单:BDFBitmapDistributionFormatDBEDoubleBufferExtensionDIXDeviceIndependentDDXDeviceDependentICCCMTheInter-ClientCommunicationConventionsManualDMXdistributedmultiheadXsystemDMPSDisplayPowerManagementSignalingDPSDisplayPostscriptDRIDirectRenderingInterfaceEVIExtendedVisualInformationFSFontServiceICEInter-ClientExchangeRXremoteexecuteCUPColormapUtilizationPolicyandExtensionDMCPDisplayManagerControlProtocolXIMXInputMethodProtocolXIX11InputExtensionProtocolXSMPXSessionManagementProtocolXPXPrintServiceXPMXPixMapFormatXTransXTransportInterfaceGCGraphiccontext1.序XWindow是一个典型的幕后英雄,很多人在用Xwindow,但是由于他们并不直接和XWindow交互,而是使用基于XWindow实现的像QT和GNOME这样的桌面环境。结果,很多人不知道XWindow的存在,甚至以为XWindow是过时了东西。还有的人虽然知道XWindow的存在,但认为XWindow会占用了大量的资源,非常不稳定,称XWindow为垃圾,这又走了另外一个极端,误以为整个桌面环境都是属于XWindow的。事实上,XWindow是一个非常经典的系统,经过二十多年的发展,它不但变得很稳定,而且被雕琢得非常精致,里面采用很多先进的设计思想。就体积而言,它也并不庞大,为嵌入式系统而精简的TinyX,可执行文件仅仅有几百K大小。XWindow在设计之初就定下了七条设计准则,现在已经广为unix程序员所周知了,这里引用一下():1.除非沒有它就無法完成一個真正完整的應用程式,否則不用增加新的功能。2.決定一個系統不是什麼和決定它是什麼同樣重要。與其去適應整個世界的需要,寧可使得系統可以擴展,這樣可以用上層相容的方式來滿足新增需求3.有根本沒有實例才會比只有一個實例更糟。4.如果問題沒有完全弄懂,可能最好根本就不要去解決它5.如果預期要用百分之90的努力去完成百分之10的工作,應該用更簡單的辦法解決。(參見更糟就是更好。)6.盡量避免複雜性。7.提供機制而不是策略。實踐中把用戶界面策略放在用戶手裡。第一條原則在設計X11時修改為:「除非制訂有真實的應用程序需要,否則不用增加新功能。」X基本上一直遵循這些原則。參考實現是從擴展和改進的著手來進行開發,同時和1987年的最初的協議幾乎保持完全相容。这些原则,放在二十多年后的今天,仍然无一不是金玉良言,让我对这些前辈们的敬意油然而生。Xwindow里值得研究的东西可以说的东西太多了,它是一个非常复杂的系统,要把它的每一个细节都搞清楚,没有数月的努力是不可能的。粗看时,它的代码并不能称为经典,甚至有些代码风格让人很难受,其中充斥着大量的#ifdef,还有一些巨长的函数,一些缩写蒙得你找不到北。然而,瑕不掩钰,如果能克服阅读代码时暂时的头痛脑胀,你会发现Xwindow的设计非常巧妙,很多时候它在概念上比其它窗口系统都要先进,以至于经过这么多年之后,它仍然是unix-like的图形系统标准,可以说许多其它窗口系统的概念都是从Xwindow学来的。本文将对XWindow的架构做些探讨,希望能在阅读本文后,对XWindow有总体上的认识,避免阅读代码时只树木不见森林的感觉,由于XWindow很庞大,不可能在一份文档里,甚至是一本书里,把所有东西讲清楚,阅读本文并不能代替阅读代码。XWindow研究笔记(2)转载时请注明出处和作者联系方式作者联系方式:李先静xianjimliathotmaildotcom2.XWindow的功能XWindow提供了一组非常底层的服务,客户端程序发送请求给XWindow,XWindow根据请求完成相应服务。通过这些服务,客户端程序可以构建期望的用户界面。根据不同的功能,可以把这些服务分为以下几大类:2.1.处理输入XWindow从键盘和鼠标接受输入,这些输入数据被当作”事件”传送给适当的客户端程序。至于哪个窗口应该接受到这些事件,是依赖于窗口管理器的(窗口管理器实际上也是一个客户端),典型的事件包括按键,鼠标移动,鼠标按下/放开等。输入设备往往是与硬件平台相关的,而且又是独占资源,所以用XWindow管理是理所当然的。应用程序通常不需要关心具体的设备,只要处理相应的事件就行了,像mouse和笔点可能发出同样的事件,而应用程序不用区分它们。输入事件也可以通过XTest扩展,由软件模拟出来的(通常用来实现软件键盘)。2.2.按层次形组织窗口XWindow提供服务让客户端程序创建/销毁窗口,所谓的窗口就是屏幕上的矩形区域,它是可以层层嵌套的,有很多操作可以作用于窗口(如,查询或改变窗口的大小和位置等),XWindow的主要功能之一就是负责管理这种按层次形组织的窗口。不过XWindow管理这些窗口是被动进行的,由窗口管理器根据用户的行为决定。它请求XWindow做相应的动作,比如移动窗口,调整窗口的大小,改变窗口的前后关系等等。第一次接触XWindow时,得知窗口管理器是一个普通的客户端时,我觉得惊讶,这种设计真是太先进了,其实它正是遵循了提供机制而不是策略这一原则。现在已经有很多窗口管理器的实现可用,它们提供不同的风格和功能,有的用于PC,有的用于嵌入式系统,像matchbox就是在嵌入式上比较流行的,像Nokia的N770/N800就是用的matchbox。2.3.提供图形操作XWindow提供了一些基本的画图操作,如画直线、矩形、圆弧和多边形等。这些图形的颜色、线宽、填充类型都可以由客户端程序指定。XWindow同时提供了许多位图操作,这些位图操作可以作用于了窗口的各个区域。XWinwod还会充分挖掘硬件的加速特性,像填充、画直线和图像叠加等操作,如果硬件支持相应的加速功能,就可以通过硬件实现,否则就用软件实现。2.4.提供文本和字体操作XWindow提供了字体相关的操作。客户端程序可以请求Xwindow在指定的区域用指定的字体显示指定的字符串,当然在此之前应该请求Xwindow加载字体,加载后客户端程序可以得到关于字体的一些信息。实际上,这一功能由于客户端字体绘制的流行,而大大弱化了,现在的字体差不多都是在客户端绘制好后,再通过XRender扩展显示到XWindow去的。在fontconfig/freetype/pango/cairo的帮助,在客户端绘制字体更容易使用。XWindow研究笔记(3)转载时请注明出处和作者联系方式作者联系方式:李先静xianjimliathotmaildotcom3.客户/服务器架构C/S架构是XWindow最基本的架构,XWindow的主体包括作为服务器运行的XServer,和中间的传输协议XProtocol,和客户封装XProtocol的函数库Xlib。应用程序通过Xlib把参数打包成XProtocol的格式,通过socket把请求发送给XServer,XServer执行请求之后再把返回值从原路返回给应用程序。与传统的C/S架构不同的是,XServer并不是单纯的接受请求然后响应请求,它还可以主动主报事件,这通常是输入设备产生的事件。当然为了避免不必要的事件传输的开销,客户端可以决定接受哪些事件,过滤掉哪些事件。XWindow作为C/S架构来设计,其理由是很充分的:串行化共享资源。窗口资源是整个系统共享的,多个应用程序都要操作这些共享资源。为了有效的管理这些资源,至少要满足三点要求才行,其一是这些资源要在全局共享的,其二是要求对这些资源串行化访问,其三是要求输入设备等事件要能主动上报给应用程序,这些要求都正是C/S模型所擅长的。远程显示。客户端在一台机器上运行,而服务器在另一个台机器上运行,这在VNC和RemoteDesktop之类的技术出现之前,这种特性为远程管理提供了非常方便的手段。客户端在远程机器上运行,而服务器XServer在本地远行,这就可以让远程的程序显示到本地机上。当然,这与传统的客户/服务器的物理位置正好反过来了。语言与无关性。这又是C/S模型的另外一个好处,Unix下的编程语言可谓百花其放,XWindow不可能为某单一语言而设计。而对于C/S模型,只要服务器端和客户端共享同样的XProtocol,两者完全可以用不同的语言开发。从理论上说,客户端是可以不依赖于任何其它库,直接打包所有请求参数,解包所有的响应数据,就可以开发出基于XWindow的应用程序。然而,这些打包解包操作比较繁琐,容易出错,也没有必要每个人都这样去做,Xlib封装了所有这些操作,简化了X程序的开发工作。由于大多数的toolkit都是C/C++写的,所以Xlib采用了C语言开发。毫无疑问,基于Xlib可以写出在XWindow上运行的GUI程序。在前面提到的XWindow提供的服务中,我们可以看出,XWindow提供的是非常底层的服务,就窗口而言,XWindow根本不知道按钮、菜单、单选框、复选框、列表框、甚至不知道窗口管理器的存在,它唯一知道的就是窗口,这些都是非常低级的操作。为了简化X应用程序的开发,不同组织开发了众多的Xtoolkit,在这些toolkit中,都实现了一些常用的组件,以及一些公共函数。XWindow的发布包带了好几种toolkit。XWindow的规范中并没有规定GUI程序看起来是什么样子的,结果不同的组织开发出来的Xtoolkit百花齐放,形成不同的视感(lookandfeel),现在可以用一种toolkit表现不同的视感了,用来模拟其它toolkit,让来自不同阵营的用户都感到舒服。这造就了大多数toolkit都能做到,让描述风格的配置文件独立于应用程序,这是一个非常有意义的进步。GTK+和QT是目前最流行的Xtoolkit,GTK+用C开发的,QT是用C++开发的,从功能、风格和易用性来看,两者各有千秋,难分伯仲。窗口管理程序的功能比较特殊,其实它不过是一个普通XWindow的客户端应用程序,后面我们会对它作比较详细的介绍。XWindow研究笔记(4)转载时请注明出处和作者联系方式作者联系方式:李先静xianjimliathotmaildotcom4.XWindow的分层视图XWindow是一个严重依赖硬件环境的系统,输入依赖于输入设备,像键盘、鼠标和触摸屏等,输出设备依赖于显卡和显卡提供的接口。为了隔离与硬件的耦合,保持良好的可移植性,分层设计是必然的选择。XWindow的分层视图如下所示:DIX(与底层无关的核心代码):DIX是与平台无关的核心代码,DIX之意可能是指“不依赖任何硬件设备”的代码。它主要包括:1.对下列资源的管理(有些资源的实现是硬件