Qtopia-free on SLA300


SL-A300 上で qt-embedded-free 2.3.2 + qtopia free 1.5.0 を動かす。 「実装」などどえらそーに称しているが 量的に小ネタで考えるところの少ない作業なので どこに興味をもてばいいのかよーわからんということで 目処だけたてて野晒しにされていた。 だが上がってみるとさすがにソースのあるとないとでは話の次元が違って、 つつくとそれなりに面白い。

ともあれ出来上がってみると、 世界時計の起動時間は 3 秒で、「ほ〜、これが SL5x00 な人達の言う "速さ" か ...」 とゆーよーな面影はそこかしこにある。確かに速かった (ROM1.2J より速い; しかも NFS 上でである)。

アイコンのデザインっつーか、 標準のフォントが proportional になってんのが一番効いてるんだろうが、 見た目のデザインも qtopia-free のが SHARP さん謹製のより良く見える。

しかし全体の完成度に関していえば ... SL5x00 の人達ってほんとに qtopia free をそのまんま使ってんのかしらん。 移植元の素材としては相当な出来だが、これそのまんまだとハードを叩く 一部のコードが抜けて (A300 固有の話かと思ったら 5x00 用コードも入ってない) いて、 A300 へポートされた qte/qtopia に慣れた目からは未完成感がかなりあった。

ちなみに欠けているコードは qtopia 1.6.0 には含まれているものもあるようで、 1.6.0 への移行を急ぐ気分もなんとなく理解した。
個人的にゃ qtopia 1.6.0 より足まわりのほう ... qte の 2.3.4 〜 3.1.2 化のほうが主要課題だと思うが。

以下で示す qtopia free の、一部の UI は(その見た目にもかかわらず)機能しないか、 あるいは A300 などの本体付属の qtopia と挙動が違う。 Reference machine の SL5x00 でも機能してないはずで、 バグではなく仕様である :-)

てとこで、本題に入る。

QT_QWS_CUSTOM

QT_QWS_CUSTOM というフラグが qte/qtopia のソースにある。 字面的には qtopia free を元ネタからカスタマイズするときには true にするというくらいの意味のはずだが、そーなっておらず、 実質的に SL-5x00 のコードを示すのに使われている。

qtopia 1.6.0 になると QT_QWS_SL5XXX, QT_QWS_SHARP というフラグが SL-5x00 を示すようになり、 QT_QWS_CUSTOM は字義を復活させ ... ようとコード書き換えてんだろーけど 1.6.0 の時点ではまだかなり混同があって QT_QWS_SHARP 外したかわりに (例えば) QT_QWS_SLA300 付けて書き加えるというだけではうまくいかず、 まだ QT_QWS_CUSTOM 周辺の書き換えが必要になってるとこがあるな。

このコードの変遷は Trolltech の人達が「QT_QWS_CUSTOM が SL-5x00 をあらすこと」 をマズいと思っている証拠みたいなもんだと思うが、 このあたりの意味の揺れにひきずられて 「SLA300 向けには QT_QWS_CUSTOM を外せ」と どこぞに書いていたこともある ── と責任転嫁しつつ(をい)、注意書き。
QT_QWS_CUSTOM はハード固有の定義を置いたヘッダ、 SL ザウルスの場合で言えば custom-linux-sharp-g++.h を取り込むためにある。 A300 が一部の QT_QWS_CUSTOM と喧嘩していようと、 QT_QWS_CUSTOM は定義しておく。

とりあえず字義をあわせて QT_QWS_SLA300 を define した linux-sla300-g++-shared を configs の下に入れた。 この場合、 ハード固有のヘッダとして custom-linux-sla300-g++.h を取り込むようになるので、 とりあえず custom-linux-sharp-g++.hcustom-linux-sla300-g++.h に cp しておく。

# cd /home/src/Qt/arm/qtopia-1.5.0/library
# cp custom-linux-sharp-g++.h custom-linux-sla300-g++.h

QT_QWS_CUSTOMQT_QWS_SLA300 を使い分けることで SL シリーズ全体と SL-A300 を切り分ける。

