マルチモニターから学ぶ X11 の screen と display
この記事は個人ブログで公開した内容を再編集したものです。
この記事について
X11 アプリケーションの開発や、X11 のプロトコルに興味がある人向けに、screen や display の概念とその歴史についてまとめた記事です。
現代の X11 では、モニターが複数あっても screen_number に 0 を使います。screen は「物理モニター」と定義されているのに、実際には異なる扱いになっています。
この背景には、X11 のマルチモニター対応の興味深い歴史があります。screen という概念は元々物理モニターを指していましたが、screen 間のウィンドウ移動ができないというプロトコル上の制約を回避するため、Xinerama、RandR といった技術の登場とともに、その意味が変化してきました。
この記事では、X11 におけるマルチモニター対応の歴史を追いながら、screen と display の定義、そして現代の X11 に至るまでの技術的背景を個人的にまとめます。
X11 の screen と display とは
X11 でアプリケーションを開発していると、screen や display といった用語に出会います。これらは X11 特有の意味を持ち、直感的に理解しにくい用語です。これらを理解するのに、(Xlib - C Language X Interface) の Introduction X Window System や Glossary が特に有用でした。以下ではこれを参照します。
screen は以下のように定義されています。
A screen is a physical monitor and hardware that can be color, grayscale, or monochrome.
つまり、screen は物理的なモニターのことです。たとえば、ラップトップのモニターと外部モニターがあれば、それぞれが screen に対応します。
一方、display は以下のように定義されています。
A set of screens for a single user with one keyboard and one pointer (usually a mouse) is called a display.
つまり、display は、キーボードとマウス、そして screen をまとめたものです。普通「ディスプレイ」といったらモニターを想像すると思うので、X11 の用語としては注意が必要です。

これらの用語は、環境変数 $DISPLAY にも現れます。$DISPLAY は以下の形式です。
On POSIX-conformant systems, the display name or DISPLAY environment variable can be a string in the format:
protocol/hostname:number.screen_number
形式についてまとめると、下記の通りです。
-
protocol: プロトコルファミリー (省略可) -
hostname: ホスト名 (省略可) -
number: ディスプレイサーバー番号 -
screen_number: スクリーン番号
たとえば、$DISPLAY が :2 の場合、ローカルマシンで起動している X ディスプレイサーバー 2 番のデフォルトスクリーン (0) を意味します。
現代では、モニターが複数ある場合でも、デフォルトスクリーン (0) が使用されます (し、省略されます)。定義に従えばモニター毎に異なる番号になるはずですが、実際には 0 だけが使われることがほとんどです。
以下では、この理由を理解するために、X11 のマルチモニター対応の歴史を見ていきます。
1 Screen = 1 モニターの時代
昔の X11 では、モニターが複数ある場合、それらをそれぞれの screen として管理していました。たとえば、:0.0 (ラップトップのモニター) と :0.1 (外部モニター) という具合です。
この時代の大きな問題は、screen 間でウィンドウを移動できなかったことです。各 screen が独自の root window を持つため、ReparentWindow リクエストで以下の制約がありました。
A Match error is generated if: The new parent is not on the same screen as the old parent.
つまり、screen 間でウィンドウを移動することはプロトコルレベルで禁止されていました。

Xinerama による screen の仮想化
この不便な状況を解決するために、Xinerama が登場しました。1990年代中盤〜後半のことです。
Xinerama がやったことはシンプルで、複数の物理モニターを1つの仮想スクリーンとして見せかける、というものです。たとえば、1920x1080 のモニター 2 台を横に並べていたとして、X サーバーは「3840x1080 の 1 つのスクリーンがあります」とクライアントに伝えます。
これにより、クライアントからは root window が 1 つしかないように見え、単一のウィンドウマネージャーが screen 間をまたいでウィンドウを管理できるようになります。

ただし、Xinerama には問題がありました。設定が静的で、物理モニターを抜き差しするたびに X サーバーの設定を書きかえて再起動しないといけませんでした。
RandR による動的な設定変更
この問題を解決したのが RandR 1.2 です。
RandR は元々、画面のリサイズと回転のために開発されました。Version 1.2 でマルチモニター対応が追加され、Xinerama と同じように、複数のモニターを 1 つのスクリーンとして扱えるようになりました。
Randr exposes the dual-head card as a single SCREEN, yet having a standard way of managing the multiple monitors.
(Multi-Monitor Desktop - freedesktop.org)
さらに、Version 1.2 では runtime configuration にも対応しました。
Also new in the X Server since X11R7.2 is the 1.2 version of the RandR
extension, which allows for runtime configuration of outputs within X Screens
and an improved static configuration system for multihead in a RandR 1.2
environment.
まとめ
この記事では、X11 の screen と display、そしてマルチモニター対応の歴史を見てきました。
screen は元々物理モニターを指していましたが、Xinerama や RandR により複数モニターを含む仮想 screen へと変化しました。これにより、screen 間のウィンドウ移動が可能になり、モニターの抜き差しにも動的に対応できるようになりました。
現代の X11 で screen_number が 0 なのは、こうした歴史的経緯によるものです。
普段何気なく抜き差しして問題なく使えているモニターの裏側で、こういう話があったと思うと興味深いです。
参考
- Xlib - C Language X Interface
- X Window System Protocol
- X11R7.3 Release Notes
- Multi-Monitor Desktop (freedesktop.org)
- Xinerama - Wikipedia
この記事が役立ったら、LIKEやコメントで教えてください!
他の技術記事や開発記録は私のブログでも公開しています。
Discussion