言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

Fonc で遊ぶ2

言語を作るのは地味であまり面白くなかったので、グラフィック機能で遊んでみる。Fonc には、cairo を使ったワークスペースのサンプルがあるが、あいにく Windows では動かないので、修正がてら Fonc の勉強

とりあえずコンパイル

$ cd function/canvas
$ make world

問題点

マウスは反応するがキーボードの入力が効かないみたい。Windows での画面入出力を制御してるらしい WinWindow.st をつらつら眺めていて色々な事が分かった。

  • Fonc の一般的なポイント
  • イベント処理固有のポイント
    • Windows イベントは次の課程で一旦リンクリスト events に格納される。
      • winWindow.h : static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
        • pepsi で処理しやすいように WM_KEYDOWN の wParam をキューに格納
      • eventQueue.h : static void enqueue(oop name, int a, int b, int c, int d)
        • wParam を pepsi の数値に変換し KeyDownEvent key に格納
    • イベントは、WinWindow>>nextEvent で pepsi のイベントオブジェクトに変換される
    • pepsi のシンボル #pointerDownEvent は C 言語では s_pointerDownEvent のように表現される。
    • プラットフォーム非依存コードは HostWindow.st
    • HostWindow>>keyDownEvent に上手くイベントの情報を渡せていないようだ。
    • エディタのキーボード処理は TextEditor>>inputEvent で行われている。

解決方法

TextEditor>>inputEvent でキーボードの情報を得る為に self inputCharacter: anEvent ucs4 としているが、ucs4 は Windows のイベント処理に現れない変数。もしかして、途中で気が変わってやり方を変えたのかも知れない。また、修飾キーの処理がごっそり抜け落ちている。

キーボード入力の仕方って深く考えた事無かったのだが、これはマルチプラットフォームで動くプログラムの良くある問題の一端である事が分かった。キーボード入力とは何か?を考えた時に、一つは、どのキーを押したか知りたい場合と、どの文字を入力したか知りたい場合がある。例えば Windows ではそれぞれ WM_KEYDOWN と WM_CHAR という別のイベントがあって、X11 はそれで全然別のやり方がある。これはややこしい。Fonc の場合 X11 のキーコードを UCS4 に変換するという力技をしているが、ちょっとそれは面倒すぎる。結論としては、多少インチキをして、WM_CHAR の文字コードをそのまま UCS4 に突っ込む事にした。アスキー文字とコントロールキャラの範囲では壊れないだろう。

しかし、この WM_CHAR ってほんとにちゃんと動くのだろうか?普通 Windows で文字列入力ってどうやるの?!

感想

マルチプラットフォーム用のコードが非常に面倒臭い。SDL を使えば済む話なのではないだろうか?