test: add tests for touch calibration
[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(4 * dx*dx + 4 * dy*dy);
67         expected_dir = atan2(dx, dy);
68
69         ev_dx = libinput_event_pointer_get_dx(ptrev);
70         ev_dy = 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);
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, unsigned 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_BUTTON_STATE_PRESSED :
126                                 LIBINPUT_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 START_TEST(pointer_button_auto_release)
156 {
157         struct libinput *libinput;
158         struct litest_device *dev;
159         struct libinput_event *event;
160         enum libinput_event_type type;
161         struct libinput_event_pointer *pevent;
162         struct {
163                 int code;
164                 int released;
165         } buttons[] = {
166                 { .code = BTN_LEFT, },
167                 { .code = BTN_MIDDLE, },
168                 { .code = BTN_EXTRA, },
169                 { .code = BTN_SIDE, },
170                 { .code = BTN_BACK, },
171                 { .code = BTN_FORWARD, },
172                 { .code = BTN_4, },
173         };
174         int events[2 * (ARRAY_LENGTH(buttons) + 1)];
175         unsigned i;
176         int button;
177         int valid_code;
178
179         /* Enable all tested buttons on the device */
180         for (i = 0; i < 2 * ARRAY_LENGTH(buttons);) {
181                 button = buttons[i / 2].code;
182                 events[i++] = EV_KEY;
183                 events[i++] = button;
184         }
185         events[i++] = -1;
186         events[i++] = -1;
187
188         libinput = litest_create_context();
189         dev = litest_add_device_with_overrides(libinput,
190                                                LITEST_MOUSE,
191                                                "Generic mouse",
192                                                NULL, NULL, events);
193
194         litest_drain_events(libinput);
195
196         /* Send pressed events, without releasing */
197         for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
198                 test_button_event(dev, buttons[i].code, 1);
199         }
200
201         litest_drain_events(libinput);
202
203         /* "Disconnect" device */
204         litest_delete_device(dev);
205
206         /* Mark all released buttons until device is removed */
207         while (1) {
208                 event = libinput_get_event(libinput);
209                 ck_assert_notnull(event);
210                 type = libinput_event_get_type(event);
211
212                 if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
213                         libinput_event_destroy(event);
214                         break;
215                 }
216
217                 ck_assert_int_eq(type, LIBINPUT_EVENT_POINTER_BUTTON);
218                 pevent = libinput_event_get_pointer_event(event);
219                 ck_assert_int_eq(libinput_event_pointer_get_button_state(pevent),
220                                  LIBINPUT_BUTTON_STATE_RELEASED);
221                 button = libinput_event_pointer_get_button(pevent);
222
223                 valid_code = 0;
224                 for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
225                         if (buttons[i].code == button) {
226                                 ck_assert_int_eq(buttons[i].released, 0);
227                                 buttons[i].released = 1;
228                                 valid_code = 1;
229                         }
230                 }
231                 ck_assert_int_eq(valid_code, 1);
232                 libinput_event_destroy(event);
233         }
234
235         /* Check that all pressed buttons has been released. */
236         for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
237                 ck_assert_int_eq(buttons[i].released, 1);
238         }
239
240         libinput_unref(libinput);
241 }
242 END_TEST
243
244 static void
245 test_wheel_event(struct litest_device *dev, int which, int amount)
246 {
247         struct libinput *li = dev->libinput;
248         struct libinput_event *event;
249         struct libinput_event_pointer *ptrev;
250
251         /* the current evdev implementation scales the scroll wheel events
252            up by a factor 10 */
253         const int scroll_step = 10;
254         int expected = amount * scroll_step;
255
256         /* mouse scroll wheels are 'upside down' */
257         if (which == REL_WHEEL)
258                 amount *= -1;
259         litest_event(dev, EV_REL, which, amount);
260         litest_event(dev, EV_SYN, SYN_REPORT, 0);
261
262         libinput_dispatch(li);
263
264         event = libinput_get_event(li);
265         ck_assert(event != NULL);
266         ck_assert_int_eq(libinput_event_get_type(event),
267                           LIBINPUT_EVENT_POINTER_AXIS);
268
269         ptrev = libinput_event_get_pointer_event(event);
270         ck_assert(ptrev != NULL);
271         ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev),
272                          which == REL_WHEEL ?
273                                 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL :
274                                 LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
275         ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), expected);
276         libinput_event_destroy(event);
277 }
278
279 START_TEST(pointer_scroll_wheel)
280 {
281         struct litest_device *dev = litest_current_device();
282
283         litest_drain_events(dev->libinput);
284
285         test_wheel_event(dev, REL_WHEEL, -1);
286         test_wheel_event(dev, REL_WHEEL, 1);
287
288         test_wheel_event(dev, REL_WHEEL, -5);
289         test_wheel_event(dev, REL_WHEEL, 6);
290
291         if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
292                 test_wheel_event(dev, REL_HWHEEL, -1);
293                 test_wheel_event(dev, REL_HWHEEL, 1);
294
295                 test_wheel_event(dev, REL_HWHEEL, -5);
296                 test_wheel_event(dev, REL_HWHEEL, 6);
297         }
298 }
299 END_TEST
300
301 START_TEST(pointer_seat_button_count)
302 {
303         const int num_devices = 4;
304         struct litest_device *devices[num_devices];
305         struct libinput *libinput;
306         struct libinput_event *ev;
307         struct libinput_event_pointer *tev;
308         int i;
309         int seat_button_count;
310         int expected_seat_button_count = 0;
311         char device_name[255];
312
313         libinput = litest_create_context();
314         for (i = 0; i < num_devices; ++i) {
315                 sprintf(device_name, "litest Generic mouse (%d)", i);
316                 devices[i] = litest_add_device_with_overrides(libinput,
317                                                               LITEST_MOUSE,
318                                                               device_name,
319                                                               NULL, NULL, NULL);
320         }
321
322         for (i = 0; i < num_devices; ++i)
323                 litest_button_click(devices[i], BTN_LEFT, true);
324
325         libinput_dispatch(libinput);
326         while ((ev = libinput_get_event(libinput))) {
327                 if (libinput_event_get_type(ev) !=
328                     LIBINPUT_EVENT_POINTER_BUTTON) {
329                         libinput_event_destroy(ev);
330                         libinput_dispatch(libinput);
331                         continue;
332                 }
333
334                 tev = libinput_event_get_pointer_event(ev);
335                 ck_assert_notnull(tev);
336                 ck_assert_int_eq(libinput_event_pointer_get_button(tev),
337                                  BTN_LEFT);
338                 ck_assert_int_eq(libinput_event_pointer_get_button_state(tev),
339                                  LIBINPUT_BUTTON_STATE_PRESSED);
340
341                 ++expected_seat_button_count;
342                 seat_button_count =
343                         libinput_event_pointer_get_seat_button_count(tev);
344                 ck_assert_int_eq(expected_seat_button_count, seat_button_count);
345
346                 libinput_event_destroy(ev);
347                 libinput_dispatch(libinput);
348         }
349
350         ck_assert_int_eq(seat_button_count, num_devices);
351
352         for (i = 0; i < num_devices; ++i)
353                 litest_button_click(devices[i], BTN_LEFT, false);
354
355         libinput_dispatch(libinput);
356         while ((ev = libinput_get_event(libinput))) {
357                 if (libinput_event_get_type(ev) !=
358                     LIBINPUT_EVENT_POINTER_BUTTON) {
359                         libinput_event_destroy(ev);
360                         libinput_dispatch(libinput);
361                         continue;
362                 }
363
364                 tev = libinput_event_get_pointer_event(ev);
365                 ck_assert_notnull(tev);
366                 ck_assert_int_eq(libinput_event_pointer_get_button(tev),
367                                  BTN_LEFT);
368                 ck_assert_int_eq(libinput_event_pointer_get_button_state(tev),
369                                  LIBINPUT_BUTTON_STATE_RELEASED);
370
371                 --expected_seat_button_count;
372                 seat_button_count =
373                         libinput_event_pointer_get_seat_button_count(tev);
374                 ck_assert_int_eq(expected_seat_button_count, seat_button_count);
375
376                 libinput_event_destroy(ev);
377                 libinput_dispatch(libinput);
378         }
379
380         ck_assert_int_eq(seat_button_count, 0);
381
382         for (i = 0; i < num_devices; ++i)
383                 litest_delete_device(devices[i]);
384         libinput_unref(libinput);
385 }
386 END_TEST
387
388 int main (int argc, char **argv) {
389
390         litest_add("pointer:motion", pointer_motion_relative, LITEST_POINTER, LITEST_ANY);
391         litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_CLICKPAD);
392         litest_add_no_device("pointer:button_auto_release", pointer_button_auto_release);
393         litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_ANY);
394         litest_add_no_device("pointer:seat button count", pointer_seat_button_count);
395
396         return litest_run(argc, argv);
397 }