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.
29 #include <libevdev/libevdev.h>
32 #include "libinput-util.h"
35 START_TEST(touch_frame_events)
37 struct litest_device *dev = litest_current_device();
38 struct libinput *li = dev->libinput;
39 struct libinput_event *event;
40 int have_frame_event = 0;
42 litest_drain_events(dev->libinput);
44 litest_touch_down(dev, 0, 10, 10);
45 libinput_dispatch(li);
47 while ((event = libinput_get_event(li))) {
48 if (libinput_event_get_type(event) == LIBINPUT_EVENT_TOUCH_FRAME)
50 libinput_event_destroy(event);
52 ck_assert_int_eq(have_frame_event, 1);
54 litest_touch_down(dev, 1, 10, 10);
55 libinput_dispatch(li);
57 while ((event = libinput_get_event(li))) {
58 if (libinput_event_get_type(event) == LIBINPUT_EVENT_TOUCH_FRAME)
60 libinput_event_destroy(event);
62 ck_assert_int_eq(have_frame_event, 2);
66 START_TEST(touch_abs_transform)
68 struct litest_device *dev;
69 struct libinput *libinput;
70 struct libinput_event *ev;
71 struct libinput_event_touch *tev;
75 struct input_absinfo abs[] = {
76 { ABS_X, 0, 32767, 75, 0, 10 },
77 { ABS_Y, 0, 32767, 129, 0, 9 },
78 { ABS_MT_POSITION_X, 0, 32767, 0, 0, 10 },
79 { ABS_MT_POSITION_Y, 0, 32767, 0, 0, 9 },
83 dev = litest_create_device_with_overrides(LITEST_WACOM_TOUCH,
84 "litest Highres touch device",
87 libinput = dev->libinput;
89 litest_touch_down(dev, 0, 100, 100);
91 libinput_dispatch(libinput);
93 while ((ev = libinput_get_event(libinput))) {
94 if (libinput_event_get_type(ev) != LIBINPUT_EVENT_TOUCH_DOWN) {
95 libinput_event_destroy(ev);
99 tev = libinput_event_get_touch_event(ev);
100 fx = libinput_event_touch_get_x_transformed(tev, 1920);
101 ck_assert_int_eq(fx, 1919.0);
102 fy = libinput_event_touch_get_y_transformed(tev, 720);
103 ck_assert_int_eq(fy, 719.0);
107 libinput_event_destroy(ev);
112 litest_delete_device(dev);
116 START_TEST(touch_many_slots)
118 struct libinput *libinput;
119 struct litest_device *dev;
120 struct libinput_event *ev;
122 const int num_tps = 100;
124 enum libinput_event_type type;
126 struct input_absinfo abs[] = {
127 { ABS_MT_SLOT, 0, num_tps - 1, 0, 0, 0 },
131 dev = litest_create_device_with_overrides(LITEST_WACOM_TOUCH,
132 "litest Multi-touch device",
134 libinput = dev->libinput;
136 for (slot = 0; slot < num_tps; ++slot)
137 litest_touch_down(dev, slot, 0, 0);
138 for (slot = 0; slot < num_tps; ++slot)
139 litest_touch_up(dev, slot);
141 libinput_dispatch(libinput);
142 while ((ev = libinput_get_event(libinput))) {
143 type = libinput_event_get_type(ev);
145 if (type == LIBINPUT_EVENT_TOUCH_DOWN)
147 else if (type == LIBINPUT_EVENT_TOUCH_UP)
150 libinput_event_destroy(ev);
151 libinput_dispatch(libinput);
154 ck_assert_notnull(ev);
155 ck_assert_int_gt(slot_count, 0);
157 libinput_dispatch(libinput);
159 type = libinput_event_get_type(ev);
160 ck_assert_int_ne(type, LIBINPUT_EVENT_TOUCH_DOWN);
161 if (type == LIBINPUT_EVENT_TOUCH_UP)
164 libinput_event_destroy(ev);
165 libinput_dispatch(libinput);
166 } while ((ev = libinput_get_event(libinput)));
168 ck_assert_int_eq(slot_count, 0);
170 litest_delete_device(dev);
174 START_TEST(touch_double_touch_down_up)
176 struct libinput *libinput;
177 struct litest_device *dev;
178 struct libinput_event *ev;
179 bool got_down = false;
182 dev = litest_current_device();
183 libinput = dev->libinput;
185 litest_touch_down(dev, 0, 0, 0);
186 litest_touch_down(dev, 0, 0, 0);
187 litest_touch_up(dev, 0);
188 litest_touch_up(dev, 0);
190 libinput_dispatch(libinput);
192 while ((ev = libinput_get_event(libinput))) {
193 switch (libinput_event_get_type(ev)) {
194 case LIBINPUT_EVENT_TOUCH_DOWN:
195 ck_assert(!got_down);
198 case LIBINPUT_EVENT_TOUCH_UP:
207 libinput_event_destroy(ev);
208 libinput_dispatch(libinput);
216 START_TEST(touch_calibration_scale)
219 struct litest_device *dev;
220 struct libinput_event *ev;
221 struct libinput_event_touch *tev;
229 const int width = 640, height = 480;
231 dev = litest_current_device();
234 for (calibration = 0.1; calibration < 1; calibration += 0.1) {
235 libinput_device_config_calibration_set_matrix(dev->libinput_device,
237 litest_drain_events(li);
239 litest_touch_down(dev, 0, 100, 100);
240 litest_touch_up(dev, 0);
242 litest_wait_for_event(li);
243 ev = libinput_get_event(li);
244 ck_assert_int_eq(libinput_event_get_type(ev),
245 LIBINPUT_EVENT_TOUCH_DOWN);
246 tev = libinput_event_get_touch_event(ev);
248 x = libinput_event_touch_get_x_transformed(tev, width);
249 y = libinput_event_touch_get_y_transformed(tev, height);
251 ck_assert_int_eq(round(x), round(width * matrix[0]));
252 ck_assert_int_eq(round(y), round(height * matrix[4]));
254 libinput_event_destroy(ev);
255 litest_drain_events(li);
257 matrix[0] = calibration;
258 matrix[4] = 1 - calibration;
263 START_TEST(touch_calibration_rotation)
266 struct litest_device *dev;
267 struct libinput_event *ev;
268 struct libinput_event_touch *tev;
272 int width = 1024, height = 480;
274 dev = litest_current_device();
277 for (i = 0; i < 4; i++) {
278 float angle = i * M_PI/2;
283 matrix[0] = cos(angle);
284 matrix[1] = -sin(angle);
285 matrix[3] = sin(angle);
286 matrix[4] = cos(angle);
293 case 1: /* 90 deg cw */
297 case 2: /* 180 deg cw */
301 case 3: /* 270 deg cw */
307 libinput_device_config_calibration_set_matrix(dev->libinput_device,
309 litest_drain_events(li);
311 litest_touch_down(dev, 0, 80, 20);
312 litest_touch_up(dev, 0);
313 litest_wait_for_event(li);
314 ev = libinput_get_event(li);
315 ck_assert_int_eq(libinput_event_get_type(ev),
316 LIBINPUT_EVENT_TOUCH_DOWN);
317 tev = libinput_event_get_touch_event(ev);
319 x = libinput_event_touch_get_x_transformed(tev, width);
320 y = libinput_event_touch_get_y_transformed(tev, height);
322 /* rounding errors... */
323 #define almost_equal(a_, b_) \
324 { ck_assert_int_ge((a_) + 0.5, (b_) - 1); \
325 ck_assert_int_le((a_) + 0.5, (b_) + 1); }
328 almost_equal(x, width * 0.8);
329 almost_equal(y, height * 0.2);
331 case 1: /* 90 deg cw */
332 almost_equal(x, width * 0.8);
333 almost_equal(y, height * 0.8);
335 case 2: /* 180 deg cw */
336 almost_equal(x, width * 0.2);
337 almost_equal(y, height * 0.8);
339 case 3: /* 270 deg cw */
340 almost_equal(x, width * 0.2);
341 almost_equal(y, height * 0.2);
347 libinput_event_destroy(ev);
348 litest_drain_events(li);
353 START_TEST(touch_calibration_translation)
356 struct litest_device *dev;
357 struct libinput_event *ev;
358 struct libinput_event_touch *tev;
366 const int width = 640, height = 480;
368 dev = litest_current_device();
371 /* translating from 0 up to 1 device width/height */
372 for (translate = 0.1; translate <= 1; translate += 0.1) {
373 libinput_device_config_calibration_set_matrix(dev->libinput_device,
375 litest_drain_events(li);
377 litest_touch_down(dev, 0, 100, 100);
378 litest_touch_up(dev, 0);
380 litest_wait_for_event(li);
381 ev = libinput_get_event(li);
382 ck_assert_int_eq(libinput_event_get_type(ev),
383 LIBINPUT_EVENT_TOUCH_DOWN);
384 tev = libinput_event_get_touch_event(ev);
386 x = libinput_event_touch_get_x_transformed(tev, width);
387 y = libinput_event_touch_get_y_transformed(tev, height);
389 /* sigh. rounding errors */
390 ck_assert_int_ge(round(x), width + round(width * matrix[2]) - 1);
391 ck_assert_int_ge(round(y), height + round(height * matrix[5]) - 1);
392 ck_assert_int_le(round(x), width + round(width * matrix[2]) + 1);
393 ck_assert_int_le(round(y), height + round(height * matrix[5]) + 1);
395 libinput_event_destroy(ev);
396 litest_drain_events(li);
398 matrix[2] = translate;
399 matrix[5] = 1 - translate;
405 main(int argc, char **argv)
407 litest_add("touch:frame", touch_frame_events, LITEST_TOUCH, LITEST_ANY);
408 litest_add_no_device("touch:abs-transform", touch_abs_transform);
409 litest_add_no_device("touch:many-slots", touch_many_slots);
410 litest_add("touch:double-touch-down-up", touch_double_touch_down_up, LITEST_TOUCH, LITEST_ANY);
411 litest_add("touch:calibration", touch_calibration_scale, LITEST_TOUCH, LITEST_TOUCHPAD);
412 litest_add("touch:calibration", touch_calibration_scale, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
413 litest_add("touch:calibration", touch_calibration_rotation, LITEST_TOUCH, LITEST_TOUCHPAD);
414 litest_add("touch:calibration", touch_calibration_rotation, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
415 litest_add("touch:calibration", touch_calibration_translation, LITEST_TOUCH, LITEST_TOUCHPAD);
416 litest_add("touch:calibration", touch_calibration_translation, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
418 return litest_run(argc, argv);