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