X Window Systemプロトコルとアーキテクチャ

X Window System（X11、X）は、ネットワーク透過なビットマップディスプレイ用ウィンドウシステムである。本項目は、X11のプロトコルと技術的構造の詳細を解説する。

 Xクライアントサーバモデルとネットワーク透過性 
Xはクライアントサーバモデルに基づいている。「Xサーバ」プログラムはグラフィックディスプレイのあるコンピュータ上で動作し、各種「クライアントプログラム」と通信する。サーバはグラフィカルな出力（ウィンドウ）の要求を受け付け、（キーボードやマウスの）ユーザー入力をクライアントに送信する。

Xでは、サーバがユーザーの使っているマシン上で動作し、クライアントは他のマシンでも動作できる。これは一般的なクライアントサーバモデル(「クライアント」がユーザーのコンピュータ上で、「サーバ」が遠隔のコンピュータ上で動作する)とは逆であり、Xを新たに使おうとする人は、この逆転に戸惑うことが多い。Xの用語はエンドユーザーやハードウェアよりもプログラムの観点を採用している。遠隔にあるプログラムはローカルなマシン上で動作するXサーバのディスプレイと接続し、クライアントとして機能する。ローカルなXディスプレイは入っているトラフィックを受け付けるので、サーバとして機能する。

サーバとクライアント間の通信プロトコルは透過性を実現している。クライアントとサーバは同じマシン上でも動作できるし、異なったマシン上でも動作できる。それらマシンのアーキテクチャやオペレーティングシステムの差異は問題にならない。クライアントとサーバ間の通信をインターネット上で行う場合、暗号化されたコネクション上でトンネリングすることでコンピュータセキュリティを確保できる。

 設計思想 
Bob ScheiflerとJim Gettysは設計にあたって、Xの基本原則を以下のように定めた（Scheifler/Gettys 1996）。

 実際のアプリケーションでどうしても必要という場合以外は、新機能を追加するな。 
 システムが何でないのかを定義することは、何であるのかを定義するのと同じように重要である。あらゆるニーズに応える必要はない。むしろ、互換性を維持した状態で拡張可能にしておけ。 
 1つでも例を挙げて一般化したほうが、全く例を挙げずに一般化するよりもマシである。 
 問題が完全に把握できないときは、解決策も提供しないのが最善の方法である。 
 作業の10%について90%の効果しか得られないときは、単純な解法を使え。 
 複雑さは可能な限り分離せよ。 
 ポリシーよりも機構を提供せよ。特にユーザインタフェースのポリシーはクライアント側に任せておけ。 

先頭の原則は、X11の設計中に「具体的アプリケーションがそれを必要としていることを知っている場合に限って、新たな機能を追加せよ」に修正された。X はだいたいにおいてこれらの原則に従ってきた。リファレンス実装は拡張性と改良を視野に入れて開発されており、1987年当時のプロトコルとほぼ完全な互換性を維持している。

 X Window System コアプロトコル 

サーバとクライアント間の通信は、ネットワーク経路上でパケットを交換することでなされる。コネクション確立はクライアント側から先にパケットを送ることでなされる。サーバはコネクション確立について受理または拒否のパケットを送り返すか、さらなる認証を求めるパケットを送る。コネクションが受理された場合、受理パケットにはクライアントがその後のサーバとのやり取りで必要とするデータが含まれている。

コネクション確立後、クライアントとサーバの間で以下の4種類のパケットがやり取りされる。

 要求 (Request): クライアントがサーバから情報を要求するか、サーバに何らかの実行を要求する。 
 応答 (Reply): サーバへの要求に対する応答。全ての要求パケットに対して応答パケットが生成されるわけではない。 
 イベント (Event): サーバがクライアントに対して、キーボードやマウスからの入力、ウィンドウの移動、リサイズ、前面への露出などのイベントを知らせる。 
 エラー (Error): 要求が不正だった場合、サーバはエラーパケットを送る。要求はキューイングされるので、要求に対するエラーは即座に返ってくるとは限らない。 

Xサーバは基本的なサービス群を提供する。クライアントはサーバとのやり取りによって、より複雑な機能を実現する。

 ウィンドウ 

