udev: factor out device_removed handling
[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 <check.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <libinput.h>
29 #include <unistd.h>
30
31 #include "libinput-util.h"
32 #include "litest.h"
33
34 static void
35 test_relative_event(struct litest_device *dev, int dx, int dy)
36 {
37         struct libinput *li = dev->libinput;
38         struct libinput_event *event;
39         struct libinput_event_pointer *ptrev;
40
41         litest_event(dev, EV_REL, REL_X, dx);
42         litest_event(dev, EV_REL, REL_Y, dy);
43         litest_event(dev, EV_SYN, SYN_REPORT, 0);
44
45         libinput_dispatch(li);
46
47         event = libinput_get_event(li);
48         ck_assert(event != NULL);
49         ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_MOTION);
50
51         ptrev = libinput_event_get_pointer_event(event);
52         ck_assert(ptrev != NULL);
53         ck_assert_int_eq(libinput_event_pointer_get_dx(ptrev), li_fixed_from_int(dx));
54         ck_assert_int_eq(libinput_event_pointer_get_dy(ptrev), li_fixed_from_int(dy));
55
56         libinput_event_destroy(event);
57 }
58
59 START_TEST(pointer_motion_relative)
60 {
61         struct litest_device *dev = litest_current_device();
62
63         litest_drain_events(dev->libinput);
64
65         test_relative_event(dev, 1, 0);
66         test_relative_event(dev, 1, 1);
67         test_relative_event(dev, 1, -1);
68         test_relative_event(dev, 0, 1);
69
70         test_relative_event(dev, -1, 0);
71         test_relative_event(dev, -1, 1);
72         test_relative_event(dev, -1, -1);
73         test_relative_event(dev, 0, -1);
74 }
75 END_TEST
76
77 static void
78 test_button_event(struct litest_device *dev, int button, int state)
79 {
80         struct libinput *li = dev->libinput;
81         struct libinput_event *event;
82         struct libinput_event_pointer *ptrev;
83
84         litest_event(dev, EV_KEY, button, state);
85         litest_event(dev, EV_SYN, SYN_REPORT, 0);
86
87         libinput_dispatch(li);
88
89         event = libinput_get_event(li);
90         ck_assert(event != NULL);
91         ck_assert_int_eq(libinput_event_get_type(event), LIBINPUT_EVENT_POINTER_BUTTON);
92
93         ptrev = libinput_event_get_pointer_event(event);
94         ck_assert(ptrev != NULL);
95         ck_assert_int_eq(libinput_event_pointer_get_button(ptrev), button);
96         ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrev),
97                          state ?
98                                 LIBINPUT_POINTER_BUTTON_STATE_PRESSED :
99                                 LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
100         libinput_event_destroy(event);
101 }
102
103 START_TEST(pointer_button)
104 {
105         struct litest_device *dev = litest_current_device();
106
107         litest_drain_events(dev->libinput);
108
109         test_button_event(dev, BTN_LEFT, 1);
110         test_button_event(dev, BTN_LEFT, 0);
111
112         /* press it twice for good measure */
113         test_button_event(dev, BTN_LEFT, 1);
114         test_button_event(dev, BTN_LEFT, 0);
115
116         if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_RIGHT)) {
117                 test_button_event(dev, BTN_RIGHT, 1);
118                 test_button_event(dev, BTN_RIGHT, 0);
119         }
120
121         if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_MIDDLE)) {
122                 test_button_event(dev, BTN_MIDDLE, 1);
123                 test_button_event(dev, BTN_MIDDLE, 0);
124         }
125 }
126 END_TEST
127
128 static void
129 test_wheel_event(struct litest_device *dev, int which, int amount)
130 {
131         struct libinput *li = dev->libinput;
132         struct libinput_event *event;
133         struct libinput_event_pointer *ptrev;
134
135         /* the current evdev implementation scales the scroll wheel events
136            up by a factor 10 */
137         const int scroll_step = 10;
138         int expected = amount * scroll_step;
139
140         /* mouse scroll wheels are 'upside down' */
141         if (which == REL_WHEEL)
142                 amount *= -1;
143         litest_event(dev, EV_REL, which, amount);
144         litest_event(dev, EV_SYN, SYN_REPORT, 0);
145
146         libinput_dispatch(li);
147
148         event = libinput_get_event(li);
149         ck_assert(event != NULL);
150         ck_assert_int_eq(libinput_event_get_type(event),
151                           LIBINPUT_EVENT_POINTER_AXIS);
152
153         ptrev = libinput_event_get_pointer_event(event);
154         ck_assert(ptrev != NULL);
155         ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev),
156                          which == REL_WHEEL ?
157                                 LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL :
158                                 LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL);
159         ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev),
160                          li_fixed_from_int(expected));
161         libinput_event_destroy(event);
162 }
163
164 START_TEST(pointer_scroll_wheel)
165 {
166         struct litest_device *dev = litest_current_device();
167
168         litest_drain_events(dev->libinput);
169
170         test_wheel_event(dev, REL_WHEEL, -1);
171         test_wheel_event(dev, REL_WHEEL, 1);
172
173         test_wheel_event(dev, REL_WHEEL, -5);
174         test_wheel_event(dev, REL_WHEEL, 6);
175
176         if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
177                 test_wheel_event(dev, REL_HWHEEL, -1);
178                 test_wheel_event(dev, REL_HWHEEL, 1);
179
180                 test_wheel_event(dev, REL_HWHEEL, -5);
181                 test_wheel_event(dev, REL_HWHEEL, 6);
182         }
183 }
184 END_TEST
185
186 int main (int argc, char **argv) {
187
188         litest_add("pointer:motion", pointer_motion_relative, LITEST_POINTER, LITEST_ANY);
189         litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_ANY);
190         litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_ANY);
191
192         return litest_run(argc, argv);
193 }