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_drain_events(li);
290
291 litest_grab_device(sw);
292
293 /* switch is on - no events */
294 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
295 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
296
297 litest_touch_down(touchpad, 0, 50, 50);
298 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
299 litest_touch_up(touchpad, 0);
300 litest_assert_empty_queue(li);
301
302 /* switch is off - motion events */
303 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
304 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
305
306 litest_touch_down(touchpad, 0, 50, 50);
307 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
308 litest_touch_up(touchpad, 0);
309 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
310
311 litest_delete_device(touchpad);
312 litest_ungrab_device(sw);
313 }
314 END_TEST
315
START_TEST(switch_disable_touchpad_during_touch)316 START_TEST(switch_disable_touchpad_during_touch)
317 {
318 struct litest_device *sw = litest_current_device();
319 struct litest_device *touchpad;
320 struct libinput *li = sw->libinput;
321 enum libinput_switch which = _i; /* ranged test */
322
323 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
324 return;
325
326 touchpad = switch_init_paired_touchpad(li);
327 litest_disable_tap(touchpad->libinput_device);
328 litest_drain_events(li);
329
330 litest_touch_down(touchpad, 0, 50, 50);
331 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5);
332 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
333
334 litest_grab_device(sw);
335 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
336 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
337 litest_ungrab_device(sw);
338
339 litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 5);
340 litest_touch_up(touchpad, 0);
341 litest_assert_empty_queue(li);
342
343 litest_delete_device(touchpad);
344 }
345 END_TEST
346
START_TEST(switch_disable_touchpad_edge_scroll)347 START_TEST(switch_disable_touchpad_edge_scroll)
348 {
349 struct litest_device *sw = litest_current_device();
350 struct litest_device *touchpad;
351 struct libinput *li = sw->libinput;
352 enum libinput_switch which = _i; /* ranged test */
353
354 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
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_grab_device(sw);
363 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
364 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
365 litest_ungrab_device(sw);
366
367 litest_touch_down(touchpad, 0, 99, 20);
368 libinput_dispatch(li);
369 litest_timeout_edgescroll();
370 libinput_dispatch(li);
371 litest_assert_empty_queue(li);
372
373 litest_touch_move_to(touchpad, 0, 99, 20, 99, 80, 60);
374 libinput_dispatch(li);
375 litest_assert_empty_queue(li);
376
377 litest_touch_move_to(touchpad, 0, 99, 80, 99, 20, 60);
378 litest_touch_up(touchpad, 0);
379 libinput_dispatch(li);
380 litest_assert_empty_queue(li);
381
382 litest_delete_device(touchpad);
383 }
384 END_TEST
385
START_TEST(switch_disable_touchpad_edge_scroll_interrupt)386 START_TEST(switch_disable_touchpad_edge_scroll_interrupt)
387 {
388 struct litest_device *sw = litest_current_device();
389 struct litest_device *touchpad;
390 struct libinput *li = sw->libinput;
391 struct libinput_event *event;
392 enum libinput_switch which = _i; /* ranged test */
393
394 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
395 return;
396
397 touchpad = switch_init_paired_touchpad(li);
398 litest_enable_edge_scroll(touchpad);
399
400 litest_drain_events(li);
401
402 litest_touch_down(touchpad, 0, 99, 20);
403 libinput_dispatch(li);
404 litest_timeout_edgescroll();
405 litest_touch_move_to(touchpad, 0, 99, 20, 99, 30, 10);
406 libinput_dispatch(li);
407 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
408
409 litest_grab_device(sw);
410 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
411 litest_ungrab_device(sw);
412 libinput_dispatch(li);
413
414 event = libinput_get_event(li);
415 litest_is_axis_event(event,
416 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
417 LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
418 libinput_event_destroy(event);
419
420 event = libinput_get_event(li);
421 litest_is_switch_event(event, which, LIBINPUT_SWITCH_STATE_ON);
422 libinput_event_destroy(event);
423
424 litest_delete_device(touchpad);
425 }
426 END_TEST
427
START_TEST(switch_disable_touchpad_already_open)428 START_TEST(switch_disable_touchpad_already_open)
429 {
430 struct litest_device *sw = litest_current_device();
431 struct litest_device *touchpad;
432 struct libinput *li = sw->libinput;
433 enum libinput_switch which = _i; /* ranged test */
434
435 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
436 return;
437
438 touchpad = switch_init_paired_touchpad(li);
439
440 litest_disable_tap(touchpad->libinput_device);
441 litest_drain_events(li);
442
443 /* default: switch is off - motion events */
444 litest_touch_down(touchpad, 0, 50, 50);
445 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
446 litest_touch_up(touchpad, 0);
447 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
448
449 /* disable switch - motion events */
450 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
451 litest_assert_empty_queue(li);
452
453 litest_touch_down(touchpad, 0, 50, 50);
454 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
455 litest_touch_up(touchpad, 0);
456 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
457
458 litest_delete_device(touchpad);
459 }
460 END_TEST
461
START_TEST(switch_dont_resume_disabled_touchpad)462 START_TEST(switch_dont_resume_disabled_touchpad)
463 {
464 struct litest_device *sw = litest_current_device();
465 struct litest_device *touchpad;
466 struct libinput *li = sw->libinput;
467 enum libinput_switch which = _i; /* ranged test */
468
469 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
470 return;
471
472 touchpad = switch_init_paired_touchpad(li);
473 litest_disable_tap(touchpad->libinput_device);
474 libinput_device_config_send_events_set_mode(touchpad->libinput_device,
475 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
476 litest_drain_events(li);
477
478 /* switch is on - no events */
479 litest_grab_device(sw);
480 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
481 litest_ungrab_device(sw);
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 }
500 END_TEST
501
START_TEST(switch_dont_resume_disabled_touchpad_external_mouse)502 START_TEST(switch_dont_resume_disabled_touchpad_external_mouse)
503 {
504 struct litest_device *sw = litest_current_device();
505 struct litest_device *touchpad, *mouse;
506 struct libinput *li = sw->libinput;
507 enum libinput_switch which = _i; /* ranged test */
508
509 if (libinput_device_switch_has_switch(sw->libinput_device, which) <= 0)
510 return;
511
512 touchpad = switch_init_paired_touchpad(li);
513 mouse = litest_add_device(li, LITEST_MOUSE);
514 litest_disable_tap(touchpad->libinput_device);
515 libinput_device_config_send_events_set_mode(touchpad->libinput_device,
516 LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE);
517 litest_drain_events(li);
518
519 litest_touch_down(touchpad, 0, 50, 50);
520 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
521 litest_touch_up(touchpad, 0);
522 litest_assert_empty_queue(li);
523
524 /* switch is on - no events */
525 litest_grab_device(sw);
526 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
527 litest_ungrab_device(sw);
528 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
529
530 litest_touch_down(touchpad, 0, 50, 50);
531 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
532 litest_touch_up(touchpad, 0);
533 litest_assert_empty_queue(li);
534
535 /* switch is off but but tp is still disabled */
536 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
537 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
538
539 litest_touch_down(touchpad, 0, 50, 50);
540 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
541 litest_touch_up(touchpad, 0);
542 litest_assert_empty_queue(li);
543
544 litest_delete_device(touchpad);
545 litest_delete_device(mouse);
546 }
547 END_TEST
548
START_TEST(lid_open_on_key)549 START_TEST(lid_open_on_key)
550 {
551 struct litest_device *sw = litest_current_device();
552 struct litest_device *keyboard;
553 struct libinput *li = sw->libinput;
554 struct libinput_event *event;
555
556 if (!switch_has_lid(sw))
557 return;
558
559 keyboard = litest_add_device(li, LITEST_KEYBOARD);
560
561 litest_grab_device(sw);
562 for (int i = 0; i < 3; i++) {
563 litest_switch_action(sw,
564 LIBINPUT_SWITCH_LID,
565 LIBINPUT_SWITCH_STATE_ON);
566 litest_drain_events(li);
567
568 litest_event(keyboard, EV_KEY, KEY_A, 1);
569 litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
570 litest_event(keyboard, EV_KEY, KEY_A, 0);
571 litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
572 libinput_dispatch(li);
573
574 event = libinput_get_event(li);
575 litest_is_switch_event(event,
576 LIBINPUT_SWITCH_LID,
577 LIBINPUT_SWITCH_STATE_OFF);
578 libinput_event_destroy(event);
579
580 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
581
582 litest_switch_action(sw,
583 LIBINPUT_SWITCH_LID,
584 LIBINPUT_SWITCH_STATE_OFF);
585 litest_assert_empty_queue(li);
586 }
587 litest_ungrab_device(sw);
588
589 litest_delete_device(keyboard);
590 }
591 END_TEST
592
START_TEST(lid_open_on_key_touchpad_enabled)593 START_TEST(lid_open_on_key_touchpad_enabled)
594 {
595 struct litest_device *sw = litest_current_device();
596 struct litest_device *keyboard, *touchpad;
597 struct libinput *li = sw->libinput;
598
599 if (!switch_has_lid(sw))
600 return;
601
602 keyboard = litest_add_device(li, LITEST_KEYBOARD);
603 touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
604
605 litest_grab_device(sw);
606 litest_switch_action(sw,
607 LIBINPUT_SWITCH_LID,
608 LIBINPUT_SWITCH_STATE_ON);
609 litest_ungrab_device(sw);
610 litest_drain_events(li);
611
612 litest_event(keyboard, EV_KEY, KEY_A, 1);
613 litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
614 litest_event(keyboard, EV_KEY, KEY_A, 0);
615 litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
616 litest_drain_events(li);
617 litest_timeout_dwt_long();
618
619 litest_touch_down(touchpad, 0, 50, 50);
620 litest_touch_move_to(touchpad, 0, 50, 50, 70, 70, 10);
621 litest_touch_up(touchpad, 0);
622 libinput_dispatch(li);
623
624 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
625
626 litest_delete_device(keyboard);
627 litest_delete_device(touchpad);
628 }
629 END_TEST
630
START_TEST(switch_suspend_with_keyboard)631 START_TEST(switch_suspend_with_keyboard)
632 {
633 struct libinput *li;
634 struct litest_device *keyboard;
635 struct litest_device *sw;
636 enum libinput_switch which = _i; /* ranged test */
637
638 li = litest_create_context();
639
640 switch(which) {
641 case LIBINPUT_SWITCH_LID:
642 sw = litest_add_device(li, LITEST_LID_SWITCH);
643 break;
644 case LIBINPUT_SWITCH_TABLET_MODE:
645 sw = litest_add_device(li, LITEST_THINKPAD_EXTRABUTTONS);
646 break;
647 default:
648 abort();
649 }
650
651 libinput_dispatch(li);
652
653 keyboard = litest_add_device(li, LITEST_KEYBOARD);
654 libinput_dispatch(li);
655
656 litest_grab_device(sw);
657 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
658 litest_drain_events(li);
659 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
660 litest_drain_events(li);
661 litest_ungrab_device(sw);
662
663 litest_delete_device(keyboard);
664 litest_drain_events(li);
665
666 litest_delete_device(sw);
667 libinput_dispatch(li);
668
669 litest_destroy_context(li);
670 }
671 END_TEST
672
START_TEST(switch_suspend_with_touchpad)673 START_TEST(switch_suspend_with_touchpad)
674 {
675 struct libinput *li;
676 struct litest_device *touchpad, *sw;
677 enum libinput_switch which = _i; /* ranged test */
678
679 li = litest_create_context();
680
681 switch(which) {
682 case LIBINPUT_SWITCH_LID:
683 sw = litest_add_device(li, LITEST_LID_SWITCH);
684 break;
685 case LIBINPUT_SWITCH_TABLET_MODE:
686 sw = litest_add_device(li, LITEST_THINKPAD_EXTRABUTTONS);
687 break;
688 default:
689 abort();
690 }
691
692 litest_drain_events(li);
693
694 touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
695 litest_drain_events(li);
696
697 litest_grab_device(sw);
698 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
699 litest_drain_events(li);
700 litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_OFF);
701 litest_drain_events(li);
702 litest_ungrab_device(sw);
703
704 litest_delete_device(sw);
705 litest_drain_events(li);
706 litest_delete_device(touchpad);
707 litest_drain_events(li);
708
709 litest_destroy_context(li);
710 }
711 END_TEST
712
START_TEST(lid_update_hw_on_key)713 START_TEST(lid_update_hw_on_key)
714 {
715 struct litest_device *sw = litest_current_device();
716 struct libinput *li = sw->libinput;
717 struct litest_device *keyboard;
718 struct libevdev *evdev;
719 struct input_event event;
720 int fd;
721 int rc;
722
723 if (!switch_has_lid(sw))
724 return;
725
726 keyboard = litest_add_device(li, LITEST_KEYBOARD);
727
728 litest_grab_device(sw);
729 litest_switch_action(sw,
730 LIBINPUT_SWITCH_LID,
731 LIBINPUT_SWITCH_STATE_ON);
732 litest_drain_events(li);
733 litest_ungrab_device(sw);
734
735 /* Separate direct libevdev context to check if the HW event goes
736 * through */
737 fd = open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY|O_NONBLOCK);
738 ck_assert_int_ge(fd, 0);
739 ck_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0);
740 ck_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1);
741
742 /* Typing on the keyboard should trigger a lid open event */
743 litest_event(keyboard, EV_KEY, KEY_A, 1);
744 litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
745 litest_event(keyboard, EV_KEY, KEY_A, 0);
746 litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
747 litest_drain_events(li);
748
749 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
750 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
751 ck_assert_int_eq(event.type, EV_SW);
752 ck_assert_int_eq(event.code, SW_LID);
753 ck_assert_int_eq(event.value, 0);
754 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
755 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
756 ck_assert_int_eq(event.type, EV_SYN);
757 ck_assert_int_eq(event.code, SYN_REPORT);
758 ck_assert_int_eq(event.value, 0);
759 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
760 ck_assert_int_eq(rc, -EAGAIN);
761
762 litest_delete_device(keyboard);
763 close(fd);
764 libevdev_free(evdev);
765 }
766 END_TEST
767
START_TEST(lid_update_hw_on_key_closed_on_init)768 START_TEST(lid_update_hw_on_key_closed_on_init)
769 {
770 struct litest_device *sw = litest_current_device();
771 struct libinput *li;
772 struct litest_device *keyboard;
773 struct libevdev *evdev = sw->evdev;
774 struct input_event event;
775 int fd;
776 int rc;
777
778 litest_grab_device(sw);
779 litest_switch_action(sw,
780 LIBINPUT_SWITCH_LID,
781 LIBINPUT_SWITCH_STATE_ON);
782 litest_ungrab_device(sw);
783
784 /* Separate direct libevdev context to check if the HW event goes
785 * through */
786 fd = open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY|O_NONBLOCK);
787 ck_assert_int_ge(fd, 0);
788 ck_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0);
789 ck_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1);
790
791 keyboard = litest_add_device(sw->libinput, LITEST_KEYBOARD);
792
793 /* separate context for the right state on init */
794 li = litest_create_context();
795 libinput_path_add_device(li,
796 libevdev_uinput_get_devnode(sw->uinput));
797 libinput_path_add_device(li,
798 libevdev_uinput_get_devnode(keyboard->uinput));
799
800 /* don't expect a switch waiting for us, this is run for an
801 * unreliable device */
802 while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) {
803 ck_assert_int_ne(libinput_next_event_type(li),
804 LIBINPUT_EVENT_SWITCH_TOGGLE);
805 libinput_event_destroy(libinput_get_event(li));
806 }
807
808 litest_event(keyboard, EV_KEY, KEY_A, 1);
809 litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
810 litest_event(keyboard, EV_KEY, KEY_A, 0);
811 litest_event(keyboard, EV_SYN, SYN_REPORT, 0);
812 /* No switch event, we're still in vanilla (open) state */
813 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
814
815 /* Make sure kernel state has updated */
816 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
817 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
818 ck_assert_int_eq(event.type, EV_SW);
819 ck_assert_int_eq(event.code, SW_LID);
820 ck_assert_int_eq(event.value, 0);
821 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
822 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
823 ck_assert_int_eq(event.type, EV_SYN);
824 ck_assert_int_eq(event.code, SYN_REPORT);
825 ck_assert_int_eq(event.value, 0);
826 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
827 ck_assert_int_eq(rc, -EAGAIN);
828
829 litest_destroy_context(li);
830 litest_delete_device(keyboard);
831 close(fd);
832 libevdev_free(evdev);
833 }
834 END_TEST
835
START_TEST(lid_update_hw_on_key_multiple_keyboards)836 START_TEST(lid_update_hw_on_key_multiple_keyboards)
837 {
838 struct litest_device *sw = litest_current_device();
839 struct libinput *li = sw->libinput;
840 struct litest_device *keyboard1, *keyboard2;
841 struct libevdev *evdev = sw->evdev;
842 struct input_event event;
843 int fd;
844 int rc;
845
846 if (!switch_has_lid(sw))
847 return;
848
849 keyboard1 = litest_add_device(li,
850 LITEST_KEYBOARD_BLADE_STEALTH_VIDEOSWITCH);
851 libinput_dispatch(li);
852
853 keyboard2 = litest_add_device(li, LITEST_KEYBOARD_BLADE_STEALTH);
854 libinput_dispatch(li);
855
856 litest_grab_device(sw);
857 litest_switch_action(sw,
858 LIBINPUT_SWITCH_LID,
859 LIBINPUT_SWITCH_STATE_ON);
860 litest_drain_events(li);
861 litest_ungrab_device(sw);
862
863 /* Separate direct libevdev context to check if the HW event goes
864 * through */
865 fd = open(libevdev_uinput_get_devnode(sw->uinput), O_RDONLY|O_NONBLOCK);
866 ck_assert_int_ge(fd, 0);
867 ck_assert_int_eq(libevdev_new_from_fd(fd, &evdev), 0);
868 ck_assert_int_eq(libevdev_get_event_value(evdev, EV_SW, SW_LID), 1);
869
870 /* Typing on the second keyboard should trigger a lid open event */
871 litest_event(keyboard2, EV_KEY, KEY_A, 1);
872 litest_event(keyboard2, EV_SYN, SYN_REPORT, 0);
873 litest_event(keyboard2, EV_KEY, KEY_A, 0);
874 litest_event(keyboard2, EV_SYN, SYN_REPORT, 0);
875 litest_drain_events(li);
876
877 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
878 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
879 ck_assert_int_eq(event.type, EV_SW);
880 ck_assert_int_eq(event.code, SW_LID);
881 ck_assert_int_eq(event.value, 0);
882 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
883 ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
884 ck_assert_int_eq(event.type, EV_SYN);
885 ck_assert_int_eq(event.code, SYN_REPORT);
886 ck_assert_int_eq(event.value, 0);
887 rc = libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event);
888 ck_assert_int_eq(rc, -EAGAIN);
889
890 litest_delete_device(keyboard1);
891 litest_delete_device(keyboard2);
892 close(fd);
893 libevdev_free(evdev);
894 }
895 END_TEST
896
START_TEST(lid_key_press)897 START_TEST(lid_key_press)
898 {
899 struct litest_device *sw = litest_current_device();
900 struct libinput *li = sw->libinput;
901
902 litest_drain_events(li);
903
904 litest_keyboard_key(sw, KEY_VOLUMEUP, true);
905 litest_keyboard_key(sw, KEY_VOLUMEUP, false);
906 libinput_dispatch(li);
907
908 /* Check that we're routing key events from a lid device too */
909 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
910 }
911 END_TEST
912
START_TEST(tablet_mode_disable_touchpad_on_init)913 START_TEST(tablet_mode_disable_touchpad_on_init)
914 {
915 struct litest_device *sw = litest_current_device();
916 struct litest_device *touchpad;
917 struct libinput *li = sw->libinput;
918
919 if (!switch_has_tablet_mode(sw))
920 return;
921
922 litest_grab_device(sw);
923 litest_switch_action(sw,
924 LIBINPUT_SWITCH_TABLET_MODE,
925 LIBINPUT_SWITCH_STATE_ON);
926 litest_drain_events(li);
927
928 /* touchpad comes with switch already on - no events */
929 touchpad = switch_init_paired_touchpad(li);
930 litest_disable_tap(touchpad->libinput_device);
931 litest_drain_events(li);
932
933 litest_touch_down(touchpad, 0, 50, 50);
934 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
935 litest_touch_up(touchpad, 0);
936 litest_assert_empty_queue(li);
937
938 litest_switch_action(sw,
939 LIBINPUT_SWITCH_TABLET_MODE,
940 LIBINPUT_SWITCH_STATE_OFF);
941 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
942
943 litest_touch_down(touchpad, 0, 50, 50);
944 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
945 litest_touch_up(touchpad, 0);
946 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
947 litest_ungrab_device(sw);
948
949 litest_delete_device(touchpad);
950 }
951 END_TEST
952
START_TEST(tablet_mode_disable_touchpad_on_resume)953 START_TEST(tablet_mode_disable_touchpad_on_resume)
954 {
955 struct litest_device *sw = litest_current_device();
956 struct litest_device *touchpad;
957 struct libinput *li = sw->libinput;
958 struct libinput_event *event;
959 bool have_switch_toggle = false;
960
961 if (!switch_has_tablet_mode(sw))
962 return;
963
964 touchpad = switch_init_paired_touchpad(li);
965 litest_disable_tap(touchpad->libinput_device);
966 litest_drain_events(li);
967
968 libinput_suspend(li);
969 litest_switch_action(sw,
970 LIBINPUT_SWITCH_TABLET_MODE,
971 LIBINPUT_SWITCH_STATE_ON);
972 litest_drain_events(li);
973 libinput_resume(li);
974 libinput_dispatch(li);
975
976 while ((event = libinput_get_event(li))) {
977 enum libinput_event_type type;
978
979 type = libinput_event_get_type(event);
980 switch (type) {
981 case LIBINPUT_EVENT_DEVICE_ADDED:
982 break;
983 case LIBINPUT_EVENT_SWITCH_TOGGLE:
984 litest_is_switch_event(event,
985 LIBINPUT_SWITCH_TABLET_MODE,
986 LIBINPUT_SWITCH_STATE_ON);
987 have_switch_toggle = true;
988 break;
989 default:
990 ck_abort();
991 }
992 libinput_event_destroy(event);
993 }
994
995 ck_assert(have_switch_toggle);
996
997 litest_touch_down(touchpad, 0, 50, 50);
998 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
999 litest_touch_up(touchpad, 0);
1000 litest_assert_empty_queue(li);
1001
1002 litest_switch_action(sw,
1003 LIBINPUT_SWITCH_TABLET_MODE,
1004 LIBINPUT_SWITCH_STATE_OFF);
1005 libinput_dispatch(li);
1006 event = libinput_get_event(li);
1007 litest_is_switch_event(event,
1008 LIBINPUT_SWITCH_TABLET_MODE,
1009 LIBINPUT_SWITCH_STATE_OFF);
1010 libinput_event_destroy(event);
1011
1012 litest_touch_down(touchpad, 0, 50, 50);
1013 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
1014 litest_touch_up(touchpad, 0);
1015 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
1016
1017 litest_delete_device(touchpad);
1018 }
1019 END_TEST
1020
START_TEST(tablet_mode_enable_touchpad_on_resume)1021 START_TEST(tablet_mode_enable_touchpad_on_resume)
1022 {
1023 struct litest_device *sw = litest_current_device();
1024 struct litest_device *touchpad;
1025 struct libinput *li = sw->libinput;
1026 struct libinput_event *event;
1027
1028 if (!switch_has_tablet_mode(sw))
1029 return;
1030
1031 touchpad = switch_init_paired_touchpad(li);
1032 litest_disable_tap(touchpad->libinput_device);
1033 litest_drain_events(li);
1034
1035 litest_switch_action(sw,
1036 LIBINPUT_SWITCH_TABLET_MODE,
1037 LIBINPUT_SWITCH_STATE_ON);
1038 libinput_suspend(li);
1039 litest_drain_events(li);
1040
1041 litest_switch_action(sw,
1042 LIBINPUT_SWITCH_TABLET_MODE,
1043 LIBINPUT_SWITCH_STATE_OFF);
1044
1045 libinput_resume(li);
1046 libinput_dispatch(li);
1047
1048 litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_ADDED);
1049
1050 litest_touch_down(touchpad, 0, 50, 50);
1051 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
1052 litest_touch_up(touchpad, 0);
1053 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
1054
1055 litest_switch_action(sw,
1056 LIBINPUT_SWITCH_TABLET_MODE,
1057 LIBINPUT_SWITCH_STATE_ON);
1058 libinput_dispatch(li);
1059 event = libinput_get_event(li);
1060 litest_is_switch_event(event,
1061 LIBINPUT_SWITCH_TABLET_MODE,
1062 LIBINPUT_SWITCH_STATE_ON);
1063 libinput_event_destroy(event);
1064
1065 litest_touch_down(touchpad, 0, 50, 50);
1066 litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10);
1067 litest_touch_up(touchpad, 0);
1068 litest_assert_empty_queue(li);
1069
1070 litest_delete_device(touchpad);
1071 }
1072 END_TEST
1073
START_TEST(tablet_mode_disable_keyboard)1074 START_TEST(tablet_mode_disable_keyboard)
1075 {
1076 struct litest_device *sw = litest_current_device();
1077 struct litest_device *keyboard;
1078 struct libinput *li = sw->libinput;
1079
1080 if (!switch_has_tablet_mode(sw))
1081 return;
1082
1083 keyboard = litest_add_device(li, LITEST_KEYBOARD);
1084 litest_drain_events(li);
1085
1086 litest_keyboard_key(keyboard, KEY_A, true);
1087 litest_keyboard_key(keyboard, KEY_A, false);
1088 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1089
1090 litest_switch_action(sw,
1091 LIBINPUT_SWITCH_TABLET_MODE,
1092 LIBINPUT_SWITCH_STATE_ON);
1093 litest_drain_events(li);
1094
1095 litest_keyboard_key(keyboard, KEY_A, true);
1096 litest_keyboard_key(keyboard, KEY_A, false);
1097 litest_assert_empty_queue(li);
1098
1099 litest_switch_action(sw,
1100 LIBINPUT_SWITCH_TABLET_MODE,
1101 LIBINPUT_SWITCH_STATE_OFF);
1102 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1103
1104 litest_keyboard_key(keyboard, KEY_A, true);
1105 litest_keyboard_key(keyboard, KEY_A, false);
1106 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1107
1108 litest_delete_device(keyboard);
1109 }
1110 END_TEST
1111
START_TEST(tablet_mode_disable_keyboard_on_init)1112 START_TEST(tablet_mode_disable_keyboard_on_init)
1113 {
1114 struct litest_device *sw = litest_current_device();
1115 struct litest_device *keyboard;
1116 struct libinput *li = sw->libinput;
1117
1118 if (!switch_has_tablet_mode(sw))
1119 return;
1120
1121 litest_switch_action(sw,
1122 LIBINPUT_SWITCH_TABLET_MODE,
1123 LIBINPUT_SWITCH_STATE_ON);
1124 litest_drain_events(li);
1125
1126 /* keyboard comes with switch already on - no events */
1127 keyboard = litest_add_device(li, LITEST_KEYBOARD);
1128 litest_drain_events(li);
1129
1130 litest_keyboard_key(keyboard, KEY_A, true);
1131 litest_keyboard_key(keyboard, KEY_A, false);
1132 litest_assert_empty_queue(li);
1133
1134 litest_switch_action(sw,
1135 LIBINPUT_SWITCH_TABLET_MODE,
1136 LIBINPUT_SWITCH_STATE_OFF);
1137 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1138
1139 litest_keyboard_key(keyboard, KEY_A, true);
1140 litest_keyboard_key(keyboard, KEY_A, false);
1141 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1142
1143 litest_delete_device(keyboard);
1144 }
1145 END_TEST
1146
START_TEST(tablet_mode_disable_keyboard_on_resume)1147 START_TEST(tablet_mode_disable_keyboard_on_resume)
1148 {
1149 struct litest_device *sw = litest_current_device();
1150 struct litest_device *keyboard;
1151 struct libinput *li = sw->libinput;
1152 struct libinput_event *event;
1153 bool have_switch_toggle = false;
1154
1155 if (!switch_has_tablet_mode(sw))
1156 return;
1157
1158 keyboard = litest_add_device(li, LITEST_KEYBOARD);
1159 litest_drain_events(li);
1160 libinput_suspend(li);
1161
1162 /* We cannot grab this device because libinput doesn't have an open
1163 * fd to this device, we need an independent grab.
1164 */
1165 libevdev_grab(sw->evdev, LIBEVDEV_GRAB);
1166 litest_switch_action(sw,
1167 LIBINPUT_SWITCH_TABLET_MODE,
1168 LIBINPUT_SWITCH_STATE_ON);
1169 libevdev_grab(sw->evdev, LIBEVDEV_UNGRAB);
1170 litest_drain_events(li);
1171
1172 libinput_resume(li);
1173 libinput_dispatch(li);
1174
1175 while ((event = libinput_get_event(li))) {
1176 enum libinput_event_type type;
1177
1178 type = libinput_event_get_type(event);
1179 switch (type) {
1180 case LIBINPUT_EVENT_DEVICE_ADDED:
1181 break;
1182 case LIBINPUT_EVENT_SWITCH_TOGGLE:
1183 litest_is_switch_event(event,
1184 LIBINPUT_SWITCH_TABLET_MODE,
1185 LIBINPUT_SWITCH_STATE_ON);
1186 have_switch_toggle = true;
1187 break;
1188 default:
1189 ck_abort();
1190 }
1191 libinput_event_destroy(event);
1192 }
1193
1194 ck_assert(have_switch_toggle);
1195
1196 litest_keyboard_key(keyboard, KEY_A, true);
1197 litest_keyboard_key(keyboard, KEY_A, false);
1198 litest_assert_empty_queue(li);
1199
1200 litest_grab_device(sw);
1201 litest_switch_action(sw,
1202 LIBINPUT_SWITCH_TABLET_MODE,
1203 LIBINPUT_SWITCH_STATE_OFF);
1204 litest_ungrab_device(sw);
1205 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1206
1207 litest_keyboard_key(keyboard, KEY_A, true);
1208 litest_keyboard_key(keyboard, KEY_A, false);
1209 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1210
1211 litest_delete_device(keyboard);
1212 }
1213 END_TEST
1214
START_TEST(tablet_mode_enable_keyboard_on_resume)1215 START_TEST(tablet_mode_enable_keyboard_on_resume)
1216 {
1217 struct litest_device *sw = litest_current_device();
1218 struct litest_device *keyboard;
1219 struct libinput *li = sw->libinput;
1220
1221 if (!switch_has_tablet_mode(sw))
1222 return;
1223
1224 keyboard = litest_add_device(li, LITEST_KEYBOARD);
1225 litest_grab_device(sw);
1226 litest_switch_action(sw,
1227 LIBINPUT_SWITCH_TABLET_MODE,
1228 LIBINPUT_SWITCH_STATE_ON);
1229 litest_drain_events(li);
1230 litest_ungrab_device(sw);
1231 libinput_suspend(li);
1232 litest_drain_events(li);
1233
1234 litest_switch_action(sw,
1235 LIBINPUT_SWITCH_TABLET_MODE,
1236 LIBINPUT_SWITCH_STATE_OFF);
1237
1238 libinput_resume(li);
1239 libinput_dispatch(li);
1240 litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_ADDED);
1241
1242 litest_keyboard_key(keyboard, KEY_A, true);
1243 litest_keyboard_key(keyboard, KEY_A, false);
1244 litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
1245
1246 litest_switch_action(sw,
1247 LIBINPUT_SWITCH_TABLET_MODE,
1248 LIBINPUT_SWITCH_STATE_ON);
1249 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1250
1251 litest_keyboard_key(keyboard, KEY_A, true);
1252 litest_keyboard_key(keyboard, KEY_A, false);
1253 litest_assert_empty_queue(li);
1254
1255 litest_delete_device(keyboard);
1256 }
1257 END_TEST
1258
START_TEST(tablet_mode_disable_trackpoint)1259 START_TEST(tablet_mode_disable_trackpoint)
1260 {
1261 struct litest_device *sw = litest_current_device();
1262 struct litest_device *trackpoint;
1263 struct libinput *li = sw->libinput;
1264
1265 if (!switch_has_tablet_mode(sw))
1266 return;
1267
1268 trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
1269 litest_drain_events(li);
1270
1271 litest_event(trackpoint, EV_REL, REL_Y, -1);
1272 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1273 litest_event(trackpoint, EV_REL, REL_Y, -1);
1274 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1275 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
1276
1277 litest_grab_device(sw);
1278 litest_switch_action(sw,
1279 LIBINPUT_SWITCH_TABLET_MODE,
1280 LIBINPUT_SWITCH_STATE_ON);
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_empty_queue(li);
1288
1289 litest_switch_action(sw,
1290 LIBINPUT_SWITCH_TABLET_MODE,
1291 LIBINPUT_SWITCH_STATE_OFF);
1292 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1293
1294 litest_event(trackpoint, EV_REL, REL_Y, -1);
1295 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1296 litest_event(trackpoint, EV_REL, REL_Y, -1);
1297 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1298 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
1299 litest_ungrab_device(sw);
1300
1301 litest_delete_device(trackpoint);
1302 }
1303 END_TEST
1304
START_TEST(tablet_mode_disable_trackpoint_on_init)1305 START_TEST(tablet_mode_disable_trackpoint_on_init)
1306 {
1307 struct litest_device *sw = litest_current_device();
1308 struct litest_device *trackpoint;
1309 struct libinput *li = sw->libinput;
1310
1311 if (!switch_has_tablet_mode(sw))
1312 return;
1313
1314 litest_grab_device(sw);
1315 litest_switch_action(sw,
1316 LIBINPUT_SWITCH_TABLET_MODE,
1317 LIBINPUT_SWITCH_STATE_ON);
1318 litest_drain_events(li);
1319
1320 /* trackpoint comes with switch already on - no events */
1321 trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
1322 litest_drain_events(li);
1323
1324 litest_event(trackpoint, EV_REL, REL_Y, -1);
1325 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1326 litest_event(trackpoint, EV_REL, REL_Y, -1);
1327 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1328 litest_assert_empty_queue(li);
1329
1330 litest_switch_action(sw,
1331 LIBINPUT_SWITCH_TABLET_MODE,
1332 LIBINPUT_SWITCH_STATE_OFF);
1333 litest_assert_only_typed_events(li, LIBINPUT_EVENT_SWITCH_TOGGLE);
1334
1335 litest_event(trackpoint, EV_REL, REL_Y, -1);
1336 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1337 litest_event(trackpoint, EV_REL, REL_Y, -1);
1338 litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
1339 litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
1340 litest_ungrab_device(sw);
1341
1342 litest_delete_device(trackpoint);
1343 }
1344 END_TEST
1345
START_TEST(dock_toggle)1346 START_TEST(dock_toggle)
1347 {
1348 struct litest_device *sw = litest_current_device();
1349 struct libinput *li = sw->libinput;
1350
1351 if (!libevdev_has_event_code(sw->evdev, EV_SW, SW_DOCK))
1352 return;
1353
1354 litest_drain_events(li);
1355
1356 litest_grab_device(sw);
1357 litest_event(sw, EV_SW, SW_DOCK, 1);
1358 libinput_dispatch(li);
1359
1360 litest_event(sw, EV_SW, SW_DOCK, 0);
1361 libinput_dispatch(li);
1362 litest_ungrab_device(sw);
1363
1364 litest_assert_empty_queue(li);
1365 }
1366 END_TEST
1367
TEST_COLLECTION(switch)1368 TEST_COLLECTION(switch)
1369 {
1370 struct range switches = { LIBINPUT_SWITCH_LID,
1371 LIBINPUT_SWITCH_TABLET_MODE + 1};
1372
1373 litest_add("switch:has", switch_has_cap, LITEST_SWITCH, LITEST_ANY);
1374 litest_add("switch:has", switch_has_lid_switch, LITEST_SWITCH, LITEST_ANY);
1375 litest_add("switch:has", switch_has_tablet_mode_switch, LITEST_SWITCH, LITEST_ANY);
1376 litest_add_ranged("switch:toggle", switch_toggle, LITEST_SWITCH, LITEST_ANY, &switches);
1377 litest_add_ranged("switch:toggle", switch_toggle_double, LITEST_SWITCH, LITEST_ANY, &switches);
1378 litest_add_ranged("switch:toggle", switch_down_on_init, LITEST_SWITCH, LITEST_ANY, &switches);
1379 litest_add("switch:toggle", switch_not_down_on_init, LITEST_SWITCH, LITEST_ANY);
1380 litest_add_ranged("switch:touchpad", switch_disable_touchpad, LITEST_SWITCH, LITEST_ANY, &switches);
1381 litest_add_ranged("switch:touchpad", switch_disable_touchpad_during_touch, LITEST_SWITCH, LITEST_ANY, &switches);
1382 litest_add_ranged("switch:touchpad", switch_disable_touchpad_edge_scroll, LITEST_SWITCH, LITEST_ANY, &switches);
1383 litest_add_ranged("switch:touchpad", switch_disable_touchpad_edge_scroll_interrupt, LITEST_SWITCH, LITEST_ANY, &switches);
1384 litest_add_ranged("switch:touchpad", switch_disable_touchpad_already_open, LITEST_SWITCH, LITEST_ANY, &switches);
1385 litest_add_ranged("switch:touchpad", switch_dont_resume_disabled_touchpad, LITEST_SWITCH, LITEST_ANY, &switches);
1386 litest_add_ranged("switch:touchpad", switch_dont_resume_disabled_touchpad_external_mouse, LITEST_SWITCH, LITEST_ANY, &switches);
1387
1388 litest_add_ranged_no_device("switch:keyboard", switch_suspend_with_keyboard, &switches);
1389 litest_add_ranged_no_device("switch:touchpad", switch_suspend_with_touchpad, &switches);
1390
1391 litest_add("lid:keyboard", lid_open_on_key, LITEST_SWITCH, LITEST_ANY);
1392 litest_add("lid:keyboard", lid_open_on_key_touchpad_enabled, LITEST_SWITCH, LITEST_ANY);
1393 litest_add_for_device("lid:buggy", lid_update_hw_on_key, LITEST_LID_SWITCH_SURFACE3);
1394 litest_add_for_device("lid:buggy", lid_update_hw_on_key_closed_on_init, LITEST_LID_SWITCH_SURFACE3);
1395 litest_add_for_device("lid:buggy", lid_update_hw_on_key_multiple_keyboards, LITEST_LID_SWITCH_SURFACE3);
1396 litest_add_for_device("lid:keypress", lid_key_press, LITEST_GPIO_KEYS);
1397
1398 litest_add("tablet-mode:touchpad", tablet_mode_disable_touchpad_on_init, LITEST_SWITCH, LITEST_ANY);
1399 litest_add("tablet-mode:touchpad", tablet_mode_disable_touchpad_on_resume, LITEST_SWITCH, LITEST_ANY);
1400 litest_add("tablet-mode:touchpad", tablet_mode_enable_touchpad_on_resume, LITEST_SWITCH, LITEST_ANY);
1401 litest_add("tablet-mode:keyboard", tablet_mode_disable_keyboard, LITEST_SWITCH, LITEST_ANY);
1402 litest_add("tablet-mode:keyboard", tablet_mode_disable_keyboard_on_init, LITEST_SWITCH, LITEST_ANY);
1403 litest_add("tablet-mode:keyboard", tablet_mode_disable_keyboard_on_resume, LITEST_SWITCH, LITEST_ANY);
1404 litest_add("tablet-mode:keyboard", tablet_mode_enable_keyboard_on_resume, LITEST_SWITCH, LITEST_ANY);
1405 litest_add("tablet-mode:trackpoint", tablet_mode_disable_trackpoint, LITEST_SWITCH, LITEST_ANY);
1406 litest_add("tablet-mode:trackpoint", tablet_mode_disable_trackpoint_on_init, LITEST_SWITCH, LITEST_ANY);
1407
1408 litest_add("lid:dock", dock_toggle, LITEST_SWITCH, LITEST_ANY);
1409 }
1410