转载:http://blog.sina.com.cn/s/blog_540b60fb0100qauu.html
发现身边的同事很多对*nix下面的X window这东西很不熟悉,想想自己从大三第一次装Linux,到现在对X系统的底层依然是基本没什么概念,不过上层的图形开发倒是做了不少了,研究生开始为糊口去写QT,到现在QT和wxWidgets都写了不少程序了,大体的概念总是懂了一些,自己总结一下先,然后翻译成E文练习一下:
1. X window据说是从W window系统演进而来(想想字母表就知道了),MIT搞的吧。应该很老了,所以API现在看起来挺落后的(包括Xt、Motif这些后来使用更广泛的X API),后来M$ Windows的图形环境设计的时候肯定是受到了X系统的影响,比如Context什么的,很像。但是X window和Windows的架构可就相差很远了。X window一开始就设计成一个标准的C/S架构,Client和Server可以在不同的机器上,其中以X协议通信,X协议的实现构建在socket编程接口上,可以是Unix域的socket或者在TCP/IP上。一个普通的PC机也可以启动多个X Server。X server的功能是负责把收到的图形信息显示到显示器上,X client则是连接到X server上告诉X server应该怎么显示。
2. X server的程序名称一般就叫X。在同一个机器上启动的多个X server分别以:0, :1, :2这样标志,或者写成:0.0, :1.0.... 这个".0"表示多显示器系统的第一个显示器,一般人不用这新奇玩意,所以我就写:1, 不写后面的.0。连上机器的名称(或者IP)就可以唯一的指定一个网络上的X server,比如10.0.0.2:0,localhost:1。如果是TCP/IP方式,server的监听端口从6000开始,很多linux发行版的启动X登录方式后启动的第一个X server是只使用Unix域的socket的,所以看不到6000这个端口,但是用"netstat -na | grep X0"可以看到有一个正在监听的unix域stream,这个就是X server了,我们可以用命令行"X :1&"
来启动第2个X server,这次再用netstat -na就可以看到6001端口正在监听了。顺便说一下,在大部分linux发行版中,用ctrl+Alt+(F7~F10来切换各个X server)。
3. X client就是一般的X程序,比如xterm, xclock这些标准程序以及KDE和Gnome这样的桌面环境里面的那一堆一堆的小程序,X client启动的时候会去连接X server,标准的X clinet程序都可以用 -display :1或者-display 10.0.0.1:2这样的形式连接到一个X server上,如果没有指定这样的命令行参数,就会去找DISPLAY这个环境变量,连接到$DISPLAY所指定的X server上去。很多个X client都可以连接到一个 X server上,分别告诉xserver它自己应该怎么显示,然后X server把它显示给用户。如果这个X server死翘翘了,那么已经连接上的Client程序都会因连接关闭而自动结束。
4. OK,现在举个例子。windows下面的X server程序比较著名的有exceed和xmanager,免费的有cygwin里带的,我喜欢用这个,功能也还不错,和linux环境相仿,这里说的在Linux下面和cygwin下面都通用。在一个console界面下(这里假设都是在bash环境下),首先用
X :1&
启动一个X server,然后回到console界面,执行
export DISPLAY=:1
接着回到console执行
xterm&
OK,在X server界面中就可以看到一个有命令行的光棍窗口了,没有标题栏,不能移动,但是有xterm的命令行界面。接着再来
xterm -geometry 80x24+300+300&
又出来一个xterm,还是没头没脑的光棍窗口,怎么会这样,还缺一个东西,窗口管理器,Xwindow系统和M$ Windows不同,窗口的标题和框架什么的不是一般X client自己负责显示,而是windows manager来管,windows manager和X server是一一对应的,一个X server不能同时运行多个windows manager,最简单的windows manager应该是twm,比较著名的有fvwm,afterstep,wmaker(不知道苹果现在还用不用这个,Jobs的NextStep项目搞出来的),当然不能不提Gnome和KDE下面带的windows manager,KDE下面是kwin,Gnome下面的是gnome-session。
现在执行
twm&
或者如果是在装了KDE的linux下也可以执行
kwin&
就可以看到带标题栏的完整窗口了,好玩吧。这个twm很简陋,但是熟悉一会也就习惯了。
M$ windows用习惯了,就觉得这个好麻烦,还搞个什么windows manager,这样是有好处的,方便实现设置窗口主题、窗口行为方式的统一管理什么的,但是也有不好的地方,比如窗口外围的装饰框架到底有多宽,X client自己不负责,就不知道。所以X client对自己窗口的client区域大小搞得很清楚,但是连上标题栏和装饰的整个窗口有多大,就搞不清楚,这个问题不知道现在解决的如何了,这个是学习QT编程的时候QT的文档中专门指出的。
5. 好了,X window系统基本上已经说清楚了,现在再说说怎么让X server和X client不在一台机器上,其实很简单对吧,执行export DISPLAY=:1这句的时候指定一个别的机器上的X server就可以了,像这样:
export DISPLAY=hostname:1
一般情况下我们是需要把远程的程序执行的时候显示到本地的显示器上。那么就先在本地启动X server,以下假设本地IP是10.0.0.2。
命令序列还是一样:
X :1&
export DISPLAY=:1
xterm&
twm&
好,现在可以在这个新启动的X server里的xterm中工作了,在这里telnet到某个*NIX系统中(最好是局域网内,速度快),然后用
echo $DISPLAY
看看有没有设置DISPLAY这个变量,不管它已经是什么,改掉它:
export DISPLAY=10.0.0.2:1
然后执行
xclock&
应该看到有东西显示到本地的显示器上了吧。随便点一下鼠标(这个twm讨厌的地方,新窗口要点一下鼠标指定位置)。这个程序可是在远程的机器上运行的,只是显示到本地。顺便说一句,exceed下的passive模式实际上就是这个工作方式。
X window最基本的东西应该就这些了。还差XDMCP、VNC中的Xvnc、SSH的X端口转发这些东西没有说,下次接着写。
这里先写个以后写的内容的概要: