Change axis events to carry all directions
[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 #include <values.h>
33
34 #include "libinput-util.h"
35 #include "litest.h"
36
37 static struct libinput_event_pointer *
38 get_accelerated_motion_event(struct libinput *li)
39 {
40         struct libinput_event *event;
41         struct libinput_event_pointer *ptrev;
42
43         while (1) {
44                 event = libinput_get_event(li);
45                 ck_assert_notnull(event);
46                 ck_assert_int_eq(libinput_event_get_type(event),
47                                  LIBINPUT_EVENT_POINTER_MOTION);
48
49                 ptrev = libinput_event_get_pointer_event(event);
50                 ck_assert_notnull(ptrev);
51
52                 if (fabs(libinput_event_pointer_get_dx(ptrev)) < DBL_MIN &&
53                     fabs(libinput_event_pointer_get_dy(ptrev)) < DBL_MIN) {
54                         libinput_event_destroy(event);
55                         continue;
56                 }
57
58                 return ptrev;
59         }
60
61         ck_abort_msg("No accelerated pointer motion event found");
62         return NULL;
63 }
64
65 static void
66 test_relative_event(struct litest_device *dev, int dx, int dy)
67 {
68         struct libinput *li = dev->libinput;
69         struct libinput_event_pointer *ptrev;
70         double ev_dx, ev_dy;
71         double expected_dir;
72         double expected_length;
73         double actual_dir;
74         double actual_length;
75
76         /* Send two deltas, as the first one may be eaten up by an
77          * acceleration filter. */
78         litest_event(dev, EV_REL, REL_X, dx);
79         litest_event(dev, EV_REL, REL_Y, dy);
80         litest_event(dev, EV_SYN, SYN_REPORT, 0);
81         litest_event(dev, EV_REL, REL_X, dx);
82         litest_event(dev, EV_REL, REL_Y, dy);
83         litest_event(dev, EV_SYN, SYN_REPORT, 0);
84
85         libinput_dispatch(li);
86
87         ptrev = get_accelerated_motion_event(li);
88
89         expected_length = sqrt(4 * dx*dx + 4 * dy*dy);
90         expected_dir = atan2(dx, dy);
91
92         ev_dx = libinput_event_pointer_get_dx(ptrev);
93         ev_dy = libinput_event_pointer_get_dy(ptrev);
94         actual_length = sqrt(ev_dx*ev_dx + ev_dy*ev_dy);
95         actual_dir = atan2(ev_dx, ev_dy);
96
97         /* Check the length of the motion vector (tolerate 1.0 indifference). */
98         ck_assert(fabs(expected_length) >= actual_length);
99
100         /* Check the direction of the motion vector (tolerate 2π/4 radians
101          * indifference). */
102         ck_assert(fabs(expected_dir - actual_dir) < M_PI_2);
103
104         libinput_event_destroy(libinput_event_pointer_get_base_event(ptrev));
105
106         litest_drain_events(dev->libinput);
107 }
108
109 START_TEST(pointer_motion_relative)
110 {
111         struct litest_device *dev = litest_current_device();
112
113         litest_drain_events(dev->libinput);
114
115         test_relative_event(dev, 1, 0);
116         test_relative_event(dev, 1, 1);
117         test_relative_event(dev, 1, -1);
118         test_relative_event(dev, 0, 1);
119
120         test_relative_event(dev, -1, 0);
121         test_relative_event(dev, -1, 1);
122         test_relative_event(dev, -1, -1);
123         test_relative_event(dev, 0, -1);
124 }
125 END_TEST
126
127 static void
128 test_absolute_event(struct litest_device *dev, double x, double y)
129 {
130         struct libinput *li = dev->libinput;
131         struct libinput_event *event;
132         struct libinput_event_pointer *ptrev;
133         double ex, ey;
134
135         litest_touch_down(dev, 0, x, y);
136         libinput_dispatch(li);
137
138         event = libinput_get_event(li);
139         ck_assert_int_eq(libinput_event_get_type(event),
140                          LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
141
142         ptrev = libinput_event_get_pointer_event(event);
143         ck_assert(ptrev != NULL);
144
145         ex = libinput_event_pointer_get_absolute_x_transformed(ptrev, 100);
146         ey = libinput_event_pointer_get_absolute_y_transformed(ptrev, 100);
147         ck_assert_int_eq(ex + 0.5, x);
148         ck_assert_int_eq(ey + 0.5, y);
149
150         libinput_event_destroy(event);
151 }
152
153 START_TEST(pointer_motion_absolute)
154 {
155         struct litest_device *dev = litest_current_device();
156
157         litest_drain_events(dev->libinput);
158
159         test_absolute_event(dev, 0, 100);
160         test_absolute_event(dev, 100, 0);
161         test_absolute_event(dev, 50, 50);
162 }
163 END_TEST
164
165 static void
166 test_unaccel_event(struct litest_device *dev, int dx, int dy)
167 {
168       struct libinput *li = dev->libinput;
169       struct libinput_event *event;
170       struct libinput_event_pointer *ptrev;
171       double ev_dx, ev_dy;
172
173       litest_event(dev, EV_REL, REL_X, dx);
174       litest_event(dev, EV_REL, REL_Y, dy);
175       litest_event(dev, EV_SYN, SYN_REPORT, 0);
176
177       libinput_dispatch(li);
178
179       event = libinput_get_event(li);
180       ck_assert_notnull(event);
181       ck_assert_int_eq(libinput_event_get_type(event),
182                        LIBINPUT_EVENT_POINTER_MOTION);
183
184       ptrev = libinput_event_get_pointer_event(event);
185       ck_assert(ptrev != NULL);
186
187       ev_dx = libinput_event_pointer_get_dx_unaccelerated(ptrev);
188       ev_dy = libinput_event_pointer_get_dy_unaccelerated(ptrev);
189
190       ck_assert_int_eq(dx, ev_dx);
191       ck_assert_int_eq(dy, ev_dy);
192
193       libinput_event_destroy(event);
194
195       litest_drain_events(dev->libinput);
196 }
197
198 START_TEST(pointer_motion_unaccel)
199 {
200       struct litest_device *dev = litest_current_device();
201
202       litest_drain_events(dev->libinput);
203
204       test_unaccel_event(dev, 10, 0);
205       test_unaccel_event(dev, 10, 10);
206       test_unaccel_event(dev, 10, -10);
207       test_unaccel_event(dev, 0, 10);
208
209       test_unaccel_event(dev, -10, 0);
210       test_unaccel_event(dev, -10, 10);
211       test_unaccel_event(dev, -10, -10);
212       test_unaccel_event(dev, 0, -10);
213 }
214 END_TEST
215
216 static void
217 test_button_event(struct litest_device *dev, unsigned int button, int state)
218 {
219         struct libinput *li = dev->libinput;
220
221         litest_event(dev, EV_KEY, button, state);
222         litest_event(dev, EV_SYN, SYN_REPORT, 0);
223
224         litest_assert_button_event(li, button,
225                                    state ?  LIBINPUT_BUTTON_STATE_PRESSED :
226                                            LIBINPUT_BUTTON_STATE_RELEASED);
227 }
228
229 START_TEST(pointer_button)
230 {
231         struct litest_device *dev = litest_current_device();
232
233         litest_drain_events(dev->libinput);
234
235         test_button_event(dev, BTN_LEFT, 1);
236         test_button_event(dev, BTN_LEFT, 0);
237
238         /* press it twice for good measure */
239         test_button_event(dev, BTN_LEFT, 1);
240         test_button_event(dev, BTN_LEFT, 0);
241
242         if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_RIGHT)) {
243                 test_button_event(dev, BTN_RIGHT, 1);
244                 test_button_event(dev, BTN_RIGHT, 0);
245         }
246
247         /* Skip middle button test on trackpoints (used for scrolling) */
248         if (!libevdev_has_property(dev->evdev, INPUT_PROP_POINTING_STICK) &&
249             libevdev_has_event_code(dev->evdev, EV_KEY, BTN_MIDDLE)) {
250                 test_button_event(dev, BTN_MIDDLE, 1);
251                 test_button_event(dev, BTN_MIDDLE, 0);
252         }
253 }
254 END_TEST
255
256 START_TEST(pointer_button_auto_release)
257 {
258         struct libinput *libinput;
259         struct litest_device *dev;
260         struct libinput_event *event;
261         enum libinput_event_type type;
262         struct libinput_event_pointer *pevent;
263         struct {
264                 int code;
265                 int released;
266         } buttons[] = {
267                 { .code = BTN_LEFT, },
268                 { .code = BTN_MIDDLE, },
269                 { .code = BTN_EXTRA, },
270                 { .code = BTN_SIDE, },
271                 { .code = BTN_BACK, },
272                 { .code = BTN_FORWARD, },
273                 { .code = BTN_4, },
274         };
275         int events[2 * (ARRAY_LENGTH(buttons) + 1)];
276         unsigned i;
277         int button;
278         int valid_code;
279
280         /* Enable all tested buttons on the device */
281         for (i = 0; i < 2 * ARRAY_LENGTH(buttons);) {
282                 button = buttons[i / 2].code;
283                 events[i++] = EV_KEY;
284                 events[i++] = button;
285         }
286         events[i++] = -1;
287         events[i++] = -1;
288
289         libinput = litest_create_context();
290         dev = litest_add_device_with_overrides(libinput,
291                                                LITEST_MOUSE,
292                                                "Generic mouse",
293                                                NULL, NULL, events);
294
295         litest_drain_events(libinput);
296
297         /* Send pressed events, without releasing */
298         for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
299                 test_button_event(dev, buttons[i].code, 1);
300         }
301
302         litest_drain_events(libinput);
303
304         /* "Disconnect" device */
305         litest_delete_device(dev);
306
307         /* Mark all released buttons until device is removed */
308         while (1) {
309                 event = libinput_get_event(libinput);
310                 ck_assert_notnull(event);
311                 type = libinput_event_get_type(event);
312
313                 if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
314                         libinput_event_destroy(event);
315                         break;
316                 }
317
318                 ck_assert_int_eq(type, LIBINPUT_EVENT_POINTER_BUTTON);
319                 pevent = libinput_event_get_pointer_event(event);
320                 ck_assert_int_eq(libinput_event_pointer_get_button_state(pevent),
321                                  LIBINPUT_BUTTON_STATE_RELEASED);
322                 button = libinput_event_pointer_get_button(pevent);
323
324                 valid_code = 0;
325                 for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
326                         if (buttons[i].code == button) {
327                                 ck_assert_int_eq(buttons[i].released, 0);
328                                 buttons[i].released = 1;
329                                 valid_code = 1;
330                         }
331                 }
332                 ck_assert_int_eq(valid_code, 1);
333                 libinput_event_destroy(event);
334         }
335
336         /* Check that all pressed buttons has been released. */
337         for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
338                 ck_assert_int_eq(buttons[i].released, 1);
339         }
340
341         libinput_unref(libinput);
342 }
343 END_TEST
344
345 static void
346 test_wheel_event(struct litest_device *dev, int which, int amount)
347 {
348         struct libinput *li = dev->libinput;
349         struct libinput_event *event;
350         struct libinput_event_pointer *ptrev;
351         enum libinput_pointer_axis axis;
352
353         /* the current evdev implementation scales the scroll wheel events
354            up by a factor 15 */
355         const int scroll_step = 15;
356         int expected = amount * scroll_step;
357
358         if (libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device))
359                 expected *= -1;
360
361         /* mouse scroll wheels are 'upside down' */
362         if (which == REL_WHEEL)
363                 amount *= -1;
364         litest_event(dev, EV_REL, which, amount);
365         litest_event(dev, EV_SYN, SYN_REPORT, 0);
366
367         libinput_dispatch(li);
368
369         event = libinput_get_event(li);
370         ck_assert(event != NULL);
371         ck_assert_int_eq(libinput_event_get_type(event),
372                           LIBINPUT_EVENT_POINTER_AXIS);
373
374         ptrev = libinput_event_get_pointer_event(event);
375         ck_assert(ptrev != NULL);
376
377         axis = (which == REL_WHEEL) ?
378                                 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL :
379                                 LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
380
381         ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev, axis),
382                          expected);
383         ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev),
384                          LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
385         libinput_event_destroy(event);
386 }
387
388 START_TEST(pointer_scroll_wheel)
389 {
390         struct litest_device *dev = litest_current_device();
391
392         litest_drain_events(dev->libinput);
393
394         test_wheel_event(dev, REL_WHEEL, -1);
395         test_wheel_event(dev, REL_WHEEL, 1);
396
397         test_wheel_event(dev, REL_WHEEL, -5);
398         test_wheel_event(dev, REL_WHEEL, 6);
399
400         if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
401                 test_wheel_event(dev, REL_HWHEEL, -1);
402                 test_wheel_event(dev, REL_HWHEEL, 1);
403
404                 test_wheel_event(dev, REL_HWHEEL, -5);
405                 test_wheel_event(dev, REL_HWHEEL, 6);
406         }
407 }
408 END_TEST
409
410 START_TEST(pointer_scroll_natural_defaults)
411 {
412         struct litest_device *dev = litest_current_device();
413
414         ck_assert_int_ge(libinput_device_config_scroll_has_natural_scroll(dev->libinput_device), 1);
415         ck_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device), 0);
416         ck_assert_int_eq(libinput_device_config_scroll_get_default_natural_scroll_enabled(dev->libinput_device), 0);
417 }
418 END_TEST
419
420 START_TEST(pointer_scroll_natural_enable_config)
421 {
422         struct litest_device *dev = litest_current_device();
423         enum libinput_config_status status;
424
425         status = libinput_device_config_scroll_set_natural_scroll_enabled(dev->libinput_device, 1);
426         ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
427         ck_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device), 1);
428
429         status = libinput_device_config_scroll_set_natural_scroll_enabled(dev->libinput_device, 0);
430         ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
431         ck_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device), 0);
432 }
433 END_TEST
434
435 START_TEST(pointer_scroll_natural_wheel)
436 {
437         struct litest_device *dev = litest_current_device();
438         struct libinput_device *device = dev->libinput_device;
439
440         litest_drain_events(dev->libinput);
441
442         libinput_device_config_scroll_set_natural_scroll_enabled(device, 1);
443
444         test_wheel_event(dev, REL_WHEEL, -1);
445         test_wheel_event(dev, REL_WHEEL, 1);
446
447         test_wheel_event(dev, REL_WHEEL, -5);
448         test_wheel_event(dev, REL_WHEEL, 6);
449
450         if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
451                 test_wheel_event(dev, REL_HWHEEL, -1);
452                 test_wheel_event(dev, REL_HWHEEL, 1);
453
454                 test_wheel_event(dev, REL_HWHEEL, -5);
455                 test_wheel_event(dev, REL_HWHEEL, 6);
456         }
457 }
458 END_TEST
459
460 START_TEST(pointer_seat_button_count)
461 {
462         const int num_devices = 4;
463         struct litest_device *devices[num_devices];
464         struct libinput *libinput;
465         struct libinput_event *ev;
466         struct libinput_event_pointer *tev;
467         int i;
468         int seat_button_count;
469         int expected_seat_button_count = 0;
470         char device_name[255];
471
472         libinput = litest_create_context();
473         for (i = 0; i < num_devices; ++i) {
474                 sprintf(device_name, "litest Generic mouse (%d)", i);
475                 devices[i] = litest_add_device_with_overrides(libinput,
476                                                               LITEST_MOUSE,
477                                                               device_name,
478                                                               NULL, NULL, NULL);
479         }
480
481         for (i = 0; i < num_devices; ++i)
482                 litest_button_click(devices[i], BTN_LEFT, true);
483
484         libinput_dispatch(libinput);
485         while ((ev = libinput_get_event(libinput))) {
486                 if (libinput_event_get_type(ev) !=
487                     LIBINPUT_EVENT_POINTER_BUTTON) {
488                         libinput_event_destroy(ev);
489                         libinput_dispatch(libinput);
490                         continue;
491                 }
492
493                 tev = libinput_event_get_pointer_event(ev);
494                 ck_assert_notnull(tev);
495                 ck_assert_int_eq(libinput_event_pointer_get_button(tev),
496                                  BTN_LEFT);
497                 ck_assert_int_eq(libinput_event_pointer_get_button_state(tev),
498                                  LIBINPUT_BUTTON_STATE_PRESSED);
499
500                 ++expected_seat_button_count;
501                 seat_button_count =
502                         libinput_event_pointer_get_seat_button_count(tev);
503                 ck_assert_int_eq(expected_seat_button_count, seat_button_count);
504
505                 libinput_event_destroy(ev);
506                 libinput_dispatch(libinput);
507         }
508
509         ck_assert_int_eq(seat_button_count, num_devices);
510
511         for (i = 0; i < num_devices; ++i)
512                 litest_button_click(devices[i], BTN_LEFT, false);
513
514         libinput_dispatch(libinput);
515         while ((ev = libinput_get_event(libinput))) {
516                 if (libinput_event_get_type(ev) !=
517                     LIBINPUT_EVENT_POINTER_BUTTON) {
518                         libinput_event_destroy(ev);
519                         libinput_dispatch(libinput);
520                         continue;
521                 }
522
523                 tev = libinput_event_get_pointer_event(ev);
524                 ck_assert_notnull(tev);
525                 ck_assert_int_eq(libinput_event_pointer_get_button(tev),
526                                  BTN_LEFT);
527                 ck_assert_int_eq(libinput_event_pointer_get_button_state(tev),
528                                  LIBINPUT_BUTTON_STATE_RELEASED);
529
530                 --expected_seat_button_count;
531                 seat_button_count =
532                         libinput_event_pointer_get_seat_button_count(tev);
533                 ck_assert_int_eq(expected_seat_button_count, seat_button_count);
534
535                 libinput_event_destroy(ev);
536                 libinput_dispatch(libinput);
537         }
538
539         ck_assert_int_eq(seat_button_count, 0);
540
541         for (i = 0; i < num_devices; ++i)
542                 litest_delete_device(devices[i]);
543         libinput_unref(libinput);
544 }
545 END_TEST
546
547 START_TEST(pointer_no_calibration)
548 {
549         struct litest_device *dev = litest_current_device();
550         struct libinput_device *d = dev->libinput_device;
551         enum libinput_config_status status;
552         int rc;
553         float calibration[6] = {0};
554
555         rc = libinput_device_config_calibration_has_matrix(d);
556         ck_assert_int_eq(rc, 0);
557         rc = libinput_device_config_calibration_get_matrix(d, calibration);
558         ck_assert_int_eq(rc, 0);
559         rc = libinput_device_config_calibration_get_default_matrix(d,
560                                                                    calibration);
561         ck_assert_int_eq(rc, 0);
562
563         status = libinput_device_config_calibration_set_matrix(d,
564                                                                calibration);
565         ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
566 }
567 END_TEST
568
569 START_TEST(pointer_left_handed_defaults)
570 {
571         struct litest_device *dev = litest_current_device();
572         struct libinput_device *d = dev->libinput_device;
573         int rc;
574
575         rc = libinput_device_config_buttons_has_left_handed(d);
576         ck_assert_int_ne(rc, 0);
577
578         rc = libinput_device_config_buttons_get_left_handed(d);
579         ck_assert_int_eq(rc, 0);
580
581         rc = libinput_device_config_buttons_get_default_left_handed(d);
582         ck_assert_int_eq(rc, 0);
583 }
584 END_TEST
585
586 START_TEST(pointer_left_handed)
587 {
588         struct litest_device *dev = litest_current_device();
589         struct libinput_device *d = dev->libinput_device;
590         struct libinput *li = dev->libinput;
591         enum libinput_config_status status;
592
593         status = libinput_device_config_buttons_set_left_handed(d, 1);
594         ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
595
596         litest_drain_events(li);
597         litest_button_click(dev, BTN_LEFT, 1);
598         litest_button_click(dev, BTN_LEFT, 0);
599
600         litest_assert_button_event(li,
601                                    BTN_RIGHT,
602                                    LIBINPUT_BUTTON_STATE_PRESSED);
603         litest_assert_button_event(li,
604                                    BTN_RIGHT,
605                                    LIBINPUT_BUTTON_STATE_RELEASED);
606
607         litest_button_click(dev, BTN_RIGHT, 1);
608         litest_button_click(dev, BTN_RIGHT, 0);
609         litest_assert_button_event(li,
610                                    BTN_LEFT,
611                                    LIBINPUT_BUTTON_STATE_PRESSED);
612         litest_assert_button_event(li,
613                                    BTN_LEFT,
614                                    LIBINPUT_BUTTON_STATE_RELEASED);
615
616         if (libevdev_has_event_code(dev->evdev,
617                                     EV_KEY,
618                                     BTN_MIDDLE)) {
619                 litest_button_click(dev, BTN_MIDDLE, 1);
620                 litest_button_click(dev, BTN_MIDDLE, 0);
621                 litest_assert_button_event(li,
622                                            BTN_MIDDLE,
623                                            LIBINPUT_BUTTON_STATE_PRESSED);
624                 litest_assert_button_event(li,
625                                            BTN_MIDDLE,
626                                            LIBINPUT_BUTTON_STATE_RELEASED);
627         }
628 }
629 END_TEST
630
631 START_TEST(pointer_left_handed_during_click)
632 {
633         struct litest_device *dev = litest_current_device();
634         struct libinput_device *d = dev->libinput_device;
635         struct libinput *li = dev->libinput;
636         enum libinput_config_status status;
637
638         litest_drain_events(li);
639         litest_button_click(dev, BTN_LEFT, 1);
640         libinput_dispatch(li);
641
642         /* Change while button is down, expect correct release event */
643         status = libinput_device_config_buttons_set_left_handed(d, 1);
644         ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
645
646         litest_button_click(dev, BTN_LEFT, 0);
647
648         litest_assert_button_event(li,
649                                    BTN_LEFT,
650                                    LIBINPUT_BUTTON_STATE_PRESSED);
651         litest_assert_button_event(li,
652                                    BTN_LEFT,
653                                    LIBINPUT_BUTTON_STATE_RELEASED);
654 }
655 END_TEST
656
657 START_TEST(pointer_left_handed_during_click_multiple_buttons)
658 {
659         struct litest_device *dev = litest_current_device();
660         struct libinput_device *d = dev->libinput_device;
661         struct libinput *li = dev->libinput;
662         enum libinput_config_status status;
663
664         litest_drain_events(li);
665         litest_button_click(dev, BTN_LEFT, 1);
666         libinput_dispatch(li);
667
668         status = libinput_device_config_buttons_set_left_handed(d, 1);
669         ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
670
671         /* No left-handed until all buttons were down */
672         litest_button_click(dev, BTN_RIGHT, 1);
673         litest_button_click(dev, BTN_RIGHT, 0);
674         litest_button_click(dev, BTN_LEFT, 0);
675
676         litest_assert_button_event(li,
677                                    BTN_LEFT,
678                                    LIBINPUT_BUTTON_STATE_PRESSED);
679         litest_assert_button_event(li,
680                                    BTN_RIGHT,
681                                    LIBINPUT_BUTTON_STATE_PRESSED);
682         litest_assert_button_event(li,
683                                    BTN_RIGHT,
684                                    LIBINPUT_BUTTON_STATE_RELEASED);
685         litest_assert_button_event(li,
686                                    BTN_LEFT,
687                                    LIBINPUT_BUTTON_STATE_RELEASED);
688 }
689 END_TEST
690
691 START_TEST(pointer_scroll_button)
692 {
693         struct litest_device *dev = litest_current_device();
694         struct libinput *li = dev->libinput;
695
696         /* Make left button switch to scrolling mode */
697         libinput_device_config_scroll_set_method(dev->libinput_device,
698                                         LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
699         libinput_device_config_scroll_set_button(dev->libinput_device,
700                                         BTN_LEFT);
701
702         litest_drain_events(li);
703
704         litest_button_scroll(dev, BTN_LEFT, 1, 6);
705         litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6);
706         litest_button_scroll(dev, BTN_LEFT, 1, -7);
707         litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -7);
708         litest_button_scroll(dev, BTN_LEFT, 8, 1);
709         litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 8);
710         litest_button_scroll(dev, BTN_LEFT, -9, 1);
711         litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -9);
712
713         /* scroll smaller than the threshold should not generate events */
714         litest_button_scroll(dev, BTN_LEFT, 1, 1);
715         /* left press without movement should not generate events */
716         litest_button_scroll(dev, BTN_LEFT, 0, 0);
717
718         litest_assert_empty_queue(li);
719
720         /* Restore default scroll behavior */
721         libinput_device_config_scroll_set_method(dev->libinput_device,
722                 libinput_device_config_scroll_get_default_method(
723                         dev->libinput_device));
724         libinput_device_config_scroll_set_button(dev->libinput_device,
725                 libinput_device_config_scroll_get_default_button(
726                         dev->libinput_device));
727 }
728 END_TEST
729
730 int main (int argc, char **argv) {
731
732         litest_add("pointer:motion", pointer_motion_relative, LITEST_RELATIVE, LITEST_ANY);
733         litest_add("pointer:motion", pointer_motion_absolute, LITEST_ABSOLUTE, LITEST_ANY);
734         litest_add("pointer:motion", pointer_motion_unaccel, LITEST_RELATIVE, LITEST_ANY);
735         litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_CLICKPAD);
736         litest_add_no_device("pointer:button_auto_release", pointer_button_auto_release);
737         litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_ANY);
738         litest_add("pointer:scroll", pointer_scroll_button, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
739         litest_add("pointer:scroll", pointer_scroll_natural_defaults, LITEST_WHEEL, LITEST_ANY);
740         litest_add("pointer:scroll", pointer_scroll_natural_enable_config, LITEST_WHEEL, LITEST_ANY);
741         litest_add("pointer:scroll", pointer_scroll_natural_wheel, LITEST_WHEEL, LITEST_ANY);
742         litest_add_no_device("pointer:seat button count", pointer_seat_button_count);
743
744         litest_add("pointer:calibration", pointer_no_calibration, LITEST_ANY, LITEST_TOUCH|LITEST_SINGLE_TOUCH|LITEST_ABSOLUTE);
745
746                                                                         /* tests touchpads too */
747         litest_add("pointer:left-handed", pointer_left_handed_defaults, LITEST_BUTTON, LITEST_ANY);
748         litest_add("pointer:left-handed", pointer_left_handed, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
749         litest_add("pointer:left-handed", pointer_left_handed_during_click, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
750         litest_add("pointer:left-handed", pointer_left_handed_during_click_multiple_buttons, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
751
752         return litest_run(argc, argv);
753 }