以前に 「Wayland でウィンドウを出す」で黒いウィンドウ矩形を出すところまで書いてみたものの、コードの多さの割にできることが少なくて、また多数のオブジェクトが出てきて難しく感じたので、自分の理解がてら図を使ってまとめてみました。
コンポジッタへの接続
アプリケーションはコンポジッタに接続して各情報をやりとりできるようにするところからスタートします。
接続後は wl_registry オブジェクトとそれのリスナー関数の登録を行います。このリスナーの中ではさらに必要なオブジェクトの生成が要求されることになります。
この部分を図にしてみたのが以下のようになります。
wl_compositor, wl_shm, wl_shell らのオブジェクトはリスナーの中から生成することになります。
これらのオブジェクトを使って、次の処理を行っていくので、wl_display_dispatch, wl_display_roundtrip らでメッセージのやりとりを行うように指示しています。
サーフェースの作成
wl_compositor から wl_surface オブジェクトを生成します。この wl_surface とはオフスクリーンサーフェースを意味します。画面上に表示するための位置やサイズ情報を持っています。またこの wl_surface から wl_shell_surface オブジェクトの生成&リスナー関数登録を行います。
wl_shell_surface はユーザーインターフェースを提供するためのオブジェクト、というか wl_surface のインタフェース実装です。ユーザー操作による移動やサイズ変更といったものを処理するために必要です。
これらの一連の流れを図にしてみたのが以下のようになります。
ピクセルデータの作成
描画する先を準備します。 wl_shm オブジェクトにより サーバーとクライアントで共有できるメモリ領域を準備していきます。
アプリケーション側で共有するための共有メモリを mmap などで作成します。その後 wl_shm から wl_shm_pool オブジェクトを生成します。そして wl_buffer という描画ピクセルデータを格納する先としてのバッファを生成します。
先ほどのサーフェースとこのバッファをアタッチすることで描画結果がウィンドウの中に反映させることができるようになります。
これらの流れを図にしてみると以下のようになります。
イベントループ
以上の準備が整ったら wl_display_dispatch 関数を実行して、メッセージループを回していきます。ウィンドウの内容更新については、wl_surface_damage, wl_surface_commit 関数らで領域および内容のコミットという指示にて行います。
まとめ
以上の流れがウィンドウを出すまでの流れとなっていました。低レベルであることは以前に述べたと思いますが、こうみると登場人物が多いですね。
もうしばらくは実装を続けて、ウィンドウとしての完成を目指していきたいと思います。