X Window System コアプロトコル

X Window System コアプロトコル（英: X Window System core protocol）とは、X Window Systemの基本プロトコルである。X Window System はビットマップ・ディスプレイのためのネットワーク型ウィンドウシステムであり、UNIX系などのオペレーティングシステムのグラフィカルユーザインタフェースの基盤となっている。X Window System はクライアントサーバモデルに基づき、サーバがディスプレイやキーボード/マウスといった入出力ハードウェアを制御する。アプリケーションプログラムは全てクライアントとして動作し、サーバ経由でユーザーや他のクライアントとやり取りする。このやり取りを規定するのが X Window System コアプロトコルである。他にも X Window System に関連したプロトコルはあるが、それらには X Window System コアプロトコル上に構築されたものと全く別個のものがある。Xコアプロトコルと呼ばれることもある。
X Window System コアプロトコルでは、パケットは要求（Request）、応答（Reply）、イベント（Event）、エラー（Error）の4種類しかなく、非同期にネットワーク上を転送される。要求パケットはクライアントからサーバに何らかの操作を依頼し（例えば、新たなウィンドウの生成）、結果としてデータを返してもらうものである。応答パケットは、そのようなデータをサーバからクライアントに返すためにある。イベントパケットは、サーバからクライアントにユーザーの操作やその他の事象の発生を知らせる。エラーパケットは、サーバからクライアントに対して、要求パケットの内容を処理しているときにエラーが発生したことを知らせる。要求パケットによって、応答パケット、イベントパケット、エラーパケットが生成される可能性がある。しかし、それ以外ではプロトコル上はパケットの送受信の順序は指定されていない。コアプロトコルへの拡張がいくつか存在し、それぞれに固有の要求/応答/イベント/エラーパケットが定義されている。
X は1984年、マサチューセッツ工科大学（MIT）で生まれた（2006年現在のリリース X11 は 1987年9月に登場）。設計者 Bob Scheifler と Jim Gettys は設計にあたっての原則として、コアプロトコルは「機構を生成するものであって、ポリシーを生成するものではない」とした。結果として、コアプロトコルにはクライアント間やクライアントとユーザー間のやり取りが具体的には示されていない。これらのやり取りに関する規定は別途行う必要があり、ICCCM や freedesktop.org の仕様が作成された。また、特定のウィジェット・ツールキットを使うことで必然的にやり取りが規定される。

ウィンドウ

一般にグラフィカルユーザインタフェースで「ウィンドウ」と呼ぶものを、X Window System では「トップレベルウィンドウ」と呼ぶ。いわゆる「親ウィンドウ」の「サブウィンドウ」と呼ばれるウィンドウ内ウィンドウも「ウィンドウ」と呼ぶ。ボタン、メニュー、アイコンなどのグラフィカルな構成要素は、実際にはサブウィンドウとして認識されている。
クライアントはウィンドウ生成を要求できる。より正確に言えば、既存のウィンドウのサブウィンドウの生成を要求できる。結果として、クライアントが生成するウィンドウ群は一種の木（階層）を形成する。この木の根をルートウィンドウと呼び、サーバが起動したときに自動的に生成される特殊なウィンドウである。他の全ウィンドウはルートウィンドウの直接的または間接的なサブウィンドウである。トップレベルウィンドウは、ルートウィンドウの直接のサブウィンドウである。見た目で言えば、ルートウィンドウは画面全体と同じ大きさであり、他のウィンドウ群の一番背後にある。
ウィンドウの内容は常に保持されるとは限らない。特に、ウィンドウが移動されたり、リサイズされたり、他のウィンドウの影に隠れたり、完全に（あるいは部分的に）見えなくなったりすると、ウィンドウの内容は破壊される可能性がある。Xサーバが、ウィンドウの内容の「バッキングストア」を管理していない場合はウィンドウの内容は失われる。クライアントはバッキングストアの保持を要求することができるが、サーバが必ずそうするという保証はない。従って、クライアントはバッキングストアを当てにしてはいけない。見える状態のウィンドウの中身が不明の場合、そのクライアントに対してイベントが送られ、内容の再描画が行われる。
ウィンドウには、一連の「属性」があり、ウィンドウの大きさと位置、背景画像、バッキングストア要否などの情報が格納されている。これら属性を調べたり、変更したりする要求パケットが存在する。
ウィンドウは InputOutput と InputOnly のどちらかである。画面に表示され、何らかの内容が描画されるものは前者である。後者のウィンドウは画面には現れず、入力を受け取るためだけに存在する。
ウィンドウの外枠とタイトルバー（ボタンも含むことがある）はウィンドウマネージャが作成するものであって、そのウィンドウを作成したクライアントは関知しない。ウィンドウマネージャは、それらの部分についての入力も受け取り、ウィンドウのリサイズなどに対応する。クライアントは一般にウィンドウマネージャによるウィンドウの変化は関知しない。しかし、最近のウィンドウマネージャの多くはトップレベルウィンドウの親ウィンドウをルートウィンドウ以外に設定変更することが多く、この変更をクライアントが無視することはできない。Xコアプロトコルの観点では、ウィンドウマネージャもクライアントの一種であり、他のアプリケーションと何ら違いはない。
ウィンドウに関する情報は xwininfo プログラムを実行することで得られる。引数に -tree を付与すると、ウィンドウの親子関係をツリー形式で表示し、それぞれの識別子や位置データも表示する。

