リアルタイムなキーボード状態の取得
概要
現在のキーボード状態をイベントを使わずに取得する。アクションゲームなどでキーイベントを使わないで現在のキーボード状態を取得したい 場合があるが、gtkにはそのような関数は用意されていない(と思う)。 そこであまり好ましくない方法であるがxlibのXQueryKeymap()関数を使用する。 Display のポインタは次のようにして取得できる。
Display* disp = GDK_WINDOW_XDISPLAY( Glib::unwrap( get_window() ) );
あとはXQueryKeymap()とXKeysymToKeycode()の組み合わせでボタン状態を取得できる。
ソース
xqkey.cpp#include <gtkmm.h> #include <gdk/gdkx.h> // GDK_WINDOW_XDISPLAY #define XK_LATIN1 #define XK_MISCELLANY #include <X11/keysymdef.h> // XK_* class MainWin : public Gtk::Window { public: MainWin(){ add_events( Gdk::BUTTON_PRESS_MASK ); } protected: virtual bool on_button_press_event( GdkEventButton* ev ); }; bool MainWin::on_button_press_event( GdkEventButton* ev ) { bool press_a = false; // キーボード状態取得 char keys[ 32 ]; Display* disp = GDK_WINDOW_XDISPLAY( Glib::unwrap( get_window() ) ); XQueryKeymap( disp, keys ); for( int i = 0; i < 32; ++i ){ for( unsigned char i2 = 0; i2 < 8 ; ++i2 ){ if( keys[ i ] & ( 1 << i2 ) ){ KeyCode code = i*8 + i2; if( XKeysymToKeycode( disp, XK_a ) == code ) press_a = true; } } } if( press_a ){ Gtk::MessageDialog diag( *this, "press a" ); diag.run(); } } int main( int argc, char *argv[] ) { Gtk::Main kit( argc, argv ); MainWin mainwin; Gtk::Main::run( mainwin ); return 0; }
コンパイル
必要なコンパイルオプションは pkg-config を使って取得する。g++ xqkey.cpp -o xqkey `pkg-config gtkmm-2.4 --cflags --libs`