diff --git a/playback.c b/playback.c index a95ac96..98b3eaa 100644 --- a/playback.c +++ b/playback.c @@ -10,13 +10,12 @@ #include #include -int handle_keyboard(char* details, int keyboard_fd); -int handle_line(char* line, int keyboard_fd, int mouse_fd); -int handle_mouse(char* details, int mouse_fd); -int read_file(char* filename, int keyboard_fd, int mouse_fd); -int setup_mouse(); -void teardown_keyboard(int fd); -void teardown_mouse(int fd); +int handle_udevice(char* details, int udevice_fd); +int handle_line(char* line, int udevice_fd); +int handle_mouse(char* details, int udevice_fd); +int read_file(char* filename, int udevice_fd); +int setup_udevice(); +void teardown_udevice(int fd); void emit(int fd, int type, int code, int val) { struct input_event ie; @@ -29,21 +28,30 @@ void emit(int fd, int type, int code, int val) { write(fd, &ie, sizeof(ie)); } -int handle_keyboard(char* details, int keyboard_fd) { +int handle_keyboard(char* details, int udevice_fd) { int code, event_type, value; int matched = sscanf(details, "%d,%d,%d", &event_type, &code, &value); if(matched != 3) { printf("Didn't match enough values for a keyboard event.\n"); return 1; } - printf("Event type: %d, Code: %d, Value: %d\n", - event_type, code, value); + // printf("Event type: %d, Code: %d, Value: %d\n", + // event_type, code, value); + if(event_type != 1) { + printf("Not sure what to do with event type %d", event_type); + return 1; + } + emit(udevice_fd, EV_KEY, code, value); + emit(udevice_fd, EV_SYN, SYN_REPORT, 0); + return 0; } -int handle_line(char* line, int keyboard_fd, int mouse_fd) { +int handle_line(char* line, int udevice_fd) { static time_t timer_seconds = 0; static long timer_nanos = 0; + static time_t total_seconds = 0; + static long total_nanos = 0; time_t seconds; long nanos; @@ -61,34 +69,47 @@ int handle_line(char* line, int keyboard_fd, int mouse_fd) { return 1; } + remaining.tv_sec = 0; + remaining.tv_nsec = 0; to_sleep.tv_sec = seconds - timer_seconds; to_sleep.tv_nsec = nanos - timer_nanos; if(to_sleep.tv_nsec < 0) { - --to_sleep.tv_nsec; + --to_sleep.tv_sec; to_sleep.tv_nsec += 1000000000L; } // printf("Timer %ld %ld\n", timer_seconds, timer_nanos); // printf("Read %ld %ld\n", seconds, nanos); // printf("Sleep %ld %ld\n", to_sleep.tv_sec, to_sleep.tv_nsec); - int result = nanosleep(&to_sleep, &remaining); while(nanosleep(&to_sleep, &remaining) == -1) { + printf("Sleep harder\n"); to_sleep.tv_sec = remaining.tv_sec; to_sleep.tv_nsec = remaining.tv_nsec; } + if(remaining.tv_sec != 0 || remaining.tv_nsec != 0) { + printf("oops, remaining.\n"); + } + total_seconds += to_sleep.tv_sec; + total_nanos += to_sleep.tv_nsec; + if(total_nanos > 1000000000L) { + total_nanos -= 1000000000L; + total_seconds += 1; + } timer_seconds = seconds; timer_nanos = nanos; + printf("%ld %ld\tslept %ld %ld\n", + total_seconds, total_nanos, to_sleep.tv_sec, to_sleep.tv_nsec); if(type == 'k') { - return handle_keyboard(details, keyboard_fd); + return handle_keyboard(details, udevice_fd); } else if(type == 'm') { - return handle_mouse(details, mouse_fd); + return handle_mouse(details, udevice_fd); } else { printf("Unexpected type %c/n", type); return 1; } } -int handle_mouse(char* details, int mouse_fd) { +int handle_mouse(char* details, int udevice_fd) { static int current_left = 0; static int current_middle = 0; static int current_right = 0; @@ -100,22 +121,30 @@ int handle_mouse(char* details, int mouse_fd) { printf("Failed to match enough data for a mouse event.\n"); return 1; } - printf("L: %d M: %d, R: %d, X: %d, Y: %d\n", - left, middle, right, x, y); + // printf("L: %d M: %d, R: %d, X: %d, Y: %d\n", + // left, middle, right, x, y); /* Move the mouse diagonally, 5 units per axis */ if(x != 0) { - emit(mouse_fd, EV_REL, REL_X, x); + emit(udevice_fd, EV_REL, REL_X, x); } if(y != 0) { - emit(mouse_fd, EV_REL, REL_Y, y); + emit(udevice_fd, EV_REL, REL_Y, y); } if(left != current_left) { - emit(mouse_fd, EV_KEY, BTN_MOUSE, left); + emit(udevice_fd, EV_KEY, BTN_LEFT, left); current_left = left; } - emit(mouse_fd, EV_SYN, SYN_REPORT, 0); + if(middle != current_middle) { + emit(udevice_fd, EV_KEY, BTN_MIDDLE, middle); + current_middle = middle; + } + if(right != current_right) { + emit(udevice_fd, EV_KEY, BTN_RIGHT, right); + current_right = right; + } + emit(udevice_fd, EV_SYN, SYN_REPORT, 0); return 0; @@ -128,17 +157,15 @@ int main(int argc, char* argv[]) { } int result = 0; - int mouse_fd = setup_mouse(); - int keyboard_fd = 0; - if(read_file(argv[1], keyboard_fd, mouse_fd)) { + int udevice_fd = setup_udevice(); + if(read_file(argv[1], udevice_fd)) { result = EXIT_FAILURE; } - teardown_keyboard(keyboard_fd); - teardown_mouse(mouse_fd); + teardown_udevice(udevice_fd); return result; } -int read_file(char* filename, int keyboard_fd, int mouse_fd) { +int read_file(char* filename, int udevice_fd) { FILE* fp; char* line = NULL; size_t len = 0; @@ -151,13 +178,13 @@ int read_file(char* filename, int keyboard_fd, int mouse_fd) { } while((read = getline(&line, &len, fp)) != -1) { - if(handle_line(line, keyboard_fd, mouse_fd)) { + if(handle_line(line, udevice_fd)) { return 1; } } } -int setup_mouse() { +int setup_udevice() { struct uinput_setup usetup; int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); @@ -165,6 +192,14 @@ int setup_mouse() { ioctl(fd, UI_SET_EVBIT, EV_KEY); + // Add keyboard keys. We could do this individually but we're super + // lazy and it appears a loop should work fine based on the linux/input-event-codes.h header + for(int i = KEY_ESC; i <= KEY_MICMUTE; i++) { + ioctl(fd, UI_SET_KEYBIT, i); + } + + // Add mouse buttons + ioctl(fd, UI_SET_KEYBIT, BTN_LEFT); ioctl(fd, UI_SET_KEYBIT, BTN_LEFT); ioctl(fd, UI_SET_EVBIT, EV_REL); @@ -188,13 +223,10 @@ int setup_mouse() { * to send. This pause is only needed in our example code! */ // sleep(1); - printf("Setup mouse to fd %d", fd); return fd; } -void teardown_mouse(int fd) { +void teardown_udevice(int fd) { ioctl(fd, UI_DEV_DESTROY); close(fd); } - -void teardown_keyboard(int fd) {}