diff --git a/Makefile b/Makefile index e969b20..3680ec7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -all: capture +all: capture playback bin: mkdir -p bin @@ -8,3 +8,6 @@ capture: bin capture.c clean: rm -Rf bin + +playback: bin playback.c + gcc playback.c -o bin/playback diff --git a/playback.c b/playback.c new file mode 100644 index 0000000..3c480fb --- /dev/null +++ b/playback.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int read_file(char* filename); + +void emit(int fd, int type, int code, int val) { + struct input_event ie; + ie.type = type; + ie.code = code; + ie.value = val; + ie.time.tv_sec = 0; + ie.time.tv_usec = 0; + + write(fd, &ie, sizeof(ie)); +} + + +int main(int argc, char* argv[]) { + if(argc < 2) { + printf("Please provide a capture file."); + exit(EXIT_FAILURE); + } + + if(read_file(argv[1])) { + exit(EXIT_FAILURE); + } + return 0; +} + +int read_file(char* filename) { + FILE* fp; + char* line = NULL; + size_t len = 0; + ssize_t read; + + fp = fopen(filename, "r"); + if (fp == NULL) { + printf("Failed to open file %s: %d\n", filename, errno); + return 1; + } + + while((read = getline(&line, &len, fp)) != -1) { + printf("%s", line); + } +} + +int setup_mouse() { + struct uinput_setup usetup; + // int i = 50; + int i = 0; + int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); + +/* enable mouse button left and relative events */ + printf("EV_KEY 0x%08x\n", EV_KEY); + printf("UI_SET_EVBIT 0x%08lx\n", UI_SET_EVBIT); + printf("UI_SET_KEYBIT 0x%08lx\n", UI_SET_KEYBIT); + printf("BTN_LEFT 0x%08x\n", BTN_LEFT); + printf("EV_REL 0x%08x\n", EV_REL); + + ioctl(fd, UI_SET_EVBIT, EV_KEY); + + ioctl(fd, UI_SET_KEYBIT, BTN_LEFT); + + ioctl(fd, UI_SET_EVBIT, EV_REL); + ioctl(fd, UI_SET_RELBIT, REL_X); + ioctl(fd, UI_SET_RELBIT, REL_Y); + + memset(&usetup, 0, sizeof(usetup)); + usetup.id.bustype = BUS_USB; + usetup.id.vendor = 0x1234; /* sample vendor */ + usetup.id.product = 0x5678; /* sample product */ + strcpy(usetup.name, "Example device"); + + ioctl(fd, UI_DEV_SETUP, &usetup); + ioctl(fd, UI_DEV_CREATE); + + /* + * On UI_DEV_CREATE the kernel will create the device node for this + * device. We are inserting a pause here so that userspace has time + * to detect, initialize the new device, and can start listening to + * the event, otherwise it will not notice the event we are about + * to send. This pause is only needed in our example code! + */ + sleep(1); + + /* Move the mouse diagonally, 5 units per axis */ + while (i--) { + emit(fd, EV_REL, REL_X, 5); + emit(fd, EV_REL, REL_Y, 5); + emit(fd, EV_SYN, SYN_REPORT, 0); + usleep(15000); + } + + // Click left mouse button. + + emit(fd, EV_KEY, BTN_MOUSE, 1); + emit(fd, EV_SYN, SYN_REPORT, 0); + emit(fd, EV_KEY, BTN_MOUSE, 0); + emit(fd, EV_SYN, SYN_REPORT, 0); + /* + * Give userspace some time to read the events before we destroy the + * device with UI_DEV_DESTOY. + */ + sleep(1); + + ioctl(fd, UI_DEV_DESTROY); + close(fd); + + return 0; +}