ピクスマップと描画領域

ピクスマップとは、描画に使われるメモリ領域である。ピクスマップの内容がそのままウィンドウとして表示されるわけではなく、ピクスマップの内容（の一部）がウィンドウに転送されたり、逆にウィンドウからピクスマップに内容が転送されたりする。これによりダブルバッファリングなどの技法が可能となっている。ウィンドウ上で可能なグラフィカルな操作の多くは、ピクスマップ上でも可能である。
ウィンドウとピクスマップを総称して「描画領域; drawables」と呼ぶ。描画領域の内容データはサーバ側に置かれる。クライアントはサーバに対して描画領域の内容を転送してもらうこともできるし、逆に内容をサーバに送ることもできる。

グラフィックコンテキストとフォント

クライアントはいくつかのグラフィック操作を要求できる。例えば、領域の生成、領域のコピー、点/直線/多角形/テキストの描画などである。これらの操作は全て、任意の描画領域（ウィンドウもピクスマップも）に対して実施可能である。
グラフィック操作要求の多くは、「グラフィックコンテキスト」を含む。これは、グラフィック操作のパラメータを格納した構造体である。グラフィックコンテキストには、前景色、背景色、テキストのフォント、その他のグラフィックパラメータが含まれる。グラフィック操作を要求する場合、クライアントはグラフィックコンテキストを作成しなければならない。グラフィックコンテキストの全パラメータがグラフィック操作に影響するわけではない。例えば、直線描画要求では、フォント指定は影響しない。
Xコアプロトコルでは、サーバ側のフォントの使用を扱う。その場合のフォントはファイルとして格納されており、サーバはローカルなファイルシステムに直接アクセスする場合もあるし、「フォントサーバ」と呼ばれるプログラムにネットワーク経由でアクセスする場合もある。クライアントは、そのサーバで利用可能なフォント一覧を要求でき、フォントのロード（まだロードされていない場合）やアンロード（他のクライアントが使っていない場合）を要求できる。クライアントはフォントについての汎用情報を要求でき、特定のテキストを特定のフォントで描画するときに必要なスペースを問い合わせることもできる。
フォント名はXコアプロトコルのレベルでは任意の文字列に過ぎない。X Logical Font Description Conventions により、フォントの属性に対応した命名規則が規定されている。この命名規則では、オプション的な属性も考慮するようになっている。
xlsfonts プログラムは、サーバが格納しているフォントの一覧を表示する。xfontsel プログラムは、フォントの字体を表示し、フォント名をコピー・アンド・ペーストで別のウィンドウに入力できる。
近年では、クライアント側でフォントを用意することが多くなり、サーバ側フォントの使用が廃れつつある。クライアント側フォントは、クライアント側でレンダリングするもので、XftやCairoライブラリを使ったり、XRender拡張を使ったりする。Xコアプロトコルにはクライアント側フォントに関する規定は存在しない。

イベント

