16.1 X视窗系统简介
如果你曾经在Linux中使用过桌面视窗系统,那么你很可能使用的是X——一个开源图形化系统。X的一个最富有创新性也最令人感到沮丧的特征,是它固守机制的要求,而不是策略的需要。它没有定义用户界面,但提供了创建用户界面的手段。这意味着你可以自由地创建自己的整个桌面环境,随意进行试验和创新。但它也在很长一段时间内妨碍了Linux和UNIX系统上用户界面的发展。在这一片相对空白的领域中,两个桌面项目逐渐浮现成为Linux用户的最爱:GNOME和KDE。然而,Linux桌面并不始于X,也不终于X。事实上,Linux中的桌面是一个相当模糊的东西,并没有哪个项目或是组织在发布的权威版本。当前主流的安装包含了大量的库、工具和应用程序,它们被总称为“桌面”。
X拥有悠久而辉煌的历史,它最初于20世纪80年代早期由MIT开发。X为当时的高端科学工作站提供一个统一的视窗系统,那些工作站都是非常昂贵的、用于复杂计算的庞然大物。
20世纪90年代,随着硬件价格的下降,一些爱好者将X移植到廉价的家用PC上,这个项目后来被称为XFree86(Intel和其他公司生产的PC处理器被称为x86处理器)。目前在Linux上发布的都是XFree86的衍生产品,大多数Linux发行版使用的是一个被称为X.Org的X变体。
X视窗系统被分为硬件级和应用程序级组件,它们分别被称为X服务器和X客户端。这些组件使用X协议进行通信。在下面几节中,我们将依次介绍它们。
16.1.1 X服务器
X服务器运行在用户的本地机器上,它在屏幕上完成低层的绘图操作。其名字中的服务器部分经常让人困惑:X服务器运行在用户的桌面PC上,而X客户端既可以运行在用户的桌面PC上,也可以运行在网络中的其他系统(包括服务器)上。这一颠倒的术语只有在你理解它时才有意义,但它通常看上去有点反其道而行之的感觉。
因为X服务器直接与显卡交互,所以你必须使用一个适合本机显卡的X服务器,并配置好合适的分辨率、刷新率、颜色深度等。其配置文件名是xorg.conf或者Xfree86Config。在过去,你通常需要手动编辑配置文件才能使得X正常工作。幸运的是,现在的Linux发行版可以自动检测正确的设置,这节省了用户的时间,也解决了很多让人头疼的问题。
X服务器通过鼠标和键盘监听用户输入,并将键盘按键和鼠标点击传输给X客户端应用程序。这些信息被称为事件(event),它们构成GUI编程的一个关键元素。我们将在本章后面详细介绍事件及其GTK+逻辑扩展——信号(signal)。
16.1.2 X客户端
X客户端是以X视窗系统作为GUI的任何程序。例如xterm、xcalc和类似Abiword的更高级的应用程序。通常情况下,X客户端等候X服务器传送的用户事件,然后通过给X服务器发送重绘消息来响应。
X客户端不需要和X服务器运行在同一台机器上。
16.1.3 X协议
X客户端和X服务器使用X协议进行通信,这使得客户端和服务器可以通过网络分离。例如,你可以在因特网或者加密的虚拟专用网(VPN)上的一台远程计算机上运行X客户端应用程序。对于绝大多数个人Linux系统来说,X客户端和X服务器都运行在同一个系统上。
16.1.4 Xlib库
Xlib是X客户端间接用于产生X协议消息的库。它提供一个非常底层的API供客户端在X服务器上绘制非常基本的元素,并响应最简单的输入。我们必须强调,Xlib是一个非常底层的库,即使使用Xlib库创建一个像菜单这样非常简单的东西,也要耗费程序员很大的精力,它需要数百行的代码。
GUI程序员不应该直接使用Xlib进行编程。你需要一个API使得诸如菜单、按钮和下拉式列表等GUI元素能够被简单方便地创建。简而言之,这就是X工具包的作用。
16.1.5 X工具包
X工具包是一个GUI库,X客户端可以利用它来极大地简化窗口、菜单和按钮等的创建。使用工具包,你通过一次函数调用就可以创建按钮、菜单、框架等类似的元素。诸如此类的GUI元素被统称为构件(widget),你在所有的现代GUI库中都能找到这个通用术语。
你有几十个X工具包可选,每个工具包都有其长处和短处。选择哪个包对于应用程序来说是一个重要的设计决定,你应该考虑以下一些因素。
❑ 应用程序针对的用户是谁?
❑ 用户是否已经安装好了工具包库?
❑ 该工具包是否支持其他流行的操作系统?
❑ 该工具包使用什么软件许可证,该许可证是否与你期望的用法一致?
❑ 该工具包是否支持你的编程语言?
❑ 该工具包是否具有现代的界面外观?
历史上最流行的工具包有Motif、OpenLook和Xt,但是它们大多已经被技术上更先进的GTK+和Qt工具包所取代,这两者分别构成了GNOME和KDE桌面的基础。
16.1.6 窗口管理器
X中最后一个部分就是窗口管理器,它负责定位屏幕上的窗口。窗口管理器通常支持独立的“工作区”,这些工作区将桌面分割,增大用户可以交互的区域。窗口管理器还负责装饰每个窗口,通常这些装饰由一个框架和一个带有最大化、最小化和关闭图标的标题栏组成。窗口管理器提供了桌面的部分界面外观,例如窗口标题栏。
常见的窗口管理器包括下面几个。
❑ Metacity:GNOME桌面的默认窗口管理器。
❑ KWin:KDE桌面的默认窗口管理器。
❑ Openbox:旨在节约资源,用于较老的、较慢的系统。
❑ Enlightenment:一个有着出色图形和效果的窗口管理器。
就和X中的一切一样,你也可以切换窗口管理器。但大多数用户都使用桌面环境自带的窗口管理器。
16.1.7 创建GUI的其他方法——平台无关的窗口API
其他一些不是特定于Linux的创建GUI的方法也是值得一提的。有些语言本身就支持GUI,并且可以在Linux下使用。
❑ Java语言使用Swing和较老的AWT API来支持创建GUI。Java GUI的界面外观并不是所有人都喜欢,而且在配置低的机器上,它的界面感觉比较笨拙,而且响应迟钝。使用Java的一大好处是,编译好的Java代码可以在任何具有Java虚拟机的平台(包括Linux、Windows、Mac OS以及移动设备)上运行而无需任何改动。更多信息请访问http://java.sun.com。
❑ C#是一个与Java非常类似的编程语言。Linux系统需要安装来自Mono项目(http://www.mono-project.com)的C#公共语言运行时环境(CLR)。Mono平台上的C#还支持Windows Forms(它也在Windows中使用),以及一个被称为Gtk#的对GTK+工具包的特殊绑定。
❑ Tcl/Tk是一个脚本语言,它非常适于快速开发GUI,并支持X、Windows和Mac OS。当需要快速原型开发,或开发一些小工具(需要脚本的简单性和可维护性)时,Tck/Tk非常棒。有关该语言的更详细资料请见http://td.tk。
❑ Python也是一个脚本语言。你可以在Python中使用Tcl/Tk的Tk部分,或使用Python的GTK+绑定来编写GTK+程序。有关该语言的更多资料请见http://www.python.org。
❑ Perl是另一个常见的Linux脚本语言。你可以在Perl中使用Tcl/Tk的Tk部分,这被称为Perl/Tk。有关Perl的更多资料请见http://www.perl.org/。
这些语言带来的平台无关特性是需要付出代价的。与本地应用程序之间共享信息(例如使用“拖放”技术)会比较困难,而且保存配置通常必须使用专用方法而非桌面标准方法。有时Java软件的销售商通过附带平台相关的扩展来回避这些问题。