Add epoll implementation to capture keyboard and mouse.
Yay, double capture!
This commit is contained in:
parent
ce83c74991
commit
54201de47b
154
capture.c
154
capture.c
|
@ -1,12 +1,25 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
void dump_event(struct timespec* start, struct input_event* event);
|
||||
int stream_events(char* device_path);
|
||||
#include <linux/input.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#define MAX_EVENTS 16
|
||||
#define CONTENT_BUFFER_SIZE 32
|
||||
|
||||
static char* KEYBOARD = "k";
|
||||
static char* MOUSE = "m";
|
||||
|
||||
int dump_event(struct timespec* start, int fd, char* type);
|
||||
|
||||
int event_content_keyboard(char* buffer, int buffer_size, struct input_event* event);
|
||||
int event_content_mouse(char* buffer, int buffer_size, struct input_event* event);
|
||||
|
||||
int stream_events(char* mouse_path, char* keyboard_path);
|
||||
|
||||
static inline void timespec_diff(struct timespec* a, struct timespec* b, struct timespec* result) {
|
||||
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||
|
@ -17,59 +30,138 @@ static inline void timespec_diff(struct timespec* a, struct timespec* b, struct
|
|||
}
|
||||
}
|
||||
|
||||
void dump_event(struct timespec* start, struct input_event* event) {
|
||||
unsigned char button, bLeft, bMiddle, bRight;
|
||||
unsigned char *ptr = (unsigned char*)event;
|
||||
int i;
|
||||
char x, y;
|
||||
int dump_event(struct timespec* start, int fd, char* type) {
|
||||
struct input_event event;
|
||||
struct timespec now;
|
||||
struct timespec diff;
|
||||
char content_buffer[CONTENT_BUFFER_SIZE];
|
||||
|
||||
int result = read(fd, &event, sizeof(struct input_event));
|
||||
if(result < 0) {
|
||||
fprintf(stderr, "Failed to read an event: %d", errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
timespec_diff(&now, start, &diff);
|
||||
|
||||
if(type == MOUSE) {
|
||||
if(event_content_mouse(content_buffer, CONTENT_BUFFER_SIZE, &event)) {
|
||||
return 1;
|
||||
}
|
||||
} else if(type == KEYBOARD) {
|
||||
if(event.type == EV_SYN) {
|
||||
return 0;
|
||||
}
|
||||
if(event_content_keyboard(content_buffer, CONTENT_BUFFER_SIZE, &event)) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Unknown event type.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%ld.%ld,%s,%s\n",
|
||||
diff.tv_sec,
|
||||
diff.tv_nsec,
|
||||
type,
|
||||
content_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int event_content_keyboard(char* buffer, int buffer_size, struct input_event* event) {
|
||||
sprintf(buffer, "?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int event_content_mouse(char* buffer, int buffer_size, struct input_event* event) {
|
||||
unsigned char button, bLeft, bMiddle, bRight;
|
||||
unsigned char *ptr = (unsigned char*)event;
|
||||
int i;
|
||||
char x, y;
|
||||
button = ptr[0];
|
||||
bLeft = button & 0x1;
|
||||
bMiddle = ( button & 0x4 ) > 0;
|
||||
bRight = ( button & 0x2 ) > 0;
|
||||
x=(char) ptr[1];y=(char) ptr[2];
|
||||
printf("%ld.%ld,m,l%d,m%d,r%d,x%d,y%d\n",
|
||||
diff.tv_sec,
|
||||
diff.tv_nsec,
|
||||
bLeft, bMiddle, bRight, x, y);
|
||||
x=(char) ptr[1];
|
||||
y=(char) ptr[2];
|
||||
|
||||
//
|
||||
// comment to disable the display of raw event structure datas
|
||||
//
|
||||
// for(i=0; i<sizeof(event); i++)
|
||||
// {
|
||||
// printf("%02X ", *ptr++);
|
||||
// }
|
||||
int chars = sprintf(buffer, "l%d,m%d,r%d,x%d,y%d",
|
||||
bLeft, bMiddle, bRight, x, y);
|
||||
return chars < 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc < 2) {
|
||||
fprintf(stderr, "You must specify a mouse input to track like /dev/input/mouse1.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int result = stream_events(argv[1]);
|
||||
if(argc < 3) {
|
||||
fprintf(stderr, "You must specify a keyboard input to track like /dev/input/event3. If you're not sure which to use read through /proc/bus/input/devices and look for 'Handlers=eventX'");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int result = stream_events(argv[1], argv[2]);
|
||||
exit(result);
|
||||
}
|
||||
|
||||
int stream_events(char* device_path) {
|
||||
int device_fd;
|
||||
int stream_events(char* mouse_path, char* keyboard_path) {
|
||||
int keyboard_fd, mouse_fd;
|
||||
struct timespec start;
|
||||
struct input_event event;
|
||||
if((device_fd = open(device_path, O_RDONLY)) == -1) {
|
||||
fprintf(stderr, "Failed to open %s. Are you running as root?\n", device_path);
|
||||
struct epoll_event event, events[MAX_EVENTS];
|
||||
|
||||
int running = 1;
|
||||
int epoll_fd = epoll_create1(0);
|
||||
if(epoll_fd < 0) {
|
||||
fprintf(stderr, "Failed to initialize epoll fd: %d", errno);
|
||||
return 1;
|
||||
}
|
||||
if((mouse_fd = open(mouse_path, O_RDONLY)) == -1) {
|
||||
fprintf(stderr, "Failed to open %s. Are you running as root?\n", mouse_path);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Device open OK\n");
|
||||
fprintf(stderr, "%s open OK\n", mouse_path);
|
||||
}
|
||||
if((keyboard_fd = open(keyboard_path, O_RDONLY)) == -1) {
|
||||
fprintf(stderr, "Failed to open %s. Are you running as root?\n", keyboard_path);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s open OK\n", keyboard_path);
|
||||
}
|
||||
event.events = EPOLLIN;
|
||||
|
||||
event.data.fd = keyboard_fd;
|
||||
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, keyboard_fd, &event)) {
|
||||
fprintf(stderr, "Failed to add keyboard file descriptor\n");
|
||||
close(epoll_fd);
|
||||
return 1;
|
||||
}
|
||||
event.data.fd = mouse_fd;
|
||||
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mouse_fd, &event)) {
|
||||
fprintf(stderr, "Failed to add mouse file descriptor\n");
|
||||
close(epoll_fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Waiting for events\n");
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
while(read(device_fd, &event, sizeof(struct input_event)))
|
||||
{
|
||||
dump_event(&start, &event);
|
||||
while(running) {
|
||||
int event_count = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
|
||||
char* type;
|
||||
for(int i = 0; i < event_count; i++) {
|
||||
if(events[i].data.fd == keyboard_fd) {
|
||||
type = KEYBOARD;
|
||||
} else if (events[i].data.fd == mouse_fd) {
|
||||
type = MOUSE;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown fd");
|
||||
return 1;
|
||||
}
|
||||
if(dump_event(&start, events[i].data.fd, type)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue