• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2015 Cedric Hnyda <chnyda@suse.com>
4  * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
5  */
6 
7 /*\
8  * [Description]
9  *
10  * Verify that /dev/input/mice receive events sent from a virtual device,
11  * that in our case is a mouse. The events are a sequence of mouse right click.
12  */
13 
14 #include <linux/uinput.h>
15 
16 #include "input_common.h"
17 
18 #define NUM_EVENTS 10
19 #define PS2_RIGHT_BTN 0x02
20 #define MOUSE_DEV "/dev/input/mice"
21 
22 static int fd_send = -1;
23 static int fd_recv = -1;
24 
recv_data(void)25 static void recv_data(void)
26 {
27 	tst_res(TINFO, "Reading events back");
28 
29 	char buf[30];
30 	int events = 0;
31 	int pressed = 0;
32 	int num_bytes = 0;
33 
34 	TST_CHECKPOINT_WAKE(0);
35 
36 	while (events < NUM_EVENTS) {
37 		memset(buf, 0, sizeof(buf));
38 
39 		num_bytes = SAFE_READ(0, fd_recv, buf, sizeof(buf));
40 
41 		for (int i = 0; i < num_bytes / 3; i++) {
42 			if (buf[3*i] & PS2_RIGHT_BTN)
43 				pressed = 1;
44 
45 			if (pressed == 1 && !(buf[3*i] & PS2_RIGHT_BTN)) {
46 				pressed = 0;
47 				events++;
48 			}
49 		}
50 	}
51 
52 	TST_EXP_EQ_LI(events, NUM_EVENTS);
53 }
54 
send_mouse_events(void)55 static void send_mouse_events(void)
56 {
57 	tst_res(TINFO, "Sending right click");
58 
59 	TST_CHECKPOINT_WAIT(0);
60 
61 	for (int i = 0; i < NUM_EVENTS; i++) {
62 		send_event(fd_send, EV_KEY, BTN_RIGHT, 1);
63 		send_event(fd_send, EV_SYN, 0, 0);
64 		usleep(1000);
65 
66 		send_event(fd_send, EV_KEY, BTN_RIGHT, 0);
67 		send_event(fd_send, EV_SYN, 0, 0);
68 		usleep(1000);
69 	}
70 }
71 
run(void)72 static void run(void)
73 {
74 	if (!SAFE_FORK()) {
75 		send_mouse_events();
76 		exit(0);
77 	}
78 
79 	recv_data();
80 }
81 
setup(void)82 static void setup(void)
83 {
84 	fd_send = open_uinput();
85 	if (fd_send == -1)
86 		tst_brk(TCONF, "Virtual device is not available");
87 
88 	setup_mouse_events(fd_send);
89 	SAFE_IOCTL(fd_send, UI_SET_EVBIT, EV_KEY);
90 	SAFE_IOCTL(fd_send, UI_SET_KEYBIT, BTN_RIGHT);
91 
92 	create_input_device(fd_send);
93 
94 	fd_recv = SAFE_OPEN(MOUSE_DEV, O_RDONLY);
95 }
96 
cleanup(void)97 static void cleanup(void)
98 {
99 	if (fd_send != -1)
100 		destroy_input_device(fd_send);
101 
102 	if (fd_recv != -1)
103 		SAFE_CLOSE(fd_recv);
104 }
105 
106 static struct tst_test test = {
107 	.test_all = run,
108 	.setup = setup,
109 	.cleanup = cleanup,
110 	.forks_child = 1,
111 	.needs_root = 1,
112 	.needs_checkpoints = 1,
113 };
114