« ^ »
[WIP]

X11と向き合う

所要時間: 約 6分

X Window Sysmte なんてもう今の時代に考える必要のないものかもしれない。そんな風に思う事のある一方で、熟知する必要はないとしても、ある程度の知識と実践を知って置くことで、できる事が増えたり、何が問題なのかという事について考える事ができるようにも思う。だから今回はX11と向き合うことにした。

XQuartz

macOS用のXサーバーの実装としてXQuartzがある。 MacOS X には以前Xがインストールされていたが、ある時期からインストールされなくなった。その代替のXサーバーとしてXQuartzが開発され続けている。

https://www.xquartz.org/

brew install --cask xquartz

macOSの場合 /opt/X11 にXがインストールされることがある。以降ではX11のコマンドを使用するため /opt/X11/bin をPATH環境変数に追加しておくと良い。Emacsではexec-pathに追加する。

X11の表示を確認

X11をインストール、Xサーバーを起動したら、次は表示できることを確認する。X11にはxeyesというコマンドが梱包されている。これはシンプルなプログラムであり、Xの表示を確認するため目が表示される。

xeyes -geometry 400x300 -display :0

https://res.cloudinary.com/symdon/image/upload/v1674895816/blog.symdon.info/1674306281/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2023-01-28_17.49.40_wna0cx.png

-geometry 800x600 で表示サイズを指定している。これは省略できる。 -display :0 ではXクラアントがXサーバーに接続する時の接続先を指定している。Xサーバーはディスプレイやスクリーンという概念があり、それぞれ複数保持できる。Xクライアントは、そのどれかを使用し表示を行う。次の形式で指定する。

[ホスト名]:ディスプレイ番号[.スクリーン番号]

ホストやスクリーン番号は省略可能であり、省略するとローカルホストのメインディスプレイが使用される。最も短かいDISPLAYの指定は :0 となる。

POSIXシステムではこの値はDISPLAY環境変数に設定される。xeyesコマンドを呼び出す際にDISPLAY環境変数を指定していれば -display :0 の部分は省略できる。

export DISPLAY=:0
Xの接続情報をDISPLAY環境変数に設定する

X11の表示を確認

X11をインストール、Xサーバーを起動し、DISPLAY環境変数を指定したら、次は表示できることを確認する。X11にはxeyesというコマンドが梱包されている。これはシンプルなプログラムであり、Xの表示を確認するため目が表示される。

xeyes

mes

xeyes -geometry 800x600 -display :0

Xlibを使用する

X11を使用する方法はいくつかある。ツールキットを用いる事の方が多いと思うが、ツールキットを開発したり、X11を直接制御したい場合、もっと階層が下の抽象度の低いものを扱う必要がある。その場合X11のライブラリであるXlibを使用することが多い1 。XlibはCで実装されている。ここではXlibを使用し、簡単なウィンドウを表示するプログラムをCで実装する。

#include <stdio.h>
#include <X11/Xlib.h>

int main () {
  Display *dis = XOpenDisplay(":0");
  Window win = XCreateSimpleWindow(dis, XDefaultRootWindow(dis),
				   100, 100, 200, 200, 4, 0, 0);
  XMapWindow(dis, win);
  XSelectInput(dis, win, KeyPressMask | ButtonPressMask | ExposureMask);
  XEvent event;
  while (1) {
    XNextEvent(dis, &event);
    printf("%d\n", event.type);
  }
  return 0;
}

私の環境のX11は /opt/X11 にインストールされているため、コンパイラがそれを読み込めるように環境変数等を調整する必要があった。

usexlib: usexlib.c
	gcc-12 -o usexlib -lX11 -I /opt/X11/include -L /opt/X11/lib usexlib.c

ビルドする。

make -f usexlib.mk
usexlibをビルドする

usexlibというバイナリファイルを生成した。これを実行する。当然だが実行する前にXを起動しておく必要がある。

./usexlib
usexlibを実行する

実行すると、何も表示しない黒い小さなウィンドウが表示される。ちなみに同様の事をしている人もいた2 3。これらを参考にした。

https://res.cloudinary.com/symdon/image/upload/v1674895687/blog.symdon.info/1674306281/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2023-01-28_17.46.59_etagwa.png

Xlibの通信の中身を確認する

先程Xlibを使用してXに小さな黒いウィンドウを表示させた。Xlibの使い方について少しだけ肌感を掴めたように思う。ただしこれでは、実際にどのようなデータがやりとりされているのか、わからないままだ。できれば通信の内容を確認したい。今回はUNIXドメインソケットを使用し通信を行っているためtcpdumpは使用できない。straceやdtrussでシステムコールを確認する方法もあるかもしれないが、直接一度受け、それを受け流すプロキシを書いたほうが、確認がしやすそうであった。つまり、次のような構成を想定している。


