Hatena::ブログ(Diary)

技術日記@kiwanami

2011-05-14

LinuxでiPadをセカンドモニターにする

はじめに

iPad」と呼ばれるディスプレイ装置はすごいデバイスです。タッチパネル付きの9.7インチIPS液晶で、解像度はXGA、しかも無線でマシンと接続できるだけでなく、わずか700g弱という重さながら、バッテリーを内蔵していて10時間以上の連続動作が可能です。

AirDisplayというソフトを使うと、簡単にMacWindowsiPadをセカンドディスプレイにすることが出来ます。

残念ながら、このiPadLinuxでセカンドディスプレイとして使う情報はありません。いろいろ検索してみましたが、やっている人は誰もいないようです。

そこでiPadLinuxでもセカンドモニターにしてみる方法を探してみました。結果としては一応セカンドモニターとして使えなくもないことが分かりました。

達成目標

ここでの「セカンドモニター」の定義ですが、iPadのAirDisplayと同じような動作を考えています。具体的には以下のようです。

前提

とりあえずは現在の自分のマシンで動くことです。

すべてVNCのポートは5901を仮定しています。

今回試した方法は一般的なハックですので、おそらくXに詳しい人なら他の環境でも容易に実現できると思います。

あと、VNCで画面を転送していますので画面の動きがすごく遅いです。動画とかは全く無理です。シェルの操作がまあまあ我慢できるぐらいの速度です。(追記 2011/05/15)

方法1: XINERAMA + x11vnc

概要

まずはXのディスプレイ拡張技術:XINERAMAを使ってを素直に拡張する方法です。dummyドライバで見えない仮想スクリーンを作って、XINERAMAで画面をつなげます。仮想スクリーンはVNC(x11vnc)でiPad側に表示させます。

XINERAMA + x11vnc

  • 良いところ
    • すべての機能要件を満たす
  • 問題
    • Xの設定変更にはXの再起動が必要
    • xrandr, compiz が使えない
インストール

必要なもの:

  • xserver-xorg-video-dummy
  • x11vnc

x11vnc は synaptic や apt-get で入ります。

問題は xserver-xorg-video-dummy です。これをパッケージから入れようとすると、現在入っている xserver-xorg-video〜 関係が軒並み削除されようとしてしまいます。ディスプレイのない環境で使うものというパッケージとして定義されているのかも知れません。さらにコードにバグも残っていますので、以下のように手動で修正して入れる必要があります。(XorgのログにWindowTableが無いといったエラーが出る場合はこの修正が必要です)

$ sudo apt-get build-dep xserver-xorg-video-dummy
$ apt-get source xserver-xorg-video-dummy
$ cd xserver-xorg-video-dummy-0.3.3
$ vi src/dummy_driver.c
  (下の修正箇所を参照)
$ dpkg-buildpackage -rfakeroot -uc -b
$ sudo cp debian/tmp/usr/lib/xorg/modules/drivers/dummy_drv.so /usr/lib/xorg/modules/drivers/dummy_drv.so

(修正箇所)

$ diff xf86-video-dummy-0.3.3/src/dummy_driver.c mod/src/dummy_driver.c
782c782
<         pWinRoot = WindowTable[DUMMYScrn->pScreen->myNum];
---
>         pWinRoot = DUMMYScrn->pScreen->root;
Xorgの設定など

最近は xorg.conf を書かないようになってきたので、昔よりもXの設定は難しくなってきました。 xorg.conf が何か分からない人はこの方法はあきらめた方が良いと思います。分かる人が分かるように簡単に書きます。

  • xorg.conf 生成
    • Ctrl+Alt+F1 から kill でXを落とす
    • sudo X -configure で現在の設定の xorg.conf を生成する
    • できた xorg.conf をひな形として取っておく
  • xorg.conf 書き換え
    • (下の設定例を参照)
    • Monitor, Screen, Device を作る
    • xinerama を有効にする
    • ServerLayoutで相対位置設定
    • /etc/x11/xorg.conf に置く

xorg.confの内容(抜粋):

