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