+----------------------------------------------+
|                                              |
| X Server  UNIX Domain socket file            |
| (XQuartz) bind /tmp/.X11-unix/X9             |
|                  ^                           |
+------------------|---------------------------+
                   |
                   |
           connect |
+------------------+--------------------------+
|                                             |
| Proxy    UNIX Domain socket file            |
|          bind /tmp/.X11-unix/X9             |
|                  ^                          |
+------------------|--------------------------+
                   |
           connect |
+------------------+--------------------------+
|                                             |
| X Client                                    |
| (usexlib)                                   |
|                                             |
+---------------------------------------------+

この中段の簡易プロキシをPythonで実装した。

import itertools
from socket import *

to_x_server = socket(AF_UNIX, SOCK_STREAM)
to_x_server.connect("/tmp/.X11-unix/X0")

proxy = socket(AF_UNIX, SOCK_STREAM)
proxy.bind("/tmp/.X11-unix/X9")
proxy.listen(1)

from_x_client, addr = proxy.accept()


def client_to_server():
    global from_x_client
    global to_x_server
    data = from_x_client.recv(10240)
    print(data)
    to_x_server.send(data)


def server_to_client():
    global from_x_client
    global to_x_server
    data = to_x_server.recv(10240)
    print(data)
    from_x_client.send(data)


def close():
    global from_x_client
    global to_x_server
    from_x_client.close()
    to_x_server.close()


for ii in itertools.count():
    print(f"-------------------- {ii} ----------------------------------")
    client_to_server()
    server_to_client()

実行し、内部の通信を確認すると、次のようなデータのやりとりが行われていた。

-------------------- 0 ----------------------------------
b'l\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x01\x00\x0b\x00\x00\x00\x13\x02\x8e\xa5\xb8\x00\x00\x00\x80\x00\xff\xff\x1f\x00\x00\x01\x00\x00\x14\x00\xff\xff\x01\x07\x00\x00  \x08\xff\x00\x00\x00\x00The X.Org Foundation\x01\x01 \x00\x00\x00\x00\x00\x04\x08 \x00\x00\x00\x00\x00\x08\x08 \x00\x00\x00\x00\x00\x0f\x10 \x00\x00\x00\x00\x00\x10\x10 \x00\x00\x00\x00\x00\x18  \x00\x00\x00\x00\x00   \x00\x00\x00\x00\x00\x10\x01\x00\x00!\x00\x00\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x1a\x00\xa0\x05l\x03}\x01\xe8\x00\x01\x00\x01\x00"\x00\x00\x00\x00\x00\x18\x07\x18\x00P\x00\x00\x00\x00\x00"\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xc1\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xc2\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xc3\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xc4\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xc5\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xc6\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xc7\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xc8\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xc9\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xca\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xcb\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xcc\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xcd\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xce\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xcf\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xd0\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xd1\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xd2\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xd3\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xd4\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xd5\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xd6\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xd7\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xd9\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xda\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xdb\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xdc\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xdd\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xde\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xdf\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xe1\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xe2\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xe3\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xe4\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xe5\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xe6\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xe7\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xea\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xeb\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xec\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xed\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xee\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xef\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xf0\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xf1\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xf3\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xf4\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xf5\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xf6\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xf7\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xf8\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xf9\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xfa\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xfb\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xfc\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xfd\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xfe\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x03\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x05\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x06\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x07\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x08\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\t\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\n\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x0b\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x0c\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\r\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x0e\x01\x00\x00\x04\x08\x00\x01\x00\x00\xff\x00\x00\xff\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00'
-------------------- 1 ----------------------------------
b'b\x00\x05\x00\x0c\x00\x00\x00BIG-REQUESTS'
b'\x01\x00\x01\x00\x00\x00\x00\x00\x01\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
-------------------- 2 ----------------------------------
b'\x87\x00\x01\x00'
b'\x01\x00\x02\x00\x00\x00\x00\x00\xff\xff?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
-------------------- 3 ----------------------------------
b'7\x00\x05\x00\x00\x00\x80\x00\x10\x01\x00\x00\x08\x00\x00\x00\xff\xff\xff\x00\x14\x00\x06\x00\x10\x01\x00\x00\x17\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xf5\x05'
b'\x01\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
-------------------- 4 ----------------------------------
b'b\x00\x05\x00\t\x00\x80\x00XKEYBOARD\x00\x00\x00'
b'\x01\x00\x05\x00\x00\x00\x00\x00\x01\x89\\\x8d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
-------------------- 5 ----------------------------------
b'\x89\x00\x02\x00\x01\x00\x00\x00'
b'\x01\x01\x06\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
-------------------- 6 ----------------------------------
b'\x01\x00\n\x00\x01\x00\x80\x00\x10\x01\x00\x00d\x00d\x00\xc8\x00\xc8\x00\x04\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xe1\x02\x00\x01\x00\x80\x00\x02\x00\x04\x00\x01\x00\x80\x00\x00\x08\x00\x00\x05\x80\x00\x00'
b'\x0c\x00\t\x00\x01\x00\x80\x00\x00\x00\x00\x00\xc8\x00\xb9\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\t\x00\x01\x00\x80\x00\x00\x00\xb9\x00\xb9\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
-------------------- 7 ----------------------------------

