• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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