1/* 2 * Copyright (c) 2015 Cedric Hnyda <chnyda@suse.com> 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of 7 * the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it would be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 /* 20 * Create a virtual device (mouse), send events to /dev/uinput 21 * and check that the events are well received in /dev/input/mice 22 */ 23 24#include <linux/input.h> 25#include <linux/uinput.h> 26 27#include "test.h" 28#include "safe_macros.h" 29#include "lapi/fcntl.h" 30#include "input_helper.h" 31 32#define NB_TEST 10 33#define PS2_RIGHT_BTN 0x02 34 35static void setup(void); 36static void send_events(void); 37static int check_events(void); 38static void cleanup(void); 39 40static int fd, fd2; 41 42char *TCID = "input03"; 43 44int main(int ac, char **av) 45{ 46 int lc; 47 int pid; 48 49 tst_parse_opts(ac, av, NULL, NULL); 50 51 setup(); 52 53 for (lc = 0; TEST_LOOPING(lc); ++lc) { 54 pid = tst_fork(); 55 56 switch (pid) { 57 case 0: 58 send_events(); 59 exit(0); 60 case -1: 61 tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); 62 default: 63 if (check_events()) 64 tst_resm(TFAIL, "Wrong data received"); 65 else 66 tst_resm(TPASS, 67 "Data received in /dev/input/mice"); 68 break; 69 } 70 71 SAFE_WAITPID(NULL, pid, NULL, 0); 72 } 73 74 cleanup(); 75 tst_exit(); 76} 77 78static void setup(void) 79{ 80 tst_require_root(); 81 82 fd = open_uinput(); 83 84 setup_mouse_events(fd); 85 SAFE_IOCTL(NULL, fd, UI_SET_EVBIT, EV_KEY); 86 SAFE_IOCTL(NULL, fd, UI_SET_KEYBIT, BTN_RIGHT); 87 88 create_device(fd); 89 90 fd2 = SAFE_OPEN(NULL, "/dev/input/mice", O_RDONLY); 91} 92 93static void send_events(void) 94{ 95 int nb; 96 97 for (nb = 0; nb < NB_TEST; ++nb) { 98 send_event(fd, EV_KEY, BTN_RIGHT, 1); 99 send_event(fd, EV_SYN, 0, 0); 100 usleep(1000); 101 send_event(fd, EV_KEY, BTN_RIGHT, 0); 102 send_event(fd, EV_SYN, 0, 0); 103 usleep(1000); 104 } 105} 106 107static int check_events(void) 108{ 109 int nb, rd, i, pressed = 0; 110 char buf[30]; 111 112 nb = 0; 113 114 while (nb < NB_TEST) { 115 rd = read(fd2, buf, sizeof(buf)); 116 117 if (rd < 0) 118 tst_brkm(TBROK | TERRNO, NULL, "read() failed"); 119 120 if (rd % 3) { 121 tst_resm(TINFO, "read() returned %i", rd); 122 return 1; 123 } 124 125 for (i = 0; i < rd / 3; i++) { 126 if (buf[3*i] & PS2_RIGHT_BTN) 127 pressed = 1; 128 129 if (pressed == 1 && !(buf[3*i] & PS2_RIGHT_BTN)) { 130 pressed = 0; 131 nb++; 132 } 133 } 134 } 135 136 return nb != NB_TEST; 137} 138 139static void cleanup(void) 140{ 141 if (fd2 > 0 && close(fd2)) 142 tst_resm(TWARN, "close(fd2) failed"); 143 144 destroy_device(fd); 145} 146