x window的奧祕

閱讀目錄html

  大名鼎鼎的 X Window 你們確定不陌生。都知道它是 Unix/Linux 下面的窗口系統,也都知道它基於 Server/Clinet 架構。在網上隨便搜一搜,也能夠找到很多 X Window 的介紹。有很多文章爲了給用戶留一個直觀的印象,每每先讓系統進入純文本界面,而後使用 startx 來啓動圖形界面,或者直接使用 X 來啓動 X Server,再而後運行一個 xterm 來作示範。我以爲以上這些文章對 X Window 的理解有限,不夠深刻,並且也不夠新。因此,我這裏寫一篇《X Window 的奧祕》,以最新的 Ubuntu-14.04 Desktop 爲例,展現如何學習 X Window。linux

  先說一點題外話。在上一篇《打造屬於本身的Vim》發表後,評論中有人讓共享一下配置文件。當時我說:配置文件又不長,本身照着圖片敲一下代碼嘛。結果這個「照着圖片敲代碼」的事情我今天本身幹了一遍,好在沒花多少時間,幾分鐘而已。緣由是由於我今天折騰 X Window 的時候,把系統給掛掉了,而後重裝系統,而後,就只好再設置一遍 Vim 了。ubuntu

瞭解本身機器上的 X Window

  X Window 實際上是一種規範,它有不少不一樣的實現,在 Linux 系統下最流行的是實現 Xorg 和 XFree86,微軟 Windows 系統下也有 X Window 的實現,蘋果的Mac 也是 X Window 的一種。要了解本身機器上運行的 X Window 到底是哪個,可使用查看進程的ps命令,以下圖:
vim

  從上圖能夠看出,Ubuntu 14.04 使用的 X Window 是 Xorg。若是使用 ps -ef 命令,還能夠看到 Xorg 運行時的命令行參數。安全

  想了解 X Window,下面這些文檔須要看一遍先:
session

  下面來講一下也許是衆所周知的基礎知識:X Window 是一個分層的架構,它分爲 Serve 和 Client。X Server 負責圖形界面的顯示,(也負責用戶的輸入),而Client 程序須要鏈接到 X Server,而後請求 X Server 繪製圖形界面,同時從 X Server 接受用戶的輸入。在桌面系統上,X Server 和 Client 程序每每安裝在同一臺機器上,平常使用基本感受不到它是分層的。可是很顯然,X Server 和 Client 也能夠分別運行在不一樣的機器上,在一臺機器上運行程序,而在另一臺機器上顯示圖形界面。架構

  X Window 中的 Server 和 Client 的概念和咱們平時接觸到的「Server/Client」概念恰好相反。不少熟悉 Internet 原理的人,第一次接觸 X Window 的這兩個概念都會搞錯。好比,我在一臺本地機器上運行 Ubuntu 14.04 桌面版,而在另一臺遠程機器上運行 CentOS 5.10(純字符界面),當我用 ssh 從 Ubuntu 鏈接到 CentOS 的時候,Ubuntu 是 Client,而 CentOS 是 Server。在 X Window 中,Server 恰恰是我面前的這臺 Ubuntu,X Server 運行在 Ubuntu 上。我能夠在 CentOS 中運行 GVim,可是窗口顯示在 Ubuntu 中,這時,GVim 是一個 Client 程序,它在遠程機器上運行,而它的窗口顯示在本地。ssh