もっとも、下準備として↑なことをした訳だが、qtopia 側からみると SL-5x00 と SL-A300 に違いがない (ぜんぶ qt-embedded で吸収) ので、 細かいカスタマイズをかけるんでなければ qtopia のほうは素でもかまわない。

タッチパネル

例によって最初に問題になるのがこいつで、 QT_QWS_IPAQstruct TS_EVENT をそのまま QT_QWS_SLA300 にくくった中に置いて終り、にしてもいいんだが。

iPAQ のカーネルのほうがどうなってるのか知らないが、qt-embedded 内では iPAQ のペンの座標は unsigned short で表現されている。 一方、ほとんど同じイベント構造体をもちながら、 SL-A300 のペンはカーネルでは short で表現されている。

A300 のペン座標はナマだと 150 〜 3800 あたり、 カーネルで calibration されたあとの座標値で 0 〜 319 の間の数値をとる。 だから物事が正しければ unsigned short でも short でもいいようなもんだが、 カーネル内の calibration が微妙にズレていると負数をとることがあるということでもある (← はしっこのほうで突然ペンが消失するのを体験したとゆーわけやな)。

つーわけで、実直に short にしておく。 iPAQ のほうもほんとは short が正しいんだと思うがなぁ:

typedef struct {
        short pressure;
        short x;
        short y;
        unsigned short pad;
} TS_EVENT;
確実に alignment をそろえるためだけに入っていることになっている "pad" の項には実は jiffies の末尾が入っている。 これは逆に short ではもったいないので、unsigned short。 もちろん誰も使ってないけど、printf debug するときのために。

make

% export QTDIR=/home/src/Qt/arm/qt-embedded-2.3.2
% ./configure -qconfig qpe -depths 16,32 -xplatform linux-sla300-g++ \
              -system-jpeg -system-libpng -system-zlib -no-qvfb -no-vnc -no-xft
% make |& tee ../make.qte.log
% cd /home/src/Qt/arm/qtopia-free-1.5.0
% export QPEDIR=/home/src/Qt/arm/qtopia-free-1.5.0
% ./configure -platform linux-sla300-g++
% make |& tee ../make.qtopia.log
てな感じで make する。気分の問題で libjpeg,libpng,zlib を qt-embedded 外に追い出したが、 素の 2.3.2 ではこーやっても内部のを使う。configure するまえに src/Makefile.in を書き換えておく。

謎だった -depths 16,32だが、-depths 16 でも動くには動いた。 ただ、アイコンの影のグラデーションが黒ベタになってしまったので、 どーやら 32bpp もいれとかなければならないらしい。 ... でもバグだろ、この挙動 ...

一周目

タッチパネルだけ整えて make してつっこむと、この時点で qte も qtopia も動く。
── と保証&断言されていてもなかなかテストできるものではない。 ROM 書き換えが要るし、 /home/QtPalmtop/ 下をぜんぶ入れ換えるというけっこ大がかりな話になるからだ。

とりあえず chroot jail 用に母艦でインストール。

# mkdir /home/src/SUBSYSTEM/arm/usr/local/qte
# export JAIL_QTDIR=/home/src/SUBSYSTEM/arm/usr/local/qte
# cd /home/src/Qt/arm/qt-embedded-2.3.2
# tar -cvp lib | tar -xpC ${JAIL_QTDIR}
# cd /home/src/Qt/arm/qtopia-free-1.5.0
# tar -cvp apps bin doc docs etc help i18n inputmethods pics plugins sounds | tar -xpC ${JAIL_QTDIR}

A300 のほうからもぐる。

# mount -t nfs atropos:/home/src/SUBSYSTEM/arm /home/root/debian
# cd /home/root/debian
# chroot . /bin/zsh
# mount -t proc proc /proc
# unset LOGNAME
# export QTDIR=/usr/local/qte
# export QPEDIR=/usr/local/qte
# LD_LIBRARY_PATH=/usr/local/qte/lib
# PATH=/root/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/qte/bin:/usr/local/bin
環境変数の書き換えは /usr/local/qte を使うよう設定しているというよりは、 元の設定が余計なことをしないよう上から塗りつぶすという意味合いのほうが大きい。 だから多分 unset してまわるだけでもいい。

# kill -1 1
# /usr/local/qte/bin/qpe
kill -1 1 は元々の qpe を止めるため ... ま、そのあたりはてきとーに。

