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