• 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 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