手もとの A300 の /home/etc/inittab は普段から qpe が外してあって、 kill -1 1 すると自動的に qpe が停止するよーになっている。 fbvnc, X, qtopia-free, opie とここんとこ qpe の alternative ばっかりテストしてるもんで。
ROM に入っている /etc/inittab (/root/etc/inittab) と RAMDISK に入っている /etc/inittab (/home/etc/inittab) はふつー同じ内容にしてあるんだろうが、 後者は起動時には使われておらず、kill -1 1 して初めて使われるようになるから、 こうしておいてもリセットするだけで正常に復帰する。

さて。なんやらデバイスがないとかゆうて落ちる。

デバイスファイル

もちろん Debian そのままの chroot jail に SL-A300 specific なデバイスファイルはない。 標準になくて、qpe を動かすまでのあいだに手で作ったもの一覧:
crw-rw-r--    1 root     root      11,   0 Feb 27 00:25 ts
crw-rw-r--    1 root     root      10, 134 Feb 27 00:26 apm_bios
crw-rw-r--    1 root     root      10, 213 Feb 27 00:27 sharp_audioctl
crw-rw-r--    1 root     root      10, 211 Feb 27 00:27 sharp_buz
crw-rw-r--    1 root     root      10, 214 Feb 27 00:27 sharp_kbdctl
crw-rw-r--    1 root     root      10, 210 Feb 27 00:27 sharp_led
crw-rw-r--    1 root     root      11,   0 Feb 27 00:27 sharp_ts
crw-rw-r--    1 root     root     254,   0 Feb 27 00:27 fl
ここまでくれば qtopia free は動くには動く。 とはいえ、細かくみてくとやることはまだある。

なにしろ reference の 5500 持ってないので、5500 の screenshot 見ながらの調整である。

LC font

lcfont*.qpf は charset が "iso10646" でなく "AnyCharSet" を名乗る。 このためか qt-embedded free からは lcfont は読めないので、一度 QImage 経由で bdf にしてから qt-embedded free で吸い上げなおして qpf に落した。 これで qt-embedded free でも使える。ついでに横倒しも作った。
... が、とうぜんフォントファイル自体は公開できないのであしからず。

このあたり、font metric がボロボロとかいろいろあったんでそのうち別項を起こす。

キーマップ

VNC server の項で触れたが、 SL-5x00 と SL-A300 は同じキーマップをもつ。 したがって、qtopia free を動かす時も何にもしなかった。カーネルから渡ってくる scancode を qtopia free はそのまま正しく扱える。

ということで、独自のキーマップをもつ B500 や C700 ではこの限りでない。

Suspend/resume

Resume は Qtopia の仕事でないから今回は関係ない。suspend のほうはというと、 こちらもなんにもしなくても動いた。

実は jail には /usr/bin/apm いれてなくて、 qpe は内部的に system("apm --suspend") することで suspend に入っているので寝てくれなくてしばらく首をひねった。 /usr/bin/apm のよーな 出自がおもいっきり PC 依存なコマンドが ARM にあるとは信じられず、 A300 付属の apm も手が入ってるやろと思ってたんだが、 ふつーに apmd パッケージの中に入ってるやつで動くんやね ...

くだんの apm --suspend の仕事は ioctl(/dev/apm_bios, APM_IOC_SUSPEND) を叩くことで、/dev/apm_bios さえ作っておけばこれでふつーに動くと。

echo 1 > /proc/sys/pm/suspend とだけ書いた shell script を /bin/apm としておいても suspend は動いたし。

なお、手で suspend するには /proc/sys/pm/suspend に 1 を送るのが 汎 linux 的に正しい書法らしいが、A300 では /proc/sys/pm/suspend への read アクセスでも suspend してしまう。 read だろーが write だろーがアクセスすればそれで問答無用で寝るコードになっている。

フロントライト

/usr/bin/fl (これこそソース不明のコマンド) がなくても /dev/fl さえ作っておけば Qtopia free からライトのコントロールはできる。

それはいいんだが、suspend/resume の時の挙動は qtopia free のコードのままだとちょい変だ。 suspend 時、qpe は backlight を強制 off にしてから寝ているため、 resume 時に apm が backlight を回復してもライトは消えたままだ。