理解 display 和虛擬控制檯

  前面提到網上不少介紹 X Window 的文章都是先讓系統進入字符界面,而後手動啓動一個 X Server。其實這徹底沒有必要,由於在同一臺機器上徹底能夠運行多個 X Server,只須要讓每一個 X Server 的 display 不一樣便可。那麼 display 到底是什麼?tcp

  在 X Window 中,能夠經過 hostname:display_number.screen_number 來指定一個屏幕。能夠這樣理解:一臺計算機能夠有多個 display,一個 display 能夠有多個屏幕。因此,display 至關因而計算機配備的一套輸入輸出設備,通常狀況下,一臺電腦只配一套鍵盤鼠標和一個顯示器,特殊狀況下,能夠配多個顯示器。學習

  如今問題出來了,個人電腦只有一套鍵盤鼠標和一個顯示器,也就是隻有一個 display,那又怎麼能運行多個 X Server 呢?那是由於在 Linux 中,還有虛擬控制檯這樣的高級特性。只須要同時按下 Ctrl+Alt+F一、Ctrl+Alt+F二、...、Ctrl+Alt+F7,就能夠在不一樣的虛擬控制檯中進行切換。在 Ubuntu 14.04 中,虛擬控制檯 1 到 6 運行的getty,也就是字符界面,虛擬控制檯 7 運行的是 Xorg。(Fedora 中不同,虛擬控制檯 1 運行的是圖形界面,其它的是字符界面。)

  咱們能夠直接運行 X Server 程序來啓動 X Server。/usr/bin/X 和 Xorg 都是 X Server 程序。其實 /usr/bin/X 是 Xorg 的符號連接,用哪個都是同樣的。

  啓動 X Server 的時候能夠指定 display 參數,由於能夠省略掉 hostname 和 screen_number,因此能夠用 :0,:1 這樣的格式來指定 display。在個人機器上,原本就有一個 X Server 在運行,display :0 已經被佔用了,因此我使用 sudo X :1 -retro 來在 display :1 上再運行一個 X Server,以下圖:

  其中的 -retro 參數是爲了讓 X Server 的背景顯示爲斜紋,不然背景爲純黑色,那就看不出來是否啓動了 X Server。啓動 X Server 後的效果以下圖:

  按 Ctrl+Alt+F7 回到 display :0,再用 ps 命令看一下,會發現系統中有兩個 Xorg 在運行,一個運行在虛擬控制檯 7,一個運行在虛擬控制檯 8。以下圖:

  在新啓動的 X Server 中運行一個 GVim 看看效果。運行 GVim 時,使用 -display :1 參數指定窗口顯示在新啓動的 X Server 上,使用 -geometry 參數指定窗口的大小和位置。而後按 Ctrl+Alt+F8 切換虛擬控制檯,看效果。命令見上圖,程序運行效果見下圖:

遠程鏈接 X Server

  若是能讓遠程機器上的 GVim 也把窗口顯示在本地機器的屏幕上,那就比較過癮了。因此,使用 ssh 鏈接到 CentOS-5.10,而後使用 gvim -display ubuntu-14:1 命令,但願將 GVim 顯示到 Ubuntu 的 display :1 上。因爲是遠程鏈接,因此 hostname 不能省略,需寫成 ubuntu-14:1,也可使用 IP 地址,寫成 192.168.1.103:1。以下圖:

  很惋惜,鏈接失敗。

  失敗的緣由是遠程訪問 X Server 須要安全認證。這個能夠理解,就像登錄郵箱須要輸入用戶名和密碼同樣,若是 X Server 不要認證就能夠隨便鏈接的話,那豈不是桌面上垃圾窗口滿天飛?安全認證的方式有不少種,具體請參考 man Xsecurity。安全認證可使用 xhost 和 xauth 這兩個程序來進行,具體使用方法參考它們的文檔。

  先用 xhost 來受權,這個比較簡單。爲了運行 xhost,須要在 X Server 上有一個終端,因此運行一個 xterm,以下圖:

  在 xterm 中輸入 sodu xhost +192.168.1.109,這樣,CentOS-5.10 中運行的 GUI 程序均可以鏈接到這個新開啓的 X Server 了。以下圖:

  在 CentOS-5.10 中運行 GVim,以下圖:

  窗口顯示在 Ubuntu 中,以下圖:

  新啓動的 X Server 界面比較醜陋,咱們仍是想讓遠程機器上的 GUI 程序直接顯示在 Ubuntu 的桌面環境中。因此,指定 display 爲 :0,以下圖:

  結果很不幸,沒法打開 display。鏈接不上,爲何呢?是安全認證的問題嗎?不是,是 lightdm 的問題,請繼續往下看。

