END_TEST START_TEST(test_uinput_check_syspath_time) { struct libevdev *dev; struct libevdev_uinput *uidev, *uidev2; const char *syspath, *syspath2; int fd, fd2; int rc; dev = libevdev_new(); ck_assert(dev != NULL); libevdev_set_name(dev, TEST_DEVICE_NAME); libevdev_enable_event_type(dev, EV_SYN); libevdev_enable_event_type(dev, EV_REL); libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); fd = open(UINPUT_NODE, O_RDWR); ck_assert_int_gt(fd, -1); fd2 = open(UINPUT_NODE, O_RDWR); ck_assert_int_gt(fd2, -1); rc = libevdev_uinput_create_from_device(dev, fd, &uidev); ck_assert_int_eq(rc, 0); /* sleep for 1.5 seconds. sysfs resolution is 1 second, so creating both devices without delay means libevdev_uinput_get_syspath can't actually differ between them. By waiting, we get different ctime for uidev and uidev2, and exercise that part of the code. */ usleep(1500000); /* create a second one to test the syspath time filtering code */ rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2); ck_assert_int_eq(rc, 0); syspath = libevdev_uinput_get_syspath(uidev); ck_assert(syspath != NULL); /* get syspath twice returns same pointer */ syspath2 = libevdev_uinput_get_syspath(uidev); ck_assert(syspath == syspath2); /* second dev has different syspath */ syspath2 = libevdev_uinput_get_syspath(uidev2); ck_assert(strcmp(syspath, syspath2) != 0); libevdev_free(dev); libevdev_uinput_destroy(uidev); libevdev_uinput_destroy(uidev2); close(fd); close(fd2); }
END_TEST START_TEST(test_uinput_check_syspath_name) { struct libevdev *dev; struct libevdev_uinput *uidev, *uidev2; const char *syspath, *syspath2; int fd, fd2; int rc; dev = libevdev_new(); ck_assert(dev != NULL); libevdev_set_name(dev, TEST_DEVICE_NAME); libevdev_enable_event_type(dev, EV_SYN); libevdev_enable_event_type(dev, EV_REL); libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); fd = open(UINPUT_NODE, O_RDWR); ck_assert_int_gt(fd, -1); fd2 = open(UINPUT_NODE, O_RDWR); ck_assert_int_gt(fd2, -1); rc = libevdev_uinput_create_from_device(dev, fd, &uidev); ck_assert_int_eq(rc, 0); /* create a second one to stress the syspath filtering code */ libevdev_set_name(dev, TEST_DEVICE_NAME " 2"); rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2); ck_assert_int_eq(rc, 0); syspath = libevdev_uinput_get_syspath(uidev); ck_assert(syspath != NULL); /* get syspath twice returns same pointer */ syspath2 = libevdev_uinput_get_syspath(uidev); ck_assert(syspath == syspath2); /* second dev has different syspath */ syspath2 = libevdev_uinput_get_syspath(uidev2); ck_assert(strcmp(syspath, syspath2) != 0); libevdev_free(dev); libevdev_uinput_destroy(uidev); libevdev_uinput_destroy(uidev2); close(fd); close(fd2); }
END_TEST START_TEST(test_uinput_events) { struct libevdev *dev; struct libevdev_uinput *uidev; int fd, fd2; int rc; const char *devnode; int i; const int nevents = 5; struct input_event events[] = { {{0, 0}, EV_REL, REL_X, 1}, {{0, 0}, EV_REL, REL_Y, -1}, {{0, 0}, EV_SYN, SYN_REPORT, 0}, {{0, 0}, EV_KEY, BTN_LEFT, 1}, {{0, 0}, EV_SYN, SYN_REPORT, 0}}; struct input_event events_read[nevents]; dev = libevdev_new(); ck_assert(dev != NULL); libevdev_set_name(dev, TEST_DEVICE_NAME); libevdev_enable_event_type(dev, EV_SYN); libevdev_enable_event_type(dev, EV_REL); libevdev_enable_event_type(dev, EV_KEY); libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL); fd = open(UINPUT_NODE, O_RDWR); ck_assert_int_gt(fd, -1); rc = libevdev_uinput_create_from_device(dev, fd, &uidev); ck_assert_int_eq(rc, 0); ck_assert(uidev != NULL); devnode = libevdev_uinput_get_devnode(uidev); ck_assert(devnode != NULL); fd2 = open(devnode, O_RDONLY); for (i = 0; i < nevents; i++) libevdev_uinput_write_event(uidev, events[i].type, events[i].code, events[i].value); rc = read(fd2, events_read, sizeof(events_read)); ck_assert_int_eq(rc, sizeof(events_read)); for (i = 0; i < nevents; i++) { ck_assert_int_eq(events[i].type, events_read[i].type); ck_assert_int_eq(events[i].code, events_read[i].code); ck_assert_int_eq(events[i].value, events_read[i].value); } libevdev_free(dev); libevdev_uinput_destroy(uidev); close(fd); close(fd2); }
END_TEST START_TEST(test_uinput_create_device_from_fd) { struct libevdev *dev, *dev2; struct libevdev_uinput *uidev; int fd, fd2; unsigned int type, code; int rc; const char *devnode; dev = libevdev_new(); ck_assert(dev != NULL); libevdev_set_name(dev, TEST_DEVICE_NAME); libevdev_enable_event_type(dev, EV_SYN); libevdev_enable_event_type(dev, EV_REL); libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); fd = open(UINPUT_NODE, O_RDWR); ck_assert_int_gt(fd, -1); rc = libevdev_uinput_create_from_device(dev, fd, &uidev); ck_assert_int_eq(rc, 0); ck_assert(uidev != NULL); ck_assert_int_eq(libevdev_uinput_get_fd(uidev), fd); devnode = libevdev_uinput_get_devnode(uidev); ck_assert(devnode != NULL); fd2 = open(devnode, O_RDONLY); ck_assert_int_gt(fd2, -1); rc = libevdev_new_from_fd(fd2, &dev2); ck_assert_int_eq(rc, 0); for (type = 0; type < EV_CNT; type++) { int max = libevdev_event_type_get_max(type); if (max == -1) continue; for (code = 0; code < max; code++) { ck_assert_int_eq(libevdev_has_event_code(dev, type, code), libevdev_has_event_code(dev2, type, code)); } } libevdev_free(dev); libevdev_free(dev2); libevdev_uinput_destroy(uidev); close(fd); close(fd2); }
FTNoIR_Protocol::FTNoIR_Protocol() : dev(NULL), uidev(NULL) { int error = 0; dev = libevdev_new(); if (!dev) goto error; CHECK_LIBEVDEV(libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD)); libevdev_set_name(dev, "opentrack headpose"); struct input_absinfo absinfo; absinfo.minimum = min_input; absinfo.maximum = max_input; absinfo.resolution = 1; absinfo.value = mid_input; absinfo.flat = 1; absinfo.fuzz = 0; CHECK_LIBEVDEV(libevdev_enable_event_type(dev, EV_ABS)); CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_X, &absinfo)); CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_Y, &absinfo)); CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_Z, &absinfo)); CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_RX, &absinfo)); CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_RY, &absinfo)); CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_RZ, &absinfo)); /* do not remove next 3 lines or udev scripts won't assign 0664 permissions -sh */ CHECK_LIBEVDEV(libevdev_enable_event_type(dev, EV_KEY)); CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_KEY, BTN_JOYSTICK, NULL)); CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_KEY, BTN_TRIGGER, NULL)); CHECK_LIBEVDEV(libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev)); return; error: if (uidev) libevdev_uinput_destroy(uidev); if (dev) libevdev_free(dev); if (error) fprintf(stderr, "libevdev error: %d\n", error); uidev = NULL; dev = NULL; }
int main(int argc, char *argv[]) { libevdev_uinput *m_uinputDev=nullptr; libevdev *evdev=libevdev_new(); libevdev_set_name(evdev, "UnifiedKeyboardCombo virtual keyboard"); libevdev_set_id_vendor(evdev,120); libevdev_set_id_product(evdev,240); libevdev_set_id_bustype(evdev,BUS_USB); libevdev_enable_event_type(evdev, EV_KEY); //enable all key events libevdev_enable_event_code(evdev,EV_KEY,KEY_W,nullptr); int rc=libevdev_uinput_create_from_device(evdev,LIBEVDEV_UINPUT_OPEN_MANAGED, &m_uinputDev); //libevdev_free(evdev); if(rc<0){ return -1; } libevdev_uinput_write_event(m_uinputDev,EV_KEY,KEY_W,1); libevdev_uinput_write_event(m_uinputDev,EV_SYN,SYN_REPORT,0); libevdev_uinput_write_event(m_uinputDev,EV_KEY,KEY_W,0); libevdev_uinput_write_event(m_uinputDev,EV_SYN,SYN_REPORT,0); libevdev_uinput_write_event(m_uinputDev,EV_KEY,KEY_W,1); libevdev_uinput_write_event(m_uinputDev,EV_SYN,SYN_REPORT,0); libevdev_uinput_write_event(m_uinputDev,EV_KEY,KEY_W,0); libevdev_uinput_write_event(m_uinputDev,EV_SYN,SYN_REPORT,0); libevdev_uinput_destroy(m_uinputDev); }
END_TEST START_TEST(test_uinput_properties) { struct libevdev *dev, *dev2; struct libevdev_uinput *uidev; int fd; int rc; const char *devnode; dev = libevdev_new(); ck_assert(dev != NULL); libevdev_set_name(dev, TEST_DEVICE_NAME); libevdev_enable_event_type(dev, EV_SYN); libevdev_enable_event_type(dev, EV_REL); libevdev_enable_event_type(dev, EV_KEY); libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL); libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD); libevdev_enable_property(dev, INPUT_PROP_MAX); rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev); ck_assert_int_eq(rc, 0); ck_assert(uidev != NULL); devnode = libevdev_uinput_get_devnode(uidev); ck_assert(devnode != NULL); fd = open(devnode, O_RDONLY); ck_assert_int_gt(fd, -1); rc = libevdev_new_from_fd(fd, &dev2); ck_assert_int_eq(rc, 0); ck_assert(libevdev_has_property(dev2, INPUT_PROP_BUTTONPAD)); ck_assert(libevdev_has_property(dev2, INPUT_PROP_MAX)); libevdev_free(dev); libevdev_free(dev2); libevdev_uinput_destroy(uidev); close(fd); }
int main(int argc, char **argv) { struct libevdev *dev = NULL; struct libevdev_uinput *uidev = NULL; int fd, ret; if (argc < 2){ fprintf(stderr, "Usage: %s <event device>\n", argv[0]); return 1; } //open the event device file descriptor fd = open(argv[1], O_RDONLY); if (fd < 0) {perror("Failed to open device"); return fd;} //create a libevdev device from the event file descriptor ret = libevdev_new_from_fd(fd, &dev); if (ret < 0) {perror("Failed to create libevdev device"); return ret;} //create a device connected to the virtual device interface /dev/uinput ret = libevdev_uinput_create_from_device( dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev); if (ret < 0) {perror("Failed to create uinput device"); return ret;} sleep(1); //EVIOCGRAB the event, this means no other client will receive the events from the device, including your window manager. // "This is generally a bad idea. Don't do this." - libevdev documentation //We need to do this to avoid douplicate keyboard events. ret = libevdev_grab(dev, LIBEVDEV_GRAB); //start the interceptor and never return intercept(uidev, dev); libevdev_uinput_destroy(uidev); libevdev_grab(dev, LIBEVDEV_UNGRAB); libevdev_free(dev); return ret; }
END_TEST START_TEST(test_uinput_create_device_invalid) { struct libevdev *dev; struct libevdev_uinput *uidev = NULL; int rc; dev = libevdev_new(); ck_assert(dev != NULL); libevdev_set_name(dev, TEST_DEVICE_NAME); libevdev_enable_event_type(dev, EV_SYN); libevdev_enable_event_type(dev, EV_REL); libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); libevdev_set_log_function(test_logfunc_ignore_error, NULL); rc = libevdev_uinput_create_from_device(dev, -1, &uidev); ck_assert_int_eq(rc, -EBADF); ck_assert(uidev == NULL); libevdev_set_log_function(test_logfunc_abort_on_error, NULL); libevdev_free(dev); }