Wednesday, February 10, 2010

polling key state on a Linux keyboard with EVIOCGKEY

Here's another quick Linux input snippet.  Sometimes you just want to check if a key is pressed down rather than using the event-driven interface from evdev.  That can be accomplished by issuing EVIOCGKEY, which asks the device for a bitmask of key states.

int is_key_pressed(int fd, int key)
{
        char key_b[KEY_MAX/8 + 1];

        memset(key_b, 0, sizeof(key_b));
        ioctl(fd, EVIOCGKEY(sizeof(key_b)), key_b);

        return !!(key_b[key/8] & (1<<(key % 8)));
}

...where 'key' can be one of the key codes specified in <linux/input.h>. For example KEY_F1 corresponds to key code 59.  'fd' is a file handle for a keyboard device.

1 comment:

Anonymous said...

Hello,

just a minor nit, I think you can better use (KEY_MAX + 7) / 8 as size for the key_b array instead of KEY_MAX/8 + 1. This saves one byte if KEY_MAX is a multiple of 8. The kernel has a macro for that (DIV_ROUND_UP).

Best regards
Uwe