1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2015 Cedric Hnyda <chnyda@suse.com> 4f08c3bdfSopenharmony_ci * Copyright (c) 2019 Cyril Hrubis <chrubis@suse.cz> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci#include <linux/input.h> 8f08c3bdfSopenharmony_ci#include <linux/uinput.h> 9f08c3bdfSopenharmony_ci#include <stdio.h> 10f08c3bdfSopenharmony_ci#include <string.h> 11f08c3bdfSopenharmony_ci 12f08c3bdfSopenharmony_ci#define TST_NO_DEFAULT_MAIN 13f08c3bdfSopenharmony_ci#include "tst_test.h" 14f08c3bdfSopenharmony_ci 15f08c3bdfSopenharmony_ci#include "tst_uinput.h" 16f08c3bdfSopenharmony_ci 17f08c3bdfSopenharmony_ci#define VIRTUAL_DEVICE "virtual-device-ltp" 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_cistatic const char *uinput_paths[] = { 20f08c3bdfSopenharmony_ci "/dev/input/uinput", 21f08c3bdfSopenharmony_ci "/dev/uinput", 22f08c3bdfSopenharmony_ci}; 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_ciint open_uinput(void) 25f08c3bdfSopenharmony_ci{ 26f08c3bdfSopenharmony_ci unsigned int i; 27f08c3bdfSopenharmony_ci int fd; 28f08c3bdfSopenharmony_ci 29f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(uinput_paths); i++) { 30f08c3bdfSopenharmony_ci fd = open(uinput_paths[i], O_WRONLY | O_NONBLOCK); 31f08c3bdfSopenharmony_ci 32f08c3bdfSopenharmony_ci if (fd > 0) { 33f08c3bdfSopenharmony_ci tst_res(TINFO, "Found uinput dev at %s", uinput_paths[i]); 34f08c3bdfSopenharmony_ci return fd; 35f08c3bdfSopenharmony_ci } 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ci if (fd < 0 && errno != ENOENT) { 38f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "open(%s)", uinput_paths[i]); 39f08c3bdfSopenharmony_ci } 40f08c3bdfSopenharmony_ci } 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci return -1; 43f08c3bdfSopenharmony_ci} 44f08c3bdfSopenharmony_ci 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_ci#define SYSFS_PREFIX "Sysfs=" 47f08c3bdfSopenharmony_ci#define HANDLERS_PREFIX "Handlers=" 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_cistatic char *parse_field(char *line, char field) 50f08c3bdfSopenharmony_ci{ 51f08c3bdfSopenharmony_ci char *value; 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_ci switch (field) { 54f08c3bdfSopenharmony_ci case 'H': 55f08c3bdfSopenharmony_ci value = strstr(line, HANDLERS_PREFIX) + sizeof(HANDLERS_PREFIX) - 1; 56f08c3bdfSopenharmony_ci break; 57f08c3bdfSopenharmony_ci case 'S': 58f08c3bdfSopenharmony_ci value = strstr(line, SYSFS_PREFIX) + sizeof(SYSFS_PREFIX) - 1; 59f08c3bdfSopenharmony_ci break; 60f08c3bdfSopenharmony_ci default: 61f08c3bdfSopenharmony_ci return NULL; 62f08c3bdfSopenharmony_ci } 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_ci value[strlen(value) - 1] = 0; 65f08c3bdfSopenharmony_ci 66f08c3bdfSopenharmony_ci return strdup(value); 67f08c3bdfSopenharmony_ci} 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_cichar *get_input_field_value(char field) 70f08c3bdfSopenharmony_ci{ 71f08c3bdfSopenharmony_ci FILE *file; 72f08c3bdfSopenharmony_ci char line[1024]; 73f08c3bdfSopenharmony_ci int flag = 0; 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci file = fopen("/proc/bus/input/devices", "r"); 76f08c3bdfSopenharmony_ci if (!file) 77f08c3bdfSopenharmony_ci return NULL; 78f08c3bdfSopenharmony_ci 79f08c3bdfSopenharmony_ci while (fgets(line, sizeof(line), file)) { 80f08c3bdfSopenharmony_ci if (strstr(line, "N: Name=\""VIRTUAL_DEVICE"\"")) 81f08c3bdfSopenharmony_ci flag = 1; 82f08c3bdfSopenharmony_ci 83f08c3bdfSopenharmony_ci if (flag) { 84f08c3bdfSopenharmony_ci if (line[0] == field) 85f08c3bdfSopenharmony_ci return parse_field(line, field); 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_ci if (line[0] == '\n') 88f08c3bdfSopenharmony_ci flag = 0; 89f08c3bdfSopenharmony_ci } 90f08c3bdfSopenharmony_ci } 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_ci fclose(file); 93f08c3bdfSopenharmony_ci return NULL; 94f08c3bdfSopenharmony_ci} 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_cistatic int check_device(void) 97f08c3bdfSopenharmony_ci{ 98f08c3bdfSopenharmony_ci FILE *file; 99f08c3bdfSopenharmony_ci char line[256]; 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ci file = fopen("/proc/bus/input/devices", "r"); 102f08c3bdfSopenharmony_ci if (!file) 103f08c3bdfSopenharmony_ci return 0; 104f08c3bdfSopenharmony_ci 105f08c3bdfSopenharmony_ci while (fgets(line, sizeof(line), file)) { 106f08c3bdfSopenharmony_ci if (strstr(line, "Name=\""VIRTUAL_DEVICE"\"")) 107f08c3bdfSopenharmony_ci return 1; 108f08c3bdfSopenharmony_ci } 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci fclose(file); 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_ci return 0; 113f08c3bdfSopenharmony_ci} 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_civoid setup_mouse_events(int fd) 116f08c3bdfSopenharmony_ci{ 117f08c3bdfSopenharmony_ci SAFE_IOCTL(fd, UI_SET_EVBIT, EV_KEY); 118f08c3bdfSopenharmony_ci SAFE_IOCTL(fd, UI_SET_KEYBIT, BTN_LEFT); 119f08c3bdfSopenharmony_ci SAFE_IOCTL(fd, UI_SET_EVBIT, EV_REL); 120f08c3bdfSopenharmony_ci SAFE_IOCTL(fd, UI_SET_RELBIT, REL_X); 121f08c3bdfSopenharmony_ci SAFE_IOCTL(fd, UI_SET_RELBIT, REL_Y); 122f08c3bdfSopenharmony_ci} 123f08c3bdfSopenharmony_ci 124f08c3bdfSopenharmony_civoid destroy_input_device(int fd) 125f08c3bdfSopenharmony_ci{ 126f08c3bdfSopenharmony_ci SAFE_IOCTL(fd, UI_DEV_DESTROY, NULL); 127f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 128f08c3bdfSopenharmony_ci} 129f08c3bdfSopenharmony_ci 130f08c3bdfSopenharmony_civoid create_input_device(int fd) 131f08c3bdfSopenharmony_ci{ 132f08c3bdfSopenharmony_ci int nb; 133f08c3bdfSopenharmony_ci struct uinput_user_dev uidev = { 134f08c3bdfSopenharmony_ci .name = VIRTUAL_DEVICE, 135f08c3bdfSopenharmony_ci .id = { 136f08c3bdfSopenharmony_ci .bustype = BUS_USB, 137f08c3bdfSopenharmony_ci .vendor = 0x1, 138f08c3bdfSopenharmony_ci .product = 0x1, 139f08c3bdfSopenharmony_ci .version = 1, 140f08c3bdfSopenharmony_ci } 141f08c3bdfSopenharmony_ci }; 142f08c3bdfSopenharmony_ci 143f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ALL, fd, &uidev, sizeof(uidev)); 144f08c3bdfSopenharmony_ci SAFE_IOCTL(fd, UI_DEV_CREATE, NULL); 145f08c3bdfSopenharmony_ci 146f08c3bdfSopenharmony_ci for (nb = 100; nb > 0; nb--) { 147f08c3bdfSopenharmony_ci if (check_device()) 148f08c3bdfSopenharmony_ci return; 149f08c3bdfSopenharmony_ci usleep(10000); 150f08c3bdfSopenharmony_ci } 151f08c3bdfSopenharmony_ci 152f08c3bdfSopenharmony_ci destroy_input_device(fd); 153f08c3bdfSopenharmony_ci tst_brk(TBROK, "Failed to create device"); 154f08c3bdfSopenharmony_ci} 155