在Linux上测试是否按下了按键而没有阻塞

时间:2015-01-15 16:40:12

标签: c++ linux keyboard

我正在搜索如何测试是否按下了某个键。测试不应该阻止程序。如果它不是太重,我可以使用一个小库,但不幸的是,ncurses太依赖于引入。

2 个答案:

答案 0 :(得分:2)

我找到了解决方案:

int khbit() const
{
    struct timeval tv;
    fd_set fds;
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    FD_ZERO(&fds);
    FD_SET(STDIN_FILENO, &fds);
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
    return FD_ISSET(STDIN_FILENO, &fds);
}

void nonblock(int state) const
{
    struct termios ttystate;
    tcgetattr(STDIN_FILENO, &ttystate);

    if ( state == 1)
    {
        ttystate.c_lflag &= (~ICANON & ~ECHO); //Not display character
        ttystate.c_cc[VMIN] = 1;
    }
    else if (state == 0)
    {
        ttystate.c_lflag |= ICANON;
    }
    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}

bool keyState(int key) const //Use ASCII table
{
    bool pressed;
    int i = khbit(); //Alow to read from terminal
    if (i != 0)
    {
        char c = fgetc(stdin);
        if (c == (char) key)
        {
            pressed = true;
        }
        else
        {
            pressed = false;
        }
    }

    return pressed;
}

int main()
{
    nonblock(1);
    int i = 0;
    while (!i)
    {
        if (cmd.keyState(32)) //32 in ASCII table correspond to Space Bar
        {
            i = 1;
        }
    }
    nonblock(0);

    return 0;
}

效果很好。谢谢你的帮助。我希望它会帮助某人:)

答案 1 :(得分:0)

我不知道你正在寻找什么

  • 我最近做了一个概念验证阅读" raw"此处输入设备节点: boost::asio read from /dev/input/event0 。示例是使用鼠标,但Linux内核统一了输入设备,因此键盘大致相同。

    这里所需要的只是UNIX权限来打开/读取设备文件(如果这对您的部署风格更方便,可以在/ etc-tree之外创建它们。)

    该示例显示事件的完整异步处理

  • 我已经使用绑定到XTest(libxtst)(实际上是发送击键);我想这可能包含你需要的功能

  • 然后有XInput(据我所知)构成XOrg方式来抽象" raw"我在第一个选项

  • 中描述的输入设备流