イベントとは、サーバからクライアントに送信されるパケットであり、クライアントが興味を持ちそうな事象が発生したことを通知するのに使われる。例えば、ユーザがキーを押下したり、マウスのボタンをクリックしたなどの事象である。イベントはユーザの入力だけではない。例えば、新たなサブウィンドウが生成された場合などにもイベントパケットが送信される。
イベントは常にいずれかのウィンドウに関連付けられている。例えば、マウスカーソルがあるウィンドウ上にあるときにクリックした場合、そのイベントはそのウィンドウと関連付けられる。イベントパケットにはそのウィンドウの識別子も含まれる。
クライアントはサーバに対してイベントパケットを他のクライアントに送るよう要求できる。これはクライアント間の通信に利用される。例えばマウスクリックで選択されたテキストをクライアントが要求する場合に、そのようなイベントが使われる。そのイベントは、その選択を保持しているウィンドウを制御しているクライアントに送られる。
Expose イベントは、ウィンドウの一部の内容が破壊された領域が画面上見えるようになったとき送信される。ウィンドウの内容はいくつかの条件が重なると破壊される。例えば、ウィンドウが別のウィンドウに隠され、サーバがバッキングストアを保持していなかった場合などである。サーバが Expose をクライアントに送信すると、クライアントはその部分を再描画しなければならない。
多くのイベントは、クライアントがそれについて興味があることを事前に表明していないと送信されない。これは、クライアントが必ずしも全てのイベントを必要としないためである。例えば、キーボード入力は受け付けるが、マウス関連のイベントは受け付けないといった状況が考えられる。イベントには、クライアントが明示的に要求していなくても必ず送信されるものもある。
クライアントは、ウィンドウの属性としてどのイベントを受け付けるかを設定できる。例えば、Expose イベントはウィンドウの再描画が必要な場合に送られるが、クライアント側でこれを受け付けない状態にすることもできる。これは、ウィンドウのイベントマスク属性を適切に設定することでなされる。
複数のクライアントが同じウィンドウのイベントを要求することもできる。その場合クライアント毎に異なるイベントマスクを設定できる。例えば、あるクライアントはキーボードのイベントだけを受け付け、別のクライアントがマウスのイベントだけを受け付けるといったことが可能である。サーバは各ウィンドウについてクライアント毎のイベントマスクを保持できるようになっている。ただし、ウィンドウ毎に1つのクライアントにしか送信できないイベントも存在する（特にマウスクリックについてのイベントやウィンドウ管理に関連した変化を知らせるイベント）。
xev プログラムは、ウィンドウに対応したイベントを表示する。特に xev -id WID とすれば、指定した識別子 WID に関わるイベントを全て表示する。

アトム

アトム（Atom）とは、文字列を表す32ビット整数である。文字列が任意の長さであるのに対してアトムは常に32ビット整数であり、プロトコル設計者は文字列を短い固定サイズで表すためにアトムを導入した。アトムは短いため、同じ文字列をパケットとして何度も送信するような場合に利用される。これによってネットワークの利用効率が向上する。アトムはまた、イベントパケットのような固定サイズのパケットで利用される。
正確には、アトムはサーバが保持する文字列の識別子である。リソース（ウィンドウやピクスマップ）の識別子に似ているが、2つの点で異なる。まず第一に、アトムの識別子はサーバが設定するのであって、クライアントは指定できない。つまり、クライアントが新たなアトム生成を要求するときは、サーバに文字列を送信するだけであり、識別子は指定しない。サーバはその文字列に識別子を割り当て、クライアントへの応答パケットでそれを返す。第二に、アトムは特定のクライアントとは関連しない。アトムは、生成されるとクライアントが終了しても存続し、サーバが終了するまで残る（リソースのデフォルトの振る舞いはそれとは異なる）。
アトムは識別子であるから、一意である。しかし、アトムとリソースの識別子は同じになることがある。アトムに対応した文字列は「アトム名; atom name」と呼ばれる。アトム名は生成後に変更することはできないし、二つのアトムが同じアトム名となることもない。従って、アトム名はアトムを指すのにも使える。「アトム ABCD」と言った場合、正確には「文字列 ABCD に対応するアトム」あるいは「名前が ABCD のアトム」を意味する。クライアントは、新たなアトム生成を要求することもできるし、ある文字列のアトム（識別子）を要求することもできる（これらは同じ意味である）。事前定義されたアトムもある（特定の識別子と文字列でサーバが生成する）。
アトムは様々な用途で使われ、主に同じサーバに接続した複数のクライアント間の通信でよく使われる。特に、後述するウィンドウのプロパティに関連して使われる。
サーバ内に保持されている全アトムの一覧は xlsatoms プログラムを使って表示できる。特に、このプログラムはそれぞれのアトム（識別番号）とその名前（対応する文字列）を表示できる。

プロパティ