Section "ServerLayout"
	Identifier     "X.org Configured"
	Screen      0  "Screen0" 0 0
	Screen      1  "Screen1" LeftOf "Screen0" # 相対位置を指定
	InputDevice    "Mouse0" "CorePointer"
	InputDevice    "Keyboard0" "CoreKeyboard"
EndSection

Section "ServerFlags" 
    Option         "Xinerama" "1" 
EndSection

#(中略:ここに入力デバイスやScreen0関係)

Section "Device"
        Identifier "Dummy Device"
        Driver "dummy"
EndSection

Section "Monitor"
        Identifier   "monitor_dummy"
        ModelName    "dummy"
        HorizSync    10-200
        VertRefresh  20-90
        Modeline "768x1024_60.00"  65.13  768 816 896 1024  1024 1025 1028 1060  -HSync +Vsync
EndSection

Section "Screen"
        Identifier "Screen1"
        Device "Dummy Device"
        DefaultDepth 24
        SubSection "Display"
                Depth      24
#               Modes      "1024x768"       # 横置きの場合
                Modes      "768x1024_60.00" # 縦置きの場合
        EndSubSection
        Monitor      "monitor_dummy"
EndSection

設定が出来たらXを起動します。(OS再起動が楽かも)

無事起動できたら、普通にログインして以下のコマンドでディスプレイを確認します。

$ xdpyinfo -ext XINERAMA
name of display:    :0.0
version number:    11.0
vendor string:    The X.Org Foundation
vendor release number:    10900000
X.Org version: 1.9.0
 : (中略)
XINERAMA version 1.1 opcode: 147
  head #0: 1440x900 @ 768,0
  head #1: 768x1024 @ 0,0

このようにXINERAMAのセクションでheadが2つ出てくれば成功です。このとき、マウスを仮想スクリーンがある方(上の設定では左側)の画面端に持って行くと、見えない画面にマウスが移動します。

もし、Xの起動に失敗した場合(画面が真っ暗なままなど)は、コンソールやsshログインしてXのログ(/var/log/xorg.0.log)を確認して、xorg.confの書き換えを行います。元に戻したい場合は xorg.conf を消して再起動するだけです。

VNCで接続

仮想スクリーンが準備できたらx11vncで見えない画面をVNCでアクセスできるようにします。以下のコマンドを入力します。(とりあえずパスワード無しにしていますので、実用時はパスワードを設定するか、sshトンネルなどでセキュリティを確保しておく必要があります。)

$ x11vnc -display :0 -rfbport 5901 -nopw -clip xinerama1

起動できたら、とりあえずは本体側でvncviewerで表示できるか確認しておきます。うまくいけばディスプレイの端から消えたマウスポインターは、VNC側の画面に表示されるはずです。

ここまでくれば、あとはiPadからVNCでアクセスするだけです。

完成風景

感想など

導入が大変ですが、ディスプレイ間でウインドウが移動できますので動作としては理想的です。

しかしながらXを再起動しなければならないため、iPadをセカンドディスプレイで使いたいような出先ではあんまりうれしくないです。また、XINERAMA を使うと compiz や randr が無効になってしまうのも個人的には残念です。というか、XINERAMA は開発終了なので出来れば依存したくありません。

理論上は XINERAMA 使わずにスクリーンを2つ作る方法もいけるはずなのですが、現時点の Xorg の実装では randr 対応・非対応の Device が混在するとXが落ちるようです。 Xorg 本体の randr 側が改善するか、 dummy を randr 対応するかになると思います。おそらく、 dummy 側が randr 対応するとX再起動無しでいけるようになるのではないかなと思っていますが、まだちょっとよく分かりません。誰か作ってくれるといいですね。

とにかく、 dummy ドライバは情報が少なかったので苦労しました。

参考URL

方法2: vnc4server+x2vnc

概要

Xorg上の仕組みで頑張る方法はあきらめて、素直にVNCで拡張する方法を考えてみました。

この方法はVNCサーバーで新規にXの画面を作り、そこをVNCiPadで表示させる方法です。ウインドウディスプレイ間を移動できませんが、マウスキーボードはx2vncで移動させることが出来ます。

vnc4server + x2vnc

インストール

必要なもの:

  • vnc4server
  • x2vnc

