リアルタイムなキーボード状態の取得
概要
現在のキーボード状態をイベントを使わずに取得する。アクションゲームなどでキーイベントを使わないで現在のキーボード状態を取得したい 場合があるが、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`