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 ) ) ;