X Window System Protocol

X11の実際のデータを確認した。何となく、何かやっているという事はわかるが、どのような意味なのかはわからない。そこで、データとドキュメントを見ながら X Window System Protocol を少しだけ覗いてみようと思う。

https://www.x.org/releases/X11R7.5/doc/x11proto/proto.html

形式

リクエスト形式

リクエストの先頭1バイトはオペコード、続く2バイトはリクエストバイト長になる。このリクエストの長さには先頭のオペコードと続くリクエストバイト長も含まれる。リクエスト自体は常に4バイト単位で構成される。

1 Byte2 Byten Byte
OPCODELENGTHDATA

リクエスト全体は4バイト単位で構成されるため、実際の長さは4の倍数となるはずだ。しかしデータによっては、全体の長さが4の倍数にならない事もある。そのような場合、余った長さに意味を持たないデータを埋めたバイトを付ける事になる。いわゆるパディング用のデータを LENGTH に含めるのだろうか。ここがよくわからない。パディング用のデータは通常 \x00 を埋めるが、特にそうしなければならないわけではない4

レスポンス形式

レスポンスの先頭4バイトはレスポンスの長さ、続くバイトに各種レスポンスのデータが含まれる。

4 Byten Byte
LENGTHDATA

エラー形式

エラー形式は32バイトで構成されていて、先頭1バイトがエラーコードになっている。

1 Byten Byte
ERRORCODEDATA

イベント形式

イベント形式は32バイトで構成されているが、今回はあまり気にしない事にする。

接続

ドキュメントを読み解くのが難しく、いまいちわからないところもあるが、できる限りあきらかなところを書いていく。接続時のリクエストでは次のようなデータが送信された。

b'l\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00'

それぞれの値は次のような意味となるようだ。

offset意味備考
0lバイトオーダーの指定l=lower, B=upper
1-2\x00\x0bプロトコルメジャーバージョン11
3-4\x00\x00プロトコルマイナーバージョン0
5\x00承認プロトコル名なし
6\x00承認プロトコルデータなし
7-11\x00\x00\x00\x00パディング

その次に送信されたデータは以下のデータだ。先程のリクエスト形式の部分とかなりフォーマットが異なるんだけれど、それは何故なんだろう。本当によくわからない。 BIG-REQUESTS という文字列があるから、それがオペコードかなと思ったけれど、オペコードは先頭1バイト目のはずだから b という事になる。続く2バイトは長さで、ここでは5バイトとなっている。最後にある BIG-REQUESTS は結局パディングなんだろうか。よくわからない。

b'b\x00\x05\x00\x0c\x00\x00\x00BIG-REQUESTS'

もう少し調べたかったがこれ以上の時間をかけられないので、今回はここまでとする。また機会があれば、調査して調べたことをまとめたい。

memo

https://qiita.com/loftkun/items/37340745f211ea5d7ece

https://qiita.com/loftkun/items/37340745f211ea5d7ece

https://xjman.dsl.gr.jp/X11R6/X11/CH01.html

http://www.yam-web.net/c-programing/x11/index.html

https://hassiweb.gitlab.io/memo/docs/memo/Docker/x11gui-to-host/

https://qiita.com/nobrin/items/59b9b645e5595365c4ac

https://qiita.com/m-tmatma/items/944237003fc2d6182eca

https://www.google.com/search?q=X11+%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&sxsrf=AJOqlzWQbeMgrzy716XjhNPmAq65TRfZPQ%3A1674305990930&ei=xuHLY7S5OKGB2roP7cOu0AY&ved=0ahUKEwi0tNbu29j8AhWhgFYBHe2hC2oQ4dUDCA8&uact=5&oq=X11+%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&gs_lcp=Cgxnd3Mtd2l6LXNlcnAQAzIFCCEQoAE6BAgjECc6BAgAEEM6BQgAEIAEOgUIABCiBDoHCAAQHhCiBDoJCCEQoAEQChAqOgcIIRCgARAKSgQIQRgASgQIRhgAUABY8hJggBRoAHABeACAAeQBiAHeEZIBBjAuMTMuMZgBAKABAcABAQ&sclient=gws-wiz-serp

https://postd.cc/running-gui-apps-with-docker/

https://kazuhira-r.hatenablog.com/entry/2021/01/16/000533

https://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20120906

https://tokoik.github.io/GLFWdraft.pdf

https://www.glfw.org/