X サーバー


X を簡単に動かすには Kdrive X server と vncviwer + vncserver の二つの方法がある。 後者のほうが手軽だが、画面描画が多くなると紙芝居と化す。 でも Kdrive X server は結局は本物の XFree86 server に近い手間がかかるんよね。

両方とも動かしてみたが、 fbvnc + Xvnc (= vncviwer + vncserver) のほうが実用的かもしんない。キーボードが常に使えるという安心感はなにものにもかえがたく。 拡大縮小と回転が自由というのも大きい。

でもとりあえず Kdrive X server の話。 キャリブレーション周り未実装なんだけど、そろそろ書いとかんと忘れる ...。

前史

iPAQ や SL5x00 用の xserver (Xipaq, Xfbdev) てのがあるので、 サーバの make を避けようと思えば避けられないこともない。

SL5x00 用はそもそもタッチパネル構造体が違うので論外として、 iPAQ 用のを試すことになる。タッチパネルのデバイス名が iPAQ と A300 では違うが、 /dev/ts も見てるのでタッチパネル的には動く。

... が、ioctl(FBIOPUT_VSCREENINFO) がひっかかる。 A300 のこの ioctl は引き数の制限がきつく、Xipaq の呼び出しでエラーを返すためだ。 A300 のカーネルの返り値のほうが正しく、 truecolor で colormap をもたない framebuffer 相手に colormap 書き換え許可を求める Xipaq のほうが間違ってるんだが、サーバ書き換えるよりカーネル書き換えるほうがラクなので ためしにカーネル側の条件を緩めると動いた。

--- drivers/video/cotulla_fb.c~ Wed Aug 28 12:24:23 2002
+++ drivers/video/cotulla_fb.c  Wed Feb 28 21:54:50 2003
@@ -197,3 +197,3 @@
        if (var->nonstd         != 0                     )      goto ERR;
-       if (var->activate       != FB_ACTIVATE_NOW       )      goto ERR;
+       // if (var->activate    != FB_ACTIVATE_NOW       )      goto ERR;
        if (var->pixclock       != 0                     )      goto ERR;

ただ、これだけでは keycode がズタボロなので結局は build することになる。 本家 XFree86 から拾ってきて build しなおすんだが、 ... 4.3.0 に上がったばっかで今は cvs 重そうやねぇ。

Build の準備

Xipaq のhowtos -- Building X for Handheldsや、 ぴろさん家の SL-C700用X11のコンパイルの方法 を参考に。

すでにクロスコンパイラ一式はもってるわけで、異なるコンパイラセットをまたもつのは避けたい。 まず、"arm-linux-" を外したセットをつくる。外さないほうも要るのと、 万が一にもパスを通したくないので別にディレクトリを掘った。

# cd /usr/local/Embedix/tools
# mkdir bin2
# cd bin
# for name in * ; do
    pushd ../bin2
    ln -sf ../bin/$name $name  
    ln -sf ../bin/$name ${name##arm-linux-} 
    popd
  done
# cd ../bin2
# ln -sf ../bin/arm-linux-gcc cc
handhelds.org 読みつつhost.defxc/config/cf/ に置く。 Xipaq server でなく Xfbdev を作成しているが、 両者の違いは機能的には pcmcia のビデオドライバを含むかどうかである。 トラブルのネタにしかならんよーなものは外すにかぎる。

さらにパスが適切に通るよう cross.def を書き換える。こんな感じ

Xfbdev の Build

% cd xc
% make World CROSSCOMPILEDIR=/usr/local/Embedix/tools/bin2
最初の一回は xc/ で make World するが、 次回からは xc/programs/Xserver/ で make all するのでいい ── というか、 make World すると rm **/*.o されてしまって ターンアラウンドタイムが冗談になんないので、かならず make all にする。

さて。手を入れることなしには動いてくれない:

フレームバッファ回り (xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c)。
上述したやつ。priv->var.activate = FB_ACTIVATE_NOW|FB_CHANGE_CMAP_VBL; してるとこを priv->var.activate = FB_ACTIVATE_NOW; に。
タッチパネル回り (xc/programs/Xserver/hw/kdrive/linux/ts.c)。
デバイス構造体が違う。っつーか、そもそも linux/h3600_ts.h がないから make 途中で止まる。てきとーに TS_EVENT を設定しとく。
キーボード回り (xc/programs/Xserver/hw/kdrive/linux/keyboard.c)。
A300 は K_MEDIUMRAW の実装をもたないので、そのままだとボタンの keycode がみんな 0 になる。K_RAW にしておく。
ふつーの linux の RAW モードは複数バイトの scancode がありえるので MEDIUMRAW (各 keycode が 1 バイト) と置き換えられないが、 A300 の scancode は必ず 1 バイトなので MEDIUMRAW 互換である。
キャリブレーション回り。
カーネル内のデフォルトキャリブレーションだと座標系が上下逆になる。 X サーバ内は透過になってるので カーネル内のキャリブレーションマトリクスに面倒みさせるか、 /dev/sharp_ts/dev/ts の間に libqte と同レベルの変換をかけるか。 ためしに fifo 挟んでみたら重負荷時にかなりマウス(ペン)が滑べったので 前者のほうがいいんだが、計算めんどくせー (カーネルのデフォルトキャリブレーションが 実は単なる透過でないことを知ってハマり中)。

とりあえずキャリブレーションを無視して作ったやつ:

Screenshots

xengine をうごかしてみた。 RandR Extension (handhelds.org 内のコピー/pdf) のおかげで landscape に動かすこともできる:
Normal; 401rpm Rotated; 160rpm

上はそれぞれ Xfbdev -schedInterval 10 -schedMax 10Xfbdev -schedInterval 10 -schedMax 10 -screen 320x240@90 として動かしたもの。

Smart Scheduler の得失

前項の screenshot では landscape は遅かった。 いちいち横倒しにするぶんだけ landscape が遅いのは当然だが、あんまり当然でもない。 "-schedInterval 10 -schedMax 10 " を外すと portrait, landscape とも 400rpm を越える:
# ./Xfbdev -screen 320x240@90
Rotate2; 402rpm

デフォルトは "-schedInterval 20 -schedMax 200" 相当である。 つまり、

くらいの意味(xc/programs/Xserver/dix/dispatch.c)な訳で、 重負荷かけるとペンの追従性はさいてーになる。 ついでに landscape のように画面描画が重いと screen update が紙芝居になる。 400rpm は越えるが、それは数字だけ。

vncviewer + Xvnc で xengine 動かしたときによく見られるマジックだが、 RandR extension は実体として vncviewer + Xvnc とほぼ同じ動作をするから、 更新ペースを落せば同じになるわけではある。

suspend/resume

Qt/Embedded 内で面倒みてたパワースイッチによる suspend/resume だが、X は何にもしてくれない。

つーても、

# echo 1 > /proc/sys/pm/suspend
程度で suspend してくれる。起きるほうは BIOS が面倒みてるのでパワースイッチでおっけ。

追記

/etc/pointercal を読んでキャリブレーションをとるようにしたもの。 一回 Qt/E でキャリブレーションをとっておけば X でも有効ってことで。

コードベースも 4.3.0 になっている。

Xfbdev を動かすには freetype 2.1.1+ の libfreetype.so も必要。

おまけな追記

gcc 3.2.3 -O3 -mcpu=xscale -mtune=xscale によって、 xengine 値は portrait で 404rpm (+1%弱)、landscape で 175rpm (+6%) になった。

やっぱこれでバス幅一杯か〜。


[日記へ] [目次へ]