Palm Programmer's Laboratory
Palm OS Programmer's Companion Volume I/3-2
3-2 低水準のイベント管理
ユーザーがアプリケーションとやりとりする方法には、以下の5種類があります。
- インプットエリアに文字、数字、記号を書く。
- ハンドヘルドのハードボタンを押下する。
- フォームやダイアログのコントロールをスタイラスでタップする。
- キーボードダイアログのオンスクリーンキーボードをタップする。
- メニューバーや特定のメニューをタップする。
最初の3つの入力方法については、Palm OS によってマネージャが提供されています。Graffiti マネージャ、キーマネージャ、そしてペンマネージャです。ほとんどのアプリケーションはこれらのマネージャに直接アクセスする必要はありません。そのかわり、アプリケーションはこれらのマネージャからイベントを受け取り、応答します。しかし、これらのマネージャのいずれかと直接やりとりしなければならない場合もあります。以下のページでは、これらのマネージャと、それを使わなければならない状況について説明します。UI オブジェクトからの入力を取得する方法については、「 4 ユーザーインターフェース 」を参照して下さい。
キーボードダイアログで画面上のキーボードをタップすることにより、ユーザーはテキストフィールドに文字を入力することができます。キーボードダイアログが閉じられた時、修正されたテキストは自動的に元のフィールドに表示されます。3つのマネージャについて先に書いたとおり、キーボードダイアログに直接アクセスする必要はまずないでしょう。ユーザーはどのテキストフィールドに対してでもキーボードダイアログを開くことができます。しかし、特定の状況ではプログラム的にキーボードダイアログを表示したいと思うかもしれません。詳細については、「 4-3 フォーム、ウィンドウ、ダイアログ 」 の“キーボードダイアログ”を参照して下さい。
メニューマネージャはタップによるメニューの表示やメニューアイテムの選択を処理します。詳細は 「 4-6 メニュー 」 を参照して下さい。
これらのマネージャに加え、低水準のイベント処理にはシステムイベントマネージャが含まれます。ほとんどのアプリケーションはシステムイベントマネージャを直接コールする必要はありません。なぜなら、必要な機能のほとんどは高水準のイベントマネージャによって提供され、システムによって自動的に処理されるからです。
この節では、以下のマネージャについて説明します。
- Graffiti マネージャ
- キーマネージャ
- ペンマネージャ
- システムイベントマネージャ
Graffiti マネージャ
Graffiti マネージャは Palm OS の Graffiti または Graffiti 2 を認識するための API を提供します。認識エンジンはペンストロークをキーイベントに変換し、イベントマネージャを介してアプリケーションに供給します。
- IMPORTANT
- Graffiti 2 フィーチャセットが存在する場合、Graffiti マネージャ API 関数の多くは廃止されたか、あるいは異なる動きをします。Graffiti マネージャ API の使用は避けて下さい。
ほとんどのアプリケーションでは Graffiti マネージャを直接コールする必要はありません。なぜなら、インプットエリアにおけるペンストロークを検出したイベントマネージャによって自動的に呼び出されるからです。
Graffiti 学習用などの特殊目的のアプリケーションでは、入力エリア以外の場所でのストロークを検出したり Graffiti の挙動をカスタマイズするために Graffiti マネージャを直接コールしたいと思うかもしれません。
GrfProcessStroke を使う
GrfProcessStroke は高水準の Graffiti マネージャ関数で、イベントマネージャがペンストロークをキーイベントに変換するために使用します。この関数は、
- ペンキューからペンストローク情報を取り出します。
- ストロークを認識します。
- 1つ以上のキーイベントをキーキューに追加します。
GrfProcessStroke は自動的にショートカットストロークを処理し、カレントウィンドウのシフトインジケーターを表示する適切なユーザーインターフェースをコールします。
アプリケーションはイベントマネージャから penUpEvent を受け取った際に GrfProcessStroke をコールすることで、(インプットエリアへの入力に加えて)アプリケーションエリアでのストロークを認識することができます。
その他の高水準な Graffiti マネージャ関数を使う
Graffiti マネージャによって提供されるその他の高水準な関数には以下のものがあります。
- シフト状態の取得、あるいは設定( CAPS ロックのオン/オフ、一時的なシフト状態など )。
- ユーザーが別のフィールドを選択した時の手書き文字認識機能への通知。手書き文字認識機能は選択フィールドの変更通知を必要とします。それは、部分的に入力されたショートカットをキャンセルし、アクセント付きかもしれない文字を表示している場合に一時的なシフト状態をクリアできるようにするためです。
Graffiti 2 フィーチャセットが存在する場合、Caps Lock ステートはサポートされないことに注意してください。Graffiti 2 では、大文字を入力する場合には文字エリアと数字エリアを境界線上でストロークを描きます。ユーザーは容易に連続した大文字を入力することができるため、Caps Lock ステートは必要ありません。
特殊目的の Graffiti マネージャ関数
その他の Graffiti マネージャ API 関数は、特殊な目的で使用するためのものです。基本的には全て Graffiti 認識エンジンへのエントリポイントで、通常は GrfProcessStroke からのみコールされます。これらの特殊な使用法としては、Graffiti認識エンジンのストロークバッファにペンの軌跡を追加したり、ストロークバッファを Graffiti 文字の ID に変換したり、Graffiti 文字を1つ以上のキーストロークの連なりにマップしたりする処理があります。
- IMPORTANT
- Graffiti 2 フィーチャセットが存在する場合、特殊目的での Graffiti マネージャ関数の使用はしないで下さい。
ショートカットへのアクセス
その他のルーチンでは、Graffiti や Graffiti 2 のショートカットデータベースへのアクセスを提供します。これは Graffiti マネージャによって所有および維持されるデータベースで、全てのショートカットを保有しています。Palm OS 3.5 以前では、このデータベースは Graffiti マネージャの初期化時にオープンされ、終了までオープンされたままになっていました。Palm OS 4.0 以降では、必要に応じてオープンされ、必要がなくなればクローズされるようになっています。
このデータベースを変更する唯一の手段は、Graffiti マネージャ API を使用することです。ショートカット一覧の取得や追加、編集、そして削除が行なえます。プリファレンスアプリケーションのショートカット画面は、このデータベースを編集するユーザーインターフェースを提供しています。
オートシフトについて
Palm OS 2.0 以降では、以下の条件で自動的に大文字が使用されます。
- ピリオドに続けてスペースか改行が入力された場合。
- その他の文終端文字( ? や ! など )に続けてスペースが入力された場合。
訳注:Palm OS 5.4 で試したところ、? や ! に続けて改行を 入力した場合でもオートシフトが行なわれました。
この機能は開発者による変更は必要ありませんが、エンドユーザーには歓迎されるでしょう。
オートシフトのルールが言語依存であることに注意して下さい。というのは、大文字表記は地域によって異なるからです。このルールは ROM のバージョンやハンドヘルドが販売される地域などによって異なります。
Graffiti ヘルプについて
Palm OS 2.0 以降では、アプリケーションは SysGraffitiReferenceDialog をコールするか仮想キーコード ── Chars.h にある graffitiReferenceChr ── をキューに追加することで Graffiti ヘルプをポップアップ表示させることができます。
Graffiti ヘルプはシステムの編集メニューから利用することもできます。ですから、システムの編集メニューを利用するアプリケーションは、ユーザーにメニュー経由で Graffiti ヘルプを利用させることができます。
キーマネージャ
キーマネージャは、Palm ハンドヘルドのハードウェアボタンを管理します。ボタン押下をキーイベントに変換し、ボタンのオートリピートも処理します。ほとんどのアプリケーションはキーマネージャを直接コールする必要はありませんが、キーのリピートレートを変更したりキーの状態を取得する場合には必要になります。
イベントマネージャはキーに関する主なインターフェースです。ボタンが押されるとアプリケーションに keyDownEvent を送ってきます。通常、アプリケーションはキー押下をイベントマネージャから通知されます。ハードウェアボタンが押される度に、アプリケーションはイベントマネージャから適切なキーコードが設定されたイベントを受信します。ハードウェアボタンの状態は、アプリケーションから KeyCurrentState 関数をコールすることでいつでも問いあわせることができます。
KeyRates 関数はハードウェアボタンのリピートレートを変更します。これはハードウェアボタンをコントローラがわりに使いたいゲームアプリケーションには有用かもしれません。キーリピートレートの現在値はキーマネージャのグローバル変数に格納されており、アプリケーションが終了する際に元に戻されなければなりません。
ペンマネージャ
ペンマネージャはハードウェアとしてのディジタイザを管理し、ディジタイザへの入力をペン座標に変換します。Palm ハンドヘルドは LCD スクリーンとその下1インチほどを覆うディジタイザを装備しています。このディジタイザは 0.35mm( 0.0138 インチ )の精度で1秒間に50ポイント以上のサンプリングを行う能力があります。ハンドヘルドが休止モードにある状態でペンがスクリーンに触れると、割込みが発行されます。ペンの接触が検出されると、システムソフトウェアはペンがスクリーンから離されるまでの間、定期的( 20msec ごと )にペンの位置をポーリングします。
ペンの動作はフォームイベントとしてアプリケーションに自動的に渡されるため、ほとんどのアプリケーションはペンマネージャを直接コールする必要はありません。
ペンの座標は変換されないそのままの状態でペンキューに追加されます。ペンキューからペン座標を取り出すシステムイベントマネージャのルーチンがコールされると、ペン座標はスクリーン座標に変換されます。
プリファレンスアプリケーションは、ディジタイザのキャリブレーションを行うためのユーザーインターフェースを提供しています。これはペンマネージャ API を使用してキャリブレーションを設定し、それをプリファレンスデータベースに保存するものです。ペンマネージャは、ディジタイザが x と y の両方向に線形であると仮定しています。そのため、キャリブレーションは x 座標と y 座標に対して適切なオフセットの加算と拡縮を行うシンプルな処理となります。
システムイベントマネージャ
システムイベントマネージャは、
- ペンとキーの低水準のイベントキュー管理をします。
- 入力エリアアイコンのタップをキーイベントに変換します。
- 入力エリア内でのペンストロークを Graffiti または Graffiti 2 認識機能に送ります。
- ユーザー操作がなければシステムを低消費電力モードにします。
ほとんどのアプリケーションはシステムイベントマネージャを直接コールする必要はありません。なぜなら、必要なほとんどの機能は高水準のイベントマネージャによって提供されるか、システムによって処理されるからです。
システムイベントマネージャを直接使用するのは、キーイベントをキーキューに追加したり、ペンストロークを構成するペン位置の集合をペンキューから取り出すような処理を必要とするアプリケーションになるでしょう。
イベントの変換:ペンストロークからキーイベントへ
システムイベントマネージャによって提供される高水準な機能の1つに、ディジタイザ上のペンストロークをキーイベントに変換するというものがあります。例えば、システムイベントマネージャはディジタイザ上の入力エリアのストロークを自動的に Graffiti または Graffiti 2 の認識機能に送り、キーイベントに変換します。アプリケーションボタン、メニューボタン、検索ボタンなどの入力エリアアイコンのタップもシステムイベントマネージャによって処理され、適切なキーイベントに変換されます。
システムがペンストロークをキーイベントに変換する際、以下のことをしています。
- ペンキューからストロークを構成するペン位置の集合を取り出します。
- ストロークを該当するキーイベントに変換します。
- キーイベントをキーキューに追加します。
このようにして、システムは EvtGetEvent 呼び出しの結果としてアプリケーションにキーイベントを返します。
ほとんどのアプリケーションは、以下に示すシステムイベントマネージャのデフォルトの挙動を利用しています。
- あらかじめ決められた入力エリア上のストロークは全てキーイベントに変換されます。
- 入力エリアアイコンのタップは全てキーイベントに変換されます。
- その他のストロークは全てアプリケーションが処理するものとして渡されます。
Graffiti 2 フィーチャセットが存在する場合、キーイベントを1つずつ処理する場合は注意が必要です。Graffiti 2 にはいくつかのマルチストローク文字が含まれています。最初のストロークが別の文字にマッチすると、Graffiti 2 エンジンはまずシングルストロークの文字をキューに追加し、続いてバックスペースとマルチストローク文字をキューに入れます。
例えば、文字 "k" の最初のストロークは文字 "l" と合致します。"k" の最初のストロークを描くと、Graffiti 2 エンジンはそれを処理して "l" の文字をキューに送ります。"k" の次のストロークを描くと、Graffiti 2 エンジンは "l" を削除するためにバックスペースを送り、次に文字 "k" を送ります。この間にアプリケーションが "l" を処理すると、それは誤った処理ということになります。
アプリケーションが受信した文字を処理する必要がある場合、以下の文字がマルチストローク文字の最初のストロークになり得るということを知っておく必要があります。
- 文字 "l" ( L の小文字 )
- 空白文字
- シングルクォート
- マイナス符号
これらの文字を受信した場合、次に受信する文字がバックスペースでないかどうかを監視する必要があります。
ペンキューの管理
ペンキューは、ディジタイザ上における過去直近のペンストロークをキャプチャするために、あらかじめシステムメモリ上に確保された領域で、ペン位置の保存と取得を FIFO 方式で行う循環型のキューです。ペン位置は通常低水準の割込みルーチンによってキューに追加され、システムイベントマネージャまたはアプリケーションによってキューから取り出されます。
表 3.1 にペン管理の概要を示します。
表 3.1 ペンキューの管理
ユーザー | システム |
---|---|
ディジタイザ上にペンを接触させる | ペンダウンのシーケンスをペンキューに追加し、ストロークのキャプチャを開始する |
文字を描く | ペンキューに定期的にペン位置を追加していく |
ペンを離す | ペンアップのシーケンスをペンキューに追加し、ストロークキャプチャを終了する |
システムイベントマネージャはペンキューの初期化とフラッシュ、およびキューに対するペン座標の追加・取出しのための API を提供します。いくつかの状態に関する情報は、キュー自体に保存されます。ストロークを取り出すためには、呼出元はペン座標を取り出す前にまずストローク情報を取り出すコール( EvtDequeuePenStrokeInfo )をしなければなりません。ペン座標を最後まで取り出したら、次のストロークを取り出すために EvtDequeuePenStrokeInfo を再びコールします。
イベントマネージャはペンキューに完全なペンストロークがあることを検出すると自動的に EvtDequeuePenStrokeInfo 関数をコールします。そのため、アプリケーションは通常この関数をコールする必要はありません。システムイベントマネージャは EvtDequeuePenStrokeInfo をコールすると、ストローク領域をイベントレコードに設定してペンアップイベントをアプリケーションに返します。アプリケーションは、それに対してペンキューからストロークを取り出すこともできますし、完全に無視することもできます。次に EvtGetEvent が呼ばれるまでの間にそのストロークがキューから取り出されなかった場合、システムイベントマネージャはそのストローク情報を自動的にフラッシュします。
キーキューの管理
キーキューは、キーイベントをキャプチャするためにあらかじめシステムメモリ上に確保された領域です。キーイベントは以下の2つの理由のうちいずれかによって発生します。
- ユーザーがデバイス上のボタンを押下した結果として
- ユーザーがディジタイザ上で描いた Graffiti または Graffiti 2 のストロークがソフトウェアによってキーイベントに変換された間接的な結果として
表 3.2 にキー管理の概要を示します。
表 3.2 キーキューの管理
ユーザーの操作 | システムの応答 |
---|---|
ハードウェアボタンを押下 | 割込みルーチンが適切なキーイベントをキーキューに追加し、一時的にハードウェアボタン割込みを無効化して 10ms ごとに動作するタイマータスクをセットします。 |
一定時間以上連続するキー押下 | タイマータスクがキーのオートリピートを処理します(タイマータスクはハードウェアのデバウンスにも使用されます)。 |
一定時間以上のキー開放 | タイマータスクがハードウェアボタンの割込みを再び有効にします。 |
ディジタイザ上の入力エリア内でのペンストローク | システムマネージャが Graffiti または Graffiti 2 認識機能を呼び出します。これらがペンキューからストロークを削除すると、ストロークを1つ以上のキーイベントに変換します。最後にこれらのキーイベントをキーキューに追加します。 |
シルクスクリーンアイコン上でのペンストローク | システムイベントマネージャがストロークを適切なキーイベントに変換してキーキューに追加します。 |
訳注:「デバウンス( debounce )」の意味がわかりませんでした。
システムイベントマネージャはキーキューの初期化とフラッシュ、およびキューに対するキーイベントの追加・取出しのための API を提供します。イベントマネージャはキューにキーがあることを検出すると自動的にキーイベントを取り出して EvtGetEvent コールを介してアプリケーションに keyDownEvent を返します。そのため、アプリケーションは通常この作業をする必要はありません。
オートオフコントロール
システムイベントマネージャはペンタップやボタン押下などのハードウェアイベントを管理するため、ハンドヘルドのオートオフタイマーをリセットする責任も負っています。システムがハードウェアイベントを検出すると、オートオフタイマーは自動的に 0 にリセットされます。アプリケーションから手動でリセットを行う必要がある場合、システムイベントマネージャの EvtResetAutoOffTimer 関数をコールします。