全部 synaptic, apt-get で入ります。

基本的な設定

まず、vnc4serverを起動します。初回はパスワードを設定が必要です。

$ vnc4server :1 -geometry 768x1024 -alwaysshared

ちなみに vnc4server の終了は以下のようです。動かしたサーバーは停止させるまでずっと裏で動いています。

$ vnc4server -kill :1

次に、ディスプレイの端とVNCの画面をつなげるためにx2vncを起動します。下の場合はディスプレイの左側がVNC画面と繋がります。

$ x2vnc -shared -west localhost:1

ここでもvncviewerで動作確認をしてみてください。

問題なければiPad側からVNCで接続してみます。うまく画面が表示されれば成功です。

快適化

マウスキーボードが使えるのはいいのですが、vnc4serverがデフォルトで用意してくれる xstartup だとターミナルが一つ表示されるだけで少し使いづらいです。そこで、使いやすくカスタマイズします。

以下に自分で使っている xstartup ファイルを示します。背景を真っ白にして、VNC内でもATOKを使えるようにして、あとは狭い画面を有効に活用できるようにタイル型ウインドウマネージャーのxmonadを導入しました。

$ cat ~/.vnc/xstartup
#!/bin/sh
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid white
/opt/atokx3/bin/atokx3start.sh
vncconfig -iconic &
gnome-terminal&
exec xmonad

xmonadでは、dmenuを入れただけで特にあまりカスタマイズはしていません。

注意点

この方法ではメインのディスプレイが「:0」、VNC側が「:1」になります。基本的に各ディスプレイのX環境は独立していて、アプリケーションは起動させたディスプレイで表示され、起動後のウインドウの移動は出来ません。

Xに慣れた人なら分かると思いますが、DISPLAY変数アプリケーション引数などで表示するディスプレイを選ぶことが出来ます。

まれにGNOMEアプリのテーマが適用されなくなるなど、多少混乱があるようです。

感想など

個人的にはこの方法を使っています。メインの環境に全く影響が無く、セカンドディスプレイ内の通常の操作だけでなく日本語入力も問題ありません。

ウインドウの移動が出来ませんが、Twitterやログ表示のような軽いアプリであれば全く問題ありません。

方法3: x11vncの特定ウインドウ表示

概要

最後はおまけのような方法です。

x11vncで指定したウインドウVNCiPadに表示させるだけです。ほとんど操作は出来ませんが、iPadで表示したいウインドウが今そこにある場合には手軽で便利かも知れません。

x11vncによる特定ウインドウ表示

導入方法

必要なものは x11vnc のみです。synaptic, apt-get で入ります。

表示したいと思ったところで以下のコマンドを入力します。「-id pick」がポイントです。

$ x11vnc -xwarppointer -nopw -rfbport 5901 -nocursorpos -nocursor -id pick

そのあと、表示したいウインドウ内部でクリックします。

あとはiPad側からVNCで接続してみます。うまく画面が表示されれば成功です。

注意点

以下のような操作ができません。大抵 x11vnc が落ちるか、調子が悪くなります。

また、指定したウインドウでないもの(そのウインドウから起動されたメニュー、ポップアップダイアログなども)も表示できません。

上のような理由から、おそらくタイル型ウインドウマネージャーとは相性が悪いと思います。

感想

ログや Twitter の TL、R や Gnuplotプロット画面、 LaTeX 編集時やWeb開発時の表示確認などの、ちらっと見るだけで良いものには便利です。また、ポート番号を変えれば方法1,2とも同居できます。

しかしながら、思わず最小化したりしてしまうとVNCの更新が止まってしまったりするため、個人的にはあまり使っていません。

まとめ

以上、いろいろ試してみました。方法2の vnc4server を使う方法が楽で良いと思います。

将来 xrandr 対応 dummy ドライバが出来て、自由にウインドウが移動できるようになると良いなと思っています。

他にも良い方法がありましたら是非教えてください。


各地のドキュメントやXのソースを読みながら、さらに Ubuntu 11.04 で Wayland がやってきたりするのを見て、まだまだディスプレイ関係は進化が続いて大変だなと思いました。