理解 lightdm 和 X Window 桌面環境的啓動過程

  X Server 的啓動方式有兩種,一種是經過顯示管理器啓動,另外一種是手動啓動。在前面的例子中,我經過直接運行 /usr/bin/X :1 來啓動了一個 X Server。直接啓動 X Server 的方法還有運行 startx 或者 xinit。手動啓動 X Server 的缺點就是啓動的 X Server 很差看。而顯示管理器啓動的不只有 X Server,還有一大堆的 Client 程序,構成了一個完整的桌面環境,界面固然就漂亮多了。

  顯示管理器(Display Manager)是什麼呢?前面我講到 display 就是一個電腦配備的一套鍵盤鼠標和顯示器,那麼顯示管理器就是這一套設備的管理器了。顯示管理器能夠直接管理這些設備,因此它能夠控制 X Server 的運行,由它來啓動 X Server 那是再合適不過了。系統啓動過程是這樣的:內核加載-->init程序運行-->顯示管理器運行--> X Server 運行-->顯示管理器鏈接到 X Server,顯示登陸界面-->用戶登陸後,登陸界面關閉,加載桌面環境。從上面的流程能夠看出,顯示管理器是 X Server 的父進程,它負責啓動 X Server,當 X Server 啓動後,它又變成了 X Server 的一個 Client 程序,鏈接到 X Server 顯示歡迎界面和登陸界面,最後,顯示管理器又是全部桌面環境的父進程,它負責啓動桌面環境須要的其它 Client 程序。

  在 Ubuntu 14.04 中,使用 lightdm 取代了傳統的 xdm、gdm 等顯示管理器。簡單來講,就是由 lightdm 負責啓動 X Server 和其它的 X 程序。不知道爲何,lightdm 在啓動 X Server 的時候,給 X Server 加上了 -nolisten tcp 參數,因此遠程計算機就沒有辦法鏈接到 Ubuntu 的桌面了。(從第 1 張圖片能夠看到該參數。)

  下一步的目標就是更改 lightdm 的配置,去掉這個 -nolisten tcp 參數。不過要達成這個目標還真是艱難啊,個人系統掛掉而後重裝就是在這裏折騰出來的。在這裏我要狠狠滴吐槽一下 freedesktop.org,在 X Window 所用的軟件中,freedesktop.org 貢獻很大,好比 lightdm、xft、fontconfig、freetype 都是這個組織貢獻的,但是,你就不能把文檔寫詳細點嗎?不只是 lightdm 的文檔不行,xft、freetype 的文檔也都不行。

  lightdm 的 man page 很是簡略,使用 sudo dpkg -L lightdm 也找不出該軟件包中有價值的東西。沒辦法,另闢蹊徑吧。在使用 sudo dpkg -L lightdm 查看該軟件包的文件時,發現它的 log 文件放在 /var/log/lightdm 文件夾下,過去看看:

  終於,從 log 文件中看到了 lightdm 啓動的全過程。首先,看到它從哪幾個目錄加載配置文件,接着,看到它啓動 X Server。從下圖光標所在的行能夠看到 X Server 啓動的全部參數,包括 -nolisten tcp 選項。

  繼續看 log 文件,下面光標所在的行顯示 lightdm 怎麼啓動 gnome-session:

  同時,我發現 /etc/lightdm/ 目錄下沒有 lightdm.conf 文件,而 /usr/share/doc/lightdm/ 目錄下有一個 lightdm.conf.gz 文件,把該文件當文檔看了一下,發現裏面果真就是 lightdm 的配置的解釋。趕快將該文件複製到 /etc/lightdm/ 目錄下並解壓,以下圖:

  而後用 Vim 編輯 /etc/lightdm/lightdm.conf 文件,將 xserver-allow-tcp=false 一行前面的註釋去掉,而且改成 xserver-allow-tcp=true。以下圖:

  最後,重啓系統。再用 ps 查看進程,發現 -nolisten tcp 選項已經沒有了。

