test: Make relative pointer event test more accepting
[platform/upstream/libinput.git] / test / pointer.c
1 /*
2  * Copyright © 2013 Red Hat, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include <config.h>
24
25 #include <stdio.h>
26 #include <check.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <libinput.h>
30 #include <math.h>
31 #include <unistd.h>
32
33 #include "libinput-util.h"
34 #include "litest.h"
35
36 static void
37 test_relative_event(struct litest_device *dev, int dx, int dy)
38 {
39         struct libinput *li = dev->libinput;
40         struct libinput_event *event;
41         struct libinput_event_pointer *ptrev;
42         double ev_dx, ev_dy;
43         double expected_dir;
44         double expected_length;
45         double actual_dir;
46         double actual_length;
47
48         /* Send two deltas, as the first one may be eaten up by an
49          * acceleration filter. */
50         litest_event(dev, EV_REL, REL_X, dx);
51         litest_event(dev, EV_REL, REL_Y, dy);
52         litest_event(dev, EV_SYN, SYN_REPORT, 0);
53         litest_event(dev, EV_REL, REL_X, dx);
54         litest_event(dev, EV_REL, REL_Y, dy);
55         litest_event(dev, EV_SYN, SYN_REPORT, 0);
56
57         libinput_dispatch(li);
58
59         event = libinput_get_event(li);
60         ck_assert(event != NULL);
61         ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_MOTION);
62
63         ptrev = libinput_event_get_pointer_event(event);
64         ck_assert(ptrev != NULL);
65
66         expected_length = sqrt(dx*dx + dy*dy);
67         expected_dir = atan2(dx, dy);
68
69         ev_dx = li_fixed_to_double(libinput_event_pointer_get_dx(ptrev));
70         ev_dy = li_fixed_to_double(libinput_event_pointer_get_dy(ptrev));
71         actual_length = sqrt(ev_dx*ev_dx + ev_dy*ev_dy);
72         actual_dir = atan2(ev_dx, ev_dy);
73
74         /* Check the length of the motion vector (tolerate 1.0 indifference). */
75         ck_assert(fabs(expected_length - actual_length) < 1.0);
76
77         /* Check the direction of the motion vector (tolerate 2π/4 radians
78          * indifference). */
79         ck_assert(fabs(expected_dir - actual_dir) < M_PI_2);
80
81         libinput_event_destroy(event);
82
83         litest_drain_events(dev->libinput);
84 }
85
86 START_TEST(pointer_motion_relative)
87 {
88         struct litest_device *dev = litest_current_device();
89
90         litest_drain_events(dev->libinput);
91
92         test_relative_event(dev, 1, 0);
93         test_relative_event(dev, 1, 1);
94         test_relative_event(dev, 1, -1);
95         test_relative_event(dev, 0, 1);
96
97         test_relative_event(dev, -1, 0);
98         test_relative_event(dev, -1, 1);
99         test_relative_event(dev, -1, -1);
100         test_relative_event(dev, 0, -1);
101 }
102 END_TEST
103
104 static void
105 test_button_event(struct litest_device *dev, int button, int state)
106 {
107         struct libinput *li = dev->libinput;
108         struct libinput_event *event;
109         struct libinput_event_pointer *ptrev;
110
111         litest_event(dev, EV_KEY, button, state);
112         litest_event(dev, EV_SYN, SYN_REPORT, 0);
113
114         libinput_dispatch(li);
115
116         event = libinput_get_event(li);
117         ck_assert(event != NULL);
118         ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_BUTTON);
119
120         ptrev = libinput_event_get_pointer_event(event);
121         ck_assert(ptrev != NULL);
122         ck_assert_int_eq(libinput_event_pointer_get_button(ptrev), button);
123         ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrev),
124                          state ?
125                                 LIBINPUT_POINTER_BUTTON_STATE_PRESSED :
126                                 LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
127         libinput_event_destroy(event);
128 }
129
130 START_TEST(pointer_button)
131 {
132         struct litest_device *dev = litest_current_device();
133
134         litest_drain_events(dev->libinput);
135
136         test_button_event(dev, BTN_LEFT, 1);
137         test_button_event(dev, BTN_LEFT, 0);
138
139         /* press it twice for good measure */
140         test_button_event(dev, BTN_LEFT, 1);
141         test_button_event(dev, BTN_LEFT, 0);
142
143         if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_RIGHT)) {
144                 test_button_event(dev, BTN_RIGHT, 1);
145                 test_button_event(dev, BTN_RIGHT, 0);
146         }
147
148         if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_MIDDLE)) {
149                 test_button_event(dev, BTN_MIDDLE, 1);
150                 test_button_event(dev, BTN_MIDDLE, 0);
151         }
152 }
153 END_TEST
154
155 static void
156 test_wheel_event(struct litest_device *dev, int which, int amount)
157 {
158         struct libinput *li = dev->libinput;
159         struct libinput_event *event;
160         struct libinput_event_pointer *ptrev;
161
162         /* the current evdev implementation scales the scroll wheel events
163            up by a factor 10 */
164         const int scroll_step = 10;
165         int expected = amount * scroll_step;
166
167         /* mouse scroll wheels are 'upside down' */
168         if (which == REL_WHEEL)
169                 amount *= -1;
170         litest_event(dev, EV_REL, which, amount);
171         litest_event(dev, EV_SYN, SYN_REPORT, 0);
172
173         libinput_dispatch(li);
174
175         event = libinput_get_event(li);
176         ck_assert(event != NULL);
177         ck_assert_int_eq(libinput_event_get_type(event),
178                           LIBINPUT_EVENT_POINTER_AXIS);
179
180         ptrev = libinput_event_get_pointer_event(event);
181         ck_assert(ptrev != NULL);
182         ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev),
183                          which == REL_WHEEL ?
184                                 LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL :
185                                 LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL);
186         ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev),
187                          li_fixed_from_int(expected));
188         libinput_event_destroy(event);
189 }
190
191 START_TEST(pointer_scroll_wheel)
192 {
193         struct litest_device *dev = litest_current_device();
194
195         litest_drain_events(dev->libinput);
196
197         test_wheel_event(dev, REL_WHEEL, -1);
198         test_wheel_event(dev, REL_WHEEL, 1);
199
200         test_wheel_event(dev, REL_WHEEL, -5);
201         test_wheel_event(dev, REL_WHEEL, 6);
202
203         if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
204                 test_wheel_event(dev, REL_HWHEEL, -1);
205                 test_wheel_event(dev, REL_HWHEEL, 1);
206
207                 test_wheel_event(dev, REL_HWHEEL, -5);
208                 test_wheel_event(dev, REL_HWHEEL, 6);
209         }
210 }
211 END_TEST
212
213 START_TEST(pointer_seat_button_count)
214 {
215         const int num_devices = 4;
216         struct litest_device *devices[num_devices];
217         struct libinput *libinput;
218         struct libinput_event *ev;
219         struct libinput_event_pointer *tev;
220         int i;
221         int seat_button_count;
222         int expected_seat_button_count = 0;
223         char device_name[255];
224
225         libinput = litest_create_context();
226         for (i = 0; i < num_devices; ++i) {
227                 sprintf(device_name, "Generic mouse (%d)", i);
228                 devices[i] = litest_add_device_with_overrides(libinput,
229                                                               LITEST_MOUSE,
230                                                               device_name,
231                                                               NULL, NULL, NULL);
232         }
233
234         for (i = 0; i < num_devices; ++i)
235                 litest_button_click(devices[i], BTN_LEFT, true);
236
237         libinput_dispatch(libinput);
238         while ((ev = libinput_get_event(libinput))) {
239                 if (libinput_event_get_type(ev) !=
240                     LIBINPUT_EVENT_POINTER_BUTTON) {
241                         libinput_event_destroy(ev);
242                         libinput_dispatch(libinput);
243                         continue;
244                 }
245
246                 tev = libinput_event_get_pointer_event(ev);
247                 ck_assert_notnull(tev);
248                 ck_assert_int_eq(libinput_event_pointer_get_button(tev),
249                                  BTN_LEFT);
250                 ck_assert_int_eq(libinput_event_pointer_get_button_state(tev),
251                                  LIBINPUT_POINTER_BUTTON_STATE_PRESSED);
252
253                 ++expected_seat_button_count;
254                 seat_button_count =
255                         libinput_event_pointer_get_seat_button_count(tev);
256                 ck_assert_int_eq(expected_seat_button_count, seat_button_count);
257
258                 libinput_event_destroy(ev);
259                 libinput_dispatch(libinput);
260         }
261
262         ck_assert_int_eq(seat_button_count, num_devices);
263
264         for (i = 0; i < num_devices; ++i)
265                 litest_button_click(devices[i], BTN_LEFT, false);
266
267         libinput_dispatch(libinput);
268         while ((ev = libinput_get_event(libinput))) {
269                 if (libinput_event_get_type(ev) !=
270                     LIBINPUT_EVENT_POINTER_BUTTON) {
271                         libinput_event_destroy(ev);
272                         libinput_dispatch(libinput);
273                         continue;
274                 }
275
276                 tev = libinput_event_get_pointer_event(ev);
277                 ck_assert_notnull(tev);
278                 ck_assert_int_eq(libinput_event_pointer_get_button(tev),
279                                  BTN_LEFT);
280                 ck_assert_int_eq(libinput_event_pointer_get_button_state(tev),
281                                  LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
282
283                 --expected_seat_button_count;
284                 seat_button_count =
285                         libinput_event_pointer_get_seat_button_count(tev);
286                 ck_assert_int_eq(expected_seat_button_count, seat_button_count);
287
288                 libinput_event_destroy(ev);
289                 libinput_dispatch(libinput);
290         }
291
292         ck_assert_int_eq(seat_button_count, 0);
293
294         for (i = 0; i < num_devices; ++i)
295                 litest_delete_device(devices[i]);
296         libinput_destroy(libinput);
297 }
298 END_TEST
299
300 int main (int argc, char **argv) {
301
302         litest_add("pointer:motion", pointer_motion_relative, LITEST_POINTER, LITEST_ANY);
303         litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_CLICKPAD);
304         litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_ANY);
305         litest_add_no_device("pointer:seat button count", pointer_seat_button_count);
306
307         return litest_run(argc, argv);
308 }