キー入力
今日はGTK+のキー入力について調べました。
WindowsのGetAsyncKeyStateやDirectInputのポーリングと違って明示的にキーの状態を問い合わせることは出来なくて*1、キーが押されたらkey-press-eventシグナルが、放されたらkey-release-eventシグナルが発行されるので、これをコールバック関数で処理することになります。
DirectInputのキーボード/マウス入力は既に非推奨だったと思うので、こっちで統一したほうがよいでしょうね。
キー情報は次の構造体で渡されます。
typedef struct { GdkEventType type; GdkWindow *window; gint8 send_event; guint32 time; guint state; guint keyval; gint length; gchar *string; guint16 hardware_keycode; guint8 group; guint is_modifier : 1; } GdkEventKey;
keyvalにGDKのキーコードが入るんですが、大文字/小文字が区別されるのが難点です。
このため、「Shift+A」を押してから「Shift」だけ放すと、「A」に対するkey-release-eventシグナルは発行されずに、(キーリピートで)「a」のkey-press-eventシグナルが発行されます。
これだとkey-press-eventシグナルが役に立たない気がします。
ただ、hardware_keycodeに実装依存のキーコードが入っているので、これを使えば同一キーの判定は出来そうです。
Win32では仮想キーコード(VK_〜)、X11ではXEventのxkey.keycodeが入っている模様。
せっかくマルチプラットフォームのツールキットを使っているのに、実装ごとに処理を切り替えるのはアレですが、「どの文字が入力されたか」という視点か、「どのキーが押されたか」という視点かの違いだと思って諦めるしかないですね。
*1:gdk_device_get_state()という関数もありますが、少なくともWin32版ではキーボードに対応していないっぽいです。