他のグラフィカルユーザインタフェースでウィンドウと呼ばれるものは、X Window Systemでは「トップレベルウィンドウ」と呼ばれる。「ウィンドウ」は他のウィンドウの中にあるウィンドウも含めた用語である（「親ウィンドウ」と「子ウィンドウ」）。ボタン、メニュー、アイコンといったグラフィカルな要素も全てウィンドウを使って実現される。

ウィンドウは常に親ウィンドウの子ウィンドウとして生成される。このため、ウィンドウ群は木のような階層を形成する。この階層構造の根にあたるウィンドウを「ルートウィンドウ」と呼び、サーバが自動的に生成する。トップレベルウィンドウは、ルートウィンドウの直接の子ウィンドウである。見た目では、ルートウィンドウは画面と同じ大きさで、全てのウィンドウの背後にある。

 識別子 
ウィンドウ、フォントなどに関する全てのデータはサーバに格納される。クライアントはそれらオブジェクトの識別子を知っている。識別子は整数であり、サーバとやり取りする際のオブジェクトを指定する名前の役割を果たす。例えば、クライアントがウィンドウを生成したい場合、サーバに対して識別子を指定してウィンドウ生成を要求する。サーバはウィンドウを生成すると、それを指定された識別子と結びつける。この識別子はその後のクライアントからの要求に使われる（例えば、そのウィンドウに文字列を描画する場合など）。

識別子はサーバ上で一意であり、クライアント間でも重ならない。2つの異なるクライアントが作成したウィンドウであっても、2つのウィンドウが同じ識別子を持つことはない。クライアントは、自身が生成したオブジェクトでなくとも、識別子さえ知っていれば、そのオブジェクトにアクセスできる。

 属性とプロパティ 
各ウィンドウには事前定義された属性群とプロパティ群があり、それらは全てサーバに格納されていて、クライアントは適切な要求によってそれらにアクセスできる。属性とは、大きさ、位置、背景色などのウィンドウに関するデータである。プロパティとは、ウィンドウに付加されたデータである。属性とは異なり、プロパティはX Window System コアプロトコルのレベルでは何の意味も持たない。クライアントは任意のデータをウィンドウのプロパティに格納できる。

プロパティには、名前と型と値がある。命令型プログラミング言語における変数に似ていて、アプリケーションは新たなプロパティを生成するときに名前と型を指定し、値を格納できる。プロパティはウィンドウ毎にあるので、各ウィンドウに同じ名前のプロパティがある場合、型と値はそれぞれ異なる。

プロパティはクライアント間通信で主に使われる。例えば、WM_NAMEという名前のプロパティはウィンドウの名前を格納するのに使われる。ウィンドウマネージャはこのプロパティを読んで、そのウィンドウの上辺に名前を表示する。

ウィンドウのプロパティ群はxpropプログラムを使って表示できる。特にxprop -rootとすればX resource（:en:X resourcesを含むルートウィンドウのプロパティが表示される。

 イベント 
イベントとは、サーバからクライアントに送信されるパケットで、クライアントが関心を持つ可能性のある事象を通知する。クライアントはサーバに対して、別のクライアントにイベントを送信するよう要求でき、これを使ってクライアント間通信がなされる。例えば、あるクライアントが現在選択されているテキストを要求する場合、選択が行われているウィンドウを制御しているクライアントにイベントが送信される。

ウィンドウの内容は状況によって破壊されることがある（例えば、別のウィンドウの陰になった場合）。破壊された内容を見えるようにするため、サーバはExposeイベントをクライアントに送り、クライアントにウィンドウの再描画の必要があることを知らせる。

他には、キーボードやマウスからの入力を知らせるイベント、新たなウィンドウの生成を知らせるイベントなどがある。

ある種のイベントは常にクライアントに送られるが、ほとんどのイベントはクライアントが事前に指定していないと送信されない。例えば、キーボード入力しか受け付けないクライアントは、キーボードに関するイベントのみを指定し、マウスに関するイベントは指定しないといったことが考えられる。

 色名称 
X Window Systemでの色の扱い方はユーザーを混乱させることがあり、歴史的経緯からいくつかの異なるモードをサポートしている。多くのアプリケーションはTrueColor（24ビットで、赤・緑・青がそれぞれ8ビット）を使用するが、古いアプリケーションや特殊なアプリケーションは異なる色モードを要求することがある。特に商用の特殊アプリケーションはPseudoColorを使用する。

