Alan Coopersmith
要用X进行开发,需要掌握有关X的客户端和服务器端设施的大量知识。本章涵盖客户端的内容。从这里开始学习如何构建、维护和开发X应用程序。
典型的X客户端应用程序依赖于许多提供一般应用所需功能的库。
应用通常使用“部件工具箱”(toolkit)来提供普通的用户界面元素,如菜单、按钮、文本框和其他小工具。现代的部件工具箱有Qt、GTK+和FLTK。老一些的部件工具箱为一些遗留应用提供支持,有Athena Widgets (Xaw)和Motif (Xm)。一些部件工具箱是跨平台的,可以帮助你的应用在非X的环境中运行,如Wayland、Android、MacOS X或者Microsoft Windows。这里有一份X部件工具箱的列表:http://en.wikipedia.org/wiki/Listofwidget_toolkits (译者注:这个页面是空的,可能被移走了。)
大部分的X应用需要进行一些渲染。X社区有很好的库来在大部分环境中支持方便、高效的绘图。这些库可以处理优化特定图形硬件、输出格式等工作。对于2D图像,现在通常使用Cairo库( http://cairographics.org ),既可以由应用直接调用,也被部件工具箱使用。对于3D图像,OpenGL API是工业标准,自由软件端是由Mesa库 ( http://mesa3d.org ) 实现的。
适当地处理文字其实比大多数开发者想的有技术含量,特别是如果他们以前只处理过7位的ASCII文本的话。处理Unicode字符,为不同语言加载适当字体,找出如何依照复杂的规则按照语言放置字符来连接字符或者覆盖不同的符号,或者仅仅指出字符是应该从左到右显示还是从右到左显示:这些问题都在已经在已有的库中解决了,如Pango (http://pango.org) 和Harfbuzz http://harfbuzz.org 。部件工具箱用这些库来处理他们提供的部件中文字的排版,Cairo用它们来处理它所渲染的画布中的文字,应用直接用它们来处理任何需要显示在屏幕上的文字。
下面所有这些库都是X的Xft扩展。Xft提供实际上在屏幕上显示字形的功能,通过fontconfig (http://fontconfig.org) 来为每个字形找到相应的字体,用Freetype (http://freetype.org) 来将每个字形渲染成图像是的Xft可以将其送至X服务器进行显示。
最终与X的服务器的通信是由一到两组库来处理的——Xlib或者XCB。每族库都为实际上的X协议请求提供了相应的编程的接口,隐藏X11协议连接和客户端请求的编码解码的细节。Xlib和XCB库将在“Xlib和XCB”一章中详述。
理论上讲,纯粹地用系统调用编写X客户端应用,自行处理所有的X协议消息的编码解码是可行的,当然这会非常浪费时间并导致许多Bug。同样,单纯地用X11库来编写X客户端应用,自行编写所有绘制菜单、按钮、文本的代码也是可行的,但也会在重复发明轮子上浪费许多时间;要实现部件工具箱所提供的许多功能将会花费许多人年,如:国际化支持、可用性、输入处理,等等。
X.Org,以及上面提到的许多开源的部件工具箱和库已为pkg-config (http://www.freedesktop.org/wiki/Software/pkg-config) 进行了标准化,可以用pkg-config来在使用相应库的时候确定编译器和连接器所需的FLAG。
比如,要知道连接libxcb和libxcb-util所需的FLAG,可以执行下面的命令:
pkg-config --libs xcb xcb-util -lxcb-util -lxcb
你不应该直接将上面命令的执行结果拷贝至你的构建脚本。而是应该在构建的时候执行pkg-config:因为结果可能会因不同平台的安装路径不同而改变(按照不同的“-I”或“-L”找到正确的执行路径),或者因版本不同而导致一些依赖变化。
如果你的软件用GNU autoconf系统进行构建,pkg-config提供一个简单的宏来在configure.ac脚本中为你的构建定义所需的FLAG。你也可以定义所需库支持的最低版本,如下面的例子:
PKG_CHECK_MODULES(XCBLIBS, [xcb >= 1.6] xcb-icccm xcb-shape)
如果所需的所有库均已找到,autoconf将按照各个库对应的pkg-config文件中所定义的适当的版本和相应的依赖在所生成的Makefile 文件中提供XCBLIBSCFLAGS和XCBLIBSLIBS变量。这些变量包含了在你构建的编译和连接阶段所需的FLAG。
下面有X.Org维护的提供C语言API的X库的列表。就像上面所述的,这些API提供了由提供者所制作的高层库所需的底层功能。许多其他编程语言的绑定,如Python、Perl和Tcl,可以从多种渠道获得。
X协议栈的核心有两代库——新一些的XCB和老一点的Xlib。本手册的“Xlib和XCB”一章阐述了其中的不同并解释了两族中的交互。
几乎所有这些库的文档都是和它们自身打包在一起的,有Unix Man Page和DocBook/XML手册格式的文档。DocBook格式文档所生成的HTML、PDF和纯文本格式的文档可以在这里找到: http://www.x.org/releases/current/doc/ 。
###XCB系的协议和工具库
新一代的X协议编码解码库构建于XCB核心之上,有按照X协议的XML定义自动生成的编码解码函数。libxcb提供连接管理功能,以及处理X协议的核心功能,额外的库则由每一个X扩展提供:
libxcb-composite libxcb-res
libxcb-damage libxcb-screensaver
libxcb-dpms libxcb-shape libxcb-xinerama
libxcb-dri2 libxcb-shm libxcb-xinput
libxcb-glx libxcb-sync libxcb-xprint
libxcb-randr libxcb-xevie libxcb-xtest
libxcb-record libxcb-xf86dri libxcb-xv
libxcb-render libxcb-xfixes libxcb-xvmc
不幸的是,并不是所有扩展都已被XCB库族所支持。XKB是一道明显的鸿沟——libxcb-xkb仍在制作中,因为XKB协议十分复杂。BigRequests和XC-MISC是处理其他请求的基础;这些扩展直接内建于libxcb而不是由单独的库提供。
有许多的工具库构建于XCB协议库族之上来提供高级的功能。这些库仍在开发之中,并且它们的API仍然不断地随着版本的更新而变化,因而可能破坏一些兼容性。
-
libxcb-icccm和libxcb-ewmh:这些库提供获取和设置ICCCM和EWMH标准规定的相应属性的功能来与窗口管理器和桌面环境交互。(详见“概念”一章的“属性”一节)
-
libxcb-image:该库可以在X服务器和客户端间移动位图。在Xlib中,XImage和XShmImage提供类似的功能。
-
libxcb-render-util:该库提供方便的函数来通过Render扩展绘制图像和文字。
-
libxcb-util:该库相当于一个百宝袋来容纳那些方便却又不能归类到其他库中的函数和定义。该库包括标准的原子常数、原子缓存、事件解码和显示结构操作。
###Xlib协议、工具库族
老一些的X协议处理是构建于libX11之上的,这个库俗称Xlib。除了协议处理,libX11也包括了许多工具性的函数。Xlib提供国际化输入法支持和ICCCM标准支持。它也提供现在由更高层库所支持的历史版本功能(如色彩管理);现代的库提供部件工具箱和应用程序间的更好结合。像XCB库族,许多扩展有它们自己的Xlib库来处理它们自己的请求。一般的老库是这样的,但是,另一些又被打包进了一个单独的libXext库。
独立扩展对应的库:
libXcomposite Composite extension
libXdamage Damage extension
libXevie XEvIE extension
libXfixes X-Fixes extension
libXfontcache X-TrueType font cache extension
libXi Xinput extension
libXinerama Xinerama extension
libXp Xprint extension
libXrandr X Resize and Rotate extension
libXrender RENDER extension
libXres X Resource extension
libXss MIT-SCREEN-SAVER extension
libXTrap X Trap extension
libXtst XTEST extension, Record extension
libXv Xvideo extension
libXvMC Xvideo Motion Compensation
libXxf86dga XFree86 Direct Graphics Access extension
libXxf86misc XFree86-Misc extension
libXxf86vm XFree86 Video Mode extension
libdmx Distributed Multihead X extension
libXext包含的扩展:
DBE - Double Buffering Extension
DPMS - Display Power Management Signalling
MIT-MISC - X11R3 Bug Compatibility Mode [obsolete]
AppGroup - Broadway Application Grouping [obsolete]
EVI - Extended Visual Information
Generic Event - X Generic Event extension
LBX - Low Bandwidth X [obsolete]
MultiBuf - Multiple Buffering Extension [obsolete]
SECURITY - X Security model extension
SHAPE - Non-rectangular Shaped Window Extension
MIT-SHM - Shared Memory Images/Pixmap Extension
SYNC - X Synchronization Extension
TOG-CUP - Colormap Utilization Protocol extension [obsolete]
XTestExt1 - X11 Input Synthesis Extension [obsolete]
这些库中不少已经不再被普遍使用或是被X服务器所支持了。但是,自从libXext将它们绑进了同一个库,它们不能简单地移除而不破坏与已经存在的应用的向后兼容性。
###X Toolkit Intrinsics和遗留部件工具箱
X.Org原先开发了X Toolkit Intrinsics(libXt)来提供多种工具箱的共同功能。libXt允许通过普通的X资源格式进行设置,支持基础的事件循环,和其他低层功能。libXt被应用于许多早期工具箱中,包括X.Org的示例Athena Widgets工具箱(libXaw),Sun的OpenLook工具箱(libXol),以及Open Software Foundation的Motif工具箱(libXm)。现代的部件工具箱却几乎都绕过了libXt。这些部件工具箱混用了一些其他的层(比如用glib来实现事件循环)和部件工具箱特定的、桌面环境特定的库代码。所以,libXt现在基本是为一些遗留应用而维护。
Athena Widgets工具包是X.Org的示例程序所使用的工具包,也用于一些其它来源的程序。原始版本(libXaw)有非常简单的2D外观,但加强版(libXaw3d)升级成了一个看起来更有3D感的界面。这两个版本都不再有活跃的开发了。现在Athena Widgets和其底层libXt一样只为了已经存在的应用而被维护。不鼓励再使用Athena Widgets开发新的应用程序。该工具包缺乏现代应用程序的操作所需的适当功能。比如,只具有最小化的国际化支持,同样辅助功能的支持也不完善,比如读屏器或其他为身体残疾的用户准备的输入设备的支持都是堪忧的。而且要在非传统的计算设备如手机、平板电脑上使用Athena Widgets也是十分尴尬的。
libXt和Athena库都是构建在Xlib协议处理库族之上的。
###库与相关的协议
虽然X11协议及其扩展是X Window系统的核心,但并不是X所用的唯一的协议,有一些额外的库供有超出这些协议的需要的软件使用。
-
libFS 处理X字体服务协议(X Font Service protocol)的编码和解码,使得X服务器和其它程序能够从远程XFS字体服务器接收字体。该库纯粹是一个历史遗留问题,不应该再被现代的客户端或服务器设置使用。
-
libICE 支持使用客户端间通信协议(Inter-Client Exchange protocol)的客户端间的通信。
-
libSM 涵盖了X会话管理协议(X Session Management protocol),构建与libICE之上。libSM为桌面环境提供一套机制来在一个X会话结束之前保存正在运行的客户端程序的状态,并在下一次登录的时候回复这个状态。
-
libXdmcp 提供X显示管理控制协议(X Display Manager Control Protocol,XDMCP)的编码解码支持。XDMCP为低性能的本地X服务器(比如运行的X终端机)提供在远程计算机上运行X客户端程序的支持。
###工具库
X.Org有许多工具库来为多客户端提供方便功能封装。下面的许多库属于Xlib协议库族。
-
libXau 处理“.Xauthority”文件。该文件被xauth、X server和窗口管理器用来存储共享的秘密数据,如MIT-MAGIC-COOKIE,用于认证试图连接至X服务器的X客户端。libXau同时被Xlib和XCB使用。
-
libXcursor 处理由Render和XFixes扩展提供的带透明混合以及动画的鼠标指针,包括。libXcursor同时被Xlib和XCB使用。[iirc --po8](译者注:原文这句话写的是“libXau is used by both Xlib and XCB”,可能为错误)
-
libXfont 是遗留的核心协议中字体渲染机制的实现。libXfont被X服务器和XFS用来加载和渲染多种字体格式。渲染部分这些字体格式的代码内建在该库中。其它格式的字体则被传送至FreeType库进行光栅化。部分X.Org的字体组件用libXfont来管理字体文件及其元数据如font文件夹。普通的客户端并不会直接调用libXfont,而是通过X协议请求来使用其功能。现代客户端则完全不使用X核心字体,转而以来fontconfig/libXft或打包了这些工具的库。因此libXfont现在完全是一个遗留功能了。
-
libfontenc 处理用于将各种编码的字符(如:ISO-8859和Unicode)映射到字体的码表。和libXfont一样,libfontenc是X.Org核心字体处理软件组的一部分,属于遗留程序,不被现代应用采用。
-
libXft 是客户端直接使用的字体库。该库通过fontconfig来寻找字体,用FreeType来渲染它们,再使用libXrender或者libX11来将渲染好的字体显示至屏幕或者图形映射。部分客户端程序并不直接使用libXft(译注:原文是“use libXft directly”,可能有错误),而是使用更高层的库如pango或者工具库所提供的API。这些API通过处理文字的形状和排版规则来确定复杂语言间字形的摆放和连接。
-
libXmu和libXmuu 是X.Org示例程序所使用的一组实用程序库。libXmuu构建于libX11库的核心功能之上。libXmu依赖于Athena部件工具箱,包含libXaw和libXt。
-
libXpm 支持XPM XPixMap图像文件格式。XPM是一种基于可移植的ASCII码的图像格式。这对于遗留的X应用程序尤其重要,因为它们可能会包含编译在他们的C代码中的XBM和XPM图像。现代应用程序则通过外部库或工具箱功能来访问图像文件。
-
libxtrans 是传输层(套接字、管道等)的共用代码实现,用于X Window系统中多种协议的实现,如libX11,libICE,libFS,xfs和X server。它并不像其他共享库一样,而是通过共用的C代码来编译到每个库或者程序中。XCB库族在libxcb中有自己的连接管理代码,并不使用libxtrans。实际上,XCB在现代Xlib中取代了许多libxtrans的实例。