1 /*
2 * Copyright © 2014 Jonas Ådahl <jadahl@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "config.h"
25
26 #include <check.h>
27 #include <stdio.h>
28
29 #include "libinput-util.h"
30 #include "litest.h"
31
START_TEST(keyboard_seat_key_count)32 START_TEST(keyboard_seat_key_count)
33 {
34 struct litest_device *devices[4];
35 const int num_devices = ARRAY_LENGTH(devices);
36 struct libinput *libinput;
37 struct libinput_event *ev;
38 struct libinput_event_keyboard *kev;
39 int i;
40 int seat_key_count = 0;
41 int expected_key_button_count = 0;
42 char device_name[255];
43
44 libinput = litest_create_context();
45 for (i = 0; i < num_devices; ++i) {
46 sprintf(device_name, "litest Generic keyboard (%d)", i);
47 devices[i] = litest_add_device_with_overrides(libinput,
48 LITEST_KEYBOARD,
49 device_name,
50 NULL, NULL, NULL);
51 }
52
53 litest_drain_events(libinput);
54
55 for (i = 0; i < num_devices; ++i)
56 litest_keyboard_key(devices[i], KEY_A, true);
57
58 libinput_dispatch(libinput);
59 while ((ev = libinput_get_event(libinput))) {
60 kev = litest_is_keyboard_event(ev,
61 KEY_A,
62 LIBINPUT_KEY_STATE_PRESSED);
63
64 ++expected_key_button_count;
65 seat_key_count =
66 libinput_event_keyboard_get_seat_key_count(kev);
67 ck_assert_int_eq(expected_key_button_count, seat_key_count);
68
69 libinput_event_destroy(ev);
70 libinput_dispatch(libinput);
71 }
72
73 ck_assert_int_eq(seat_key_count, num_devices);
74
75 for (i = 0; i < num_devices; ++i)
76 litest_keyboard_key(devices[i], KEY_A, false);
77
78 libinput_dispatch(libinput);
79 while ((ev = libinput_get_event(libinput))) {
80 kev = libinput_event_get_keyboard_event(ev);
81 ck_assert_notnull(kev);
82 ck_assert_int_eq(libinput_event_keyboard_get_key(kev), KEY_A);
83 ck_assert_int_eq(libinput_event_keyboard_get_key_state(kev),
84 LIBINPUT_KEY_STATE_RELEASED);
85
86 --expected_key_button_count;
87 seat_key_count =
88 libinput_event_keyboard_get_seat_key_count(kev);
89 ck_assert_int_eq(expected_key_button_count, seat_key_count);
90
91 libinput_event_destroy(ev);
92 libinput_dispatch(libinput);
93 }
94
95 ck_assert_int_eq(seat_key_count, 0);
96
97 for (i = 0; i < num_devices; ++i)
98 litest_delete_device(devices[i]);
99 litest_destroy_context(libinput);
100 }
101 END_TEST
102
START_TEST(keyboard_ignore_no_pressed_release)103 START_TEST(keyboard_ignore_no_pressed_release)
104 {
105 struct litest_device *dev;
106 struct libinput *unused_libinput;
107 struct libinput *libinput;
108 struct libinput_event *event;
109 struct libinput_event_keyboard *kevent;
110 int events[] = {
111 EV_KEY, KEY_A,
112 -1, -1,
113 };
114 enum libinput_key_state expected_states[] = {
115 LIBINPUT_KEY_STATE_PRESSED,
116 LIBINPUT_KEY_STATE_RELEASED,
117 };
118
119 /* We can't send pressed -> released -> pressed events using uinput
120 * as such non-symmetric events are dropped. Work-around this by first
121 * adding the test device to the tested context after having sent an
122 * initial pressed event. */
123 unused_libinput = litest_create_context();
124 dev = litest_add_device_with_overrides(unused_libinput,
125 LITEST_KEYBOARD,
126 "Generic keyboard",
127 NULL, NULL, events);
128
129 litest_keyboard_key(dev, KEY_A, true);
130 litest_drain_events(unused_libinput);
131
132 libinput = litest_create_context();
133 libinput_path_add_device(libinput,
134 libevdev_uinput_get_devnode(dev->uinput));
135 litest_drain_events(libinput);
136
137 litest_keyboard_key(dev, KEY_A, false);
138 litest_keyboard_key(dev, KEY_A, true);
139 litest_keyboard_key(dev, KEY_A, false);
140
141 libinput_dispatch(libinput);
142
143 ARRAY_FOR_EACH(expected_states, state) {
144 event = libinput_get_event(libinput);
145 ck_assert_notnull(event);
146 ck_assert_int_eq(libinput_event_get_type(event),
147 LIBINPUT_EVENT_KEYBOARD_KEY);
148 kevent = libinput_event_get_keyboard_event(event);
149 ck_assert_int_eq(libinput_event_keyboard_get_key(kevent),
150 KEY_A);
151 ck_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
152 *state);
153 libinput_event_destroy(event);
154 libinput_dispatch(libinput);
155 }
156
157 litest_assert_empty_queue(libinput);
158 litest_delete_device(dev);
159 litest_destroy_context(libinput);
160 litest_destroy_context(unused_libinput);
161 }
162 END_TEST
163
START_TEST(keyboard_key_auto_release)164 START_TEST(keyboard_key_auto_release)
165 {
166 struct libinput *libinput;
167 struct litest_device *dev;
168 struct libinput_event *event;
169 enum libinput_event_type type;
170 struct libinput_event_keyboard *kevent;
171 struct {
172 int code;
173 int released;
174 } keys[] = {
175 { .code = KEY_A, },
176 { .code = KEY_S, },
177 { .code = KEY_D, },
178 { .code = KEY_G, },
179 { .code = KEY_Z, },
180 { .code = KEY_DELETE, },
181 { .code = KEY_F24, },
182 };
183 int events[2 * (ARRAY_LENGTH(keys) + 1)];
184 unsigned i;
185 int key;
186 int valid_code;
187
188 /* Enable all tested keys on the device */
189 i = 0;
190 while (i < 2 * ARRAY_LENGTH(keys)) {
191 key = keys[i / 2].code;
192 events[i++] = EV_KEY;
193 events[i++] = key;
194 }
195 events[i++] = -1;
196 events[i++] = -1;
197
198 libinput = litest_create_context();
199 dev = litest_add_device_with_overrides(libinput,
200 LITEST_KEYBOARD,
201 "Generic keyboard",
202 NULL, NULL, events);
203
204 litest_drain_events(libinput);
205
206 /* Send pressed events, without releasing */
207 for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
208 key = keys[i].code;
209 litest_event(dev, EV_KEY, key, 1);
210 litest_event(dev, EV_SYN, SYN_REPORT, 0);
211
212 libinput_dispatch(libinput);
213
214 event = libinput_get_event(libinput);
215 litest_is_keyboard_event(event,
216 key,
217 LIBINPUT_KEY_STATE_PRESSED);
218 libinput_event_destroy(event);
219 }
220
221 litest_drain_events(libinput);
222
223 /* "Disconnect" device */
224 litest_delete_device(dev);
225
226 /* Mark all released keys until device is removed */
227 while (1) {
228 event = libinput_get_event(libinput);
229 ck_assert_notnull(event);
230 type = libinput_event_get_type(event);
231
232 if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
233 libinput_event_destroy(event);
234 break;
235 }
236
237 ck_assert_int_eq(type, LIBINPUT_EVENT_KEYBOARD_KEY);
238 kevent = libinput_event_get_keyboard_event(event);
239 ck_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
240 LIBINPUT_KEY_STATE_RELEASED);
241 key = libinput_event_keyboard_get_key(kevent);
242
243 valid_code = 0;
244 for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
245 if (keys[i].code == key) {
246 ck_assert_int_eq(keys[i].released, 0);
247 keys[i].released = 1;
248 valid_code = 1;
249 }
250 }
251 ck_assert_int_eq(valid_code, 1);
252 libinput_event_destroy(event);
253 }
254
255 /* Check that all pressed keys has been released. */
256 for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
257 ck_assert_int_eq(keys[i].released, 1);
258 }
259
260 litest_destroy_context(libinput);
261 }
262 END_TEST
263
START_TEST(keyboard_has_key)264 START_TEST(keyboard_has_key)
265 {
266 struct litest_device *dev = litest_current_device();
267 struct libinput_device *device = dev->libinput_device;
268 unsigned int code;
269 int evdev_has, libinput_has;
270
271 ck_assert(libinput_device_has_capability(
272 device,
273 LIBINPUT_DEVICE_CAP_KEYBOARD));
274
275 for (code = 0; code < KEY_CNT; code++) {
276 evdev_has = libevdev_has_event_code(dev->evdev, EV_KEY, code);
277 libinput_has = libinput_device_keyboard_has_key(device, code);
278 ck_assert_int_eq(evdev_has, libinput_has);
279 }
280 }
281 END_TEST
282
START_TEST(keyboard_keys_bad_device)283 START_TEST(keyboard_keys_bad_device)
284 {
285 struct litest_device *dev = litest_current_device();
286 struct libinput_device *device = dev->libinput_device;
287 unsigned int code;
288 int has_key;
289
290 if (libinput_device_has_capability(device,
291 LIBINPUT_DEVICE_CAP_KEYBOARD))
292 return;
293
294 for (code = 0; code < KEY_CNT; code++) {
295 has_key = libinput_device_keyboard_has_key(device, code);
296 ck_assert_int_eq(has_key, -1);
297 }
298 }
299 END_TEST
300
START_TEST(keyboard_time_usec)301 START_TEST(keyboard_time_usec)
302 {
303 struct litest_device *dev = litest_current_device();
304 struct libinput *li = dev->libinput;
305 struct libinput_event_keyboard *kev;
306 struct libinput_event *event;
307 uint64_t time_usec;
308
309 if (!libevdev_has_event_code(dev->evdev, EV_KEY, KEY_A))
310 return;
311
312 litest_drain_events(dev->libinput);
313
314 litest_keyboard_key(dev, KEY_A, true);
315 libinput_dispatch(li);
316
317 event = libinput_get_event(li);
318 kev = litest_is_keyboard_event(event,
319 KEY_A,
320 LIBINPUT_KEY_STATE_PRESSED);
321
322 time_usec = libinput_event_keyboard_get_time_usec(kev);
323 ck_assert_int_eq(libinput_event_keyboard_get_time(kev),
324 (uint32_t) (time_usec / 1000));
325
326 libinput_event_destroy(event);
327 litest_drain_events(dev->libinput);
328 }
329 END_TEST
330
START_TEST(keyboard_no_buttons)331 START_TEST(keyboard_no_buttons)
332 {
333 struct litest_device *dev = litest_current_device();
334 struct libinput *li = dev->libinput;
335 struct libinput_event *event;
336 int code;
337 const char *name;
338
339 litest_drain_events(dev->libinput);
340
341 for (code = 0; code < KEY_MAX; code++) {
342 if (!libevdev_has_event_code(dev->evdev, EV_KEY, code))
343 continue;
344
345 name = libevdev_event_code_get_name(EV_KEY, code);
346 if (!name || !strneq(name, "KEY_", 4))
347 continue;
348
349 litest_keyboard_key(dev, code, true);
350 litest_keyboard_key(dev, code, false);
351 libinput_dispatch(li);
352
353 event = libinput_get_event(li);
354 litest_is_keyboard_event(event,
355 code,
356 LIBINPUT_KEY_STATE_PRESSED);
357 libinput_event_destroy(event);
358 event = libinput_get_event(li);
359 litest_is_keyboard_event(event,
360 code,
361 LIBINPUT_KEY_STATE_RELEASED);
362 libinput_event_destroy(event);
363 }
364 }
365 END_TEST
366
START_TEST(keyboard_frame_order)367 START_TEST(keyboard_frame_order)
368 {
369 struct litest_device *dev = litest_current_device();
370 struct libinput *li = dev->libinput;
371
372 if (!libevdev_has_event_code(dev->evdev, EV_KEY, KEY_A) ||
373 !libevdev_has_event_code(dev->evdev, EV_KEY, KEY_LEFTSHIFT))
374 return;
375
376 litest_drain_events(li);
377
378 litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 1);
379 litest_event(dev, EV_KEY, KEY_A, 1);
380 litest_event(dev, EV_SYN, SYN_REPORT, 0);
381 libinput_dispatch(li);
382
383 litest_assert_key_event(li,
384 KEY_LEFTSHIFT,
385 LIBINPUT_KEY_STATE_PRESSED);
386 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
387
388 litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 0);
389 litest_event(dev, EV_KEY, KEY_A, 0);
390 litest_event(dev, EV_SYN, SYN_REPORT, 0);
391 libinput_dispatch(li);
392
393 litest_assert_key_event(li,
394 KEY_LEFTSHIFT,
395 LIBINPUT_KEY_STATE_RELEASED);
396 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
397
398 litest_event(dev, EV_KEY, KEY_A, 1);
399 litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 1);
400 litest_event(dev, EV_SYN, SYN_REPORT, 0);
401 libinput_dispatch(li);
402
403 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
404 litest_assert_key_event(li,
405 KEY_LEFTSHIFT,
406 LIBINPUT_KEY_STATE_PRESSED);
407
408 litest_event(dev, EV_KEY, KEY_A, 0);
409 litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 0);
410 litest_event(dev, EV_SYN, SYN_REPORT, 0);
411 libinput_dispatch(li);
412
413 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
414 litest_assert_key_event(li,
415 KEY_LEFTSHIFT,
416 LIBINPUT_KEY_STATE_RELEASED);
417
418 libinput_dispatch(li);
419 }
420 END_TEST
421
START_TEST(keyboard_leds)422 START_TEST(keyboard_leds)
423 {
424 struct litest_device *dev = litest_current_device();
425 struct libinput_device *device = dev->libinput_device;
426
427 /* we can't actually test the results here without physically
428 * looking at the LEDs. So all we do is trigger the code for devices
429 * with and without LEDs and check that it doesn't go boom
430 */
431
432 libinput_device_led_update(device,
433 LIBINPUT_LED_NUM_LOCK);
434 libinput_device_led_update(device,
435 LIBINPUT_LED_CAPS_LOCK);
436 libinput_device_led_update(device,
437 LIBINPUT_LED_SCROLL_LOCK);
438
439 libinput_device_led_update(device,
440 LIBINPUT_LED_NUM_LOCK|
441 LIBINPUT_LED_CAPS_LOCK);
442 libinput_device_led_update(device,
443 LIBINPUT_LED_NUM_LOCK|
444 LIBINPUT_LED_CAPS_LOCK |
445 LIBINPUT_LED_SCROLL_LOCK);
446 libinput_device_led_update(device, 0);
447 libinput_device_led_update(device, -1);
448 }
449 END_TEST
450
START_TEST(keyboard_no_scroll)451 START_TEST(keyboard_no_scroll)
452 {
453 struct litest_device *dev = litest_current_device();
454 struct libinput_device *device = dev->libinput_device;
455 enum libinput_config_scroll_method method;
456 enum libinput_config_status status;
457
458 method = libinput_device_config_scroll_get_method(device);
459 ck_assert_int_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
460 method = libinput_device_config_scroll_get_default_method(device);
461 ck_assert_int_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
462
463 status = libinput_device_config_scroll_set_method(device,
464 LIBINPUT_CONFIG_SCROLL_2FG);
465 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
466 status = libinput_device_config_scroll_set_method(device,
467 LIBINPUT_CONFIG_SCROLL_EDGE);
468 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
469 status = libinput_device_config_scroll_set_method(device,
470 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
471 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
472 status = libinput_device_config_scroll_set_method(device,
473 LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
474 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
475 }
476 END_TEST
477
TEST_COLLECTION(keyboard)478 TEST_COLLECTION(keyboard)
479 {
480 litest_add_no_device(keyboard_seat_key_count);
481 litest_add_no_device(keyboard_ignore_no_pressed_release);
482 litest_add_no_device(keyboard_key_auto_release);
483 litest_add(keyboard_has_key, LITEST_KEYS, LITEST_ANY);
484 litest_add(keyboard_keys_bad_device, LITEST_ANY, LITEST_ANY);
485 litest_add(keyboard_time_usec, LITEST_KEYS, LITEST_ANY);
486
487 litest_add(keyboard_no_buttons, LITEST_KEYS, LITEST_ANY);
488 litest_add(keyboard_frame_order, LITEST_KEYS, LITEST_ANY);
489
490 litest_add(keyboard_leds, LITEST_ANY, LITEST_ANY);
491
492 litest_add(keyboard_no_scroll, LITEST_KEYS, LITEST_WHEEL);
493 }
494