各ウィンドウには、事前定義された属性群とプロパティ群があり、サーバに全て格納され、クライアントからは適当な要求でアクセスできる。属性はウィンドウに関するデータであり、サイズ、位置、背景色などがある。プロパティはウィンドウにアタッチされた任意のデータである。属性とは対照的に、プロパティはXコアプロトコルのレベルでは何の意味もない。クライアントはウィンドウのプロパティとして任意のデータを格納できる。
プロパティには、名前、データ型、値がある。プロパティは命令型プログラミングにおける変数に似ていて、クライアントが名前とデータ型を指定して生成でき、任意の値を格納できる。プロパティはウィンドウに対応しているため、同じプロパティ名を複数のウィンドウそれぞれで使い、それぞれ異なる型の異なる値を格納できる。
プロパティの名前、データ型、値は全て文字列である。より正確に言えば、これらは全てアトムであり、サーバに格納されている文字列に対応していて、クライアントからはその識別子でアクセス可能である。クライアントはあるプロパティに対して、その名前を格納したアトムの識別子を使ってアクセスする。
プロパティは主にクライアント間通信に使われる。例えば、WM_NAME という名前のプロパティ（正確には、"WM_NAME" という文字列に対応したアトムをプロパティ名とするプロパティ）にはウィンドウの名前が格納される。ウィンドウマネージャは、一般にこのプロパティを読み、タイトルバーにウィンドウ名を表示する。
クライアント間通信には、ルートウィンドウのプロパティを使ったものもある。例えば、freedesktop.org のウィンドウマネージャ仕様によれば、ウィンドウマネージャは現在のアクティブウィンドウの識別子をルートウィンドウの _NET_ACTIVE_WINDOW というプロパティに格納するべきとしている。プログラムのパラメータを含むXリソースもルートウィンドウのプロパティとして格納される。そうすることで、（別のコンピュータ上で動作していても）全てのクライアントがそれらにアクセスできる。
xprop プログラムは指定されたウィンドウのプロパティ一覧を表示する。xprop -root とすれば、ルートウィンドウの各プロパティの名前、型、値を表示する。

その他

他にもXコアプロトコルには要求やイベントが存在する。まず、ウィンドウ間の親子関係に関する要求がある。クライアントは、ウィンドウの親の変更要求が可能である。また、ウィンドウの親子関係に関する情報を要求することもできる。他にセレクションに関する要求があるが、これは主に他のプロトコルで扱われる。入力フォーカスやカーソル形状についての要求もある。クライアントは、特定のリソース（ウィンドウ、ピクスマップなど）の所有者を終了させる要求もでき、サーバはそのコネクションを終了させる。また、クライアントはサーバにNOP要求を送信することもできる。

拡張

X Window System コアプロトコルは、拡張性を考慮して設計された。Xコアプロトコルには、利用可能な拡張や、拡張の要求/応答/イベント/エラーパケットをどう作ればよいかを問い合わせる機構を備えている。
特に、特定の拡張に対応したデータについて利用可能な拡張の一覧を要求できる。拡張のパケットは、Xコアプロトコルのパケットとよく似ている。Xコアプロトコルでは、要求/応答/イベント/エラーパケット内にそのパケットのタイプを示す整数が含まれている。例えば、新たなウィンドウの生成要求は 1 である。この整数の一部範囲が拡張用に予約されている。

認可

クライアントがサーバとのコネクションを確立しようとした時、サーバのとりうる応答としては、受理するか、拒否するか、認証を要求するかのいずれかである。認証要求には、使用する認証手法の名称が含まれる。Xコアプロトコルでは認証プロセスは規定されておらず、使っている認証の種類に依存する。さもなくば、サーバは単に受理パケットか拒否パケットを送るだけである。
通常のクライアントとサーバのやり取りで認証に関わる要求は「ホストによるアクセス制御; host-based access method」だけである。クライアントは、この認証手法を有効にする要求ができ、接続を認可されているホスト（クライアント）の一覧を読んだり変更したりできる。一般のアプリケーションはこれらの要求を使うことはない。これらを使うプログラムとして xhost があり、ユーザやシェルスクリプトがアクセス可能ホスト一覧を読み書きできるようにする。ホストによるアクセス制御は、安全ではないと言われている。

X Window System コアプロトコルで指定されないこと

X Window System コアプロトコルでは、クライアント間通信は規定されておらず、ウィンドウを使ってGUIに一般的に存在する視覚的要素（ボタンやメニューなど）をどう実現するかも規定していない。GUI要素は、ウィジェット・ツールキットと呼ばれるクライアントライブラリで実装される。クライアント間通信は、ICCCM や freedesktop.org の仕様など他の標準でカバーされている。
クライアント間通信は、セレクション、カットバッファ、ドラッグ・アンド・ドロップと関係がある。これらはユーザが利用するウィンドウ間のデータ転送手法である。ウィンドウが他のプログラムに制御されている場合もあるため、データ交換のためのプロトコルは必須である。クライアント間通信はXウィンドウマネージャとも関係がある。ウィンドウマネージャはウィンドウ群の見た目を制御し、GUIとしてのルック・アンド・フィール全般を制御する。他にもクライアント間通信に関わる問題として、Xセッションマネージャが関与する部分がある。
ユーザセッションの開始方法もXコアプロトコルではカバーされていない。通常、Xディスプレイマネージャが自動的に行う。しかし、ユーザが xinit や startx プログラムを手動で起動してセッションを開始することもできる。