1c0abf9e6Sopenharmony_ci// SPDX-License-Identifier: MIT 2c0abf9e6Sopenharmony_ci/* 3c0abf9e6Sopenharmony_ci * Copyright © 2013 Red Hat, Inc. 4c0abf9e6Sopenharmony_ci */ 5c0abf9e6Sopenharmony_ci 6c0abf9e6Sopenharmony_ci#include "config.h" 7c0abf9e6Sopenharmony_ci#include <linux/input.h> 8c0abf9e6Sopenharmony_ci#include <errno.h> 9c0abf9e6Sopenharmony_ci#include <unistd.h> 10c0abf9e6Sopenharmony_ci#include <stdlib.h> 11c0abf9e6Sopenharmony_ci#include <fcntl.h> 12c0abf9e6Sopenharmony_ci#include <libevdev/libevdev-uinput.h> 13c0abf9e6Sopenharmony_ci 14c0abf9e6Sopenharmony_ci#include "test-common.h" 15c0abf9e6Sopenharmony_ci#define UINPUT_NODE "/dev/uinput" 16c0abf9e6Sopenharmony_ci 17c0abf9e6Sopenharmony_ciSTART_TEST(test_uinput_create_device) 18c0abf9e6Sopenharmony_ci{ 19c0abf9e6Sopenharmony_ci struct libevdev *dev, *dev2; 20c0abf9e6Sopenharmony_ci struct libevdev_uinput *uidev; 21c0abf9e6Sopenharmony_ci int fd, uinput_fd; 22c0abf9e6Sopenharmony_ci unsigned int type, code; 23c0abf9e6Sopenharmony_ci int rc; 24c0abf9e6Sopenharmony_ci const char *devnode; 25c0abf9e6Sopenharmony_ci 26c0abf9e6Sopenharmony_ci dev = libevdev_new(); 27c0abf9e6Sopenharmony_ci ck_assert(dev != NULL); 28c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME); 29c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_SYN); 30c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_REL); 31c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); 32c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); 33c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_MAX, NULL); 34c0abf9e6Sopenharmony_ci 35c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev); 36c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 37c0abf9e6Sopenharmony_ci ck_assert(uidev != NULL); 38c0abf9e6Sopenharmony_ci 39c0abf9e6Sopenharmony_ci uinput_fd = libevdev_uinput_get_fd(uidev); 40c0abf9e6Sopenharmony_ci ck_assert_int_gt(uinput_fd, -1); 41c0abf9e6Sopenharmony_ci 42c0abf9e6Sopenharmony_ci devnode = libevdev_uinput_get_devnode(uidev); 43c0abf9e6Sopenharmony_ci ck_assert(devnode != NULL); 44c0abf9e6Sopenharmony_ci 45c0abf9e6Sopenharmony_ci fd = open(devnode, O_RDONLY); 46c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd, -1); 47c0abf9e6Sopenharmony_ci rc = libevdev_new_from_fd(fd, &dev2); 48c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 49c0abf9e6Sopenharmony_ci 50c0abf9e6Sopenharmony_ci for (type = 0; type < EV_CNT; type++) { 51c0abf9e6Sopenharmony_ci int max = libevdev_event_type_get_max(type); 52c0abf9e6Sopenharmony_ci if (max == -1) 53c0abf9e6Sopenharmony_ci continue; 54c0abf9e6Sopenharmony_ci 55c0abf9e6Sopenharmony_ci for (code = 0; code < (unsigned int)max; code++) { 56c0abf9e6Sopenharmony_ci ck_assert_int_eq(libevdev_has_event_code(dev, type, code), 57c0abf9e6Sopenharmony_ci libevdev_has_event_code(dev2, type, code)); 58c0abf9e6Sopenharmony_ci } 59c0abf9e6Sopenharmony_ci } 60c0abf9e6Sopenharmony_ci 61c0abf9e6Sopenharmony_ci libevdev_free(dev); 62c0abf9e6Sopenharmony_ci libevdev_free(dev2); 63c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev); 64c0abf9e6Sopenharmony_ci close(fd); 65c0abf9e6Sopenharmony_ci 66c0abf9e6Sopenharmony_ci /* uinput fd is managed, so make sure it did get closed */ 67c0abf9e6Sopenharmony_ci ck_assert_int_eq(close(uinput_fd), -1); 68c0abf9e6Sopenharmony_ci ck_assert_int_eq(errno, EBADF); 69c0abf9e6Sopenharmony_ci 70c0abf9e6Sopenharmony_ci} 71c0abf9e6Sopenharmony_ciEND_TEST 72c0abf9e6Sopenharmony_ci 73c0abf9e6Sopenharmony_ciSTART_TEST(test_uinput_create_device_invalid) 74c0abf9e6Sopenharmony_ci{ 75c0abf9e6Sopenharmony_ci struct libevdev *dev; 76c0abf9e6Sopenharmony_ci struct libevdev_uinput *uidev = NULL; 77c0abf9e6Sopenharmony_ci int rc; 78c0abf9e6Sopenharmony_ci 79c0abf9e6Sopenharmony_ci dev = libevdev_new(); 80c0abf9e6Sopenharmony_ci ck_assert(dev != NULL); 81c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME); 82c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_SYN); 83c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_REL); 84c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); 85c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); 86c0abf9e6Sopenharmony_ci 87c0abf9e6Sopenharmony_ci libevdev_set_log_function(test_logfunc_ignore_error, NULL); 88c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, -1, &uidev); 89c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, -EBADF); 90c0abf9e6Sopenharmony_ci ck_assert(uidev == NULL); 91c0abf9e6Sopenharmony_ci libevdev_set_log_function(test_logfunc_abort_on_error, NULL); 92c0abf9e6Sopenharmony_ci 93c0abf9e6Sopenharmony_ci libevdev_free(dev); 94c0abf9e6Sopenharmony_ci} 95c0abf9e6Sopenharmony_ciEND_TEST 96c0abf9e6Sopenharmony_ci 97c0abf9e6Sopenharmony_ciSTART_TEST(test_uinput_create_device_from_fd) 98c0abf9e6Sopenharmony_ci{ 99c0abf9e6Sopenharmony_ci struct libevdev *dev, *dev2; 100c0abf9e6Sopenharmony_ci struct libevdev_uinput *uidev; 101c0abf9e6Sopenharmony_ci int fd, fd2; 102c0abf9e6Sopenharmony_ci unsigned int type, code; 103c0abf9e6Sopenharmony_ci int rc; 104c0abf9e6Sopenharmony_ci const char *devnode; 105c0abf9e6Sopenharmony_ci 106c0abf9e6Sopenharmony_ci dev = libevdev_new(); 107c0abf9e6Sopenharmony_ci ck_assert(dev != NULL); 108c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME); 109c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_SYN); 110c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_REL); 111c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); 112c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); 113c0abf9e6Sopenharmony_ci 114c0abf9e6Sopenharmony_ci fd = open(UINPUT_NODE, O_RDWR); 115c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd, -1); 116c0abf9e6Sopenharmony_ci 117c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, fd, &uidev); 118c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 119c0abf9e6Sopenharmony_ci ck_assert(uidev != NULL); 120c0abf9e6Sopenharmony_ci 121c0abf9e6Sopenharmony_ci ck_assert_int_eq(libevdev_uinput_get_fd(uidev), fd); 122c0abf9e6Sopenharmony_ci 123c0abf9e6Sopenharmony_ci devnode = libevdev_uinput_get_devnode(uidev); 124c0abf9e6Sopenharmony_ci ck_assert(devnode != NULL); 125c0abf9e6Sopenharmony_ci 126c0abf9e6Sopenharmony_ci fd2 = open(devnode, O_RDONLY); 127c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd2, -1); 128c0abf9e6Sopenharmony_ci rc = libevdev_new_from_fd(fd2, &dev2); 129c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 130c0abf9e6Sopenharmony_ci 131c0abf9e6Sopenharmony_ci for (type = 0; type < EV_CNT; type++) { 132c0abf9e6Sopenharmony_ci int max = libevdev_event_type_get_max(type); 133c0abf9e6Sopenharmony_ci if (max == -1) 134c0abf9e6Sopenharmony_ci continue; 135c0abf9e6Sopenharmony_ci 136c0abf9e6Sopenharmony_ci for (code = 0; code < (unsigned int)max; code++) { 137c0abf9e6Sopenharmony_ci ck_assert_int_eq(libevdev_has_event_code(dev, type, code), 138c0abf9e6Sopenharmony_ci libevdev_has_event_code(dev2, type, code)); 139c0abf9e6Sopenharmony_ci } 140c0abf9e6Sopenharmony_ci } 141c0abf9e6Sopenharmony_ci 142c0abf9e6Sopenharmony_ci libevdev_free(dev); 143c0abf9e6Sopenharmony_ci libevdev_free(dev2); 144c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev); 145c0abf9e6Sopenharmony_ci close(fd); 146c0abf9e6Sopenharmony_ci close(fd2); 147c0abf9e6Sopenharmony_ci} 148c0abf9e6Sopenharmony_ciEND_TEST 149c0abf9e6Sopenharmony_ci 150c0abf9e6Sopenharmony_ci#ifdef __FreeBSD__ 151c0abf9e6Sopenharmony_ciSTART_TEST(test_uinput_check_devnode_bsd) 152c0abf9e6Sopenharmony_ci{ 153c0abf9e6Sopenharmony_ci struct libevdev *dev; 154c0abf9e6Sopenharmony_ci struct libevdev_uinput *uidev, *uidev2; 155c0abf9e6Sopenharmony_ci const char *devnode, *devnode2; 156c0abf9e6Sopenharmony_ci int fd, fd2; 157c0abf9e6Sopenharmony_ci int rc; 158c0abf9e6Sopenharmony_ci 159c0abf9e6Sopenharmony_ci dev = libevdev_new(); 160c0abf9e6Sopenharmony_ci ck_assert(dev != NULL); 161c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME); 162c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_SYN); 163c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_REL); 164c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); 165c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); 166c0abf9e6Sopenharmony_ci 167c0abf9e6Sopenharmony_ci fd = open(UINPUT_NODE, O_RDWR); 168c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd, -1); 169c0abf9e6Sopenharmony_ci fd2 = open(UINPUT_NODE, O_RDWR); 170c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd2, -1); 171c0abf9e6Sopenharmony_ci 172c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, fd, &uidev); 173c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 174c0abf9e6Sopenharmony_ci 175c0abf9e6Sopenharmony_ci /* create a second one */ 176c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME " 2"); 177c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2); 178c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 179c0abf9e6Sopenharmony_ci 180c0abf9e6Sopenharmony_ci devnode = libevdev_uinput_get_devnode(uidev); 181c0abf9e6Sopenharmony_ci ck_assert(devnode != NULL); 182c0abf9e6Sopenharmony_ci 183c0abf9e6Sopenharmony_ci /* get syspath twice returns same pointer */ 184c0abf9e6Sopenharmony_ci devnode2 = libevdev_uinput_get_devnode(uidev); 185c0abf9e6Sopenharmony_ci ck_assert(devnode == devnode2); 186c0abf9e6Sopenharmony_ci 187c0abf9e6Sopenharmony_ci /* second dev has different devnode */ 188c0abf9e6Sopenharmony_ci devnode2 = libevdev_uinput_get_devnode(uidev2); 189c0abf9e6Sopenharmony_ci ck_assert(strcmp(devnode, devnode2) != 0); 190c0abf9e6Sopenharmony_ci 191c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev2); 192c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev); 193c0abf9e6Sopenharmony_ci 194c0abf9e6Sopenharmony_ci close(fd2); 195c0abf9e6Sopenharmony_ci close(fd); 196c0abf9e6Sopenharmony_ci 197c0abf9e6Sopenharmony_ci libevdev_free(dev); 198c0abf9e6Sopenharmony_ci} 199c0abf9e6Sopenharmony_ciEND_TEST 200c0abf9e6Sopenharmony_ci 201c0abf9e6Sopenharmony_ciSTART_TEST(test_uinput_check_syspath_bsd) 202c0abf9e6Sopenharmony_ci{ 203c0abf9e6Sopenharmony_ci struct libevdev *dev; 204c0abf9e6Sopenharmony_ci struct libevdev_uinput *uidev; 205c0abf9e6Sopenharmony_ci const char *syspath; 206c0abf9e6Sopenharmony_ci int fd; 207c0abf9e6Sopenharmony_ci int rc; 208c0abf9e6Sopenharmony_ci 209c0abf9e6Sopenharmony_ci dev = libevdev_new(); 210c0abf9e6Sopenharmony_ci ck_assert(dev != NULL); 211c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME); 212c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_SYN); 213c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_REL); 214c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); 215c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); 216c0abf9e6Sopenharmony_ci 217c0abf9e6Sopenharmony_ci fd = open(UINPUT_NODE, O_RDWR); 218c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd, -1); 219c0abf9e6Sopenharmony_ci 220c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, fd, &uidev); 221c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 222c0abf9e6Sopenharmony_ci 223c0abf9e6Sopenharmony_ci syspath = libevdev_uinput_get_syspath(uidev); 224c0abf9e6Sopenharmony_ci /* FreeBSD should always return NULL for libevdev_unput_get_syspath() */ 225c0abf9e6Sopenharmony_ci ck_assert(syspath == NULL); 226c0abf9e6Sopenharmony_ci 227c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev); 228c0abf9e6Sopenharmony_ci 229c0abf9e6Sopenharmony_ci close(fd); 230c0abf9e6Sopenharmony_ci 231c0abf9e6Sopenharmony_ci libevdev_free(dev); 232c0abf9e6Sopenharmony_ci} 233c0abf9e6Sopenharmony_ciEND_TEST 234c0abf9e6Sopenharmony_ci 235c0abf9e6Sopenharmony_ci#else /* !__FreeBSD__ */ 236c0abf9e6Sopenharmony_ci 237c0abf9e6Sopenharmony_ciSTART_TEST(test_uinput_check_syspath_time) 238c0abf9e6Sopenharmony_ci{ 239c0abf9e6Sopenharmony_ci struct libevdev *dev; 240c0abf9e6Sopenharmony_ci struct libevdev_uinput *uidev, *uidev2; 241c0abf9e6Sopenharmony_ci const char *syspath, *syspath2; 242c0abf9e6Sopenharmony_ci int fd, fd2; 243c0abf9e6Sopenharmony_ci int rc; 244c0abf9e6Sopenharmony_ci 245c0abf9e6Sopenharmony_ci dev = libevdev_new(); 246c0abf9e6Sopenharmony_ci ck_assert(dev != NULL); 247c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME); 248c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_SYN); 249c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_REL); 250c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); 251c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); 252c0abf9e6Sopenharmony_ci 253c0abf9e6Sopenharmony_ci fd = open(UINPUT_NODE, O_RDWR); 254c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd, -1); 255c0abf9e6Sopenharmony_ci fd2 = open(UINPUT_NODE, O_RDWR); 256c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd2, -1); 257c0abf9e6Sopenharmony_ci 258c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, fd, &uidev); 259c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 260c0abf9e6Sopenharmony_ci 261c0abf9e6Sopenharmony_ci /* sleep for 1.5 seconds. sysfs resolution is 1 second, so 262c0abf9e6Sopenharmony_ci creating both devices without delay means 263c0abf9e6Sopenharmony_ci libevdev_uinput_get_syspath can't actually differ between 264c0abf9e6Sopenharmony_ci them. By waiting, we get different ctime for uidev and uidev2, 265c0abf9e6Sopenharmony_ci and exercise that part of the code. 266c0abf9e6Sopenharmony_ci */ 267c0abf9e6Sopenharmony_ci usleep(1500000); 268c0abf9e6Sopenharmony_ci 269c0abf9e6Sopenharmony_ci /* create a second one to test the syspath time filtering code */ 270c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2); 271c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 272c0abf9e6Sopenharmony_ci 273c0abf9e6Sopenharmony_ci syspath = libevdev_uinput_get_syspath(uidev); 274c0abf9e6Sopenharmony_ci ck_assert(syspath != NULL); 275c0abf9e6Sopenharmony_ci 276c0abf9e6Sopenharmony_ci /* get syspath twice returns same pointer */ 277c0abf9e6Sopenharmony_ci syspath2 = libevdev_uinput_get_syspath(uidev); 278c0abf9e6Sopenharmony_ci ck_assert(syspath == syspath2); 279c0abf9e6Sopenharmony_ci 280c0abf9e6Sopenharmony_ci /* second dev has different syspath */ 281c0abf9e6Sopenharmony_ci syspath2 = libevdev_uinput_get_syspath(uidev2); 282c0abf9e6Sopenharmony_ci ck_assert(strcmp(syspath, syspath2) != 0); 283c0abf9e6Sopenharmony_ci 284c0abf9e6Sopenharmony_ci libevdev_free(dev); 285c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev); 286c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev2); 287c0abf9e6Sopenharmony_ci 288c0abf9e6Sopenharmony_ci close(fd); 289c0abf9e6Sopenharmony_ci close(fd2); 290c0abf9e6Sopenharmony_ci} 291c0abf9e6Sopenharmony_ciEND_TEST 292c0abf9e6Sopenharmony_ci 293c0abf9e6Sopenharmony_ciSTART_TEST(test_uinput_check_syspath_name) 294c0abf9e6Sopenharmony_ci{ 295c0abf9e6Sopenharmony_ci struct libevdev *dev; 296c0abf9e6Sopenharmony_ci struct libevdev_uinput *uidev, *uidev2; 297c0abf9e6Sopenharmony_ci const char *syspath, *syspath2; 298c0abf9e6Sopenharmony_ci int fd, fd2; 299c0abf9e6Sopenharmony_ci int rc; 300c0abf9e6Sopenharmony_ci 301c0abf9e6Sopenharmony_ci dev = libevdev_new(); 302c0abf9e6Sopenharmony_ci ck_assert(dev != NULL); 303c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME); 304c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_SYN); 305c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_REL); 306c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); 307c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); 308c0abf9e6Sopenharmony_ci 309c0abf9e6Sopenharmony_ci fd = open(UINPUT_NODE, O_RDWR); 310c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd, -1); 311c0abf9e6Sopenharmony_ci fd2 = open(UINPUT_NODE, O_RDWR); 312c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd2, -1); 313c0abf9e6Sopenharmony_ci 314c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, fd, &uidev); 315c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 316c0abf9e6Sopenharmony_ci 317c0abf9e6Sopenharmony_ci /* create a second one to stress the syspath filtering code */ 318c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME " 2"); 319c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2); 320c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 321c0abf9e6Sopenharmony_ci 322c0abf9e6Sopenharmony_ci syspath = libevdev_uinput_get_syspath(uidev); 323c0abf9e6Sopenharmony_ci ck_assert(syspath != NULL); 324c0abf9e6Sopenharmony_ci 325c0abf9e6Sopenharmony_ci /* get syspath twice returns same pointer */ 326c0abf9e6Sopenharmony_ci syspath2 = libevdev_uinput_get_syspath(uidev); 327c0abf9e6Sopenharmony_ci ck_assert(syspath == syspath2); 328c0abf9e6Sopenharmony_ci 329c0abf9e6Sopenharmony_ci /* second dev has different syspath */ 330c0abf9e6Sopenharmony_ci syspath2 = libevdev_uinput_get_syspath(uidev2); 331c0abf9e6Sopenharmony_ci ck_assert(strcmp(syspath, syspath2) != 0); 332c0abf9e6Sopenharmony_ci 333c0abf9e6Sopenharmony_ci libevdev_free(dev); 334c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev); 335c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev2); 336c0abf9e6Sopenharmony_ci 337c0abf9e6Sopenharmony_ci close(fd); 338c0abf9e6Sopenharmony_ci close(fd2); 339c0abf9e6Sopenharmony_ci} 340c0abf9e6Sopenharmony_ciEND_TEST 341c0abf9e6Sopenharmony_ci 342c0abf9e6Sopenharmony_ci#endif /* __FreeBSD __ */ 343c0abf9e6Sopenharmony_ci 344c0abf9e6Sopenharmony_ciSTART_TEST(test_uinput_events) 345c0abf9e6Sopenharmony_ci{ 346c0abf9e6Sopenharmony_ci struct libevdev *dev; 347c0abf9e6Sopenharmony_ci struct libevdev_uinput *uidev; 348c0abf9e6Sopenharmony_ci int fd, fd2; 349c0abf9e6Sopenharmony_ci int rc; 350c0abf9e6Sopenharmony_ci const char *devnode; 351c0abf9e6Sopenharmony_ci int i; 352c0abf9e6Sopenharmony_ci const int nevents = 5; 353c0abf9e6Sopenharmony_ci struct input_event events[] = { {{0, 0}, EV_REL, REL_X, 1}, 354c0abf9e6Sopenharmony_ci {{0, 0}, EV_REL, REL_Y, -1}, 355c0abf9e6Sopenharmony_ci {{0, 0}, EV_SYN, SYN_REPORT, 0}, 356c0abf9e6Sopenharmony_ci {{0, 0}, EV_KEY, BTN_LEFT, 1}, 357c0abf9e6Sopenharmony_ci {{0, 0}, EV_SYN, SYN_REPORT, 0}}; 358c0abf9e6Sopenharmony_ci struct input_event events_read[nevents]; 359c0abf9e6Sopenharmony_ci 360c0abf9e6Sopenharmony_ci dev = libevdev_new(); 361c0abf9e6Sopenharmony_ci ck_assert(dev != NULL); 362c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME); 363c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_SYN); 364c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_REL); 365c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_KEY); 366c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); 367c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); 368c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL); 369c0abf9e6Sopenharmony_ci 370c0abf9e6Sopenharmony_ci fd = open(UINPUT_NODE, O_RDWR); 371c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd, -1); 372c0abf9e6Sopenharmony_ci 373c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, fd, &uidev); 374c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 375c0abf9e6Sopenharmony_ci ck_assert(uidev != NULL); 376c0abf9e6Sopenharmony_ci 377c0abf9e6Sopenharmony_ci devnode = libevdev_uinput_get_devnode(uidev); 378c0abf9e6Sopenharmony_ci ck_assert(devnode != NULL); 379c0abf9e6Sopenharmony_ci 380c0abf9e6Sopenharmony_ci fd2 = open(devnode, O_RDONLY); 381c0abf9e6Sopenharmony_ci 382c0abf9e6Sopenharmony_ci for (i = 0; i < nevents; i++) 383c0abf9e6Sopenharmony_ci libevdev_uinput_write_event(uidev, events[i].type, events[i].code, events[i].value); 384c0abf9e6Sopenharmony_ci 385c0abf9e6Sopenharmony_ci rc = read(fd2, events_read, sizeof(events_read)); 386c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, sizeof(events_read)); 387c0abf9e6Sopenharmony_ci 388c0abf9e6Sopenharmony_ci for (i = 0; i < nevents; i++) { 389c0abf9e6Sopenharmony_ci ck_assert_int_eq(events[i].type, events_read[i].type); 390c0abf9e6Sopenharmony_ci ck_assert_int_eq(events[i].code, events_read[i].code); 391c0abf9e6Sopenharmony_ci ck_assert_int_eq(events[i].value, events_read[i].value); 392c0abf9e6Sopenharmony_ci } 393c0abf9e6Sopenharmony_ci 394c0abf9e6Sopenharmony_ci libevdev_free(dev); 395c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev); 396c0abf9e6Sopenharmony_ci close(fd); 397c0abf9e6Sopenharmony_ci close(fd2); 398c0abf9e6Sopenharmony_ci} 399c0abf9e6Sopenharmony_ciEND_TEST 400c0abf9e6Sopenharmony_ci 401c0abf9e6Sopenharmony_ciSTART_TEST(test_uinput_properties) 402c0abf9e6Sopenharmony_ci{ 403c0abf9e6Sopenharmony_ci struct libevdev *dev, *dev2; 404c0abf9e6Sopenharmony_ci struct libevdev_uinput *uidev; 405c0abf9e6Sopenharmony_ci int fd; 406c0abf9e6Sopenharmony_ci int rc; 407c0abf9e6Sopenharmony_ci const char *devnode; 408c0abf9e6Sopenharmony_ci 409c0abf9e6Sopenharmony_ci dev = libevdev_new(); 410c0abf9e6Sopenharmony_ci ck_assert(dev != NULL); 411c0abf9e6Sopenharmony_ci libevdev_set_name(dev, TEST_DEVICE_NAME); 412c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_SYN); 413c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_REL); 414c0abf9e6Sopenharmony_ci libevdev_enable_event_type(dev, EV_KEY); 415c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); 416c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); 417c0abf9e6Sopenharmony_ci libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL); 418c0abf9e6Sopenharmony_ci libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD); 419c0abf9e6Sopenharmony_ci libevdev_enable_property(dev, INPUT_PROP_MAX); 420c0abf9e6Sopenharmony_ci 421c0abf9e6Sopenharmony_ci rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev); 422c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 423c0abf9e6Sopenharmony_ci ck_assert(uidev != NULL); 424c0abf9e6Sopenharmony_ci 425c0abf9e6Sopenharmony_ci devnode = libevdev_uinput_get_devnode(uidev); 426c0abf9e6Sopenharmony_ci ck_assert(devnode != NULL); 427c0abf9e6Sopenharmony_ci 428c0abf9e6Sopenharmony_ci fd = open(devnode, O_RDONLY); 429c0abf9e6Sopenharmony_ci ck_assert_int_gt(fd, -1); 430c0abf9e6Sopenharmony_ci rc = libevdev_new_from_fd(fd, &dev2); 431c0abf9e6Sopenharmony_ci ck_assert_int_eq(rc, 0); 432c0abf9e6Sopenharmony_ci 433c0abf9e6Sopenharmony_ci ck_assert(libevdev_has_property(dev2, INPUT_PROP_BUTTONPAD)); 434c0abf9e6Sopenharmony_ci ck_assert(libevdev_has_property(dev2, INPUT_PROP_MAX)); 435c0abf9e6Sopenharmony_ci 436c0abf9e6Sopenharmony_ci libevdev_free(dev); 437c0abf9e6Sopenharmony_ci libevdev_free(dev2); 438c0abf9e6Sopenharmony_ci libevdev_uinput_destroy(uidev); 439c0abf9e6Sopenharmony_ci close(fd); 440c0abf9e6Sopenharmony_ci} 441c0abf9e6Sopenharmony_ciEND_TEST 442c0abf9e6Sopenharmony_ci 443c0abf9e6Sopenharmony_ciTEST_SUITE_ROOT_PRIVILEGES(uinput_suite) 444c0abf9e6Sopenharmony_ci{ 445c0abf9e6Sopenharmony_ci Suite *s = suite_create("libevdev uinput device tests"); 446c0abf9e6Sopenharmony_ci 447c0abf9e6Sopenharmony_ci add_test(s, test_uinput_create_device); 448c0abf9e6Sopenharmony_ci add_test(s, test_uinput_create_device_invalid); 449c0abf9e6Sopenharmony_ci add_test(s, test_uinput_create_device_from_fd); 450c0abf9e6Sopenharmony_ci#ifdef __FreeBSD__ 451c0abf9e6Sopenharmony_ci add_test(s, test_uinput_check_devnode_bsd); 452c0abf9e6Sopenharmony_ci add_test(s, test_uinput_check_syspath_bsd); 453c0abf9e6Sopenharmony_ci#else 454c0abf9e6Sopenharmony_ci add_test(s, test_uinput_check_syspath_time); 455c0abf9e6Sopenharmony_ci add_test(s, test_uinput_check_syspath_name); 456c0abf9e6Sopenharmony_ci#endif 457c0abf9e6Sopenharmony_ci 458c0abf9e6Sopenharmony_ci add_test(s, test_uinput_events); 459c0abf9e6Sopenharmony_ci 460c0abf9e6Sopenharmony_ci add_test(s, test_uinput_properties); 461c0abf9e6Sopenharmony_ci 462c0abf9e6Sopenharmony_ci return s; 463c0abf9e6Sopenharmony_ci} 464