X11プロトコルでは、色は32ビットの符号なし整数で表され、これを「ピクセル値」と呼ぶ。原色の強さを指定する場合は、それぞれの色成分を16ビット整数で表す。色の表現には以下のモードがあるが、あるディスプレイ機器でこれらが全てサポートされているとは限らない。

DirectColor: ピクセル値は赤・緑・青のビット列に分割される。それぞれの成分に独立したカラーマップがある。カラーマップ上のエントリは全て変更可能である。
TrueColor: DirectColor と同じだが、カラーマップのエントリはハードウェアによって決まっていて、変更できない。通常、赤・緑・青はそれぞれの光の強さを表している。
GrayScale: ピクセル値は単一のカラーマップのインデックスであり、白黒階調を表す。カラーマップのエントリは変更可能である。
StaticGray: GrayScale と同じだが、カラーマップのエントリはハードウェアによって決まっていて、変更できない。
PseudoColor: ピクセル値は単一のカラーマップのインデックスであり、カラーマップの各エントリが色を示している。カラーマップのエントリは変更可能である。
StaticColor: PseudoColor と同じだが、カラーマップのエントリはハードウェアによって決まっていて、変更できない。

 Xlibなどのクライアントライブラリ 

クライアントプログラムの多くは、Xlibというクライアント用ライブラリを経由してサーバと通信する。さらに、多くの場合Xlibを直接使うのではなく、Motif、GTK、Qt といったライブラリを使う。

 クライアント間通信 
X Window System コアプロトコルは、クライアント間の通信機構としてプロパティとイベントを提供しており、特にクライアント間のメッセージイベントがある。しかし、そのやり取りを規定するプロトコルは存在しない。そのようなプロトコルは個別のクライアント間通信規定で扱われる。

Inter-Client Communication Conventions Manualは、セレクションによるそのようなデータ交換のプロトコルとウィンドウマネージャとアプリケーションのやり取りを規定している。しかし、この仕様には混乱があり、理解するのが困難と言われてきた。アプリケーションのルック・アンド・フィールと通信の一貫性は、一般にデスクトップ環境を指定してプログラミングすることで保たれる。

Inter-Client Exchange (ICE) プロトコルはクライアント間のやり取りのためのプロトコル構築のフレームワークとなり、これを使って特定のプロトコルを構築できる。例えば、X Session Manager Protocol (XSMP) はICEに基づくプロトコルで、Xセッションマネージャ（後述）とアプリケーション間のやり取りを規定している。

より新しい規定としてfreedesktop.orgによる仕様群がある。これには、Xdnd（ドラッグ・アンド・ドロップ規定）、Xembed（あるアプリケーションを別のアプリケーションの子ウィンドウとして動作させる際の詳細な規定）などがある。

 セレクション、カットバッファ、ドラッグ・アンド・ドロップ 
セレクション (selection)、カットバッファ (cut buffer)、ドラッグ・アンド・ドロップ (drag-and-drop) は、ユーザーがX Window Systemでウィンドウからウィンドウにデータを転送するための機構である。セレクションとカットバッファは一般に、ユーザーがウィンドウ内のテキストなどの何らかのデータを選択し、それを他のウィンドウに貼り付けるのに使われる。ドラッグ・アンド・ドロップは、ユーザーがウィンドウ内の何かを選択し、選択したものの上でマウスをクリックし、それを他のウィンドウにドラッグするという場合に使われる。

2つのウィンドウはそれぞれ独立した別々のアプリケーションが制御しているので、Xサーバに接続された2つのクライアントが相互にやり取りしないとデータ転送できない。X Window System コアプロトコルはセレクションの交換に対応した要求やイベントを用意しているが、転送自体はクライアント同士のイベント送信とウィンドウプロパティで実現され、これはセレクションの転送に限った話ではない。

クライアント間で転送されるデータには様々なものがある。テキストであることが多いが、ピクスマップや数値やオブジェクトのリストなどもある。

セレクションとドラッグ・アンド・ドロップは能動的機構である。あるウィンドウ上でテキストを選択した場合、そのウィンドウを制御しているクライアントがデータを要求しているアプリケーションにデータを転送するプロトコルを能動的にサポートしていなければならない。対照的にカットバッファは受動的機構である。ユーザーがテキストを選択した場合、その内容はカットバッファに転送され、元のウィンドウを制御していたアプリケーションが終了してウィンドウが消えても、カットバッファ内の内容は残る。

 ウィンドウマネージャ 

