12
May
Posted by Derek@TheDailyLinux in Programming » 12 Comments »
Grab Raw Keyboard Input from Event Device Node (/dev/input/event)
The following is a quick c program that will capture raw keyboard data from the event device node such as /dev/input/event1. Simply compile and run with the specific device node as an argument. ie. ./keyboard_key_capture /dev/input/event1.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>
void handler (int sig)
{
printf ("nexiting...(%d)n", sig);
exit (0);
}
void perror_exit (char *error)
{
perror (error);
handler (9);
}
int main (int argc, char *argv[])
{
struct input_event ev[64];
int fd, rd, value, size = sizeof (struct input_event);
char name[256] = "Unknown";
char *device = NULL;
//Setup check
if (argv[1] == NULL){
printf("Please specify (on the command line) the path to the dev event interface devicen");
exit (0);
}
if ((getuid ()) != 0)
printf ("You are not root! This may not work...n");
if (argc > 1)
device = argv[1];
//Open Device
if ((fd = open (device, O_RDONLY)) == -1)
printf ("%s is not a vaild device.n", device);
//Print Device Name
ioctl (fd, EVIOCGNAME (sizeof (name)), name);
printf ("Reading From : %s (%s)n", device, name);
while (1){
if ((rd = read (fd, ev, size * 64)) < size)
perror_exit ("read()");
value = ev[0].value;
if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){ // Only read the key press event
printf ("Code[%d]n", (ev[1].code));
}
}
return 0;
}
Here is an example output from running the above command. Notice that Code[] is printed before the key that was pressed.
# ./keyb_key_cap_x86 /dev/input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd Reading From : /dev/input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd (Dell Dell USB Keyboard) Code[30] aCode[48] bCode[46] cCode[32] dCode[18] eCode[33] fCode[34] gCode[35] hCode[23] iCode[36] jCode[37] kCode[38] lCode[50] mCode[49] nCode[24] oCode[25] pCode[16] qCode[19] rCode[31] sCode[20] tCode[22] uCode[47] vCode[17] wCode[45] xCode[21] yCode[44] zCode[2] 1Code[3] 2Code[4] 3Code[5] 4Code[6] 5Code[7] 6Code[8] 7Code[9] 8Code[10] 9Code[11] 0
This is only an example program that I picked up from work. I hope it will be of use to somebody out there so it can quickly help you get started with your project.
Feel free to donate if this post prevented any headaches! Another way to show your appreciation is to take a gander at these relative ads that you may be interested in:
Here are some similar posts that you may be interested in:
There's 12 Comments So Far
August 12th, 2010 at 9:54 am
What license are you posting this under?
I’m including it in an keyboard monitoring app I wrote (nealy verbatim), and you
never specified a license.
August 12th, 2010 at 10:57 am
Good question. Anything I post on this site is open game to everybody. I wouldn’t say there is any license, but if I were to give it one I suppose it would fall under the BSD License which allows everyone to use and redistribute the program as they wish.
Just don’t use it for evil.
August 12th, 2010 at 2:29 pm
“Just don’t use it for evil.
”
Decide yourself
The project is at http://github.com/adamnew123456/kbmon
It is (in it’s slightly modified form) in “src/kbd-demo.c”
December 22nd, 2010 at 4:25 am
Hi, thank you very much for this program! I just wonder why did you skip ev[0]? it was not working for me. I have modified it in a such way:
instead of this code:
if (value != ‘ ‘ && ev[1].value == 1 && ev[1].type == 1){ // Only read the key press event
printf (“Code[%d]n”, (ev[1].code));
}
i used this:
if (ev[0].value == 1 && ev[0].type == EV_KEY) // Only read the key press event
printf (“Code[%d]n”, (ev[0].code));
December 22nd, 2010 at 8:05 am
It was more of a throw-it-together program for testing purposes. I’m happy to hear that 1) you’ve found it useful and 2) you have brought an improvement to the table! Thank you!
December 27th, 2010 at 3:37 am
Thank you for posting this. I’ve been working on the same thing for about a day now and while I can read the output from event(x) I was having a difficult time figuring out its format, especially since I haven’t had much practice with UTF. After digging through the Linux kernel device drivers I got lucky finding your included headers and got pointed in the right direction. Thanks a ton!
February 9th, 2011 at 1:22 pm
is it possible to have the ((rd = read (fd, ev, size * 64)) < size) non blocking (if no key is pressed) ?
February 9th, 2011 at 1:53 pm
hum found
sorry 
O_RDONLY | O_NONBLOCK
February 15th, 2011 at 5:03 am
Thank you for this good example!
July 18th, 2011 at 6:27 am
Hi all,
I have a problem with reading USB keyboard event file. I can read this file using this program but the problem is that some characters that I type are read multiple times(2 or 3 times). Like I type on my keyboard some number, for example code(73) and my application reads this thing often 2 times, or 3 times. I’ve been looking for this all over the Internet and I didn’t find anything useable to solve this problem yet. Could anyone help me with this?
Or could anyone explain me if the keyboard event file is somehow buffered and if there is any way to clean this file after every reading from this file? Maybe this could solve my problem that some characters are read multiple – 2 or 3 times.
October 24th, 2011 at 6:40 am
Thanks man. It was really helpful
Who Linked To This Post?
Share your thoughts, leave a comment!