sodiumイオンにっき2.0

トップ アンテナ はてなアンテナに追加 WikiPage 本棚.org 今日はなんの日 <前の日記(2008 11/18) 次の日記(2008 11/20)> 最新 編集
2002|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|

 この日記にツッコミを入れたい人は、ツッコミを入れたい日付をクリックすると、フォームが現れることもある模様です。


2008 11/19 [長年日記]

「Xlibを使ったプログラムでキーボードイベントが取得できない」解決編

次のようなプログラムで、キーボード入力ができなかった。

#include <stdio.h>
#include <X11/Xlib.h>
 
main()
{
    Display *dsp;   /* ディスプレイ構造体の宣言 */
    Window  win;    /* ウィンドウ構造体の宣言 */
    XEvent  ev;     /* イベント構造体 */
    XSetWindowAttributes att;
    char buf[64];
    KeySym keysym;
 
    dsp = XOpenDisplay( NULL ); /* ディスプレイのオープン */
    if (dsp == NULL) {
        fputs("can not connect display\n", stderr);
        exit(1);
    }
    /* ウィンドウの生成 */
    win = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), 0, 0, 800, 400, 1,
                              BlackPixel(dsp,0), WhitePixel(dsp,0));
    att.override_redirect = True;
    XChangeWindowAttributes(dsp, win, CWOverrideRedirect, &att);
 
    XSelectInput(dsp, win,
		ButtonPressMask|
		ButtonReleaseMask|
		KeyPressMask|
		KeyReleaseMask|
		EnterWindowMask|
		LeaveWindowMask
	);
    XMapWindow(dsp, win);   /* ウィンドウの表示 */
    XFlush(dsp);
 
    while (True) {              /* イベントの無限ループの開始 */
        XNextEvent(dsp, &ev);   /* 新しいイベントを受け取る */
        switch (ev.type) {      /* イベントのタイプで処理を分ける */
        case ButtonPress:
            printf("event.type=ButtonPress No=[%d]\n", ev.xbutton.button);
            switch (ev.xbutton.button) {
            case 3:
                goto CLOSE_WINDOW;
                break;
            default:
                break;
            }
            break;
        case KeyPress:
        case KeyRelease:
            printf("event.type=%s\n",
			        (ev.type == KeyPress) ? "KeyPress" : "KeyRelease");
            if (XLookupString(&(ev.xkey),buf,sizeof(buf),&keysym,NULL) >= 1) {
                if (isprint(buf[0])) {
                    printf("KeyPress=[%s] keysym = [%x]\n", buf, keysym);
                } else {
                    printf("KeyPress=[%02x][%02x] keysym=[%x]\n",
					        buf[0], buf[1], keysym);
                }
            } else {
                printf("keysym = [%x]\n", buf, keysym);
            }
            break;
        case EnterNotify:
            printf("event.type=EnterNotify No=[%d]\n", ev.xbutton.button);
            break;
        case LeaveNotify:
            printf("event.type=LeaveNotify No=[%d]\n", ev.xbutton.button);
            break;
        default:
            break;
        }
    }
CLOSE_WINDOW:
    XCloseDisplay( dsp );   /* ディスプレイのクローズ */
	exit(0);
}

原因は、XChangeWindowAttributes()でウィンドウマネージャから独立していたので、ウィンドウにマウスが乗ってもキーボードのフォーカスがウィンドウに当たっていなかったから、らしいです。

なので、EnterNotifyイベントに

            XSetInputFocus(dsp, win, RevertToParent, CurrentTime);

を追加して、自分で入力フォーカスを設定したらキーボードイベントが取得できるようになりました。

以上、覚書メモ

なんか、これが解決したら気が抜けてしまってグダグダになってます。

Tags: X computer

[]