从Linux输入设备访问密钥

 上海千恩万燮 发布于 2023-02-06 12:55

打开输入设备,

#include 
#include 
#include 
#include 
#include 
#include 
#include 

static const char *const evval[3] = {
    "RELEASED",
    "PRESSED ",
    "REPEATED"
};

int main(void)
{
    const char *dev = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
    struct input_event ev;
    ssize_t n;
    int fd;

    fd = open(dev, O_RDONLY);
    if (fd == -1) {
        fprintf(stderr, "Cannot open %s: %s.\n", dev, strerror(errno));
        return EXIT_FAILURE;
    }

然后从设备中读取键盘事件:

    while (1) {
        n = read(fd, &ev, sizeof ev);
        if (n == (ssize_t)-1) {
            if (errno == EINTR)
                continue;
            else
                break;
        } else
        if (n != sizeof ev) {
            errno = EIO;
            break;
        }

如果发生任何错误,或者如果用户空间仅接收部分事件结构(不应该发生,但可能在某些未来/错误的内核中),则上述片段从循环中突破.您可能希望使用更强大的读取循环; 我个人会被替换最后一个满足breakcontinue,所以,局部的事件结构被忽略.

然后,您可以检查ev事件结构以查看发生的情况,并完成程序:

        if (ev.type == EV_KEY && ev.value >= 0 && ev.value <= 2)
            printf("%s 0x%04x (%d)\n", evval[ev.value], (int)ev.code, (int)ev.code);

    }
    fflush(stdout);
    fprintf(stderr, "%s.\n", strerror(errno));
    return EXIT_FAILURE;
}

对于按键,

ev.time:活动时间(struct timeval类型)

ev.type: EV_KEY

ev.code:KEY_*,密钥标识符; 查看完整列表/usr/include/linux/input.h

ev.value:0如果按键释放,1如果按键,2如果是自动重复按键

有关更多详细信息,请参阅Linux内核源代码中的Documentation/input/input.txt.

命名常量/usr/include/linux/input.h非常稳定,因为它是一个内核用户空间接口,内核开发人员非常努力地保持兼容性.(也就是说,您可能会偶尔会有新代码,但现有代码很少会发生变化.)

1 个回答
  • 打开输入设备,

    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <linux/input.h>
    #include <string.h>
    #include <stdio.h>
    
    static const char *const evval[3] = {
        "RELEASED",
        "PRESSED ",
        "REPEATED"
    };
    
    int main(void)
    {
        const char *dev = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
        struct input_event ev;
        ssize_t n;
        int fd;
    
        fd = open(dev, O_RDONLY);
        if (fd == -1) {
            fprintf(stderr, "Cannot open %s: %s.\n", dev, strerror(errno));
            return EXIT_FAILURE;
        }
    

    然后从设备中读取键盘事件:

        while (1) {
            n = read(fd, &ev, sizeof ev);
            if (n == (ssize_t)-1) {
                if (errno == EINTR)
                    continue;
                else
                    break;
            } else
            if (n != sizeof ev) {
                errno = EIO;
                break;
            }
    

    如果发生任何错误,或者如果用户空间仅接收部分事件结构(不应该发生,但可能在某些未来/错误的内核中),则上述片段从循环中突破.您可能希望使用更强大的读取循环; 我个人会被替换最后一个满足breakcontinue,所以,局部的事件结构被忽略.

    然后,您可以检查ev事件结构以查看发生的情况,并完成程序:

            if (ev.type == EV_KEY && ev.value >= 0 && ev.value <= 2)
                printf("%s 0x%04x (%d)\n", evval[ev.value], (int)ev.code, (int)ev.code);
    
        }
        fflush(stdout);
        fprintf(stderr, "%s.\n", strerror(errno));
        return EXIT_FAILURE;
    }
    

    对于按键,

    ev.time:活动时间(struct timeval类型)

    ev.type: EV_KEY

    ev.code:KEY_*,密钥标识符; 查看完整列表/usr/include/linux/input.h

    ev.value:0如果按键释放,1如果按键,2如果是自动重复按键

    有关更多详细信息,请参阅Linux内核源代码中的Documentation/input/input.txt.

    命名常量/usr/include/linux/input.h非常稳定,因为它是一个内核用户空间接口,内核开发人员非常努力地保持兼容性.(也就是说,您可能会偶尔会有新代码,但现有代码很少会发生变化.)

    2023-02-06 12:59 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有