Reading and writing to the Linux keyboard buffer
This is not a question, it is an answer post:
I had a project where I needed to stuff the Linux keyboard with some keystrokes to control a web browser remotely. I couldn't believe how little information there was on the keyboard buffer and how much time it took me to figure it all out. I saw many posts with similar questions but very few with any real working answers and code. So, I thought I'd post what I figured out.
1) First determine the event ID of your keyboard at the command line using either: $cat /proc/bus/input/devices
or
viewing the var/log/Xorg.0.log searching for "keyboard"
2) Edit the posted code and insert the event id for your system in the following code segment:
char *device = "/dev/input/event4";
3) When running the program you will need to be logged in a su or sudo user.
Run the command with: $ sudo ./a.out
4) All keyboard key defines can be located in the header file:
#include <linux/input.h>
Here is a snippet of a working writer/reader in its entirety:
I hope this can help others.
#include <stdio.h>
#include <fcntl.h>
#include <linux/input.h>
#include <sstream>
#define EV_PRESSED 1
#define EV_RELEASED 0
#define EV_REPEAT 2
/*
* Purpose: Stuffs the Linux keyboard buffer with a key and
* reads it back out of the buffer.
* All key definitions can be found in input.h file:
* /usr/src/linux-headers-3.2.0-23/include/linux
*
*/
main()
{
/************************************************
* IMPORTANT
* you need to execute this code as the su or
* sudo user in order to open the device properly.
***********************************************/
printf("Starting the keyboard buffer writer/reader \n");
int fd = 0;
char *device = "/dev/input/event4"; // This is the keyboard device as identified using both: $cat /proc/bus/input/devices
// and looking in the var/log/Xorg.0.log searching for "keyboard"
// Write a key to the keyboard buffer
if( (fd = open(device, O_RDWR)) > 0 )
{
struct input_event event;
printf("The keyboard code is: %d \n", KEY_B); // Note: these are not the same as ASCII codes.
// Press a key (stuff the keyboard with a keypress)
event.type = EV_KEY;
event.value = EV_PRESSED;
event.code = KEY_B;
write(fd, &event, sizeof(struct input_event));
// Release the key
event.value = EV_RELEASED;
event.code = KEY_B;
write(fd, &event, sizeof(struct input_event));
close(fd);
}
// Read the key back from the keyboard buffer
int fd1 = 0;
if( (fd1 = open(device, O_RDONLY)) > 0 ) // It's important to open a new file descriptor here or the program will block.
{
struct input_event event;
unsigned int scan_code = 0;
if(event.type != EV_KEY)
{
return 0; // Keyboard events are always of type EV_KEY
}
if(event.value == EV_RELEASED)
{
scan_code = event.code;
printf("read back scan_code is: %d \n", scan_code);
}
close(fd1);
}
}
Last edited by jtyrrell; 07-13-2012 at 08:01 AM.
|