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 *state;
115 enum libinput_key_state expected_states[] = {
116 LIBINPUT_KEY_STATE_PRESSED,
117 LIBINPUT_KEY_STATE_RELEASED,
118 };
119
120 /* We can't send pressed -> released -> pressed events using uinput
121 * as such non-symmetric events are dropped. Work-around this by first
122 * adding the test device to the tested context after having sent an
123 * initial pressed event. */
124 unused_libinput = litest_create_context();
125 dev = litest_add_device_with_overrides(unused_libinput,
126 LITEST_KEYBOARD,
127 "Generic keyboard",
128 NULL, NULL, events);
129
130 litest_keyboard_key(dev, KEY_A, true);
131 litest_drain_events(unused_libinput);
132
133 libinput = litest_create_context();
134 libinput_path_add_device(libinput,
135 libevdev_uinput_get_devnode(dev->uinput));
136 litest_drain_events(libinput);
137
138 litest_keyboard_key(dev, KEY_A, false);
139 litest_keyboard_key(dev, KEY_A, true);
140 litest_keyboard_key(dev, KEY_A, false);
141
142 libinput_dispatch(libinput);
143
144 ARRAY_FOR_EACH(expected_states, state) {
145 event = libinput_get_event(libinput);
146 ck_assert_notnull(event);
147 ck_assert_int_eq(libinput_event_get_type(event),
148 LIBINPUT_EVENT_KEYBOARD_KEY);
149 kevent = libinput_event_get_keyboard_event(event);
150 ck_assert_int_eq(libinput_event_keyboard_get_key(kevent),
151 KEY_A);
152 ck_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
153 *state);
154 libinput_event_destroy(event);
155 libinput_dispatch(libinput);
156 }
157
158 litest_assert_empty_queue(libinput);
159 litest_delete_device(dev);
160 litest_destroy_context(libinput);
161 litest_destroy_context(unused_libinput);
162 }
163 END_TEST
164
START_TEST(keyboard_key_auto_release)165 START_TEST(keyboard_key_auto_release)
166 {
167 struct libinput *libinput;
168 struct litest_device *dev;
169 struct libinput_event *event;
170 enum libinput_event_type type;
171 struct libinput_event_keyboard *kevent;
172 struct {
173 int code;
174 int released;
175 } keys[] = {
176 { .code = KEY_A, },
177 { .code = KEY_S, },
178 { .code = KEY_D, },
179 { .code = KEY_G, },
180 { .code = KEY_Z, },
181 { .code = KEY_DELETE, },
182 { .code = KEY_F24, },
183 };
184 int events[2 * (ARRAY_LENGTH(keys) + 1)];
185 unsigned i;
186 int key;
187 int valid_code;
188
189 /* Enable all tested keys on the device */
190 i = 0;
191 while (i < 2 * ARRAY_LENGTH(keys)) {
192 key = keys[i / 2].code;
193 events[i++] = EV_KEY;
194 events[i++] = key;
195 }
196 events[i++] = -1;
197 events[i++] = -1;
198
199 libinput = litest_create_context();
200 dev = litest_add_device_with_overrides(libinput,
201 LITEST_KEYBOARD,
202 "Generic keyboard",
203 NULL, NULL, events);
204
205 litest_drain_events(libinput);
206
207 /* Send pressed events, without releasing */
208 for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
209 key = keys[i].code;
210 litest_event(dev, EV_KEY, key, 1);
211 litest_event(dev, EV_SYN, SYN_REPORT, 0);
212
213 libinput_dispatch(libinput);
214
215 event = libinput_get_event(libinput);
216 litest_is_keyboard_event(event,
217 key,
218 LIBINPUT_KEY_STATE_PRESSED);
219 libinput_event_destroy(event);
220 }
221
222 litest_drain_events(libinput);
223
224 /* "Disconnect" device */
225 litest_delete_device(dev);
226
227 /* Mark all released keys until device is removed */
228 while (1) {
229 event = libinput_get_event(libinput);
230 ck_assert_notnull(event);
231 type = libinput_event_get_type(event);
232
233 if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
234 libinput_event_destroy(event);
235 break;
236 }
237
238 ck_assert_int_eq(type, LIBINPUT_EVENT_KEYBOARD_KEY);
239 kevent = libinput_event_get_keyboard_event(event);
240 ck_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
241 LIBINPUT_KEY_STATE_RELEASED);
242 key = libinput_event_keyboard_get_key(kevent);
243
244 valid_code = 0;
245 for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
246 if (keys[i].code == key) {
247 ck_assert_int_eq(keys[i].released, 0);
248 keys[i].released = 1;
249 valid_code = 1;
250 }
251 }
252 ck_assert_int_eq(valid_code, 1);
253 libinput_event_destroy(event);
254 }
255
256 /* Check that all pressed keys has been released. */
257 for (i = 0; i < ARRAY_LENGTH(keys); ++i) {
258 ck_assert_int_eq(keys[i].released, 1);
259 }
260
261 litest_destroy_context(libinput);
262 }
263 END_TEST
264
START_TEST(keyboard_has_key)265 START_TEST(keyboard_has_key)
266 {
267 struct litest_device *dev = litest_current_device();
268 struct libinput_device *device = dev->libinput_device;
269 unsigned int code;
270 int evdev_has, libinput_has;
271
272 ck_assert(libinput_device_has_capability(
273 device,
274 LIBINPUT_DEVICE_CAP_KEYBOARD));
275
276 for (code = 0; code < KEY_CNT; code++) {
277 evdev_has = libevdev_has_event_code(dev->evdev, EV_KEY, code);
278 libinput_has = libinput_device_keyboard_has_key(device, code);
279 ck_assert_int_eq(evdev_has, libinput_has);
280 }
281 }
282 END_TEST
283
START_TEST(keyboard_keys_bad_device)284 START_TEST(keyboard_keys_bad_device)
285 {
286 struct litest_device *dev = litest_current_device();
287 struct libinput_device *device = dev->libinput_device;
288 unsigned int code;
289 int has_key;
290
291 if (libinput_device_has_capability(device,
292 LIBINPUT_DEVICE_CAP_KEYBOARD))
293 return;
294
295 for (code = 0; code < KEY_CNT; code++) {
296 has_key = libinput_device_keyboard_has_key(device, code);
297 ck_assert_int_eq(has_key, -1);
298 }
299 }
300 END_TEST
301
START_TEST(keyboard_time_usec)302 START_TEST(keyboard_time_usec)
303 {
304 struct litest_device *dev = litest_current_device();
305 struct libinput *li = dev->libinput;
306 struct libinput_event_keyboard *kev;
307 struct libinput_event *event;
308 uint64_t time_usec;
309
310 if (!libevdev_has_event_code(dev->evdev, EV_KEY, KEY_A))
311 return;
312
313 litest_drain_events(dev->libinput);
314
315 litest_keyboard_key(dev, KEY_A, true);
316 libinput_dispatch(li);
317
318 event = libinput_get_event(li);
319 kev = litest_is_keyboard_event(event,
320 KEY_A,
321 LIBINPUT_KEY_STATE_PRESSED);
322
323 time_usec = libinput_event_keyboard_get_time_usec(kev);
324 ck_assert_int_eq(libinput_event_keyboard_get_time(kev),
325 (uint32_t) (time_usec / 1000));
326
327 libinput_event_destroy(event);
328 litest_drain_events(dev->libinput);
329 }
330 END_TEST
331
START_TEST(keyboard_no_buttons)332 START_TEST(keyboard_no_buttons)
333 {
334 struct litest_device *dev = litest_current_device();
335 struct libinput *li = dev->libinput;
336 struct libinput_event *event;
337 int code;
338 const char *name;
339
340 litest_drain_events(dev->libinput);
341
342 for (code = 0; code < KEY_MAX; code++) {
343 if (!libevdev_has_event_code(dev->evdev, EV_KEY, code))
344 continue;
345
346 name = libevdev_event_code_get_name(EV_KEY, code);
347 if (!name || !strneq(name, "KEY_", 4))
348 continue;
349
350 litest_keyboard_key(dev, code, true);
351 litest_keyboard_key(dev, code, false);
352 libinput_dispatch(li);
353
354 event = libinput_get_event(li);
355 litest_is_keyboard_event(event,
356 code,
357 LIBINPUT_KEY_STATE_PRESSED);
358 libinput_event_destroy(event);
359 event = libinput_get_event(li);
360 litest_is_keyboard_event(event,
361 code,
362 LIBINPUT_KEY_STATE_RELEASED);
363 libinput_event_destroy(event);
364 }
365 }
366 END_TEST
367
START_TEST(keyboard_frame_order)368 START_TEST(keyboard_frame_order)
369 {
370 struct litest_device *dev = litest_current_device();
371 struct libinput *li = dev->libinput;
372
373 if (!libevdev_has_event_code(dev->evdev, EV_KEY, KEY_A) ||
374 !libevdev_has_event_code(dev->evdev, EV_KEY, KEY_LEFTSHIFT))
375 return;
376
377 litest_drain_events(li);
378
379 litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 1);
380 litest_event(dev, EV_KEY, KEY_A, 1);
381 litest_event(dev, EV_SYN, SYN_REPORT, 0);
382 libinput_dispatch(li);
383
384 litest_assert_key_event(li,
385 KEY_LEFTSHIFT,
386 LIBINPUT_KEY_STATE_PRESSED);
387 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
388
389 litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 0);
390 litest_event(dev, EV_KEY, KEY_A, 0);
391 litest_event(dev, EV_SYN, SYN_REPORT, 0);
392 libinput_dispatch(li);
393
394 litest_assert_key_event(li,
395 KEY_LEFTSHIFT,
396 LIBINPUT_KEY_STATE_RELEASED);
397 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
398
399 litest_event(dev, EV_KEY, KEY_A, 1);
400 litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 1);
401 litest_event(dev, EV_SYN, SYN_REPORT, 0);
402 libinput_dispatch(li);
403
404 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
405 litest_assert_key_event(li,
406 KEY_LEFTSHIFT,
407 LIBINPUT_KEY_STATE_PRESSED);
408
409 litest_event(dev, EV_KEY, KEY_A, 0);
410 litest_event(dev, EV_KEY, KEY_LEFTSHIFT, 0);
411 litest_event(dev, EV_SYN, SYN_REPORT, 0);
412 libinput_dispatch(li);
413
414 litest_assert_key_event(li, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
415 litest_assert_key_event(li,
416 KEY_LEFTSHIFT,
417 LIBINPUT_KEY_STATE_RELEASED);
418
419 libinput_dispatch(li);
420 }
421 END_TEST
422
START_TEST(keyboard_leds)423 START_TEST(keyboard_leds)
424 {
425 struct litest_device *dev = litest_current_device();
426 struct libinput_device *device = dev->libinput_device;
427
428 /* we can't actually test the results here without physically
429 * looking at the LEDs. So all we do is trigger the code for devices
430 * with and without LEDs and check that it doesn't go boom
431 */
432
433 libinput_device_led_update(device,
434 LIBINPUT_LED_NUM_LOCK);
435 libinput_device_led_update(device,
436 LIBINPUT_LED_CAPS_LOCK);
437 libinput_device_led_update(device,
438 LIBINPUT_LED_SCROLL_LOCK);
439
440 libinput_device_led_update(device,
441 LIBINPUT_LED_NUM_LOCK|
442 LIBINPUT_LED_CAPS_LOCK);
443 libinput_device_led_update(device,
444 LIBINPUT_LED_NUM_LOCK|
445 LIBINPUT_LED_CAPS_LOCK |
446 LIBINPUT_LED_SCROLL_LOCK);
447 libinput_device_led_update(device, 0);
448 libinput_device_led_update(device, -1);
449 }
450 END_TEST
451
START_TEST(keyboard_no_scroll)452 START_TEST(keyboard_no_scroll)
453 {
454 struct litest_device *dev = litest_current_device();
455 struct libinput_device *device = dev->libinput_device;
456 enum libinput_config_scroll_method method;
457 enum libinput_config_status status;
458
459 method = libinput_device_config_scroll_get_method(device);
460 ck_assert_int_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
461 method = libinput_device_config_scroll_get_default_method(device);
462 ck_assert_int_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
463
464 status = libinput_device_config_scroll_set_method(device,
465 LIBINPUT_CONFIG_SCROLL_2FG);
466 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
467 status = libinput_device_config_scroll_set_method(device,
468 LIBINPUT_CONFIG_SCROLL_EDGE);
469 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
470 status = libinput_device_config_scroll_set_method(device,
471 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
472 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
473 status = libinput_device_config_scroll_set_method(device,
474 LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
475 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
476 }
477 END_TEST
478
TEST_COLLECTION(keyboard)479 TEST_COLLECTION(keyboard)
480 {
481 litest_add_no_device(keyboard_seat_key_count);
482 litest_add_no_device(keyboard_ignore_no_pressed_release);
483 litest_add_no_device(keyboard_key_auto_release);
484 litest_add(keyboard_has_key, LITEST_KEYS, LITEST_ANY);
485 litest_add(keyboard_keys_bad_device, LITEST_ANY, LITEST_ANY);
486 litest_add(keyboard_time_usec, LITEST_KEYS, LITEST_ANY);
487
488 litest_add(keyboard_no_buttons, LITEST_KEYS, LITEST_ANY);
489 litest_add(keyboard_frame_order, LITEST_KEYS, LITEST_ANY);
490
491 litest_add(keyboard_leds, LITEST_ANY, LITEST_ANY);
492
493 litest_add(keyboard_no_scroll, LITEST_KEYS, LITEST_WHEEL);
494 }
495