ウィンドウマネージャは、ウィンドウの全体的見た目や他のGUI要素を制御する。X Window System が使用されているマシン毎に異なる見た目となるのは、主にウィンドウマネージャが違うためか、あるいはウィンドウマネージャの設定が異なるためである。

ウィンドウマネージャは、ウィンドウの位置決め、ウィンドウ周囲の装飾の配置、アイコンの処理、特定キーストロークの処理（例えば ALT-F4 押下でウィンドウをアイコン化するなど）といった処理をする。

Xサーバから見れば、ウィンドウマネージャも通常のクライアントと違いはない。初期の位置決めや周囲の装飾の配置は、ウィンドウマネージャによる以下のような要求で制御される。

 アプリケーションは、サーバがウィンドウの子ウィンドウを表示する前に、イベントを送信してもらうよう設定できる。
 アプリケーションは、親ウィンドウの変更を要求できる。

ウィンドウマネージャは、第一の要求を使ってトップレベルウィンドウ（ルートウィンドウの子ウィンドウ）の表示要求をインターセプトする。他のアプリケーションがトップレベルウィンドウの表示を要求すると、サーバは表示する前にウィンドウマネージャにイベントを送る。多くのウィンドウマネージャはRe-parenting Window Managerと呼ばれ、フレームウィンドウと呼ばれる大きなトップレベルウィンドウを生成し、本来のウィンドウをその子ウィンドウとして表示する。画面上はフレームウィンドウの内側に本来のウィンドウが表示される。フレームウィンドウは若干大きいので、周辺部分は元のウィンドウで覆われない。この部分が周囲の装飾（ボーダーやタイトルバー）の表示に使われる。

ウィンドウマネージャはフレームウィンドウでのマウスクリックを管理する。このため、ボーダー部分やタイトルバー部分でマウスをクリックしてドラッグすることで、ウィンドウを移動させたり、サイズを変更したりできる。

ウィンドウマネージャはアイコンや関連するGUI要素の制御も行う。アイコンという概念はX Window System コアプロトコルのレベルでは存在せず、ウィンドウマネージャによって実装されている。例えば、ウィンドウを「アイコン化」するとき、FVWMなどのウィンドウマネージャがウィンドウをアンマップし、見えないようにし、アイコン名のウィンドウと（もしあれば）アイコンの画像のウィンドウを生成する。このようにアイコンの制御は完全にウィンドウマネージャが行っている。中には全くアイコンを実装していないウィンドウマネージャもある（例えば wm2）。

 セッションマネージャ 
「セッション (session)」の状態とは、大まかに言えばある時点での「デスクトップの状態」、すなわちウィンドウ群の現在の内容の総体である。より正確に言えば、それらウィンドウ群を管理しているアプリケーションと、それらアプリケーションが要求されたときにウィンドウの状態を復元するのに必要とする情報の集まりである。Xセッションマネージャとは、セッションの状態を保存し復元するプログラムである。

セッションマネージャを使うと何ができるかというと、ログアウトして再びログインしたときに、ログアウト前と全く同じウィンドウ群が表示されるという効果がわかりやすい。このため、セッションマネージャはログアウト時点の動作中アプリケーションの名前を記録しておき、再度ログインした際にそれらを再開させる。各アプリケーションの状態も復元するには、アプリケーション自体が実行状態をセッションマネージャの要求に応じて保存し、再開時に復元できるようになっている必要がある。

X Window Systemにはデフォルトのセッションマネージャとしてxsmがある。他のセッションマネージャとしては、例えばKDEのデフォルトのセッションマネージャであるksmserverなどがある。

 Xディスプレイマネージャ 

Xディスプレイマネージャは、X Window Systemのグラフィカルなログインプロンプトを表示するプログラムである。それだけでなく、Xディスプレイマネージャはローカルのコンピュータ上で1つ以上のXサーバを起動し、遠隔にあるコンピュータで動作するXクライアントからのコネクション要求を受信する。ローカルなサーバはディスプレイマネージャによって起動され、相互に接続し、ログイン画面を表示する。遠隔のサーバはディスプレイマネージャとは独立して起動され、ディスプレイマネージャと接続する。この場合、ディスプレイマネージャは一種のグラフィカルなtelnetサーバのように働く。Xサーバがディスプレイマネージャと接続することでセッションが開始される。このとき、このセッションで実行されるプログラムはディスプレイマネージャの動作しているコンピュータ上で動作するが、入出力はXサーバの動作するコンピュータ上で行われる（そして、ユーザーはそのXサーバの動作する遠隔のコンピュータを使っている）。

