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