X窗口系统的协议和架构
在电脑中,X窗口系统(常称作 X11、X)是一种以位图显示的网络透明化窗口系统。本条目详述 X11 的协议及其技术架构。
X C/S模型和网络透明性
[编辑]X 基于C/S模型。运作在电脑上的X 伺服器程序以图形显示,并以各种客户端程序进行通讯。X 伺服器接受图形输出(窗口画面)方面的请求,并回传用户的输入(键盘、滑鼠)。
在 X窗口系统 中,伺服器可以在用户的电脑上执行,而在其他的机器上执行客户端。也可以反过来,客户端在用户的电脑上执行,而伺服端在远程电脑上执行。X窗口系统 使用的术语是以程序为基准,而不是用户或硬件。远程的程序连接到本地的 X 伺服器,那些远程的程序就视为客户端;本地的 X 接受所传入的消息,这部分就视为伺服端。
主从间通讯协议的网络透明:伺服器和客户端可以执行在同一机器或不同机器上,那些机器更可以是不同的硬件架构或操作系统。主从之间的通讯安全,可以加密连线的方式加强。
设计原则
[编辑]Bob Scheifler 和 Jim Gettys 陈述的早期 X 的基本原则如下(Scheifler/Gettys 于 1996 所列):
- 不要加入新的功能,除非没有它就不能完成实际所需的应用程式。
- 决定一个系统不是什么和决定系统是什么同样重要。不要满足全部的需求;而是使系统具有可扩展性,额外的需求可以向上兼容的方式来满足。
- 只有完全没实例,才会比只有一个实例来的更糟。
- 如果没把问题弄清楚,不解决它也许会是最好的。
- 如果预期要用 90% 的努力去完成 10% 的工作,就用更简单的方法解决。(参见更糟就是更好。)
- 尽量避免复杂性。
- 提供机制而不是提供方针,用户界面的方针由实际应用者自主。
后来在设计 X11 时,将第一项原则修改为:“不要加入新的功能,除非你知道某些实际的应用程式会需要它”。X 基本上一直遵循这些原则,参考实现的扩展及改进也是以此原则来着手,也因为奉行上述原则,使至今的最新版 X 仍能与最初(1987年)发布的协议标准几乎完全兼容。
X窗口系统 核心协议
[编辑]伺服器和客户端之间的通讯,是由网络通道上的交换数据包所完成。由客户端建立连线,并发送第一个数据包。伺服器以回传数据包来答复,数据包中陈述接受或拒绝连线,或要求进一步的验证。如果接受连线,接受数据包内会包含客户端接下来和伺服器交互所需的资料。
建立连线之后,在客户端和伺服器的通道上,会有四种交换数据包的类型:
- 请求:客户端请求伺服器的资讯,或者请求伺服器进行一个动作。
- 回应:伺服器回应请求。并非所有的请求都会产生回复。
- 事件:伺服器发送事件给客户端,例如,键盘或滑鼠的输入,或移动、调整、显示窗口。
- 错误:如果请求无效时,伺服器会发送一个错误数据包。因为请求是以排队方式处理,所以经由请求所产生的错误数据包,并不会立即发送。
X 伺服器提供一系统基本的服务。客户端程序可以和伺服器交互,以实现更复杂的功能。
窗口
[编辑]在 X窗口系统以及各种图形化用户界面中,窗口即为一个顶层窗口。窗口也用来指窗口内部的窗口,这类窗口是父窗口的子窗口。图形化组件,如按钮、菜单、图标等等,都是使用窗口来实现的。
任何窗口都只能是父窗口之下的子窗口,使窗口以树状的层次结构结构组织起来,层次结构结构最根部的窗口便称为根窗口,而根窗口是由伺服器自动建立的。顶层窗口即直接隶属于根窗口的子窗口。根窗口即整个屏幕画面,且其他窗口都在根窗口之下。
识别子
[编辑]所有关于窗口的资料、字体等等,皆存放在伺服器上。客户端知道那些物件的识别子,和伺服器交互时,物件以整数为名称。例如,当客户端希望建立一个窗口时,便指定一个识别子,并请求伺服器建立一个窗口。伺服器会建立一个窗口,并与指定的识别子关系。稍后客户端可使用这个识别子进行请求,例如在窗口上画上一个字符串。
识别子在伺服器上是独一无二的,在多个客户端之间也不例外。例如,即使是由两个不同客户端所建立的窗口,也不会同时具有相同的识别子。即使某个物件不是由自己的客户端所建立的,只要指定相对应的识别子,就可存取另一个客户端所建立的物件。
属性
[编辑]每一个窗口都有一组预先定义的属性值(Attributes)和属性(Properties),并存放在伺服器上,客户端可以适当的请求方式取存。属性值是有关窗口方面的资料,如大小、位置、背景色等等。属性则是附属于窗口上的资料片断。与属性值相反,属性在 X窗口系统 核心协议的层次中并没有其他含意。客户端可在窗口的属性中存放属性值资料。
属性以名称、类型和值来描述,属性相当于指令式编程语言的变量,应用程式可以指定名称、类型和值来建立新的属性。属性和窗口连系:两个相同名称的属性可存在于两个不同的窗口,且可具有不同的类型和值。
属性大多用于客户端之间的通讯。例如,名称为 WM_NAME
的属性,用来存放窗口的名称;窗口管理器通常会读取这个属性,并在窗口顶部显示名称。
窗口的属性可以 xprop
程序显示。xprop -root
更可显示根窗口的属性,包括 X资源(程序参数)。
事件
[编辑]事件是由伺服器发送到客户端用以通讯的数据包,发送一些客户端可能感兴趣的事物。客户端可以请求伺服器发送事件给另一个客户端;这部分用于客户端之间的通讯。例如,当客户端请求目前所选取的文字,就会发送事件给客户端,以处理目前所持有的选取内容。
在某些情况下,窗口的内容可能会被销毁(例如当窗口隐蔽时)。当再度观看被销毁的区域时,伺服器会产生一个 Expose
(显露)事件,用以通知客户端重绘窗口已消失的部分。
其他事件是用来通知键盘或滑鼠输入的客户端、建立新窗口等等。
某些类型的事件会不断发送给客户端,但大多数的事件只在客户端预先表示关心时才会发送。因为客户端可能只需要关心某类型的事件。例如,客户端可能会关心关于键盘的事件,但却不关心关于滑鼠的事件。
色彩模式
[编辑]对于 X窗口系统处理色彩的方式,有时用户会感到迷惑,且 X窗口系统 支持有史以来各种不同的模式。现今大多数的应用程式皆使用真实色(TrueColor)(24 位元色彩,红、绿、蓝各有 8 位元),不过比较旧或特殊的应用程式,可能会要求使用其他的色彩模式。许多商业用的专业应用程式使用伪彩色(PseudoColor)。
目前的 X11 协议在大多数的图形运算中,是使用一个 32 位元无负号整数来表示一个颜色,称为像素值。当转移到原色的饱和度时,对每一个色彩元素使用 16 位元整数。便有如下的色彩表示,但实际装置未必能全部支持。
- 直接色(DirectColor):像素值分为红、绿、蓝子域,每一个子域索引一份独立的色彩映射,可改变色彩映射的内容。
- 真实色(TrueColor):与直接色大致相同,但色彩映射的内容是由硬件预先定义,不可改变。通常每个红、绿、蓝色彩映射提供一个(接近)线性斜度的饱和度。
- 灰阶(GrayScale):像素值索引一份色彩映射,且无色彩饱和度(黑白)。可改变色彩映射的内容。
- 静态灰阶(StaticGray):与灰阶大致相同,但色彩映射的内容是由硬件预先定义,不可改变。
- 伪彩色(PseudoColor)(Chunky):像素值索引一份色彩饱和度方面的色彩映射。可改变色彩映射的内容。
- 静态色(StaticColor):与伪彩色大致相同,但色彩映射的内容是由硬件预先定义,不可改变。
Xlib 和其他的客户端程序库
[编辑]大部分的客户端程序借由 Xlib 客户端程序库与伺服器交流。特别是客户端大多使用 Xaw、Motif、GTK+、Qt 之类使用到 Xlib 的程序库,以便与伺服器交互。
客户端之间的通讯
[编辑]X窗口系统 核心协议提供了客户端之间通讯的机制:窗口属性和事件,特别是客户端对客户端的消息事件。不过这部分并未指明任何协议,协议部分由客户端之间的通讯协议单独管理。
客户端之间的通讯协议手册指明借由选取和应用程式的窗口管理器交互,以交换资料。但这个规格被认为过于困难和混乱;应用程式的质量和通讯的一贯性,通常是由指定的桌面环境所提供。
客户端之间的交换协议(ICE)指定了用以建立客户端间互相通讯的框架,因此,特定的协议可建立在其上。特别是 X 期间管理器协议(XSMP)便是建基于 ICE 的协议,以期间管理器托管应用程式间的交互。这个程序是在交互期间结束时,用来维护存放的桌面状态,并在同一用户再次开始另一个期间时恢复。
较新的协议包含在 freedesktop 规范,包括拖曳协议 Xdnd,用以选取要转移的资料,然后拖曳到另一个窗口上。还有嵌入式应用程式协议 Xembed,详述应用程式如何在另一个应用程式的子窗口之中执行。
选取、剪切缓冲器和拖曳
[编辑]选取、剪切缓冲器和拖曳机制在 X窗口系统中,是给用户从某个窗口传递资料给另一个窗口。选取、剪切缓冲器通常用于,用户在窗口中选取文字和其他资料,并在另一个窗口中粘贴。拖曳用于,用户在窗口中选取某些东西,然后对选取区按住按钮,并拖曳到另一个窗口。
由于两个窗口可能由两个不同的应用程式所持有,资料传递需要两个不同的客户端连接相同的 X 伺服器才能交互。X窗口系统 核心协议包含明确选择交换的请求和事件类型,不过传递的完成,主要是由一般的客户端对客户端事件发送,和未指明选择发送的窗口属性。
客户端之间发送的资料可以是不同的类型:通常是文字,不过也可以是图形、数字、物件的列表等等。
选取和拖曳是主动机制:在窗口中选取文字以后,客户端所处理的窗口必须主动支持相关的协议,才能发送资料到需要它的应用程式。相反的,剪切缓冲器则是被动机制:当用户选取文字时,其内容会发送到剪切缓冲器,即使应用程式所处理的窗口已结束并销毁窗口,缓冲器的内容仍会保留下来。
窗口管理器
[编辑]窗口管理器是用来控管窗口整体的外观,以及其他图形化用户界面的要素。在不同的安装中,X窗口系统会有不同的外观,主要是因为使用不同的窗口管理器,或是不同的窗口管理器配置。
窗口管理器维护窗口的位置、周围加上装饰性的边框、处理图标、处理滑鼠对窗口外表的点击(在“幕后”)、处理按键(例如按下 ALT-F4 时,将窗口缩小成图标)等等。
从 X 伺服器的角度来看,窗口管理器和其他的客户端并没有什么不同。起始位置和窗口周围的装饰性边框,是由窗口管理器使用如下请求处理的:
- 应用程式可以请求伺服器不要满足特定窗口的子窗口映射(显示)要求,并把事件发送过来。
- 应用程式可以请求改变窗口的亲属关系。
窗口管理器使用第一个请求,拦截所有映射顶层窗口(根窗口的子窗口)的请求。每当另一个应用程式请求映射顶层窗口,伺服器不会去做,反而发送事件给窗口管理器。大部分的窗口管理器会改变窗口的亲属关系:建立更大的顶层窗口(称作框架窗口),并改变原窗口的亲属关系为自己的子窗口;相当于在框架窗口内部放置原窗口。框架窗口(而不是在原窗口上)多出来的空间,是用来装饰窗口周围的框架(“边框”和“标题栏”)。
窗口管理器管理滑鼠在框架窗口上的点击。例如,当用户在边框或标题栏上点击并按住时,便允许改变大小或移动窗口。
窗口管理器也负责处理图标和图形组件的显示关系。图标并不存在于 X窗口系统 核心协议的层次上,那些是由窗口管理器实现的。例如,当窗口“图标化”时,窗口管理器 FVWM 取消映射那个窗口,使其不可见,并建立一个图标名称的窗口,且图标的图像可能和那个窗口有关。图标的意义和处理完全由窗口管理器来决定:某些窗口管理器,如 wm2,根本不实现图标功能。
期间管理器
[编辑]概略地说,在一个特定时间中,期间的状态就是“桌面的状态”:一组窗口及其当下的内容。更精确地说,就是一系列应用程式管理的这些窗口和资讯,其允许应用程式在需要时还原所管理窗口的情况。X 期间管理器便是一个保存并还原期间状态的程序。
使用期间管理器最明显的作用,便是从一个交互期间退出,当再次登录时,有可能在相同的状态下恰好发现相同的窗口。关于这部分的运作,在退出时,期间管理器程序存储执行中应用程式的名称,并在登录时再次启动它们。并按照应用程式状态的次序来还原(需要还原窗口的内容),应用程式必须能够保存这些执行状态,并在再次启动时,能够根据期间管理器的请求来读回这些状态。
X窗口系统含有一个默认的期间管理器,称作 xsm
。特定的桌面系统中也已开发了其他的期间管理器:例如,ksmserver
是 KDE 默认的期间管理器。
X 显示管理器
[编辑]X显示管理器在 X窗口系统中,是一个用来显示图形化登录提示的程序。更广泛的说,显示管理器在本机电脑上执行一个或多个 X 伺服器,并接受来自远程电脑上执行的 X 伺服器的新连线。本机伺服器借由显示管理器来启动,然后显示管理器连线到伺服器,以呈现出用户登录画面。远程伺服器从显示管理器独立启动并且与之连线。在这个情况下,显示管理器的运作就如同图形化的 telnet 伺服器:X 伺服器可连接到显示管理器,并启动一个期间;期间之中的程序执行在显示管理器的同一部电脑上,不过在电脑上的输出和输入是由 X 伺服器执行(用户面前的那部电脑)。
XDM 是 X窗口系统所提供最基本的显示管理器。其他的显示管理器还有 GDM(GNOME)、KDM(KDE)、WDM(使用 Window Maker 的 WING 组件集),以及 entrance(使用 Enlightenment v.17 的架构)。
用户界面组件
[编辑]X 早期的组件工具包有 Xaw(雅典娜工程组件集)、OLIT(OPEN LOOK 内部工具包)、XView、Motif、Tk。OLIT 和 XView 为 AT&T 和昇阳的 OPEN LOOK GUI 起基础工具包的作用。
Motif 为 Common Desktop Environment(CDE)提供基础工具包,即用于商业化 Unix 系统的标准桌面环境,如 Solaris 和 HP-UX。(GNOME 也用于 Solaris 9,且即将成为未来版本的标准。)
更多最新的工具包还包括 Qt(用于 KDE)、GTK+(用于 GNOME)、wxWidgets、FLTK、FOX。
扩展
[编辑]X 伺服器被设计成简单而可扩展。如此一来,许多功能就存在于扩展协议之中。
在协议层次上,每个扩展都可以指定新的请求/事件/错误的数据包类型。客户端应用程式使用客户端程序库,以促进存取由扩展所提供的功能。据说为目前的 X 伺服器编写扩展是相当困难的,这归咎于 X 伺服器缺乏模块化的设计。XCB 项目是一个长期的目标,朝向根据 XML 协议描述,自动化产生客户端和伺服端的扩展。
以下是一部分已开发的扩展列表,以引入的时间排列:
扩展 | 描述和注解 |
---|---|
AIGLX | 支持间接 GLX 绘图。 |
Composite | 整个窗口层次结构之外的幕外绘制,允许应用程式和组件管理器能在任何情况下作用。某些情况需要此功能,如用于窗口和阴影的 Alpha 半透明。 |
Damage | 追踪窗口的修改范围,并在维持必要的显示下,将带宽消耗降到最低。 |
XFixes | 若干协议的修改。 |
Extended-Visual-Information (EvIE) | |
Distributed Multihead (DMX) | |
XvMC | 支持卸载视频对 GPU 的动态补偿。 |
GLX | 支持窗口内部的 OpenGL 绘图。 |
XRender | 硬件加速的 Alpha 影像混合。 |
Resize and Rotate (RANDR) | 即时调整桌面的大小,以及侧向旋转或上下翻转。 |
Xinerama | 将桌面拆解,以对应多屏幕。 |
Display Power Management Signaling (DPMS) | 允许控制屏幕的电源节能模式。 |
XPRINT | |
X keyboard extension | 改善键盘布局的处理。 |
DOUBLE-BUFFER | |
RECORD | |
MIT-SHM | 增进共享存储器的使用性能。 |
SYNC | |
XTEST | |
XInputExtension | 支持绘图板之类的输入装置。 |
BIG-REQUESTS | |
XC-MISC | |
X video extension | 支持硬件视频重叠,以及播放时的硬件视频缩放。亦称 Xv(不要和 xv 程序混淆)。 |
Shape | 支持非矩形和部分透明(二进制,非 alpha 半透明)的窗口。 |
DEC-XTRAP | |
MIT-SCREEN-SAVER | |
MIT-SUNDRY-NONSTANDARD | |
SECURITY | |
TOG-CUP | |
X-Resource | |
XC-APPGROUP | |
XFree86-Bigfont | |
XFree86-DGA | |
XFree86-Misc | |
XFree86-VidModeExtension |
废弃的扩展
[编辑]扩展 | 描述和注解 |
---|---|
Low Bandwidth Extension (LBX) | 以安全壳层连线的 X tunneled 取代,且证明比 LBX 快速。 |
PEX | “PHIGS 扩展到 X 上”,以支持 PHIGS 3D 场景图形 API。已被运用 OpenGL 的 GLX 所取代。 |
XImage Extension | 以 MIT-SHM 取代。 |
参阅
[编辑]参考文献
[编辑]- Robert W. Scheifler and James Gettys: X窗口系统 System: Core and extension protocols, X version 11, releases 6 and 6.1, Digital Press 1996, ISBN 1-55558-148-X
- X窗口系统s 入门
- 开放源始码桌面技术蓝图 (Jim Gettys, 09 Dec 2003)