Add support for hotkey on capture.
We need this so that we can ensure to line up where our character is before we get going.
This commit is contained in:
parent
a3579fd339
commit
e65e442276
89
capture.c
89
capture.c
|
@ -14,12 +14,12 @@
|
||||||
static char* KEYBOARD = "k";
|
static char* KEYBOARD = "k";
|
||||||
static char* MOUSE = "m";
|
static char* MOUSE = "m";
|
||||||
|
|
||||||
int dump_event(struct timespec* start, int fd, char* type);
|
int dump_event(struct timespec* start, struct input_event* event, char* type);
|
||||||
|
|
||||||
int event_content_keyboard(char* buffer, int buffer_size, struct input_event* event);
|
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 event_content_mouse(char* buffer, int buffer_size, struct input_event* event);
|
||||||
|
|
||||||
int stream_events(char* mouse_path, char* keyboard_path);
|
int stream_events(char* mouse_path, char* keyboard_path, int hotkey_scancode);
|
||||||
|
|
||||||
static inline void timespec_diff(struct timespec* a, struct timespec* b, struct timespec* result) {
|
static inline void timespec_diff(struct timespec* a, struct timespec* b, struct timespec* result) {
|
||||||
result->tv_sec = a->tv_sec - b->tv_sec;
|
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||||
|
@ -29,32 +29,44 @@ static inline void timespec_diff(struct timespec* a, struct timespec* b, struct
|
||||||
result->tv_nsec += 1000000000L;
|
result->tv_nsec += 1000000000L;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void timeval_diff(struct timeval* a, struct timeval* b, struct timeval* result) {
|
||||||
|
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||||
|
result->tv_usec = a->tv_usec - b->tv_usec;
|
||||||
|
if (result->tv_usec < 0) {
|
||||||
|
--result->tv_sec;
|
||||||
|
result->tv_usec += 1000000L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void time_diff(struct timeval* a, struct timespec* b, struct timeval* result) {
|
||||||
|
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||||
|
result->tv_usec = a->tv_usec - (b->tv_nsec / 1000);
|
||||||
|
if (result->tv_usec < 0) {
|
||||||
|
--result->tv_sec;
|
||||||
|
result->tv_usec += 1000000L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int dump_event(struct timespec* start, int fd, char* type) {
|
int dump_event(struct timespec* start, struct input_event* event, char* type) {
|
||||||
struct input_event event;
|
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
struct timespec diff;
|
struct timespec diff;
|
||||||
char content_buffer[CONTENT_BUFFER_SIZE];
|
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);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
timespec_diff(&now, start, &diff);
|
timespec_diff(&now, start, &diff);
|
||||||
|
// time_diff(&(event.time), start, &diff);
|
||||||
|
|
||||||
if(type == MOUSE) {
|
if(type == MOUSE) {
|
||||||
if(event_content_mouse(content_buffer, CONTENT_BUFFER_SIZE, &event)) {
|
if(event_content_mouse(content_buffer, CONTENT_BUFFER_SIZE, event)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else if(type == KEYBOARD) {
|
} else if(type == KEYBOARD) {
|
||||||
// Ignore all but EV_KEY events on keyboard, they have no useful content.
|
// Ignore all but EV_KEY events on keyboard, they have no useful content.
|
||||||
if(event.type != EV_KEY) {
|
if(event->type != EV_KEY) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(event_content_keyboard(content_buffer, CONTENT_BUFFER_SIZE, &event)) {
|
if(event_content_keyboard(content_buffer, CONTENT_BUFFER_SIZE, event)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -98,6 +110,7 @@ int event_content_mouse(char* buffer, int buffer_size, struct input_event* event
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
int hotkey_scancode;
|
||||||
if(argc < 2) {
|
if(argc < 2) {
|
||||||
fprintf(stderr, "You must specify a mouse input to track like /dev/input/mouse1.");
|
fprintf(stderr, "You must specify a mouse input to track like /dev/input/mouse1.");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -106,15 +119,25 @@ int main(int argc, char* argv[]) {
|
||||||
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'");
|
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);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
int result = stream_events(argv[1], argv[2]);
|
if(argc < 4) {
|
||||||
|
fprintf(stderr, "You must specify a character to indicate when to start and stop capture. 53 for 'z'.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
int matched = sscanf(argv[3], "%d", &hotkey_scancode);
|
||||||
|
if(matched != 1) {
|
||||||
|
fprintf(stderr, "Failed to read hotkey scancode.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
int result = stream_events(argv[1], argv[2], hotkey_scancode);
|
||||||
exit(result);
|
exit(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int stream_events(char* mouse_path, char* keyboard_path) {
|
int stream_events(char* mouse_path, char* keyboard_path, int hotkey_scancode) {
|
||||||
int keyboard_fd, mouse_fd;
|
int keyboard_fd, mouse_fd;
|
||||||
struct timespec start;
|
struct timespec start;
|
||||||
struct epoll_event event, events[MAX_EVENTS];
|
struct epoll_event e_event, events[MAX_EVENTS];
|
||||||
|
|
||||||
|
int has_seen_hotkey = 0;
|
||||||
int running = 1;
|
int running = 1;
|
||||||
int epoll_fd = epoll_create1(0);
|
int epoll_fd = epoll_create1(0);
|
||||||
if(epoll_fd < 0) {
|
if(epoll_fd < 0) {
|
||||||
|
@ -135,36 +158,54 @@ int stream_events(char* mouse_path, char* keyboard_path) {
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "%s open OK\n", keyboard_path);
|
fprintf(stderr, "%s open OK\n", keyboard_path);
|
||||||
}
|
}
|
||||||
event.events = EPOLLIN;
|
e_event.events = EPOLLIN;
|
||||||
|
|
||||||
event.data.fd = keyboard_fd;
|
e_event.data.fd = keyboard_fd;
|
||||||
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, keyboard_fd, &event)) {
|
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, keyboard_fd, &e_event)) {
|
||||||
fprintf(stderr, "Failed to add keyboard file descriptor\n");
|
fprintf(stderr, "Failed to add keyboard file descriptor\n");
|
||||||
close(epoll_fd);
|
close(epoll_fd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
event.data.fd = mouse_fd;
|
e_event.data.fd = mouse_fd;
|
||||||
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mouse_fd, &event)) {
|
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mouse_fd, &e_event)) {
|
||||||
fprintf(stderr, "Failed to add mouse file descriptor\n");
|
fprintf(stderr, "Failed to add mouse file descriptor\n");
|
||||||
close(epoll_fd);
|
close(epoll_fd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Waiting for events\n");
|
fprintf(stderr, "Waiting for hotkey\n");
|
||||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
struct input_event i_event;
|
||||||
while(running) {
|
while(running) {
|
||||||
int event_count = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
|
int event_count = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
|
||||||
char* type;
|
char* type;
|
||||||
for(int i = 0; i < event_count; i++) {
|
for(int i = 0; i < event_count; i++) {
|
||||||
|
int result = read(events[i].data.fd, &i_event, sizeof(struct input_event));
|
||||||
|
if(result < 0) {
|
||||||
|
fprintf(stderr, "Failed to read an event: %d", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(events[i].data.fd == keyboard_fd) {
|
if(events[i].data.fd == keyboard_fd) {
|
||||||
type = KEYBOARD;
|
type = KEYBOARD;
|
||||||
|
if(i_event.type == EV_KEY && i_event.code == hotkey_scancode && i_event.value == 1) {
|
||||||
|
if(has_seen_hotkey) {
|
||||||
|
fprintf(stderr, "Stop capture\n");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
has_seen_hotkey = 1;
|
||||||
|
fprintf(stderr, "Start capture\n");
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (events[i].data.fd == mouse_fd) {
|
} else if (events[i].data.fd == mouse_fd) {
|
||||||
type = MOUSE;
|
type = MOUSE;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown fd");
|
fprintf(stderr, "Unknown fd");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(dump_event(&start, events[i].data.fd, type)) {
|
// Wait for the hotkey to start capture
|
||||||
|
if(has_seen_hotkey && dump_event(&start, &i_event, type)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue