どんなプログラムのチュートリアルでもまず最初に要求されるのは、 どうやら例の``Hello world'' プログラムみたいですね。 このプログラムを動作させることで、少なくとも、Palm OS プログラムの 作成方法、コンパイル方法とインストールの仕方を把握できるはずです。
ひとつ注意しておくべきなのは、Palm OS プログラムはイベントドリブン だということです。 基本的には、他の(make や more や pilot-xfer などのような)直線的な プログラムとはちょっと違って、Palm OS アプリケーションはおおむね、 イベントを待ち、それを処理するというような構造をしています。 イベントというのは、ペンダウン・アップ、グラフィティ入力、アラーム などの、それぞれ異なるイベントが発生したことを指します。
これは、``Hello World'' プログラムのソースコードです: (訳注: 以下では参考のために、ソースコードのコメント部分も日本語に訳出して いますが、実際に gcc で日本語のコメントが通るかどうかは確認していません)
#include <System/SysAll.h>
#include <UI/UIAll.h>
// ---------------------------------------------------------------------
// PilotMain は、初期化コード(startup)から呼び出され、単純なイベントを
// 処理するループから成ります。
// ---------------------------------------------------------------------
DWord PilotMain( Word cmd, Ptr cmdPBP, Word launchFlags )
{
EventType event;
if (cmd == sysAppLaunchCmdNormalLaunch) {
// 文字列を表示する
WinDrawChars( "Hello, world!", 13, 55, 60 );
// メインのイベントループ:
do {
// イベントが到着するまで眠る
EvtGetEvent( &event, evtWaitForever );
// まずはシステムにイベントを処理する機会を与える
SysHandleEvent( &event );
// 通常はここでその他のイベントの処理をおこなう。
// appStopEvent を受け取ったら PilotMain からリターンする
} while (event.eType != appStopEvent);
}
return;
}
以上のコードをお好きな方法で、``hello.c'' というファイル名のテキストファイル
として保存してください
(実際にはファイルの名前は最後が ``.c'' でありさえすればなんでもよいのですが、
ここではこういう名前を使います)。
Prc-tools で使われている bin ディレクトリがちゃんとデフォールトパスに 含まれている(パスが通っている)ことを確認して、以下のコマンドを入力して ください:
m68k-palmos-coff-gcc -O2 -g hello.c -o hello
m68k-palmos-coff-obj-res hello
build-prc hello.prc "Hello, World" WRLD *.hello.grc
m68k-palmos-coff-gcc
は、prc-tools によって生成された GCC クロスコンパイラ。
m68k-palmos-coff-obj-res
は、m68k-palmos-coff-gcc
によって生成された
プログラムを、Palm OS アプリケーションに必要ないくつものセクションに
分割してくれます。
build-prc
はプログラムセクションを組み立て、コマンドラインで指定された
情報を付加して最終的な Palm OS プログラムを生成します。
さて、Palm OS デバイスのメモリ内容のバックアップは既に済んでいますよね。
いよいよhello.prc
をインストールしてみましょう。
インストール方法は以下の通りです:
pilot-xfer --port /dev/ttyS1 --install hello.prc
(ここで指定したシリアルデバイスは、あなたの環境にあわせて変更してください)
さあ、クレードルの HotSync ボタンを押しましょう。
HotSync が完了したら、アプリケーションランチャーから ``Hello, World'' という 名前のアプリケーションが見えるはずです。これをダブルタップすれば、 画面の真ん中あたりに、``Hello, World!'' という文字が現れるはずです。
さて、この``Hello, World''プログラムの構成要素を説明したいと思います。
System/SysAll.h
をインクルードすることで、実はたくさんのシステム
インクルードファイルを一度にインクルードすることになります。
この中でいくつか見ておきたいファイルがあるかもしれませんね。
たとえば、m68k-palmos-coff/include/PalmOS2/Common.h
では
Palm OS ライブラリ全体で使われるような typedef 宣言が含まれているので
目を通しておいて損はないと思います。
UI/UIAll.h
は、ユーザインターフェースに関するたくさんのインクルード
ファイルをインクルードしています。
すべての Palm OS アプリケーションには(訳注: Hack や DA は除く)、
この PilotMain()
関数が存在しなければなりません。
これは通常の C 言語における、main()
関数と同じ役割を果たすものです。
DWord PilotMain( Word cmd, Ptr cmdPBP, Word launchFlags )
プログラムが起動された時に、cmd
には Launch Codeが渡されます。
このLaunch Code によって、アプリケーションに対して通常とは異なる
動作を要求することも可能です。
Launch Code は、cmd
引数で渡されます。
それぞれのプログラムはこの Launch Code の値をチェックして、自分がそれに応答
できるかどうかを調べます。
``Hello, World'' プログラムでは、「normal program launch」以外のコードは
無視するようになっています。
if (cmd == sysAppLaunchCmdNormalLaunch) {
Launch codeには、いろいろな状況に対処するためにたくさんの種類があります。
どんなコードが存在するのかを全部知るためには、
m68k-palmos-coff/include/PalmOS2/System/SystemMgr.h
を読んでください。
WinDrawChars()
関数は、指定された画面上の座標に文字列を表示します。
WinDrawChars( "Hello, world!", 13, 55, 60 );
アプリケーションは、appStopEvent
を受け取るまで(その意味の通り)
走り続けます。
// メイン・イベントループ
do {
.
.
.
// appStopEvent を受け取ったら PilotMain からリターンする
} while (event.eType != appStopEvent);
アプリケーションがこのイベントを受け取った場合には、必要な後始末をした後に、
PilotMain
からリターンするようにします。
EvtGetEvent
関数は最初の引数を変更するので副作用があります。
この関数から帰ってくるときには、すなわちいくつかのイベントが
発生して、OS がアプリケーションに対してそれを通知しているという状態です。
EvtGetEvent( &event, evtWaitForever );
実は、アプリケーションは自分に渡されるすべての制御権を握っています。
しかし、通常のアプリケーションではほとんどのイベントを Palm OS に
処理して欲しい場合が多いでしょう。このために、システムが提供している
イベント処理ルーチン関数が提供されています。
SysHandleEvent()
を呼び出すことで、ボタンや Graffiti 関連の
イベントをシステムに処理させることができます。
この関数を呼び出さないと Palm OS は、別のアプリケーションを起動するために
ボタンが押されたというイベントを処理することができません。
これはすなわち現在のアプリケーションに対して appStopEvent
が
送られないことを意味します。その結果、``Hello, World''プログラムは
どうやっても終了できなくなってしまうことになります。
実際、電源オフのボタンもきかなくなってしまうんです!
さあ、試してみましょう。
SysHandleEvent()
を呼び出しているところをコメントアウトして、
再コンパイル、再インストールしてなにが起こるか試してみてください。
ソフトリセットするためのゼムクリップを用意しておいてくださいね!
恐らく気がついたと思いますが、このプログラムはイベントに関しては、 オペレーティングシステムに処理させるためにそのイベントを渡し直すこと 以外にはなにもおこなっていません。 次の機会にはもっとエキサイティングな例を書くことを約束します!