I had to write some userspace code to read and write to a keyboard device in Linux using C++. I thought it would be as simple and open(), read() and write(). I was close but was missing a couple key items: scan codes and input_event.
Open Device
Opening the keyboard device is the same as opening any other device in linux
char *device = "/dev/input/event1";
if( (fd = open(device, O_RDWR)) < 0 )
{
// Read or Write to device
}
Read Keyboard Device
Read from the keyboard device. Instead of passing a char array as the buffer, pass an input_event struct to store the results of the read. KEY_UP or any other scan code numeric value is specific to your Linux key mapping. KEY_UP is defined for your
Linux setup so do not forget to include linux/input.h. Use the definition for the key scan code and not the actual scan code numeric value.
#define EV_PRESSED 1
#define EV_RELEASED 0
#define EV_REPEAT 2
struct input_event event;
unsigned int scan_code = 0;
int num_bytes = read(fd, &event, sizeof(struct input_event));
if(event.type != EV_KEY)
return; // Keyboard events are always of type EV_KEY
if(event.value == EV_RELEASED)
{
scan_code = event.code;
if(scan_code == KEY_UP)
// Do something if keyboard up arrow pressed
}
Write to Keyboard Device
To write to the device, you populate the input_event struct with the key scan code. You also set the type to EV_KEY and the value to either “press” or “release”. To represent a keyboard, you must do a press and a release because some code may be looking for
a key press or a key released.
// Press the key down
event.type = EV_KEY;
event.value = EV_PRESSED;
event.code = KEY_UP;
write(fd, &event, sizeof(struct input_event));
// Release the key
event.value = EV_RELEASED;
event.code = KEY_UP;
write(fd, &event, sizeof(struct input_event));