搞定 xauth

  搞定了 -nolisten tcp 以後,要想從遠程計算接鏈接到 Ubuntu 桌面,仍是須要安全認證。在前面的例子中,我使用了 xhost。xhost 是最簡單的認證方式。在這裏我要試一下別的認證方式,好比 MIT-MAGIC-COOKIE-1。如上圖,先使用 xauth list 命令查看一下當前的受權記錄,發現只有一條,並且 display 是 ubuntu-14/unix:0,很顯然,這是一個本地受權,因此須要使用 xauth add 命令添加一個使用 ip 地址的受權,後面的 key 照抄就好了。最後,使用 xauth extract 和 xauth merge 配合管道和 ssh 將該受權記錄合併到 CentOS-5.10 中。

  在 CentOS-5.10 中啓動 GVim,指定 display 爲 192.168.1.103:0,GVim 窗口就出如今了 Ubuntu中。以下圖:

X Server 的配置

  可使用不一樣的方法對 X Server 進行配置,前面的例子是直接指定命令行參數。除了指定命令行參數,還可使用環境變量和配置文件。X Server 的配置文件爲通常是 /etc/X11/xorg.conf 或 /etc/X11/xorg.conf.d/ 目錄下的 .conf 文件,固然,配置文件也能夠放在其它的目錄中,具體信息,請參看 man xorg.conf。

  若是沒有配置文件,X Server 將在啓動的時候自動檢測硬件,而後生成一個內置的配置。Ubuntu 系統就沒有配置文件。不過不要緊,若是須要使用配置文件的時候,能夠經過 X Server 的 -configure 參數生成一個配置文件,裏面包含當前自動檢測出的配置。若是須要任何個性化的配置,對該文件進行修改便可。

現有的圖形界面中能夠運行嵌套的 X Server

  咱們上面運行的 X Server 都是直接佔用了計算機的整個顯示器和鍵盤鼠標,事實上,在現有的圖形界面中,還能夠以窗口模式運行另一個 X Server,稱爲 nested X Server。最經常使用的 nested X Server 是 Xephyr,在 Ubuntu 中能夠經過以下命令安裝它:

sudo aptitude install xserver-xephyr

  Xephyr 的使用很是簡單,能夠經過 man Xephyr 命令查看它的使用手冊。若是輸入 Xephyr :1 命令,就能夠在現有圖形界面中打開一個窗口模式的 X Server,以下圖:

  之後再啓動 GUI 程序,就能夠經過程序的 -display 選項讓程序運行在這個嵌套的 X Server 中,以下圖:

  怎麼樣,是否是很好玩呢?除了好玩,還頗有用,好比調試窗口管理器啊、鏈接遠程桌面啊什麼的都用得着。固然,我這裏只是簡單展現一下原來 X Window 還能夠這麼玩。

總結:

  1.在一個 Linux 系統中存在多個虛擬控制檯,因此能夠啓動多個 X Server;

  2.啓動 X Server 的方式有兩種,一種是使用 /usr/bin/X、startx、xinit 手動啓動,一種是經過顯示管理器啓動;

  3.Ubuntu 使用的顯示管理器是 lightdm,這是一個比較新的、輕量級的顯示管理器,可是文檔不夠詳細;

  4.遠程計算機鏈接本地的 X Server,須要 X Server 開放 TCP 端口,還要搞定安全認證;

  5.X Server 的配置,能夠經過命令行參數,能夠經過環境變量,還能夠經過配置文件;

  6.能夠在現有的圖形界面下以窗口模式運行嵌套的 X Server,經常使用的軟件是 Xephyr;

相關文章
相關標籤/搜索