Opie でつっぱしってるさなかに 2/28 以来の X な話なのは、 X 入れるつもりで SL-C750 買っちゃったからともいう。 A300 ではシャープの手書き文字認識を捨てる気にならず Opie 使ってるが、 C750 ではハードキーもつのに何を好き好んで わざわざ手書きで入力せにゃならん? ということで、 最初から X 導入が前提になっている。
このあたり、SL-C700 のカーネルをつっこむという予定はあるが、 C750/760 のバッテリの容量管理が C700 から変わってるはずなんで、 そのままつっこんで大丈夫かどうかかならずしも自信はない (A と違い、C はカーネル層がバッテリの温度/電圧/容量を監視/管理している) ... が 760 ならともかく 750 で気にするほどのことはなかろ。C700 に大容量バッテリつっこんでる人達もいることだし。
X の準備のほうは、例によって母艦に作ってある Debian/arm の sarge に chroot して Xfbdev 起動。
# mount -t nfs atropos:/home/src/SUBSYSTEM/arm /mnt/net # cd /mnt/net # /sbin/chroot . /bin/zsh # mount -t proc proc /proc # PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin # /etc/init.d/nfs-common start # cd # Xfbdev -schedInterval 10 -schedMax 10 -screen 640x480@270 & # export DISPLAY=192.168.129.201:0.0 # xengineで xengine が動き出す ... 130rpm かい。A300 より遅いんかい -_-;;
テストしかしてないので xinit 使わず直叩きしているが、 window manager なども動かしたければ、
% Xfbdev -schedInterval 10 -schedMax 10 -screen 640x480@270 & % export DISPLAY=192.168.129.201:0.0 % sh .xinitrcとでもすればリモートからでもふつーの環境を立ち上げることができる (通常 xinit はリモートからの起動を阻止するようになっているはずだ)。
Xfbdev は A300 のと同じバイナリで動く。 C750 の /etc/pointercal をもってきておけば、ペンも合っていた。 libqte の /etc/pointercal 周りのコードは A と C とで変わってないんやね。
X11/Xlib.h の
typedef struct { /* normal 16 bit characters are two bytes */
unsigned char byte1;
unsigned char byte2;
} XChar2b;
が、arm linux の gcc では sizeof(XChar2b) == 4 になるのだが、
X server、Xlib 自身を含め多くのアプリで sizeof(XChar2b) == 2
を仮定するコードになっているために、
文字列を表示させると 1 文字おきになったり文字列の後半が欠けたりする、
というヤツだ。
かつて arm architecture ではまともに 16 bit word を扱うことができなかった ── 多少なりと使えるようになったのは thumb instruction set (16 bit 語長/命令) のサポート以後だ ── ということの名残りだろうが、迷惑な話ではある。
ここで道は 3 つ。2 にそろえるか、4 にそろえるか、 どちらにもそろえずその時々で正しく動くようにするか。 3 つ目のは論外としても、2 か 4 かはけっこう悩む。 4 にそろえると正しい作法のアプリは rebuild しなくてもいい ... Debian/arm の X 関連バイナリがそのまま使える (もちろん正しい作法のやつ限定; どんだけあるかが勝負か?) というのは魅力的だし、 物事の態度としても正しいと思うのだが、2 にそろえた。
明示的に XChar2b を使ったことで 4 になっているコードを 2 にするには ソースからコンパイルしなおせば勝手に直るが、 2 を仮定したコードを 4 に直すにはソースに手を入れなければならないからだ。 ... 堂々と胸はって言うことではないよーな気もしないでもない。
手で直すといっても、sizeof(XChar2b) が 2 でない可能性にも いちおー配慮の跡がある X server や Xlib とか、 それに krxvt, kterm 程度ならば 2 → 4 の変更につきあってもいいが、 emacs あたりになってくるとそろそろヤな予感がするだろう ... 極めつけは Qt である。 Qt では arm linux でも sizeof(QChar) == 2 になっている。 そして、sizeof(QChar) == sizeof(XChar2b) が仮定されている。 ついでに qstring.h のコメント中に堂々と明示されている。 こんなもん、どうやって直せと? ← つーか、そもそもそんなもんを C750 で動かそーとか思うなよ。
なお、gnome 方面はかなり性質が良く、 Xlib 以下さえ直せば GUI 層より上はバイナリがそのまま使えるっぽい。 てことはつまり、実装的に重いとゆーことでもあるが ... XChar2b が透過的に見えてないってことだからな。
さて。2 に pack するのだが、具体的にはこんだけ (Xlib.h.diff):
--- Xlib.h~ Thu Oct 17 05:14:38 2002
+++ Xlib.h Tue Jun 17 01:06:01 2003
@@ -1059,7 +1059,7 @@
typedef struct { /* normal 16 bit characters are two bytes */
unsigned char byte1;
unsigned char byte2;
-} XChar2b;
+} __attribute__ ((packed)) XChar2b;
typedef struct {
XChar2b *chars; /* two byte characters */
裁判の判決文よろしく口上がえらい長いわりに肝心のコードはたった 1 行だったりするんだが、 パッチの場所が場所で影響範囲がしゃれにならんもんでねぇ。 もちろん arm 以外では影響はでない (定義によって出るはずはない)。
このパッチ、gcc でしか使えないよーな気がすんだが、 別売のコンパイラが出てる訳でなし、まあ、よかろ。 そもそも gcc 以外では何もせんでも 2 かもしんないし。
ちなみに sizeof(QChar) が 2 になってるのは、 むろん QChar の定義にもちゃんと __attribute__ ((packed)) がついているからである。
そーなると、host.def の内容も Xlib 向けオプションをまともなものに (つまり、 Debian/arm バイナリとかと整合性がとれるように) しなければならない。
... なんか作業内容的にとおってもデジャブなんだけど 気付かなかったことにして objdump -TC libX11.so | sort して名前を比較する。 Xkb* あたりが足りなかったので 結局こーなった (host.def):
#define KDriveXServer YES
#define KdriveServerExtraDefines -DITSY -DMAXSCREENS=2
#define CrossCompiling YES
#define TouchScreen YES
#define ItsyCompilerBug YES
#undef BuildDBE
#define BuildDBE YES
#undef BuildRandR
#define BuildRandR YES
#define BuildXInputLib YES
#define ProjectRoot /usr/X11R6
#define Freetype2Dir $(TOP)/extras/freetype2
#define Freetype2LibDir $(TOP)/exports/lib
#define BuildXTrueType YES
#define BuildScreenSaverExt YES
#define BuildScreenSaverLibrary YES
#define SharedLibXss YES
#define ServerXdmcpDefines
#define BuildLibraries YES
#define BuildXF86MiscLibrary YES
#define BuildXKBlib YES
#define BuildXKBfilelib YES
#define BuildXKBuilib YES
#define XfbdevServer YES
#define StandardDefines -Dlinux -D__arm__ -D_POSIX_SOURCE \
-D_BSD_SOURCE -D_GNU_SOURCE
#define LinuxLocaleDefines
#define XawI18nDefines -DHAS_WCHAR_H -DHAS_WCTYPE_H -DNO_WIDEC_H
#define MakeLocalFontDir YES
#define InstallXinitConfig YES
Debian sarge の XFree86 4.2.1 のパッケージを Xlib.h だけ直したあとは SL-C750 上で dpkg-buildpackage の自力 build てのが最もコンパチなんだろーが ... 2 日で build 終ってくれるかなぁ ...?
上記ので build した X server, Xlib バイナリ一式とパッチ:
元ソースは XFree86 の cvs 20030614 時点のである。krxvt については、-km (multibyte font) を指定しない場合は XDrawString16() 任せなので 下位層さえ整合していれば rebuild なしでもちゃんと動くように見えるが、 ~/.Xdefaults などで指定する場合には XChar2b を直接触り、 しかも中途半端に sizeof(XChar2b) == 2 を仮定するため、結局 rebuild しなければならない。 バグあり Xlib との組み合わせで krxvt が日本語が出たり出なかったりの理由もこのあたり。
いちおー make したんだが、おもいっきり glibc 2.3 依存してしまったので略。
config は emacs21 の場合:
% ../emacs-21.2-emcws/configure --prefix=/usr --with-canna --with-x --build=i686-linux \ --with-jpeg --with-tiff --with-gif --with-png --with-x-toolkit=athena --target=arm-linux arm-linux-gnu
mule の場合:
% ../mule-2.3-19.34/configure --build=i586-linux --host=arm-linux --with-terminal-face \ --with-mcpath --srcdir=/home/src/emacs/mule/mule-2.3-19.34 --with-x --with-x-toolkit=athena --with-canna
emacs21 には prefix 付けたので /usr/ 直下に入るが、 mule は prefix 付けるの忘れたので /usr/local/ 下に入る。うぅ、ごめんよぉ (実は確信犯だ。マジすまん)。
また、without X 環境用のものと違い、両者とも canna 対応になっている。 emacs21 のほうは要するに emcws (canna 直接対応) である。 pure emacs21 は ~/.canna 見てくれないので好かん (きっぱり)。
日本語カタログは Xlib 任せ。Xlib さえ直せば rebuild なしで動く。 ↑では Debian/arm sarge の gimp 1.2 バイナリを動かしている (fvwm のほうは日本語非対応である ... まあ rebuild もしてねーし)。 さすがにこんなの rebuild したくねーぞ、らっき〜と喜んでたら ──
本体の表示はともかく、メニューやらなんやらがとってもおかしいのは Qt がおかしいのか、設定だけのことなのか ...![]()
KDE の C750 による自前 build なんて、はたして 3 日で終るか?
クロスで build するにも、Qt/X11 にクロス向けの configuration 付いてないっすけど ...
もともとまともに動かすつもりないのでとりあえず pending.
swap なしでも動いてるようだが、けっこ重い。
まあ、軽い X11 な web ブラウザなら、 naorou さん家で紹介されてる dillo か w3m でよかろ。gnome が無問題っぽいので phoenix という解もありそうだが、未確認。 Debian にバイナリ入ってないから自前で build しなきゃいけないんだもん。
もともとフリーではなかったので non-free セクションにあったんだが、
non-free にも置けないことになったのか。
まぁ、gqview 使えばいい話ではあるが。
RandR extension は起動時に横倒しにするだけが能でなく、 この仮想スクリーンのサイズそのものが on-the-fly で切替えられるようになった。... ことになっている (をい)。
C750 の X の場合で言えば、
% xrandr -display odetto:0.0 -q SZ: Pixels Physical Refresh *0 480 x 640 ( 163mm x 217mm ) Current rotation - normal Current reflection - none Rotations possible - normal left inverted right Reflections possible - X Axis Y Axis
xrandr というコマンドで rotate と resize が出来ることになっているが、 まだ SZ index が 0 の一通りしかサポートしかないので、resize はできない (QVGA に変えたりはできない)。 rotate のほうは
% xrandr -o leftなどとすれば回る。"left" というのは左に回す、ふつーの viewstyle の向きのことである:
... このカラーリング、現物ではかなり明るいんだが、こーしてみるとなんか暗いな ...。![]()
![]()
閑話休題。ここでいう resize の意味がちょいと不明で、 つまり inputstyle 位置で 横 640 縦 480 で使ってるのと、viewstyle 位置で 横 480 縦 640 で使う時の差は rotate だけなのか、resize 動作が入ってるのか ... というあたりのことだが。
なにぶん window manager が対応してないと画面の扱いがわけわかめになるのは容易に想像がつくと思うが、 実際に RandR に対応しているのは waimea の cvs のものしか知らない (... かったんだが、stable の 0.4.0 も対応してるみたいだな、いつのまにか ...)。 waimea 使ったことないんで、このあたり RandR の動作とどういう風にすりあわせてるのかよく分からん。
fvwm で使うと、landscape から portrait に切替えた時に画面の再配置はない (これは仕方無い) ので、 右下隅にはっつけていた pager が portrait 時に画面外に出てしまうとかいう動作をするほか、 fvwm 自身は 横 640 の縦 480 的な画面と思っているらしく、上下方向の EdgeResistance を有効にしておくと edge 上から 480 ピクセル目あたりで window 移動が EdgeResistance 的にひっかかる動作をする。
X 的には正しく横 480 の縦 640 という扱いになっていて、X の draw や mouse の pointing はちゃんと動くが、 たとえば480 ピクセル目よりも下側で fvwm のメニューを出そうとすると fvwm 的な画面最下部、つまり上から 480 ピクセル目を メニュー下端とする位置にメニューがでる。
このままでもなんとか使えるような気もするし、やっぱもうすこし対応してほしいという気もするし、ってか。
みっつ目のは window manager の設定のほうでなんとかするつもりでいたが、 考えるまでもなく xv みたいに中央/右が存在することを前提にする I/F のもあるから、 押せるようにはなってないといけないやね。
kterm など xmkmf が必要なもののクロスコンパイルについては
% cd kterm-6.2.0 % xmkmf /home/src/X/xc-20030614-k4/ % makeのようにターゲットの X のソースツリーを指定すると、その中の configuration を使って xmkmf してくれるようになる。 man xmkmf すると「だれも使ってねーよ、そんなの」とか書いてあるが、使えた :-)
まぁ、ふつーはぴろさん家の 「X11のコンパイル再び」にあるように、 xc/programs/ に付け加えてしまうのだろーな。
セルフの場合は、/usr/X11R6/lib/X11/config/ にバイナリ一式のをコピーしたあと、 host.def 中の CrossCompiling の項を "NO" にしておけば、セルフでふつーに xmkmf が使えるようになる。