有没有办法检查 /dev/input/ 中的哪个事件文件用于键盘输入?

问题描述 投票:0回答:2

基本上,我想做的是使用“/dev/input/”中的文件捕获用户的键盘输入。但是,我遇到的一个问题是处理键盘输入的文件在事件文件上是不同的。我这是什么意思?好吧,在我的特定机器上,“/dev/input/event5”适用于该程序,但我发现,在某些人的机器上,该文件可能是 event4、event0、event3 甚至 event17。

有没有一种方法可以让我以编程方式找出哪个文件处理键盘输入?

如果您想测试代码,请确保您以 root 权限运行。您需要它们来打开“/dev/input/”中的任何文件。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/input.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>
 
#define UK "UNKNOWN"
#define ESCAPE(key) (key == KEY_ESC)
#define SHIFT(key)  ((key == KEY_LEFTSHIFT) || (key == KEY_RIGHTSHIFT))
 
static const char *keycodes[] =
{
    "RESERVED", "ESC", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
    "-", "=", "BACKSPACE", "TAB", "q", "w", "e", "r", "t", "y", "u", "i",
    "o", "p", "[", "]", "ENTER", "L_CTRL", "a", "s", "d", "f", "g", "h",
    "j", "k", "l", ";", "'", "`", "L_SHIFT", "\\", "z", "x", "c", "v", "b",
    "n", "m", ",", ".", "/", "R_SHIFT", "*", "L_ALT", "SPACE", "CAPS_LOCK", 
    "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "NUM_LOCK",
    "SCROLL_LOCK", "NL_7", "NL_8", "NL_9", "-", "NL_4", "NL5",
    "NL_6", "+", "NL_1", "NL_2", "NL_3", "INS", "DEL", UK, UK, UK,
    "F11", "F12", UK, UK,   UK, UK, UK, UK, UK, "R_ENTER", "R_CTRL", "/", 
    "PRT_SCR", "R_ALT", UK, "HOME", "UP", "PAGE_UP", "LEFT", "RIGHT", "END", 
    "DOWN", "PAGE_DOWN", "INSERT", "DELETE", UK, UK, UK, UK,UK, UK, UK, 
    "PAUSE"
};
 
static const char *shifted_keycodes[] =
{
    "RESERVED", "ESC", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", 
    "_", "+", "BACKSPACE", "TAB", "Q", "W", "E", "R", "T", "Y", "U", "I", 
    "O", "P", "{", "}", "ENTER", "L_CTRL", "A", "S", "D", "F", "G", "H", 
    "J", "K", "L", ":", "\"", "~", "L_SHIFT", "|", "Z", "X", "C", "V", "B", 
    "N", "M", "<", ">", "?", "R_SHIFT", "*", "L_ALT", "SPACE", "CAPS_LOCK", 
    "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "NUM_LOCK", 
    "SCROLL_LOCK", "HOME", "UP", "PGUP", "-", "LEFT", "NL_5", 
    "R_ARROW", "+", "END", "DOWN", "PGDN", "INS", "DEL", UK, UK, UK, 
    "F11", "F12", UK, UK,   UK, UK, UK, UK, UK, "R_ENTER", "R_CTRL", "/", 
    "PRT_SCR", "R_ALT", UK, "HOME", "UP", "PAGE_UP", "LEFT", "RIGHT", "END", 
    "DOWN", "PAGE_DOWN", "INSERT", "DELETE", UK, UK, UK, UK,UK, UK, UK, 
    "PAUSE"
};
 
static int running;
static int keyboard_fd;
 
static void sig_handler(int signo)
{
    running = 0;
}
 
void input_demo_init(char *keyboard_eventfile)
{
    signal(SIGINT, sig_handler);
 
    running = 1;
 
    if ((keyboard_fd = open(keyboard_eventfile, O_RDONLY)) < 0) {
        fprintf(stderr, "\nUnable to read from the device\n");
        exit(EXIT_FAILURE);
    }
}
 
void input_demo_exit(void)
{
    close(keyboard_fd);
}
 
void input_demo_run(void)
{
    int shift_flag = 0;
    struct input_event event;
 
    while (running) {
        read(keyboard_fd, &event, sizeof(event));
 
        /* If a key from the keyboard is pressed */
        if (event.type == EV_KEY && event.value == 1) {
            if (ESCAPE(event.code))
                return;
 
            if (SHIFT(event.code))
                shift_flag = event.code;
 
            if (shift_flag && !SHIFT(event.code))
                printf("%s\n", shifted_keycodes[event.code]);
            
            else if (!shift_flag && !SHIFT(event.code))
                printf("%s\n", keycodes[event.code]);
        }
        else {
            /* If a key from the keyboard is released */
            if (event.type == EV_KEY && event.value == 0)
                if (SHIFT(event.code))
                    shift_flag = 0;
        }
    }
}
 
int main(int argc, char **argv) {
 
    input_demo_init("/dev/input/event5");
    input_demo_run();
    input_demo_exit();
 
    return 0;
}
c linux input low-level evdev
2个回答
1
投票

你可以试试

cat /proc/bus/input/devices
I: Bus=001e Vendor=0000 Product=0000 Version=0001
N: Name="vc4"
P: Phys=vc4/input0
S: Sysfs=/devices/platform/soc/fef00700.hdmi/rc/rc0/input1
U: Uniq=
H: Handlers=kbd event0
B: PROP=20
B: EV=100017
B: KEY=ffffc000000000 3ff 0 400000320fc200 40830c900000000 0 210300 49d2c040ec00 1e378000000000 8010000010000000
B: REL=3
B: MSC=10

I: Bus=001e Vendor=0000 Product=0000 Version=0001
N: Name="vc4"
P: Phys=vc4/input0
S: Sysfs=/devices/platform/soc/fef05700.hdmi/rc/rc1/input2
U: Uniq=
H: Handlers=kbd event1
B: PROP=20
B: EV=100017
B: KEY=ffffc000000000 3ff 0 400000320fc200 40830c900000000 0 210300 49d2c040ec00 1e378000000000 8010000010000000
B: REL=3
B: MSC=10

希望能帮到你。


0
投票

这个答案基于此处 Edit2 上的答案:https://unix.stackexchange.com/a/94329/28489。这也可能有帮助: https://github.com/torvalds/linux/blob/02de58b24d2e1b2cf947d57205bd2221d897193c/include/linux/input.h#L45

键盘通常发送这三种事件类型:EV_SYN、EV_KEY 和 EV_MSC。

要阅读“/dev/input/event5”中发布的事件:

    if(ioctl(keyboard_fd, EVIOCGRAB, 1) < 0) print("error");
    unsigned long evbits;
    int request = EVIOCGBIT(0, sizeof(unsigned long));
    if(ioctl(keyboard_fd, EVIOCGBIT(0, sizeof(unsigned long)), & evbits) <0) print("error") // to get what type of events that this device broadcast.
    keyboardEventsMask = 0x13 // this corresponds to 0001 0011 The three on flags correspond to EV_MSC, EV_KEY, and EV_SYN respectivaly.
    var result = keyboardEventsMask & evbits;
    if(result == keyboardEventsMask) // Yes, /dev/input/event5 is a keyboard.

注意:上面的链接还建议使用

ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), &keybit);

检查设备广播的按键
© www.soinside.com 2019 - 2024. All rights reserved.