4

Linux の C でキーボードまたはマウスのイベントを追跡するにはどうすればよいですか?

たとえば、ユーザーが押した場合ESC Shiftなど、追跡できるはずです。マウスも同じ方法です。ユーザーがマウスを動かしたり、左右にクリックしたりした場合。

実装のアイデアは、タイマー付きの小さなスクリーンセーバーを作成することであり、キーボードまたはマウスのイベントを追跡してタイマーをリセットする方法に苦労しています。

4

2 に答える 2

3

1 つの可能性は、入力サブシステムを使用することです。この記事を見てみましょう: 入力サブシステムの使用 ( http://www.linuxjournal.com/article/6429 )

もう 1 つは、ファイル /dev/input/event* を読み取ろうとする作業スレッドを作成することです。たとえば、キーボードの場合は次のようになります。

// (const char *)ptr - pass your device like "/dev/input/event2" here
fd = open((const char *)ptr, O_RDONLY);

if (fd < 0)
{
    fprintf(stderr, "failed to open input device %s: %s\n", (const char *)ptr, strerror(errno));
    return NULL;
}

struct timeval escapeDown = { 0, 0};
int code;
while (1)
{
    if (read(fd, &ev, sizeof(struct input_event)) < 0)
    {
        fprintf(stderr, "failed to read input event from input device %s: %s\n", (const char *)ptr, strerror(errno));
        if (errno == EINTR)
            continue;
        break;
    }

    code = -1;
    if (ev.type == EV_KEY)
    {
        switch (ev.code)
        {
        case eEsc:
            if (ev.value == 1)
            {
                escapeDown = ev.time;
                printf("DOWN: ESC\n");
            }
            else if (ev.value == 0 && escapeDown.tv_sec)
            {
                printf("UP:   ESC\n");
                if (isLongPressed(&escapeDown, &ev.time))
                    code = eEscLong;
                else
                    code = eEsc;

                escapeDown.tv_sec  = 0;
                escapeDown.tv_usec = 0;
            }
            break;
        case eOk:
        case eUp:
        case eRight:
        case eLeft:
        case eDown:
            if (ev.value == 0)
            {
                printf("UP:   %s\n", keyName(ev.code));
                code = ev.code;
            }
            else if (ev.value == 1)
            {
                printf("DOWN: %s\n", keyName(ev.code));
            }
            escapeDown.tv_sec  = 0;
            escapeDown.tv_usec = 0;
            break;
        default:
            break;
        }
    }
    if (code > 0)
    {
        struct sMsg* pMsg = malloc(sizeof(struct sMsg));
        if (pMsg)
        {
            pMsg->nMsgType = eMsgKeyLogger;
            pMsg->nIntValue= code;
            postMsg(pMsg);
        }
        printf("generated keyboard event: %u %s\n",
               code,
               keyName(code));
    }
    else
        usleep(100);
}

close(fd);
于 2013-03-18T08:55:07.720 に答える
2

プロジェクトのサイズと性質を考慮して、GLUTを確認することをお勧めします。これは実際には OpenGL の便利なライブラリですが、使いやすいクロスプラットフォームの入力処理とタイマー機能も提供します。将来的に他のプラットフォームに移行したい場合に備えて。それ以外は、アプリケーションのグラフィカルな性質とうまく調和します。

編集:リンクしたプロジェクトは、実際には、全体的に強化された API を備えた元の GLUT の後継です。元の API リファレンスについては、こちらを参照してください

あなたの場合、次のようなものを使用できます。

void keyboardFunc(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 'a':
        break;
    /* etc */
    }
}

void displayFunc()
{
    /* Statements issuing the drawing of your screensaver */
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);

    /* Other initialization code */

    glutKeyboardFunc(keyboardFunc);
    glutDisplayFunc(displayFunc);

    glutMainLoop();
}
于 2013-03-18T08:57:32.883 に答える