使用 EVIOCSMASK 过滤键码

Filtering keycodes with EVIOCSMASK

/dev/input/event* 文件读取时,我只想接收代码为 224225EV_KEY 事件。我该怎么做?


据我所知,我需要 运行 ioctl(fd, EVIOCSMASK, &mask),但我不明白如何根据我的规格设置 struct input_mask

我尝试将 type 设置为 EV_KEY,但这似乎过滤了 out EV_KEY,如果我在 [=] 中设置任何内容19=](例如代码数组和指向它的指针),然后 ioctl returns -1.

这里是一个如何设置掩码的例子

    struct input_mask mask;

    bitset_put(types, KEY_BRIGHTNESSDOWN); // event ID 224
    bitset_put(types, KEY_BRIGHTNESSUP); // event ID 225

    mask = (struct input_mask) {
            .type = EV_KEY,
            .codes_size = sizeof(types),
            .codes_ptr = PTR_TO_UINT64(types),
    };

    if (ioctl(b->fd, EVIOCSMASK, &mask) < 0)
    {
      //log the error here and check errno to get a nice description about the error
    }...

正如你所看到的代码很容易理解,你声明要接收哪种事件类型(这里'EV_KEY')然后一个数组来过滤出你可以获得哪些事件here

看看include/linux/input.h:

The event mask is a per-client mask that specifies which events are forwarded to the client. Each event code is represented by a single bit in the event mask. If the bit is set, the event is passed to the client normally.

换句话说:

#include <stdlib.h>
#include <limits.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <errno.h>

#define  ULONG_BITS  (CHAR_BIT * sizeof (unsigned long))

static void set_bit(unsigned long bits[], size_t bit)
{
    bits[bit / ULONG_BITS] |= 1UL << (bit % ULONG_BITS);
}

static void set_keymask(int fd)
{
    unsigned long      bits[(KEY_CNT + ULONG_BITS - 1) / ULONG_BITS] = { 0 };
    struct input_mask  mask;

    mask.type = EV_KEY;
    mask.codes_size = KEY_CNT;
    mask.codes_ptr = &bits;

    /* Only report KEY_BRIGHTNESSDOWN and KEY_BRIGHTNESSUP */
    set_bit(bits, KEY_BRIGHTNESSDOWN);
    set_bit(bits, KEY_BRIGHTNESSUP);

    if (ioctl(fd, EVIOSMASK, &mask))
        return errno;

    return 0;
}