もちろん resume 直後に強制 on のコードが入っていて、 これで 5x00 でのライト制御をしてるんだろーが、 A300 では resume 直後はライトのコントロールができないので、 ライトは消えたままになる。 設定そのものは復帰しているので、パネルに触るかなにかすればライトは点灯するが。

A300 の apm event の処理か /dev/fl のバグっぽいのだが、 そもそも suspend でライトを消してからってので suspend のアクションが遅れてるのがナンなので、 コードをまるごと外した。A300 ではこれでも正しく動く。

サウンド、キークリック

Qtopia free が /dev/audio を扱っているはずはない。 もし /dev/audio を使っていたのなら、それをカーネルに実装しておくだろう。 A300 の初期カーネルにそんなもんはなかった(正しくは、バグってた)のだから、 もちろん qtopia にはない。

/dev/mixer, /dev/dsp を使っており、 そして qtopia free からは 16bit stereo, 44100Hz をデフォルトとしているので、 A300 の 32kHz 問題にもあたらない。そのまま動く。

... はずだと信じて疑わなかったし、実際そうだったのだが、 キープレスやペンタッチで音を出す設定で何にも起こらなかった。 クリック音が出るはずの設定 (← そういうものが qtopia free にはある。A300 の qtopia にはないけど) にしてもうんともすんともいわない。

これ、SL-5x00 でも動作しないはずだ ── と思うのだが。 これを動かすには CUSTOM_SOUND_TOUCHCUSTOM_SOUND_KEYCLICK を正しく定義してやればいいのだけれど、そんなもんの定義はどこにも入ってないんである。 5x00 用に SHARP_BUZ_TOUCHSOUND てのも定義されていて、 やっぱりどこにも使われてる様子がないんだが、もしかしてソースが欠けてるのかしらん。

このあたり、qtopia 1.6.0 では SL-5x00 向けに CUSTOM_SOUND_TOUCH 等の定義が入った (src/libraries/qtopia/custom-linux-sharp-g++.cppqtopia_buz_touch(bool))。 1.6.0 ならタッチパネルやボタンを 叩くと音が鳴るという設定にすることができる。

この 1.6.0 のコードをそのままもってくれば SL-5x00 では鳴ると思う。A300 の場合、 下請けになってるカーネル側の ioctl(SHARP_BUZZER_MAKESOUND) の実装がないので、 鳴らない。ったく、C700 のカーネルには入ってるのに。

もっとも A300 でペンタッチを鳴らせると手書き認識でそーとーうざいことになりそうだし、 キークリックでブザーを鳴らす必要がない(物理的にクリック音がある)ので もともと使う気はないが ...

パッチ

バイナリのほうはというと、libqte/libqpe だけをシャープのから置き換えることはできないし、 もちろん ipkg でインストールする訳にもいかないので、 ライブラリのバイナリだけを公開する意味はないと思う。

Screenshot

Qtopia free (en) Qtopia free (rotated, ja)
ひとつ目のは本来のやつ。ふたつ目のは lcfont つっこんで language を日本語とし、 (右辺を下にして)横倒しにしたもの。 並び順が微妙に違うのは ... えーと、ソートのルール忘れた。

C700 の landscape と違い、横にアイコンは 3 つしか並ばない。内部的に決め打ちになっていて、 half VGA の Psion5 などで Qtopia 動かすと 640pixels の幅のあいだに アイコンが 3 つしかないというかなりシュールな表示になる。 PC の LinuxFb の全画面でも 3 つしか並ばないのはもうなんつーか ... qtopia 1.5.0 ってば、ほんとーに 240x320 のことしか考えられてない。
にしても、こーしてみると lcfont の英字品質ってアカンな ...

ところでアイコンがシャープの qtopia 由来のやつを使ったものと比べると、 qtopia free → A300 → B500/C700 という アイコンのデザインの変化の一貫性が見てとれる。 淡い色が好きなのね > ザウルスのデザイナーさん。

NEXT EPISODE

Qtopia free を片付けた勢いで OPIE に侵攻したものの、予想外の抵抗を受ける! 次回、『OPIE の戦い』


[日記へ] [目次へ]