2 * Copyright © 2013 Red Hat, Inc.
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.
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.
33 #include "libinput-util.h"
37 test_relative_event(struct litest_device *dev, int dx, int dy)
39 struct libinput *li = dev->libinput;
40 struct libinput_event *event;
41 struct libinput_event_pointer *ptrev;
44 double expected_length;
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);
57 libinput_dispatch(li);
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);
63 ptrev = libinput_event_get_pointer_event(event);
64 ck_assert(ptrev != NULL);
66 expected_length = sqrt(4 * dx*dx + 4 * dy*dy);
67 expected_dir = atan2(dx, dy);
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);
74 /* Check the length of the motion vector (tolerate 1.0 indifference). */
75 ck_assert(fabs(expected_length) >= actual_length);
77 /* Check the direction of the motion vector (tolerate 2π/4 radians
79 ck_assert(fabs(expected_dir - actual_dir) < M_PI_2);
81 libinput_event_destroy(event);
83 litest_drain_events(dev->libinput);
86 START_TEST(pointer_motion_relative)
88 struct litest_device *dev = litest_current_device();
90 litest_drain_events(dev->libinput);
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);
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);
105 test_button_event(struct litest_device *dev, unsigned int button, int state)
107 struct libinput *li = dev->libinput;
108 struct libinput_event *event;
109 struct libinput_event_pointer *ptrev;
111 litest_event(dev, EV_KEY, button, state);
112 litest_event(dev, EV_SYN, SYN_REPORT, 0);
114 libinput_dispatch(li);
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);
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),
125 LIBINPUT_BUTTON_STATE_PRESSED :
126 LIBINPUT_BUTTON_STATE_RELEASED);
127 libinput_event_destroy(event);
130 START_TEST(pointer_button)
132 struct litest_device *dev = litest_current_device();
134 litest_drain_events(dev->libinput);
136 test_button_event(dev, BTN_LEFT, 1);
137 test_button_event(dev, BTN_LEFT, 0);
139 /* press it twice for good measure */
140 test_button_event(dev, BTN_LEFT, 1);
141 test_button_event(dev, BTN_LEFT, 0);
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);
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);
156 test_wheel_event(struct litest_device *dev, int which, int amount)
158 struct libinput *li = dev->libinput;
159 struct libinput_event *event;
160 struct libinput_event_pointer *ptrev;
162 /* the current evdev implementation scales the scroll wheel events
164 const int scroll_step = 10;
165 int expected = amount * scroll_step;
167 /* mouse scroll wheels are 'upside down' */
168 if (which == REL_WHEEL)
170 litest_event(dev, EV_REL, which, amount);
171 litest_event(dev, EV_SYN, SYN_REPORT, 0);
173 libinput_dispatch(li);
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);
180 ptrev = libinput_event_get_pointer_event(event);
181 ck_assert(ptrev != NULL);
182 ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev),
184 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL :
185 LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
186 ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), expected);
187 libinput_event_destroy(event);
190 START_TEST(pointer_scroll_wheel)
192 struct litest_device *dev = litest_current_device();
194 litest_drain_events(dev->libinput);
196 test_wheel_event(dev, REL_WHEEL, -1);
197 test_wheel_event(dev, REL_WHEEL, 1);
199 test_wheel_event(dev, REL_WHEEL, -5);
200 test_wheel_event(dev, REL_WHEEL, 6);
202 if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
203 test_wheel_event(dev, REL_HWHEEL, -1);
204 test_wheel_event(dev, REL_HWHEEL, 1);
206 test_wheel_event(dev, REL_HWHEEL, -5);
207 test_wheel_event(dev, REL_HWHEEL, 6);
212 START_TEST(pointer_seat_button_count)
214 const int num_devices = 4;
215 struct litest_device *devices[num_devices];
216 struct libinput *libinput;
217 struct libinput_event *ev;
218 struct libinput_event_pointer *tev;
220 int seat_button_count;
221 int expected_seat_button_count = 0;
222 char device_name[255];
224 libinput = litest_create_context();
225 for (i = 0; i < num_devices; ++i) {
226 sprintf(device_name, "litest Generic mouse (%d)", i);
227 devices[i] = litest_add_device_with_overrides(libinput,
233 for (i = 0; i < num_devices; ++i)
234 litest_button_click(devices[i], BTN_LEFT, true);
236 libinput_dispatch(libinput);
237 while ((ev = libinput_get_event(libinput))) {
238 if (libinput_event_get_type(ev) !=
239 LIBINPUT_EVENT_POINTER_BUTTON) {
240 libinput_event_destroy(ev);
241 libinput_dispatch(libinput);
245 tev = libinput_event_get_pointer_event(ev);
246 ck_assert_notnull(tev);
247 ck_assert_int_eq(libinput_event_pointer_get_button(tev),
249 ck_assert_int_eq(libinput_event_pointer_get_button_state(tev),
250 LIBINPUT_BUTTON_STATE_PRESSED);
252 ++expected_seat_button_count;
254 libinput_event_pointer_get_seat_button_count(tev);
255 ck_assert_int_eq(expected_seat_button_count, seat_button_count);
257 libinput_event_destroy(ev);
258 libinput_dispatch(libinput);
261 ck_assert_int_eq(seat_button_count, num_devices);
263 for (i = 0; i < num_devices; ++i)
264 litest_button_click(devices[i], BTN_LEFT, false);
266 libinput_dispatch(libinput);
267 while ((ev = libinput_get_event(libinput))) {
268 if (libinput_event_get_type(ev) !=
269 LIBINPUT_EVENT_POINTER_BUTTON) {
270 libinput_event_destroy(ev);
271 libinput_dispatch(libinput);
275 tev = libinput_event_get_pointer_event(ev);
276 ck_assert_notnull(tev);
277 ck_assert_int_eq(libinput_event_pointer_get_button(tev),
279 ck_assert_int_eq(libinput_event_pointer_get_button_state(tev),
280 LIBINPUT_BUTTON_STATE_RELEASED);
282 --expected_seat_button_count;
284 libinput_event_pointer_get_seat_button_count(tev);
285 ck_assert_int_eq(expected_seat_button_count, seat_button_count);
287 libinput_event_destroy(ev);
288 libinput_dispatch(libinput);
291 ck_assert_int_eq(seat_button_count, 0);
293 for (i = 0; i < num_devices; ++i)
294 litest_delete_device(devices[i]);
295 libinput_unref(libinput);
299 int main (int argc, char **argv) {
301 litest_add("pointer:motion", pointer_motion_relative, LITEST_POINTER, LITEST_ANY);
302 litest_add("pointer:button", pointer_button, LITEST_BUTTON, LITEST_CLICKPAD);
303 litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_ANY);
304 litest_add_no_device("pointer:seat button count", pointer_seat_button_count);
306 return litest_run(argc, argv);