キーイベント時の情報
KeyPress/KeyRelease イベントが来た時、押されたキーの文字列や KeySym を取得したい場合は、XLookupString 関数などを使います。
キーイベントの keycode を元に、キーマップデータから KeySym を取得します (修飾子は判断しません)。
index は、キーマップデータのインデックス位置です。
基本的に、0 が Shift OFF 時、1 が Shift ON 時です。詳細は前のページをご覧ください。
NoSymbol (0) が返る場合もあります。
キーイベントから、各修飾子を適用した KeySym と、そのキーの文字列 (エディタに出力するような文字列) を取得します。
キーイベントから KeySym を取得
KeySym XLookupKeysym(XKeyEvent *key_event, int index);
キーイベントの keycode を元に、キーマップデータから KeySym を取得します (修飾子は判断しません)。
index は、キーマップデータのインデックス位置です。
基本的に、0 が Shift OFF 時、1 が Shift ON 時です。詳細は前のページをご覧ください。
NoSymbol (0) が返る場合もあります。
キーイベントから KeySym や文字列を取得
<X11/Xutil.h> int XLookupString(XKeyEvent *event_struct, char *buffer_return, int bytes_buffer, KeySym *keysym_return, XComposeStatus *status_in_out);
キーイベントから、各修飾子を適用した KeySym と、そのキーの文字列 (エディタに出力するような文字列) を取得します。
buffer_return | ISO Latin-1 文字、または ASCII 制御文字に変換され、その文字列が返る。 |
---|---|
bytes_buffer | buffer_return のバッファバイト数 |
keysym_return | KeySym が返る |
status_in_out | 基本的に NULL にします |
戻り値 | バッファに格納された文字数 |
オートリピート
X でキーのオートリピートが ON の場合は、キーが押されている間、一定間隔で KeyPress と KeyRelease イベントが交互に生成されます。
a のキーをずっと押していれば、エディタ上に "aaa..." と入力されることになります。
オートリピートの ON/OFF を切り替えることはできますが、X サーバーのグローバル設定を変更することになるので、すべてのクライアントに適用されてしまいます。
そのため、基本的にはデフォルトのまま (ON の状態) で、オートリピートによる KeyPress と KeyRelease イベントを、自分で解釈して処理した方が良いです。
KeyRelease の直後に、同じ keycode と time で KeyPress が来た場合は、オートリピートによるものと判断できます。
a のキーをずっと押していれば、エディタ上に "aaa..." と入力されることになります。
オートリピートの ON/OFF を切り替えることはできますが、X サーバーのグローバル設定を変更することになるので、すべてのクライアントに適用されてしまいます。
そのため、基本的にはデフォルトのまま (ON の状態) で、オートリピートによる KeyPress と KeyRelease イベントを、自分で解釈して処理した方が良いです。
KeyRelease の直後に、同じ keycode と time で KeyPress が来た場合は、オートリピートによるものと判断できます。
プログラム
XLookupString() で、KeySym と文字列を取得して表示しています。
オートリピート時のイベントも確認してみてください。
ポインタボタンを押すと終了します。
<16-key2.c>
XLookupString() で取得した文字列は、ASCII 制御文字の場合があるので、Enter キーなら 13、Tab キーなら 9、Delete キーなら 127 になります。
'a' や '1' などの表示可能な文字かどうかは、最初の文字で判断してください。
オートリピート時のイベントも確認してみてください。
ポインタボタンを押すと終了します。
$ cc -o run 16-key2.c util.c -lX11
<16-key2.c>
#include <stdio.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include "util.h" int main(int argc,char **argv) { Display *disp; XSetWindowAttributes attr; Window win; XEvent ev; KeySym ksym; char m[16],*name; int len; disp = XOpenDisplay(NULL); if(!disp) return 1; //ウィンドウ作成 attr.background_pixel = 0; attr.event_mask = ButtonPressMask | KeyPressMask | KeyReleaseMask; win = XCreateWindow(disp, DefaultRootWindow(disp), 0, 0, 200, 200, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel | CWEventMask, &attr); XMapWindow(disp, win); //イベント while(1) { XNextEvent(disp, &ev); switch(ev.type) { case KeyPress: case KeyRelease: len = XLookupString((XKeyEvent *)&ev, m, 15, &ksym, 0); m[len] = 0; name = XKeysymToString(ksym); printf("[%s] keycode(%u) keysym(%lu)[%s] time(%lu)", (ev.type == KeyPress)? "Press": "Release", ev.xkey.keycode, ksym, (name)? name: "-", ev.xkey.time); if(len) { if(m[0] >= 0x20 && m[0] < 0x7f) printf(" '%s'", m); else printf(" <%d>", m[0]); } printf("\n"); put_state(ev.xkey.state); fflush(stdout); break; case ButtonPress: goto END; } } END: XCloseDisplay(disp); return 0; }
XLookupString() で取得した文字列は、ASCII 制御文字の場合があるので、Enter キーなら 13、Tab キーなら 9、Delete キーなら 127 になります。
'a' や '1' などの表示可能な文字かどうかは、最初の文字で判断してください。