• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2017 James Ye <jye836@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 <fcntl.h>
28 #include <libinput.h>
29 
30 #include "libinput-util.h"
31 #include "litest.h"
32 
33 static inline bool
switch_has_lid(struct litest_device * dev)34 switch_has_lid(struct litest_device *dev)
35 {
36 	return libinput_device_switch_has_switch(dev->libinput_device,
37 						 LIBINPUT_SWITCH_LID) > 0;
38 }
39 
40 static inline bool
switch_has_tablet_mode(struct litest_device * dev)41 switch_has_tablet_mode(struct litest_device *dev)
42 {
43 	return libinput_device_switch_has_switch(dev->libinput_device,
44 						 LIBINPUT_SWITCH_TABLET_MODE) > 0;
45 }
46 
START_TEST(switch_has_cap)47 START_TEST(switch_has_cap)
48 {
49 	struct litest_device *dev = litest_current_device();
50 
51 	/* Need to check for this specific device here because the
52 	 * unreliable tablet mode switch removes the capability too */
53 	if (dev->which == LITEST_TABLET_MODE_UNRELIABLE) {
54 		ck_assert(!libinput_device_has_capability(dev->libinput_device,
55 							  LIBINPUT_DEVICE_CAP_SWITCH));
56 		return;
57 	}
58 
59 	ck_assert(libinput_device_has_capability(dev->libinput_device,
60 						 LIBINPUT_DEVICE_CAP_SWITCH));
61 
62 }
63 END_TEST
64 
START_TEST(switch_has_lid_switch)65 START_TEST(switch_has_lid_switch)
66 {
67 	struct litest_device *dev = litest_current_device();
68 
69 	if (!libevdev_has_event_code(dev->evdev, EV_SW, SW_LID))
70 		return;
71 
72 	ck_assert_int_eq(libinput_device_switch_has_switch(dev->libinput_device,
73 							   LIBINPUT_SWITCH_LID),
74 			 1);
75 }
76 END_TEST
77 
78 static bool
tablet_mode_switch_is_reliable(struct litest_device * dev)79 tablet_mode_switch_is_reliable(struct litest_device *dev)
80 {
81 	bool is_unreliable = false;
82 
83        quirks_get_bool(dev->quirks,
84 		QUIRK_MODEL_TABLET_MODE_SWITCH_UNRELIABLE,
85 		&is_unreliable);
86 
87 	return !is_unreliable;
88 }
89 
START_TEST(switch_has_tablet_mode_switch)90 START_TEST(switch_has_tablet_mode_switch)
91 {
92 	struct litest_device *dev = litest_current_device();
93 	int has_switch;
94 
95 	if (!libevdev_has_event_code(dev->evdev, EV_SW, SW_TABLET_MODE))
96 		return;
97 
98 	has_switch = libinput_device_switch_has_switch(dev->libinput_device,
99 						       LIBINPUT_SWITCH_TABLET_MODE);
100 
101 	if (!tablet_mode_switch_is_reliable(dev))
102 		ck_assert_int_ne(has_switch, 1);
103 	else
104 		ck_assert_int_eq(has_switch, 1);
105 }
106 END_TEST
107 
START_TEST(switch_toggle)108 START_TEST(switch_toggle)
109 {
110 	struct litest_device *dev = litest_current_device();
111 	struct libinput *li = dev->libinput;
112 	struct libinput_event *event;
113 	enum libinput_switch sw = _i; /* ranged test */
114 
115 	litest_drain_events(li);
116 
117 	litest_grab_device(dev);
118 	litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON);
119 	libinput_dispatch(li);
120 
121 	if (libinput_device_switch_has_switch(dev->libinput_device, sw) > 0) {
122 		event = libinput_get_event(li);
123 		litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_ON);
124 		libinput_event_destroy(event);
125 	} else {
126 		litest_assert_empty_queue(li);
127 	}
128 
129 	litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_OFF);
130 	libinput_dispatch(li);
131 
132 	if (libinput_device_switch_has_switch(dev->libinput_device, sw) > 0) {
133 		event = libinput_get_event(li);
134 		litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_OFF);
135 		libinput_event_destroy(event);
136 	}
137 
138 	litest_assert_empty_queue(li);
139 	litest_ungrab_device(dev);
140 }
141 END_TEST
142 
START_TEST(switch_toggle_double)143 START_TEST(switch_toggle_double)
144 {
145 	struct litest_device *dev = litest_current_device();
146 	struct libinput *li = dev->libinput;
147 	struct libinput_event *event;
148 	enum libinput_switch sw = _i; /* ranged test */
149 
150 	if (libinput_device_switch_has_switch(dev->libinput_device, sw) <= 0)
151 		return;
152 
153 	litest_drain_events(li);
154 
155 	litest_grab_device(dev);
156 	litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON);
157 	libinput_dispatch(li);
158 
159 	event = libinput_get_event(li);
160 	litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_ON);
161 	libinput_event_destroy(event);
162 
163 	/* This will be filtered by the kernel, so this test is a bit
164 	 * useless */
165 	litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON);
166 	libinput_dispatch(li);
167 
168 	litest_assert_empty_queue(li);
169 	litest_ungrab_device(dev);
170 }
171 END_TEST
172 
173 static bool
lid_switch_is_reliable(struct litest_device * dev)174 lid_switch_is_reliable(struct litest_device *dev)
175 {
176 	char *prop;
177 	bool is_reliable = false;
178 
179 	if (quirks_get_string(dev->quirks,
180 			      QUIRK_ATTR_LID_SWITCH_RELIABILITY,
181 			      &prop)) {
182 		is_reliable = streq(prop, "reliable");
183 	}
184 
185 
186 	return is_reliable;
187 }
188 
START_TEST(switch_down_on_init)189 START_TEST(switch_down_on_init)
190 {
191 	struct litest_device *dev = litest_current_device();
192 	struct libinput *li;
193 	struct libinput_event *event;
194 	enum libinput_switch sw = _i; /* ranged test */
195 
196 	if (libinput_device_switch_has_switch(dev->libinput_device, sw) <= 0)
197 		return;
198 
199 	if (sw == LIBINPUT_SWITCH_LID && !lid_switch_is_reliable(dev))
200 		return;
201 
202 	litest_grab_device(dev);
203 	litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON);
204 	litest_ungrab_device(dev);
205 
206 	/* need separate context to test */
207 	li = litest_create_context();
208 	libinput_path_add_device(li,
209 				 libevdev_uinput_get_devnode(dev->uinput));
210 	libinput_dispatch(li);
211 
212 	litest_wait_for_event_of_type(li, LIBINPUT_EVENT_SWITCH_TOGGLE, -1);
213 	event = libinput_get_event(li);
214 	litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_ON);
215 	libinput_event_destroy(event);
216 
217 	while ((event = libinput_get_event(li))) {
218 		ck_assert_int_ne(libinput_event_get_type(event),
219 				 LIBINPUT_EVENT_SWITCH_TOGGLE);
220 		libinput_event_destroy(event);
221 	}
222 
223 	litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_OFF);
224 	libinput_dispatch(li);
225 	event = libinput_get_event(li);
226 	litest_is_switch_event(event, sw, LIBINPUT_SWITCH_STATE_OFF);
227 	libinput_event_destroy(event);
228 	litest_assert_empty_queue(li);
229 
230 	litest_destroy_context(li);
231 }
232 END_TEST
233 
START_TEST(switch_not_down_on_init)234 START_TEST(switch_not_down_on_init)
235 {
236 	struct litest_device *dev = litest_current_device();
237 	struct libinput *li;
238 	struct libinput_event *event;
239 	enum libinput_switch sw = LIBINPUT_SWITCH_LID;
240 
241 	if (libinput_device_switch_has_switch(dev->libinput_device, sw) <= 0)
242 		return;
243 
244 	if (sw == LIBINPUT_SWITCH_LID && lid_switch_is_reliable(dev))
245 		return;
246 
247 	litest_grab_device(dev);
248 	litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_ON);
249 	litest_ungrab_device(dev);
250 
251 	/* need separate context to test */
252 	li = litest_create_context();
253 	libinput_path_add_device(li,
254 				 libevdev_uinput_get_devnode(dev->uinput));
255 	libinput_dispatch(li);
256 
257 	while ((event = libinput_get_event(li)) != NULL) {
258 		ck_assert_int_ne(libinput_event_get_type(event),
259 				 LIBINPUT_EVENT_SWITCH_TOGGLE);
260 		libinput_event_destroy(event);
261 	}
262 
263 	litest_switch_action(dev, sw, LIBINPUT_SWITCH_STATE_OFF);
264 	litest_assert_empty_queue(li);
265 	litest_destroy_context(li);
266 }
267 END_TEST
268 
269 static inline struct litest_device *
switch_init_paired_touchpad(struct libinput * li)270 switch_init_paired_touchpad(struct libinput *li)
271 {
272 	enum litest_device_type which = LITEST_SYNAPTICS_I2C;
273 
274 	return litest_add_device(li, which);
275 }
276 
START_TEST(switch_disable_touchpad)277 START_TEST(switch_disable_touchpad)
278 {
279 	struct litest_device *sw = litest_current_device();
280 	struct litest_device *touchpad;
281 	struct libinput *li = sw->libinput;
282 	enum libinput_switch which = _i; /* ranged test */
283 
284 	if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
285 		return;
286 
287 	touchpad = switch_init_paired_touchpad(li);
288 	litest_disable_tap(touchpad->libinput_device);
289 	litest_disable_hold_gestures(touchpad->libinput_device);
290 	litest_drain_events(li);
291 
292 	litest_grab_device(sw);
293 
294 	/* switch is on - no events */
295 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
296 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
297 
298 	litest_touch_down(touchpad, 0, 50, 50);
299 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
300 	litest_touch_up(touchpad, 0);
301 	litest_assert_empty_queue(li);
302 
303 	/* switch is off - motion events */
304 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
305 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
306 
307 	litest_touch_down(touchpad, 0, 50, 50);
308 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
309 	litest_touch_up(touchpad, 0);
310 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
311 
312 	litest_delete_device(touchpad);
313 	litest_ungrab_device(sw);
314 }
315 END_TEST
316 
START_TEST(switch_disable_touchpad_during_touch)317 START_TEST(switch_disable_touchpad_during_touch)
318 {
319 	struct litest_device *sw = litest_current_device();
320 	struct litest_device *touchpad;
321 	struct libinput *li = sw->libinput;
322 	enum libinput_switch which = _i; /* ranged test */
323 
324 	if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
325 		return;
326 
327 	touchpad = switch_init_paired_touchpad(li);
328 	litest_disable_tap(touchpad->libinput_device);
329 	litest_disable_hold_gestures(touchpad->libinput_device);
330 	litest_drain_events(li);
331 
332 	litest_touch_down(touchpad, 0, 50, 50);
333 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5);
334 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
335 
336 	litest_grab_device(sw);
337 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
338 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
339 	litest_ungrab_device(sw);
340 
341 	litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 5);
342 	litest_touch_up(touchpad, 0);
343 	litest_assert_empty_queue(li);
344 
345 	litest_delete_device(touchpad);
346 }
347 END_TEST
348 
START_TEST(switch_disable_touchpad_edge_scroll)349 START_TEST(switch_disable_touchpad_edge_scroll)
350 {
351 	struct litest_device *sw = litest_current_device();
352 	struct litest_device *touchpad;
353 	struct libinput *li = sw->libinput;
354 	enum libinput_switch which = _i; /* ranged test */
355 
356 	if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
357 		return;
358 
359 	touchpad = switch_init_paired_touchpad(li);
360 	litest_enable_edge_scroll(touchpad);
361 
362 	litest_drain_events(li);
363 
364 	litest_grab_device(sw);
365 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
366 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
367 	litest_ungrab_device(sw);
368 
369 	litest_touch_down(touchpad, 0, 99, 20);
370 	libinput_dispatch(li);
371 	litest_timeout_edgescroll();
372 	libinput_dispatch(li);
373 	litest_assert_empty_queue(li);
374 
375 	litest_touch_move_to(touchpad, 0, 99, 20, 99, 80, 60);
376 	libinput_dispatch(li);
377 	litest_assert_empty_queue(li);
378 
379 	litest_touch_move_to(touchpad, 0, 99, 80, 99, 20, 60);
380 	litest_touch_up(touchpad, 0);
381 	libinput_dispatch(li);
382 	litest_assert_empty_queue(li);
383 
384 	litest_delete_device(touchpad);
385 }
386 END_TEST
387 
START_TEST(switch_disable_touchpad_edge_scroll_interrupt)388 START_TEST(switch_disable_touchpad_edge_scroll_interrupt)
389 {
390 	struct litest_device *sw = litest_current_device();
391 	struct litest_device *touchpad;
392 	struct libinput *li = sw->libinput;
393 	struct libinput_event *event;
394 	enum libinput_switch which = _i; /* ranged test */
395 
396 	if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
397 		return;
398 
399 	touchpad = switch_init_paired_touchpad(li);
400 	litest_enable_edge_scroll(touchpad);
401 
402 	litest_drain_events(li);
403 
404 	litest_touch_down(touchpad, 0, 99, 20);
405 	libinput_dispatch(li);
406 	litest_timeout_edgescroll();
407 	litest_touch_move_to(touchpad, 0, 99, 20, 99, 30, 10);
408 	libinput_dispatch(li);
409 	litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
410 
411 	litest_grab_device(sw);
412 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
413 	litest_ungrab_device(sw);
414 	libinput_dispatch(li);
415 
416 	litest_assert_axis_end_sequence(li,
417 					LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
418 					LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
419 					LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
420 
421 	event = libinput_get_event(li);
422 	litest_is_switch_event(event, which, LIBINPUT_SWITCH_STATE_ON);
423 	libinput_event_destroy(event);
424 
425 	litest_delete_device(touchpad);
426 }
427 END_TEST
428 
START_TEST(switch_disable_touchpad_already_open)429 START_TEST(switch_disable_touchpad_already_open)
430 {
431 	struct litest_device *sw = litest_current_device();
432 	struct litest_device *touchpad;
433 	struct libinput *li = sw->libinput;
434 	enum libinput_switch which = _i; /* ranged test */
435 
436 	if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
437 		return;
438 
439 	touchpad = switch_init_paired_touchpad(li);
440 
441 	litest_disable_tap(touchpad->libinput_device);
442 	litest_disable_hold_gestures(touchpad->libinput_device);
443 	litest_drain_events(li);
444 
445 	/* default: switch is off - motion events */
446 	litest_touch_down(touchpad, 0, 50, 50);
447 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
448 	litest_touch_up(touchpad, 0);
449 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
450 
451 	/* disable switch - motion events */
452 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
453 	litest_assert_empty_queue(li);
454 
455 	litest_touch_down(touchpad, 0, 50, 50);
456 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
457 	litest_touch_up(touchpad, 0);
458 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
459 
460 	litest_delete_device(touchpad);
461 }
462 END_TEST
463 
START_TEST(switch_dont_resume_disabled_touchpad)464 START_TEST(switch_dont_resume_disabled_touchpad)
465 {
466 	struct litest_device *sw = litest_current_device();
467 	struct litest_device *touchpad;
468 	struct libinput *li = sw->libinput;
469 	enum libinput_switch which = _i; /* ranged test */
470 
471 	if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
472 		return;
473 
474 	touchpad = switch_init_paired_touchpad(li);
475 	litest_disable_tap(touchpad->libinput_device);
476 	litest_disable_hold_gestures(touchpad->libinput_device);
477 	libinput_device_config_send_events_set_mode(touchpad->libinput_device,
478 						    LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
479 	litest_drain_events(li);
480 
481 	/* switch is on - no events */
482 	litest_grab_device(sw);
483 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
484 	litest_ungrab_device(sw);
485 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
486 
487 	litest_touch_down(touchpad, 0, 50, 50);
488 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
489 	litest_touch_up(touchpad, 0);
490 	litest_assert_empty_queue(li);
491 
492 	/* switch is off but but tp is still disabled */
493 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
494 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
495 
496 	litest_touch_down(touchpad, 0, 50, 50);
497 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
498 	litest_touch_up(touchpad, 0);
499 	litest_assert_empty_queue(li);
500 
501 	litest_delete_device(touchpad);
502 }
503 END_TEST
504 
START_TEST(switch_dont_resume_disabled_touchpad_external_mouse)505 START_TEST(switch_dont_resume_disabled_touchpad_external_mouse)
506 {
507 	struct litest_device *sw = litest_current_device();
508 	struct litest_device *touchpad, *mouse;
509 	struct libinput *li = sw->libinput;
510 	enum libinput_switch which = _i; /* ranged test */
511 
512 	if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
513 		return;
514 
515 	touchpad = switch_init_paired_touchpad(li);
516 	mouse = litest_add_device(li, LITEST_MOUSE);
517 	litest_disable_tap(touchpad->libinput_device);
518 	litest_disable_hold_gestures(touchpad->libinput_device);
519 	libinput_device_config_send_events_set_mode(touchpad->libinput_device,
520 						    LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE);
521 	litest_drain_events(li);
522 
523 	litest_touch_down(touchpad, 0, 50, 50);
524 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
525 	litest_touch_up(touchpad, 0);
526 	litest_assert_empty_queue(li);
527 
528 	/* switch is on - no events */
529 	litest_grab_device(sw);
530 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
531 	litest_ungrab_device(sw);
532 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
533 
534 	litest_touch_down(touchpad, 0, 50, 50);
535 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
536 	litest_touch_up(touchpad, 0);
537 	litest_assert_empty_queue(li);
538 
539 	/* switch is off but but tp is still disabled */
540 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
541 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
542 
543 	litest_touch_down(touchpad, 0, 50, 50);
544 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
545 	litest_touch_up(touchpad, 0);
546 	litest_assert_empty_queue(li);
547 
548 	litest_delete_device(touchpad);
549 	litest_delete_device(mouse);
550 }
551 END_TEST
552 
START_TEST(lid_open_on_key)553 START_TEST(lid_open_on_key)
554 {
555 	struct litest_device *sw = litest_current_device();
556 	struct litest_device *keyboard;
557 	struct libinput *li = sw->libinput;
558 	struct libinput_event *event;
559 
560 	if (!switch_has_lid(sw))
561 		return;
562 
563 	keyboard = litest_add_device(li, LITEST_KEYBOARD);
564 
565 	litest_grab_device(sw);
566 	for (int i = 0; i < 3; i++) {
567 		litest_switch_action(sw,
568 				     LIBINPUT_SWITCH_LID,
569 				     LIBINPUT_SWITCH_STATE_ON);
570 		litest_drain_events(li);
571 
572 		litest_event(keyboard, EV_KEY, KEY_A, 1);
573 		litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
574 		litest_event(keyboard, EV_KEY, KEY_A, 0);
575 		litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
576 		libinput_dispatch(li);
577 
578 		event = libinput_get_event(li);
579 		litest_is_switch_event(event,
580 				       LIBINPUT_SWITCH_LID,
581 				       LIBINPUT_SWITCH_STATE_OFF);
582 		libinput_event_destroy(event);
583 
584 		litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
585 
586 		litest_switch_action(sw,
587 				     LIBINPUT_SWITCH_LID,
588 				     LIBINPUT_SWITCH_STATE_OFF);
589 		litest_assert_empty_queue(li);
590 	}
591 	litest_ungrab_device(sw);
592 
593 	litest_delete_device(keyboard);
594 }
595 END_TEST
596 
START_TEST(lid_open_on_key_touchpad_enabled)597 START_TEST(lid_open_on_key_touchpad_enabled)
598 {
599 	struct litest_device *sw = litest_current_device();
600 	struct litest_device *keyboard, *touchpad;
601 	struct libinput *li = sw->libinput;
602 
603 	if (!switch_has_lid(sw))
604 		return;
605 
606 	keyboard = litest_add_device(li, LITEST_KEYBOARD);
607 	touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
608 
609 	litest_disable_hold_gestures(touchpad->libinput_device);
610 
611 	litest_grab_device(sw);
612 	litest_switch_action(sw,
613 			     LIBINPUT_SWITCH_LID,
614 			     LIBINPUT_SWITCH_STATE_ON);
615 	litest_ungrab_device(sw);
616 	litest_drain_events(li);
617 
618 	litest_event(keyboard, EV_KEY, KEY_A, 1);
619 	litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
620 	litest_event(keyboard, EV_KEY, KEY_A, 0);
621 	litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
622 	litest_drain_events(li);
623 	litest_timeout_dwt_long();
624 
625 	litest_touch_down(touchpad, 0, 50, 50);
626 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 70, 10);
627 	litest_touch_up(touchpad, 0);
628 	libinput_dispatch(li);
629 
630 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
631 
632 	litest_delete_device(keyboard);
633 	litest_delete_device(touchpad);
634 }
635 END_TEST
636 
START_TEST(switch_suspend_with_keyboard)637 START_TEST(switch_suspend_with_keyboard)
638 {
639 	struct libinput *li;
640 	struct litest_device *keyboard;
641 	struct litest_device *sw;
642 	enum libinput_switch which = _i; /* ranged test */
643 
644 	li = litest_create_context();
645 
646 	switch(which) {
647 	case LIBINPUT_SWITCH_LID:
648 		sw = litest_add_device(li, LITEST_LID_SWITCH);
649 		break;
650 	case LIBINPUT_SWITCH_TABLET_MODE:
651 		sw = litest_add_device(li, LITEST_THINKPAD_EXTRABUTTONS);
652 		break;
653 	default:
654 		abort();
655 	}
656 
657 	libinput_dispatch(li);
658 
659 	keyboard = litest_add_device(li, LITEST_KEYBOARD);
660 	libinput_dispatch(li);
661 
662 	litest_grab_device(sw);
663 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
664 	litest_drain_events(li);
665 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
666 	litest_drain_events(li);
667 	litest_ungrab_device(sw);
668 
669 	litest_delete_device(keyboard);
670 	litest_drain_events(li);
671 
672 	litest_delete_device(sw);
673 	libinput_dispatch(li);
674 
675 	litest_destroy_context(li);
676 }
677 END_TEST
678 
START_TEST(switch_suspend_with_touchpad)679 START_TEST(switch_suspend_with_touchpad)
680 {
681 	struct libinput *li;
682 	struct litest_device *touchpad, *sw;
683 	enum libinput_switch which = _i; /* ranged test */
684 
685 	li = litest_create_context();
686 
687 	switch(which) {
688 	case LIBINPUT_SWITCH_LID:
689 		sw = litest_add_device(li, LITEST_LID_SWITCH);
690 		break;
691 	case LIBINPUT_SWITCH_TABLET_MODE:
692 		sw = litest_add_device(li, LITEST_THINKPAD_EXTRABUTTONS);
693 		break;
694 	default:
695 		abort();
696 	}
697 
698 	litest_drain_events(li);
699 
700 	touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
701 	litest_drain_events(li);
702 
703 	litest_grab_device(sw);
704 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
705 	litest_drain_events(li);
706 	litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
707 	litest_drain_events(li);
708 	litest_ungrab_device(sw);
709 
710 	litest_delete_device(sw);
711 	litest_drain_events(li);
712 	litest_delete_device(touchpad);
713 	litest_drain_events(li);
714 
715 	litest_destroy_context(li);
716 }
717 END_TEST
718 
START_TEST(lid_update_hw_on_key)719 START_TEST(lid_update_hw_on_key)
720 {
721 	struct litest_device *sw = litest_current_device();
722 	struct libinput *li = sw->libinput;
723 	struct litest_device *keyboard;
724 	struct libevdev *evdev;
725 	struct input_event event;
726 	int fd;
727 	int rc;
728 
729 	if (!switch_has_lid(sw))
730 		return;
731 
732 	keyboard = litest_add_device(li, LITEST_KEYBOARD);
733 
734 	litest_grab_device(sw);
735 	litest_switch_action(sw,
736 			     LIBINPUT_SWITCH_LID,
737 			     LIBINPUT_SWITCH_STATE_ON);
738 	litest_drain_events(li);
739 	litest_ungrab_device(sw);
740 
741 	/* Separate direct libevdev context to check if the HW event goes
742 	 * through */
743 	fd = open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY|O_NONBLOCK);
744 	ck_assert_int_ge(fd, 0);
745 	ck_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0);
746 	ck_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1);
747 
748 	/* Typing on the keyboard should trigger a lid open event */
749 	litest_event(keyboard, EV_KEY, KEY_A, 1);
750 	litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
751 	litest_event(keyboard, EV_KEY, KEY_A, 0);
752 	litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
753 	litest_drain_events(li);
754 
755 	rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
756 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
757 	ck_assert_int_eq(event.type, EV_SW);
758 	ck_assert_int_eq(event.code, SW_LID);
759 	ck_assert_int_eq(event.value, 0);
760 	rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
761 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
762 	ck_assert_int_eq(event.type, EV_SYN);
763 	ck_assert_int_eq(event.code, SYN_REPORT);
764 	ck_assert_int_eq(event.value, 0);
765 	rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
766 	ck_assert_int_eq(rc, -EAGAIN);
767 
768 	litest_delete_device(keyboard);
769 	close(fd);
770 	libevdev_free(evdev);
771 }
772 END_TEST
773 
START_TEST(lid_update_hw_on_key_closed_on_init)774 START_TEST(lid_update_hw_on_key_closed_on_init)
775 {
776 	struct litest_device *sw = litest_current_device();
777 	struct libinput *li;
778 	struct litest_device *keyboard;
779 	struct libevdev *evdev = sw->evdev;
780 	struct input_event event;
781 	int fd;
782 	int rc;
783 
784 	litest_grab_device(sw);
785 	litest_switch_action(sw,
786 			     LIBINPUT_SWITCH_LID,
787 			     LIBINPUT_SWITCH_STATE_ON);
788 	litest_ungrab_device(sw);
789 
790 	/* Separate direct libevdev context to check if the HW event goes
791 	 * through */
792 	fd = open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY|O_NONBLOCK);
793 	ck_assert_int_ge(fd, 0);
794 	ck_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0);
795 	ck_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1);
796 
797 	keyboard = litest_add_device(sw->libinput, LITEST_KEYBOARD);
798 
799 	/* separate context for the right state on init */
800 	li = litest_create_context();
801 	libinput_path_add_device(li,
802 				 libevdev_uinput_get_devnode(sw->uinput));
803 	libinput_path_add_device(li,
804 				 libevdev_uinput_get_devnode(keyboard->uinput));
805 
806 	/* don't expect a switch waiting for us, this is run for an
807 	 * unreliable device */
808 	while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) {
809 		ck_assert_int_ne(libinput_next_event_type(li),
810 				 LIBINPUT_EVENT_SWITCH_TOGGLE);
811 		libinput_event_destroy(libinput_get_event(li));
812 	}
813 
814 	litest_event(keyboard, EV_KEY, KEY_A, 1);
815 	litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
816 	litest_event(keyboard, EV_KEY, KEY_A, 0);
817 	litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
818 	/* No switch event, we're still in vanilla (open) state */
819 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
820 
821 	/* Make sure kernel state has updated */
822 	rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
823 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
824 	ck_assert_int_eq(event.type, EV_SW);
825 	ck_assert_int_eq(event.code, SW_LID);
826 	ck_assert_int_eq(event.value, 0);
827 	rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
828 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
829 	ck_assert_int_eq(event.type, EV_SYN);
830 	ck_assert_int_eq(event.code, SYN_REPORT);
831 	ck_assert_int_eq(event.value, 0);
832 	rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
833 	ck_assert_int_eq(rc, -EAGAIN);
834 
835 	litest_destroy_context(li);
836 	litest_delete_device(keyboard);
837 	close(fd);
838 	libevdev_free(evdev);
839 }
840 END_TEST
841 
START_TEST(lid_update_hw_on_key_multiple_keyboards)842 START_TEST(lid_update_hw_on_key_multiple_keyboards)
843 {
844 	struct litest_device *sw = litest_current_device();
845 	struct libinput *li = sw->libinput;
846 	struct litest_device *keyboard1, *keyboard2;
847 	struct libevdev *evdev = sw->evdev;
848 	struct input_event event;
849 	int fd;
850 	int rc;
851 
852 	if (!switch_has_lid(sw))
853 		return;
854 
855 	keyboard1 = litest_add_device(li,
856 				LITEST_KEYBOARD_BLADE_STEALTH_VIDEOSWITCH);
857 	libinput_dispatch(li);
858 
859 	keyboard2 = litest_add_device(li, LITEST_KEYBOARD_BLADE_STEALTH);
860 	libinput_dispatch(li);
861 
862 	litest_grab_device(sw);
863 	litest_switch_action(sw,
864 			     LIBINPUT_SWITCH_LID,
865 			     LIBINPUT_SWITCH_STATE_ON);
866 	litest_drain_events(li);
867 	litest_ungrab_device(sw);
868 
869 	/* Separate direct libevdev context to check if the HW event goes
870 	 * through */
871 	fd = open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY|O_NONBLOCK);
872 	ck_assert_int_ge(fd, 0);
873 	ck_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0);
874 	ck_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1);
875 
876 	/* Typing on the second keyboard should trigger a lid open event */
877 	litest_event(keyboard2, EV_KEY, KEY_A, 1);
878 	litest_event(keyboard2, EV_SYN, SYN_REPORT, 0);
879 	litest_event(keyboard2, EV_KEY, KEY_A, 0);
880 	litest_event(keyboard2, EV_SYN, SYN_REPORT, 0);
881 	litest_drain_events(li);
882 
883 	rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
884 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
885 	ck_assert_int_eq(event.type, EV_SW);
886 	ck_assert_int_eq(event.code, SW_LID);
887 	ck_assert_int_eq(event.value, 0);
888 	rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
889 	ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
890 	ck_assert_int_eq(event.type, EV_SYN);
891 	ck_assert_int_eq(event.code, SYN_REPORT);
892 	ck_assert_int_eq(event.value, 0);
893 	rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
894 	ck_assert_int_eq(rc, -EAGAIN);
895 
896 	litest_delete_device(keyboard1);
897 	litest_delete_device(keyboard2);
898 	close(fd);
899 	libevdev_free(evdev);
900 }
901 END_TEST
902 
START_TEST(lid_key_press)903 START_TEST(lid_key_press)
904 {
905 	struct litest_device *sw = litest_current_device();
906 	struct libinput *li = sw->libinput;
907 
908 	litest_drain_events(li);
909 
910 	litest_keyboard_key(sw, KEY_VOLUMEUP, true);
911 	litest_keyboard_key(sw, KEY_VOLUMEUP, false);
912 	libinput_dispatch(li);
913 
914 	/* Check that we're routing key events from a lid device too */
915 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
916 }
917 END_TEST
918 
START_TEST(tablet_mode_disable_touchpad_on_init)919 START_TEST(tablet_mode_disable_touchpad_on_init)
920 {
921 	struct litest_device *sw = litest_current_device();
922 	struct litest_device *touchpad;
923 	struct libinput *li = sw->libinput;
924 
925 	if (!switch_has_tablet_mode(sw))
926 		return;
927 
928 	litest_grab_device(sw);
929 	litest_switch_action(sw,
930 			     LIBINPUT_SWITCH_TABLET_MODE,
931 			     LIBINPUT_SWITCH_STATE_ON);
932 	litest_drain_events(li);
933 
934 	/* touchpad comes with switch already on - no events */
935 	touchpad = switch_init_paired_touchpad(li);
936 	litest_disable_tap(touchpad->libinput_device);
937 	litest_disable_hold_gestures(touchpad->libinput_device);
938 	litest_drain_events(li);
939 
940 	litest_touch_down(touchpad, 0, 50, 50);
941 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
942 	litest_touch_up(touchpad, 0);
943 	litest_assert_empty_queue(li);
944 
945 	litest_switch_action(sw,
946 			     LIBINPUT_SWITCH_TABLET_MODE,
947 			     LIBINPUT_SWITCH_STATE_OFF);
948 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
949 
950 	litest_touch_down(touchpad, 0, 50, 50);
951 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
952 	litest_touch_up(touchpad, 0);
953 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
954 	litest_ungrab_device(sw);
955 
956 	litest_delete_device(touchpad);
957 }
958 END_TEST
959 
START_TEST(tablet_mode_disable_touchpad_on_resume)960 START_TEST(tablet_mode_disable_touchpad_on_resume)
961 {
962 	struct litest_device *sw = litest_current_device();
963 	struct litest_device *touchpad;
964 	struct libinput *li = sw->libinput;
965 	struct libinput_event *event;
966 	bool have_switch_toggle = false;
967 
968 	if (!switch_has_tablet_mode(sw))
969 		return;
970 
971 	touchpad = switch_init_paired_touchpad(li);
972 	litest_disable_tap(touchpad->libinput_device);
973 	litest_disable_hold_gestures(touchpad->libinput_device);
974 	litest_drain_events(li);
975 
976 	libinput_suspend(li);
977 	litest_switch_action(sw,
978 			     LIBINPUT_SWITCH_TABLET_MODE,
979 			     LIBINPUT_SWITCH_STATE_ON);
980 	litest_drain_events(li);
981 	libinput_resume(li);
982 	libinput_dispatch(li);
983 
984 	while ((event = libinput_get_event(li))) {
985 		enum libinput_event_type type;
986 
987 		type = libinput_event_get_type(event);
988 		switch (type) {
989 		case LIBINPUT_EVENT_DEVICE_ADDED:
990 			break;
991 		case LIBINPUT_EVENT_SWITCH_TOGGLE:
992 			litest_is_switch_event(event,
993 					       LIBINPUT_SWITCH_TABLET_MODE,
994 					       LIBINPUT_SWITCH_STATE_ON);
995 			have_switch_toggle = true;
996 			break;
997 		default:
998 			ck_abort();
999 		}
1000 		libinput_event_destroy(event);
1001 	}
1002 
1003 	ck_assert(have_switch_toggle);
1004 
1005 	litest_touch_down(touchpad, 0, 50, 50);
1006 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
1007 	litest_touch_up(touchpad, 0);
1008 	litest_assert_empty_queue(li);
1009 
1010 	litest_switch_action(sw,
1011 			     LIBINPUT_SWITCH_TABLET_MODE,
1012 			     LIBINPUT_SWITCH_STATE_OFF);
1013 	libinput_dispatch(li);
1014 	event = libinput_get_event(li);
1015 	litest_is_switch_event(event,
1016 			       LIBINPUT_SWITCH_TABLET_MODE,
1017 			       LIBINPUT_SWITCH_STATE_OFF);
1018 	libinput_event_destroy(event);
1019 
1020 	litest_touch_down(touchpad, 0, 50, 50);
1021 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
1022 	litest_touch_up(touchpad, 0);
1023 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
1024 
1025 	litest_delete_device(touchpad);
1026 }
1027 END_TEST
1028 
START_TEST(tablet_mode_enable_touchpad_on_resume)1029 START_TEST(tablet_mode_enable_touchpad_on_resume)
1030 {
1031 	struct litest_device *sw = litest_current_device();
1032 	struct litest_device *touchpad;
1033 	struct libinput *li = sw->libinput;
1034 	struct libinput_event *event;
1035 
1036 	if (!switch_has_tablet_mode(sw))
1037 		return;
1038 
1039 	touchpad = switch_init_paired_touchpad(li);
1040 	litest_disable_tap(touchpad->libinput_device);
1041 	litest_drain_events(li);
1042 
1043 	litest_switch_action(sw,
1044 			     LIBINPUT_SWITCH_TABLET_MODE,
1045 			     LIBINPUT_SWITCH_STATE_ON);
1046 	libinput_suspend(li);
1047 	litest_drain_events(li);
1048 
1049 	litest_switch_action(sw,
1050 			     LIBINPUT_SWITCH_TABLET_MODE,
1051 			     LIBINPUT_SWITCH_STATE_OFF);
1052 
1053 	libinput_resume(li);
1054 	libinput_dispatch(li);
1055 
1056 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_ADDED);
1057 
1058 	litest_touch_down(touchpad, 0, 50, 50);
1059 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
1060 	litest_touch_up(touchpad, 0);
1061 	litest_drain_events_of_type(li,
1062 				    LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
1063 				    LIBINPUT_EVENT_GESTURE_HOLD_END,
1064 				    -1);
1065 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
1066 
1067 	litest_switch_action(sw,
1068 			     LIBINPUT_SWITCH_TABLET_MODE,
1069 			     LIBINPUT_SWITCH_STATE_ON);
1070 	libinput_dispatch(li);
1071 	event = libinput_get_event(li);
1072 	litest_is_switch_event(event,
1073 			       LIBINPUT_SWITCH_TABLET_MODE,
1074 			       LIBINPUT_SWITCH_STATE_ON);
1075 	libinput_event_destroy(event);
1076 
1077 	litest_touch_down(touchpad, 0, 50, 50);
1078 	litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
1079 	litest_touch_up(touchpad, 0);
1080 	litest_assert_empty_queue(li);
1081 
1082 	litest_delete_device(touchpad);
1083 }
1084 END_TEST
1085 
START_TEST(tablet_mode_disable_keyboard)1086 START_TEST(tablet_mode_disable_keyboard)
1087 {
1088 	struct litest_device *sw = litest_current_device();
1089 	struct litest_device *keyboard;
1090 	struct libinput *li = sw->libinput;
1091 
1092 	if (!switch_has_tablet_mode(sw))
1093 		return;
1094 
1095 	keyboard = litest_add_device(li, LITEST_KEYBOARD);
1096 	litest_drain_events(li);
1097 
1098 	litest_keyboard_key(keyboard, KEY_A, true);
1099 	litest_keyboard_key(keyboard, KEY_A, false);
1100 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1101 
1102 	litest_switch_action(sw,
1103 			     LIBINPUT_SWITCH_TABLET_MODE,
1104 			     LIBINPUT_SWITCH_STATE_ON);
1105 	litest_drain_events(li);
1106 
1107 	litest_keyboard_key(keyboard, KEY_A, true);
1108 	litest_keyboard_key(keyboard, KEY_A, false);
1109 	litest_assert_empty_queue(li);
1110 
1111 	litest_switch_action(sw,
1112 			     LIBINPUT_SWITCH_TABLET_MODE,
1113 			     LIBINPUT_SWITCH_STATE_OFF);
1114 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1115 
1116 	litest_keyboard_key(keyboard, KEY_A, true);
1117 	litest_keyboard_key(keyboard, KEY_A, false);
1118 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1119 
1120 	litest_delete_device(keyboard);
1121 }
1122 END_TEST
1123 
START_TEST(tablet_mode_disable_keyboard_on_init)1124 START_TEST(tablet_mode_disable_keyboard_on_init)
1125 {
1126 	struct litest_device *sw = litest_current_device();
1127 	struct litest_device *keyboard;
1128 	struct libinput *li = sw->libinput;
1129 
1130 	if (!switch_has_tablet_mode(sw))
1131 		return;
1132 
1133 	litest_switch_action(sw,
1134 			     LIBINPUT_SWITCH_TABLET_MODE,
1135 			     LIBINPUT_SWITCH_STATE_ON);
1136 	litest_drain_events(li);
1137 
1138 	/* keyboard comes with switch already on - no events */
1139 	keyboard = litest_add_device(li, LITEST_KEYBOARD);
1140 	litest_drain_events(li);
1141 
1142 	litest_keyboard_key(keyboard, KEY_A, true);
1143 	litest_keyboard_key(keyboard, KEY_A, false);
1144 	litest_assert_empty_queue(li);
1145 
1146 	litest_switch_action(sw,
1147 			     LIBINPUT_SWITCH_TABLET_MODE,
1148 			     LIBINPUT_SWITCH_STATE_OFF);
1149 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1150 
1151 	litest_keyboard_key(keyboard, KEY_A, true);
1152 	litest_keyboard_key(keyboard, KEY_A, false);
1153 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1154 
1155 	litest_delete_device(keyboard);
1156 }
1157 END_TEST
1158 
START_TEST(tablet_mode_disable_keyboard_on_resume)1159 START_TEST(tablet_mode_disable_keyboard_on_resume)
1160 {
1161 	struct litest_device *sw = litest_current_device();
1162 	struct litest_device *keyboard;
1163 	struct libinput *li = sw->libinput;
1164 	struct libinput_event *event;
1165 	bool have_switch_toggle = false;
1166 
1167 	if (!switch_has_tablet_mode(sw))
1168 		return;
1169 
1170 	keyboard = litest_add_device(li, LITEST_KEYBOARD);
1171 	litest_drain_events(li);
1172 	libinput_suspend(li);
1173 
1174 	/* We cannot grab this device because libinput doesn't have an open
1175 	 * fd to this device, we need an independent grab.
1176 	 */
1177 	libevdev_grab(sw->evdev, LIBEVDEV_GRAB);
1178 	litest_switch_action(sw,
1179 			     LIBINPUT_SWITCH_TABLET_MODE,
1180 			     LIBINPUT_SWITCH_STATE_ON);
1181 	libevdev_grab(sw->evdev, LIBEVDEV_UNGRAB);
1182 	litest_drain_events(li);
1183 
1184 	libinput_resume(li);
1185 	libinput_dispatch(li);
1186 
1187 	while ((event = libinput_get_event(li))) {
1188 		enum libinput_event_type type;
1189 
1190 		type = libinput_event_get_type(event);
1191 		switch (type) {
1192 		case LIBINPUT_EVENT_DEVICE_ADDED:
1193 			break;
1194 		case LIBINPUT_EVENT_SWITCH_TOGGLE:
1195 			litest_is_switch_event(event,
1196 					       LIBINPUT_SWITCH_TABLET_MODE,
1197 					       LIBINPUT_SWITCH_STATE_ON);
1198 			have_switch_toggle = true;
1199 			break;
1200 		default:
1201 			ck_abort();
1202 		}
1203 		libinput_event_destroy(event);
1204 	}
1205 
1206 	ck_assert(have_switch_toggle);
1207 
1208 	litest_keyboard_key(keyboard, KEY_A, true);
1209 	litest_keyboard_key(keyboard, KEY_A, false);
1210 	litest_assert_empty_queue(li);
1211 
1212 	litest_grab_device(sw);
1213 	litest_switch_action(sw,
1214 			     LIBINPUT_SWITCH_TABLET_MODE,
1215 			     LIBINPUT_SWITCH_STATE_OFF);
1216 	litest_ungrab_device(sw);
1217 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1218 
1219 	litest_keyboard_key(keyboard, KEY_A, true);
1220 	litest_keyboard_key(keyboard, KEY_A, false);
1221 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1222 
1223 	litest_delete_device(keyboard);
1224 }
1225 END_TEST
1226 
START_TEST(tablet_mode_enable_keyboard_on_resume)1227 START_TEST(tablet_mode_enable_keyboard_on_resume)
1228 {
1229 	struct litest_device *sw = litest_current_device();
1230 	struct litest_device *keyboard;
1231 	struct libinput *li = sw->libinput;
1232 
1233 	if (!switch_has_tablet_mode(sw))
1234 		return;
1235 
1236 	keyboard = litest_add_device(li, LITEST_KEYBOARD);
1237 	litest_grab_device(sw);
1238 	litest_switch_action(sw,
1239 			     LIBINPUT_SWITCH_TABLET_MODE,
1240 			     LIBINPUT_SWITCH_STATE_ON);
1241 	litest_drain_events(li);
1242 	litest_ungrab_device(sw);
1243 	libinput_suspend(li);
1244 	litest_drain_events(li);
1245 
1246 	litest_switch_action(sw,
1247 			     LIBINPUT_SWITCH_TABLET_MODE,
1248 			     LIBINPUT_SWITCH_STATE_OFF);
1249 
1250 	libinput_resume(li);
1251 	libinput_dispatch(li);
1252 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_ADDED);
1253 
1254 	litest_keyboard_key(keyboard, KEY_A, true);
1255 	litest_keyboard_key(keyboard, KEY_A, false);
1256 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1257 
1258 	litest_switch_action(sw,
1259 			     LIBINPUT_SWITCH_TABLET_MODE,
1260 			     LIBINPUT_SWITCH_STATE_ON);
1261 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1262 
1263 	litest_keyboard_key(keyboard, KEY_A, true);
1264 	litest_keyboard_key(keyboard, KEY_A, false);
1265 	litest_assert_empty_queue(li);
1266 
1267 	litest_delete_device(keyboard);
1268 }
1269 END_TEST
1270 
START_TEST(tablet_mode_disable_trackpoint)1271 START_TEST(tablet_mode_disable_trackpoint)
1272 {
1273 	struct litest_device *sw = litest_current_device();
1274 	struct litest_device *trackpoint;
1275 	struct libinput *li = sw->libinput;
1276 
1277 	if (!switch_has_tablet_mode(sw))
1278 		return;
1279 
1280 	trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
1281 	litest_drain_events(li);
1282 
1283 	litest_event(trackpoint, EV_REL, REL_Y, -1);
1284 	litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1285 	litest_event(trackpoint, EV_REL, REL_Y, -1);
1286 	litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1287 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
1288 
1289 	litest_grab_device(sw);
1290 	litest_switch_action(sw,
1291 			     LIBINPUT_SWITCH_TABLET_MODE,
1292 			     LIBINPUT_SWITCH_STATE_ON);
1293 	litest_drain_events(li);
1294 
1295 	litest_event(trackpoint, EV_REL, REL_Y, -1);
1296 	litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1297 	litest_event(trackpoint, EV_REL, REL_Y, -1);
1298 	litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1299 	litest_assert_empty_queue(li);
1300 
1301 	litest_switch_action(sw,
1302 			     LIBINPUT_SWITCH_TABLET_MODE,
1303 			     LIBINPUT_SWITCH_STATE_OFF);
1304 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1305 
1306 	litest_event(trackpoint, EV_REL, REL_Y, -1);
1307 	litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1308 	litest_event(trackpoint, EV_REL, REL_Y, -1);
1309 	litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1310 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
1311 	litest_ungrab_device(sw);
1312 
1313 	litest_delete_device(trackpoint);
1314 }
1315 END_TEST
1316 
START_TEST(tablet_mode_disable_trackpoint_on_init)1317 START_TEST(tablet_mode_disable_trackpoint_on_init)
1318 {
1319 	struct litest_device *sw = litest_current_device();
1320 	struct litest_device *trackpoint;
1321 	struct libinput *li = sw->libinput;
1322 
1323 	if (!switch_has_tablet_mode(sw))
1324 		return;
1325 
1326 	litest_grab_device(sw);
1327 	litest_switch_action(sw,
1328 			     LIBINPUT_SWITCH_TABLET_MODE,
1329 			     LIBINPUT_SWITCH_STATE_ON);
1330 	litest_drain_events(li);
1331 
1332 	/* trackpoint comes with switch already on - no events */
1333 	trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
1334 	litest_drain_events(li);
1335 
1336 	litest_event(trackpoint, EV_REL, REL_Y, -1);
1337 	litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1338 	litest_event(trackpoint, EV_REL, REL_Y, -1);
1339 	litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1340 	litest_assert_empty_queue(li);
1341 
1342 	litest_switch_action(sw,
1343 			     LIBINPUT_SWITCH_TABLET_MODE,
1344 			     LIBINPUT_SWITCH_STATE_OFF);
1345 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1346 
1347 	litest_event(trackpoint, EV_REL, REL_Y, -1);
1348 	litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1349 	litest_event(trackpoint, EV_REL, REL_Y, -1);
1350 	litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1351 	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
1352 	litest_ungrab_device(sw);
1353 
1354 	litest_delete_device(trackpoint);
1355 }
1356 END_TEST
1357 
START_TEST(dock_toggle)1358 START_TEST(dock_toggle)
1359 {
1360 	struct litest_device *sw = litest_current_device();
1361 	struct libinput *li = sw->libinput;
1362 
1363 	if (!libevdev_has_event_code(sw->evdev, EV_SW, SW_DOCK))
1364 		return;
1365 
1366 	litest_drain_events(li);
1367 
1368 	litest_grab_device(sw);
1369 	litest_event(sw, EV_SW, SW_DOCK, 1);
1370 	libinput_dispatch(li);
1371 
1372 	litest_event(sw, EV_SW, SW_DOCK, 0);
1373 	libinput_dispatch(li);
1374 	litest_ungrab_device(sw);
1375 
1376 	litest_assert_empty_queue(li);
1377 }
1378 END_TEST
1379 
TEST_COLLECTION(switch)1380 TEST_COLLECTION(switch)
1381 {
1382 	struct range switches = { LIBINPUT_SWITCH_LID,
1383 				  LIBINPUT_SWITCH_TABLET_MODE + 1};
1384 
1385 	litest_add(switch_has_cap, LITEST_SWITCH, LITEST_ANY);
1386 	litest_add(switch_has_lid_switch, LITEST_SWITCH, LITEST_ANY);
1387 	litest_add(switch_has_tablet_mode_switch, LITEST_SWITCH, LITEST_ANY);
1388 	litest_add_ranged(switch_toggle, LITEST_SWITCH, LITEST_ANY, &switches);
1389 	litest_add_ranged(switch_toggle_double, LITEST_SWITCH, LITEST_ANY, &switches);
1390 	litest_add_ranged(switch_down_on_init, LITEST_SWITCH, LITEST_ANY, &switches);
1391 	litest_add(switch_not_down_on_init, LITEST_SWITCH, LITEST_ANY);
1392 	litest_add_ranged(switch_disable_touchpad, LITEST_SWITCH, LITEST_ANY, &switches);
1393 	litest_add_ranged(switch_disable_touchpad_during_touch, LITEST_SWITCH, LITEST_ANY, &switches);
1394 	litest_add_ranged(switch_disable_touchpad_edge_scroll, LITEST_SWITCH, LITEST_ANY, &switches);
1395 	litest_add_ranged(switch_disable_touchpad_edge_scroll_interrupt, LITEST_SWITCH, LITEST_ANY, &switches);
1396 	litest_add_ranged(switch_disable_touchpad_already_open, LITEST_SWITCH, LITEST_ANY, &switches);
1397 	litest_add_ranged(switch_dont_resume_disabled_touchpad, LITEST_SWITCH, LITEST_ANY, &switches);
1398 	litest_add_ranged(switch_dont_resume_disabled_touchpad_external_mouse, LITEST_SWITCH, LITEST_ANY, &switches);
1399 
1400 	litest_add_ranged_no_device(switch_suspend_with_keyboard, &switches);
1401 	litest_add_ranged_no_device(switch_suspend_with_touchpad, &switches);
1402 
1403 	litest_add(lid_open_on_key, LITEST_SWITCH, LITEST_ANY);
1404 	litest_add(lid_open_on_key_touchpad_enabled, LITEST_SWITCH, LITEST_ANY);
1405 	litest_add_for_device(lid_update_hw_on_key, LITEST_LID_SWITCH_SURFACE3);
1406 	litest_add_for_device(lid_update_hw_on_key_closed_on_init, LITEST_LID_SWITCH_SURFACE3);
1407 	litest_add_for_device(lid_update_hw_on_key_multiple_keyboards, LITEST_LID_SWITCH_SURFACE3);
1408 	litest_add_for_device(lid_key_press, LITEST_GPIO_KEYS);
1409 
1410 	litest_add(tablet_mode_disable_touchpad_on_init, LITEST_SWITCH, LITEST_ANY);
1411 	litest_add(tablet_mode_disable_touchpad_on_resume, LITEST_SWITCH, LITEST_ANY);
1412 	litest_add(tablet_mode_enable_touchpad_on_resume, LITEST_SWITCH, LITEST_ANY);
1413 	litest_add(tablet_mode_disable_keyboard, LITEST_SWITCH, LITEST_ANY);
1414 	litest_add(tablet_mode_disable_keyboard_on_init, LITEST_SWITCH, LITEST_ANY);
1415 	litest_add(tablet_mode_disable_keyboard_on_resume, LITEST_SWITCH, LITEST_ANY);
1416 	litest_add(tablet_mode_enable_keyboard_on_resume, LITEST_SWITCH, LITEST_ANY);
1417 	litest_add(tablet_mode_disable_trackpoint, LITEST_SWITCH, LITEST_ANY);
1418 	litest_add(tablet_mode_disable_trackpoint_on_init, LITEST_SWITCH, LITEST_ANY);
1419 
1420 	litest_add(dock_toggle, LITEST_SWITCH, LITEST_ANY);
1421 }
1422