Wednesday, February 10, 2010

Linux input event (evdev) snippet: find a keyboard by name

Here's a (hopefully useful) function for opening a keyboard (input event device) by name on Linux. For example, you want to open a device named "My Keyboard" but you don't know it's at /dev/input/event2. This function will open "/dev/input" and ask for the device name from each "eventN" device. It will return the file descriptor for the first device whose name matches (and the descriptor will be left open) or -1 if none matched.

#include <linux/input.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int get_kb_fd(char *input_name)
{
        int fd;
        struct dirent *dp;
        char name[32];
        char dev[32];
        DIR *dir;

        dir = opendir("/dev/input");
        if (!dir)
                return 1;

        while ((dp = readdir(dir)) != NULL) {
                if (dp->d_name && !strncmp(dp->d_name, "event", 5)) {
                        snprintf(dev, sizeof(dev), "/dev/input/%s", dp->d_name);
                        fd = open(dev, O_RDONLY);
                        if (fd == -1)
                                continue;
                        if (ioctl(fd, EVIOCGNAME(32), name) < 0) {
                                close(fd);
                                continue;
                        }

                        if (!strcmp(name, input_name)) {
                                closedir(dir);
                                return fd;
                        } else { /* not what we wanted, check another */
                                close(fd);
                                fd = -1;
                        }
                }
        }

        closedir(dir);
        return -1;
}

No comments: