Trouble with libevdev_grab

Alex Barker alex at 1stleg.com
Sun Jan 7 23:35:42 UTC 2024


Hi,

I'm having some trouble with libevdev_grab and I am not exactly sure what
is going on. Basically what happens is when I press enter to start the
program, the key release seems to get lost and the enter key gets stuck
until I press the enter key again. The only thing I've come across that
maybe related was [this](
https://lists.freedesktop.org/archives/input-tools/2015-December/001228.html)
old post about needing to drain the fd before passing it to
libevdev_set_fd.  I am not sure if that's why I seem to be getting a stuck
key and I have no idea how I should be draining the fd if that is the case.
I have attached a simple example program that illustrates the issue.
Hopefully someone can point me in the right direction.

Thanks!

// gcc libevdev_grab.c -I/usr/include/libevdev-1.0 -levdev

#include <errno.h>
#include <fcntl.h>
#include <libevdev/libevdev.h>
#include <libevdev/libevdev-uinput.h>
#include <stdio.h>

// FIXME switch out for your keyboard device
#define DEV_PATH
"/dev/input/by-id/usb-Microsoft_Microsoft_Ergonomic_Keyboard_605519294221-event-kbd"

int main()
{
    int fd = open(DEV_PATH, O_RDONLY | O_NONBLOCK);
    if (fd < 0) {
        fprintf(stderr, "Failed to open file: %s\n", DEV_PATH);
        return 1;
    }


    struct libevdev *evdev;
    int err = libevdev_new_from_fd(fd, &evdev);
    if (err < 0) {
        fprintf(stderr, "Failed to create evdev from file descriptor!
(%d)\n", err);
        return 1;
    }


    struct libevdev_uinput *uinput;
    err = libevdev_uinput_create_from_device(evdev,
LIBEVDEV_UINPUT_OPEN_MANAGED, &uinput);
    if (err < 0) {
        fprintf(stderr, "Failed to create uinput from device! (%d)\n", err);
        return 1;
    }


//*
    err = libevdev_grab(evdev, LIBEVDEV_GRAB);
    if (err != 0) {
        fprintf(stderr, "Failed to grab evdev! (%d)\n", err);
        return 1;
    }
//*/

    struct input_event ev;
    while (1) {
        int status = -EAGAIN;
        unsigned int flags = LIBEVDEV_READ_FLAG_NORMAL;
        do {
            status = libevdev_next_event(evdev, flags, &ev);
            if (err == LIBEVDEV_READ_STATUS_SYNC) {
                flags = LIBEVDEV_READ_FLAG_SYNC;
            }

            if (status != -EAGAIN) {
                printf("Event: %d %d %d\n", ev.type, ev.code, ev.value);
            }

//*
            libevdev_uinput_write_event(uinput, ev.type, ev.code, ev.value);
//*/
        } while (status != -EAGAIN);
    }

    return 0;
}


More information about the Input-tools mailing list