XDMはX Window Systemの基本のディスプレイマネージャである。他のディスプレイマネージャとしては、GNOME ディスプレイマネージャー (GDM)、KDEディスプレイマネージャ (KDM) などがある。

 ユーザインタフェースの要素 
初期のX向けウィジェット・ツールキットとしては、Xaw (Athena Widget Set)、OLIT (OPEN LOOK Instrinsics Toolkit)、XView、Motif、Tkなどがある。OLITとXViewはサン・マイクロシステムズのかつてのデスクトップ環境 OpenWindows のベースとなっている。

Motifは Common Desktop Environment (CDE) のベースとなっており、Solaris、AIX、HP-UXといった商用UNIXのデスクトップ環境として使われていた。

比較的新しいツールキットとしては、Qt（KDE）、GTK（GNOME）、wxWidgets、FLTKなどがある。

 拡張 
Xサーバは単純だが拡張可能となるよう設計された。そのため、プロトコルに対して様々な機能拡張がなされている。

プロトコルレベルでは、拡張は要求/イベント/エラーのパケットの新たな型として認識される。クライアントのアプリケーションは拡張ライブラリを通して拡張機能にアクセスできる。Xサーバ実装への拡張の追加は、サーバがモジュール設計になっていないため、難しいと言われている。XCBプロジェクトの長期目標の一つとして、XMLによるプロトコル記述から拡張機能のクライアント側とサーバ側のコードを自動生成するというものがある。

以下は、これまで開発された拡張の一部である。

 拡張名 内容と備考 Composite ウィンドウの階層全体を画面外で描画できるようにする。半透明なウィンドウやウィンドウに影を付ける場合に必要。 Damage ウィンドウの変更された部分の描画で、なるべく帯域幅を消費しないようにする。 XFixes いくつかのプロトコルの変更 Extended-Visual-Information (EvIE) クライアントが全てのキーボード/マウス・イベントをインターセプトできるようにする。 Distributed Multihead (DMX) DMX Xサーバとの通信 X-Video Motion Compensation (XvMC) GPUが動画処理をサポートしている場合、GPUにオフロードする。 GLX OpenGLを使った描画のサポート XRender ハードウェアを使ったアルファブレンディングによる画像合成の高速化 Resize and Rotate (XRandR) 画面の解像度、方向などを動的に変更する。 Xinerama デスクトップを複数のディスプレイ機器にまたがった状態にする。 Display Power Management Signaling (DPMS) ディスプレイ機器の節電モード制御 XPRINT X keyboard extension キーボードのキー配置制御の拡張 DOUBLE-BUFFER ちらつきのないアニメーション RECORD MIT-SHM 共有メモリを使った性能向上 SYNC Xサーバとクライアントの時刻同期をサポート。 XTEST XInputExtension グラフィックタブレットなどの入力デバイスサポート BIG-REQUESTS 262140バイト以上の長さの要求を可能にする。 XC-MISC X video extension ハードウェアによるビデオオーバーレイとビデオ再生時の拡大縮小をサポート。Xv と略記されることもある。 Shape 矩形以外のウィンドウや部分的に透明なウィンドウのサポート DEC-XTRAP MIT-SCREEN-SAVER MIT-SUNDRY-NONSTANDARD SECURITY TOG-CUP カラーマップ利用ポリシーの提供 X-Resource XC-APPGROUP XFree86-Bigfont XFree86-DGA ダイレクト・リニア・フレームバッファへのアクセス (Direct Graphics Access) XFree86-Misc XFree86-VidModeExtension モードラインとガンマの動的設定

 廃止された拡張 

 拡張名 内容と備考 Low Bandwidth X (LBX) Secure Shellのコネクションを利用したトンネリングの方が性能がよいため、廃れた。 PHIGS Extension to X (PEX) PHIGSによる3次元グラフィックスAPIサポート。OpenGLに対応したGLXの方がよく使われている。 XImage Extension MIT-SHMが代替として使われている。