| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037 |
- /*
- * Copyright © 2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
- #include <config.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <libinput.h>
- #include <stdio.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include "libinput-util.h"
- #include "litest.h"
- struct counter {
- int open_func_count;
- int close_func_count;
- };
- static int
- open_restricted_count(const char *path, int flags, void *data)
- {
- struct counter *c = data;
- int fd;
- c->open_func_count++;
- fd = open(path, flags);
- return fd < 0 ? -errno : fd;
- }
- static void
- close_restricted_count(int fd, void *data)
- {
- struct counter *c = data;
- c->close_func_count++;
- close(fd);
- }
- static const struct libinput_interface counting_interface = {
- .open_restricted = open_restricted_count,
- .close_restricted = close_restricted_count,
- };
- static int
- open_restricted(const char *path, int flags, void *data)
- {
- int fd = open(path, flags);
- return fd < 0 ? -errno : fd;
- }
- static void
- close_restricted(int fd, void *data)
- {
- close(fd);
- }
- static const struct libinput_interface simple_interface = {
- .open_restricted = open_restricted,
- .close_restricted = close_restricted,
- };
- START_TEST(path_create_NULL)
- {
- struct libinput *li;
- struct counter counter;
- counter.open_func_count = 0;
- counter.close_func_count = 0;
- li = libinput_path_create_context(NULL, NULL);
- litest_assert(li == NULL);
- li = libinput_path_create_context(&counting_interface, &counter);
- litest_assert_notnull(li);
- libinput_unref(li);
- litest_assert_int_eq(counter.open_func_count, 0);
- litest_assert_int_eq(counter.close_func_count, 0);
- }
- END_TEST
- START_TEST(path_create_invalid)
- {
- struct libinput *li;
- struct libinput_device *device;
- const char *path = "/tmp";
- struct counter counter;
- counter.open_func_count = 0;
- counter.close_func_count = 0;
- li = libinput_path_create_context(&counting_interface, &counter);
- litest_assert_notnull(li);
- litest_disable_log_handler(li);
- device = libinput_path_add_device(li, path);
- litest_assert(device == NULL);
- litest_assert_int_eq(counter.open_func_count, 0);
- litest_assert_int_eq(counter.close_func_count, 0);
- litest_restore_log_handler(li);
- libinput_unref(li);
- litest_assert_int_eq(counter.close_func_count, 0);
- }
- END_TEST
- START_TEST(path_create_invalid_kerneldev)
- {
- struct libinput *li;
- struct libinput_device *device;
- const char *path = "/dev/uinput";
- struct counter counter;
- counter.open_func_count = 0;
- counter.close_func_count = 0;
- li = libinput_path_create_context(&counting_interface, &counter);
- litest_assert_notnull(li);
- litest_disable_log_handler(li);
- device = libinput_path_add_device(li, path);
- litest_assert(device == NULL);
- litest_assert_int_eq(counter.open_func_count, 1);
- litest_assert_int_eq(counter.close_func_count, 1);
- litest_restore_log_handler(li);
- libinput_unref(li);
- litest_assert_int_eq(counter.close_func_count, 1);
- }
- END_TEST
- START_TEST(path_create_invalid_file)
- {
- struct libinput *li;
- struct libinput_device *device;
- char path[] = "/tmp/litest_path_XXXXXX";
- int fd;
- struct counter counter;
- umask(002);
- fd = mkstemp(path);
- litest_assert_int_ge(fd, 0);
- close(fd);
- counter.open_func_count = 0;
- counter.close_func_count = 0;
- li = libinput_path_create_context(&counting_interface, &counter);
- unlink(path);
- litest_disable_log_handler(li);
- litest_assert_notnull(li);
- device = libinput_path_add_device(li, path);
- litest_assert(device == NULL);
- litest_assert_int_eq(counter.open_func_count, 0);
- litest_assert_int_eq(counter.close_func_count, 0);
- litest_restore_log_handler(li);
- libinput_unref(li);
- litest_assert_int_eq(counter.close_func_count, 0);
- }
- END_TEST
- START_TEST(path_create_pathmax_file)
- {
- struct libinput *li;
- struct libinput_device *device;
- struct counter counter;
- _autofree_ char *path = zalloc(PATH_MAX * 2);
- memset(path, 'a', PATH_MAX * 2 - 1);
- counter.open_func_count = 0;
- counter.close_func_count = 0;
- li = libinput_path_create_context(&counting_interface, &counter);
- litest_set_log_handler_bug(li);
- litest_assert_notnull(li);
- device = libinput_path_add_device(li, path);
- litest_assert(device == NULL);
- litest_assert_int_eq(counter.open_func_count, 0);
- litest_assert_int_eq(counter.close_func_count, 0);
- litest_restore_log_handler(li);
- libinput_unref(li);
- litest_assert_int_eq(counter.close_func_count, 0);
- }
- END_TEST
- START_TEST(path_create_destroy)
- {
- struct libinput *li;
- struct libinput_device *device;
- struct libevdev_uinput *uinput;
- struct counter counter;
- counter.open_func_count = 0;
- counter.close_func_count = 0;
- /* clang-format off */
- uinput = litest_create_uinput_device("test device", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- /* clang-format on */
- li = libinput_path_create_context(&counting_interface, &counter);
- litest_assert_notnull(li);
- litest_disable_log_handler(li);
- litest_assert(libinput_get_user_data(li) == &counter);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
- litest_assert_notnull(device);
- litest_assert_int_eq(counter.open_func_count, 1);
- libevdev_uinput_destroy(uinput);
- libinput_unref(li);
- litest_assert_int_eq(counter.close_func_count, 1);
- }
- END_TEST
- START_TEST(path_force_destroy)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li;
- struct libinput_device *device;
- li = libinput_path_create_context(&simple_interface, NULL);
- litest_assert_notnull(li);
- libinput_ref(li);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput));
- litest_assert_notnull(device);
- while (libinput_unref(li) != NULL)
- ;
- }
- END_TEST
- START_TEST(path_set_user_data)
- {
- struct libinput *li;
- int data1, data2;
- li = libinput_path_create_context(&simple_interface, &data1);
- litest_assert_notnull(li);
- litest_assert(libinput_get_user_data(li) == &data1);
- libinput_set_user_data(li, &data2);
- litest_assert(libinput_get_user_data(li) == &data2);
- libinput_unref(li);
- }
- END_TEST
- START_TEST(path_added_seat)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_device *device;
- struct libinput_seat *seat;
- const char *seat_name;
- litest_dispatch(li);
- event = libinput_get_event(li);
- litest_assert_notnull(event);
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- device = libinput_event_get_device(event);
- seat = libinput_device_get_seat(device);
- litest_assert_notnull(seat);
- seat_name = libinput_seat_get_logical_name(seat);
- litest_assert_str_eq(seat_name, "default");
- libinput_event_destroy(event);
- }
- END_TEST
- START_TEST(path_seat_change)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_device *device;
- struct libinput_seat *seat1, *seat2;
- const char *seat1_name;
- const char *seat2_name = "new seat";
- int rc;
- litest_dispatch(li);
- event = libinput_get_event(li);
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- device = libinput_event_get_device(event);
- libinput_device_ref(device);
- seat1 = libinput_device_get_seat(device);
- libinput_seat_ref(seat1);
- seat1_name = libinput_seat_get_logical_name(seat1);
- libinput_event_destroy(event);
- litest_drain_events(li);
- rc = libinput_device_set_seat_logical_name(device, seat2_name);
- litest_assert_int_eq(rc, 0);
- litest_dispatch(li);
- event = libinput_get_event(li);
- litest_assert_notnull(event);
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
- litest_assert(libinput_event_get_device(event) == device);
- libinput_event_destroy(event);
- event = libinput_get_event(li);
- litest_assert_notnull(event);
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- litest_assert(libinput_event_get_device(event) != device);
- libinput_device_unref(device);
- device = libinput_event_get_device(event);
- seat2 = libinput_device_get_seat(device);
- litest_assert_str_ne(libinput_seat_get_logical_name(seat2), seat1_name);
- litest_assert_str_eq(libinput_seat_get_logical_name(seat2), seat2_name);
- libinput_event_destroy(event);
- libinput_seat_unref(seat1);
- /* litest: swap the new device in, so cleanup works */
- libinput_device_unref(dev->libinput_device);
- libinput_device_ref(device);
- dev->libinput_device = device;
- }
- END_TEST
- START_TEST(path_added_device)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_device *device;
- litest_dispatch(li);
- event = libinput_get_event(li);
- litest_assert_notnull(event);
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- device = libinput_event_get_device(event);
- litest_assert_notnull(device);
- libinput_event_destroy(event);
- }
- END_TEST
- START_TEST(path_add_device)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_device *device;
- litest_dispatch(li);
- event = libinput_get_event(li);
- litest_assert_notnull(event);
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- device = libinput_event_get_device(event);
- litest_assert_notnull(device);
- _autofree_ char *sysname1 = safe_strdup(libinput_device_get_sysname(device));
- libinput_event_destroy(event);
- litest_assert_empty_queue(li);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput));
- litest_assert_notnull(device);
- litest_dispatch(li);
- event = libinput_get_event(li);
- litest_assert_notnull(event);
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- device = libinput_event_get_device(event);
- litest_assert_notnull(device);
- _autofree_ char *sysname2 = safe_strdup(libinput_device_get_sysname(device));
- libinput_event_destroy(event);
- litest_assert_str_eq(sysname1, sysname2);
- }
- END_TEST
- START_TEST(path_add_invalid_path)
- {
- struct libinput_device *device;
- _litest_context_destroy_ struct libinput *li = litest_create_context();
- litest_disable_log_handler(li);
- device = libinput_path_add_device(li, "/tmp/");
- litest_restore_log_handler(li);
- litest_assert(device == NULL);
- litest_dispatch(li);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(path_device_sysname)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_event *ev;
- struct libinput_device *device;
- const char *sysname;
- litest_dispatch(dev->libinput);
- ev = libinput_get_event(dev->libinput);
- litest_assert_notnull(ev);
- litest_assert_event_type(ev, LIBINPUT_EVENT_DEVICE_ADDED);
- device = libinput_event_get_device(ev);
- litest_assert_notnull(device);
- sysname = libinput_device_get_sysname(device);
- litest_assert_notnull(sysname);
- litest_assert_int_gt(strlen(sysname), 1U);
- litest_assert(strchr(sysname, '/') == NULL);
- litest_assert(strstartswith(sysname, "event"));
- libinput_event_destroy(ev);
- }
- END_TEST
- START_TEST(path_remove_device)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_device *device;
- int remove_event = 0;
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput));
- litest_assert_notnull(device);
- litest_drain_events(li);
- libinput_path_remove_device(device);
- litest_dispatch(li);
- while ((event = libinput_get_event(li))) {
- enum libinput_event_type type;
- type = libinput_event_get_type(event);
- if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
- remove_event++;
- libinput_event_destroy(event);
- }
- litest_assert_int_eq(remove_event, 1);
- }
- END_TEST
- START_TEST(path_double_remove_device)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_device *device;
- int remove_event = 0;
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(dev->uinput));
- litest_assert_notnull(device);
- litest_drain_events(li);
- libinput_path_remove_device(device);
- libinput_path_remove_device(device);
- litest_dispatch(li);
- while ((event = libinput_get_event(li))) {
- enum libinput_event_type type;
- type = libinput_event_get_type(event);
- if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
- remove_event++;
- libinput_event_destroy(event);
- }
- litest_assert_int_eq(remove_event, 1);
- }
- END_TEST
- START_TEST(path_suspend)
- {
- struct libinput *li;
- struct libinput_device *device;
- struct libevdev_uinput *uinput;
- int rc;
- void *userdata = &rc;
- /* clang-format off */
- uinput = litest_create_uinput_device("test device", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- /* clang-format on */
- li = libinput_path_create_context(&simple_interface, userdata);
- litest_assert_notnull(li);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
- litest_assert_notnull(device);
- libinput_suspend(li);
- libinput_resume(li);
- libevdev_uinput_destroy(uinput);
- libinput_unref(li);
- }
- END_TEST
- START_TEST(path_double_suspend)
- {
- struct libinput *li;
- struct libinput_device *device;
- struct libevdev_uinput *uinput;
- int rc;
- void *userdata = &rc;
- /* clang-format off */
- uinput = litest_create_uinput_device("test device", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- /* clang-format on */
- li = libinput_path_create_context(&simple_interface, userdata);
- litest_assert_notnull(li);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
- litest_assert_notnull(device);
- libinput_suspend(li);
- libinput_suspend(li);
- libinput_resume(li);
- libevdev_uinput_destroy(uinput);
- libinput_unref(li);
- }
- END_TEST
- START_TEST(path_double_resume)
- {
- struct libinput *li;
- struct libinput_device *device;
- struct libevdev_uinput *uinput;
- int rc;
- void *userdata = &rc;
- /* clang-format off */
- uinput = litest_create_uinput_device("test device", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- /* clang-format on */
- li = libinput_path_create_context(&simple_interface, userdata);
- litest_assert_notnull(li);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
- litest_assert_notnull(device);
- libinput_suspend(li);
- libinput_resume(li);
- libinput_resume(li);
- libevdev_uinput_destroy(uinput);
- libinput_unref(li);
- }
- END_TEST
- START_TEST(path_add_device_suspend_resume)
- {
- struct libinput *li;
- struct libinput_device *device;
- struct libinput_event *event;
- struct libevdev_uinput *uinput1, *uinput2;
- int rc;
- int nevents;
- void *userdata = &rc;
- /* clang-format off */
- uinput1 = litest_create_uinput_device("test device", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- uinput2 = litest_create_uinput_device("test device 2", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- /* clang-format on */
- li = libinput_path_create_context(&simple_interface, userdata);
- litest_assert_notnull(li);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput1));
- litest_assert_notnull(device);
- libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput2));
- litest_dispatch(li);
- nevents = 0;
- while ((event = libinput_get_event(li))) {
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- libinput_event_destroy(event);
- nevents++;
- }
- litest_assert_int_eq(nevents, 2);
- libinput_suspend(li);
- litest_dispatch(li);
- nevents = 0;
- while ((event = libinput_get_event(li))) {
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
- libinput_event_destroy(event);
- nevents++;
- }
- litest_assert_int_eq(nevents, 2);
- libinput_resume(li);
- litest_dispatch(li);
- nevents = 0;
- while ((event = libinput_get_event(li))) {
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- libinput_event_destroy(event);
- nevents++;
- }
- litest_assert_int_eq(nevents, 2);
- libevdev_uinput_destroy(uinput1);
- libevdev_uinput_destroy(uinput2);
- libinput_unref(li);
- }
- END_TEST
- START_TEST(path_add_device_suspend_resume_fail)
- {
- struct libinput *li;
- struct libinput_device *device;
- struct libinput_event *event;
- struct libevdev_uinput *uinput1, *uinput2;
- int rc;
- int nevents;
- void *userdata = &rc;
- /* clang-format off */
- uinput1 = litest_create_uinput_device("test device", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- uinput2 = litest_create_uinput_device("test device 2", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- /* clang-format on */
- li = libinput_path_create_context(&simple_interface, userdata);
- litest_assert_notnull(li);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput1));
- litest_assert_notnull(device);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput2));
- litest_assert_notnull(device);
- litest_dispatch(li);
- nevents = 0;
- while ((event = libinput_get_event(li))) {
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- libinput_event_destroy(event);
- nevents++;
- }
- litest_assert_int_eq(nevents, 2);
- libinput_suspend(li);
- litest_dispatch(li);
- nevents = 0;
- while ((event = libinput_get_event(li))) {
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
- libinput_event_destroy(event);
- nevents++;
- }
- litest_assert_int_eq(nevents, 2);
- /* now drop one of the devices */
- libevdev_uinput_destroy(uinput1);
- rc = libinput_resume(li);
- litest_assert_int_eq(rc, -1);
- litest_dispatch(li);
- nevents = 0;
- while ((event = libinput_get_event(li))) {
- enum libinput_event_type type;
- type = libinput_event_get_type(event);
- /* We expect one device being added, second one fails,
- * causing a removed event for the first one */
- if (type != LIBINPUT_EVENT_DEVICE_ADDED &&
- type != LIBINPUT_EVENT_DEVICE_REMOVED)
- litest_abort_msg("Unexpected event type");
- libinput_event_destroy(event);
- nevents++;
- }
- litest_assert_int_eq(nevents, 2);
- libevdev_uinput_destroy(uinput2);
- libinput_unref(li);
- }
- END_TEST
- START_TEST(path_add_device_suspend_resume_remove_device)
- {
- struct libinput *li;
- struct libinput_device *device;
- struct libinput_event *event;
- struct libevdev_uinput *uinput1, *uinput2;
- int rc;
- int nevents;
- void *userdata = &rc;
- /* clang-format off */
- uinput1 = litest_create_uinput_device("test device", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- uinput2 = litest_create_uinput_device("test device 2", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- /* clang-format on */
- li = libinput_path_create_context(&simple_interface, userdata);
- litest_assert_notnull(li);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput1));
- litest_assert_notnull(device);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput2));
- libinput_device_ref(device);
- litest_dispatch(li);
- nevents = 0;
- while ((event = libinput_get_event(li))) {
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- libinput_event_destroy(event);
- nevents++;
- }
- litest_assert_int_eq(nevents, 2);
- libinput_suspend(li);
- litest_dispatch(li);
- nevents = 0;
- while ((event = libinput_get_event(li))) {
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
- libinput_event_destroy(event);
- nevents++;
- }
- litest_assert_int_eq(nevents, 2);
- /* now drop and remove one of the devices */
- libevdev_uinput_destroy(uinput2);
- libinput_path_remove_device(device);
- libinput_device_unref(device);
- rc = libinput_resume(li);
- litest_assert_int_eq(rc, 0);
- litest_dispatch(li);
- nevents = 0;
- while ((event = libinput_get_event(li))) {
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_ADDED);
- libinput_event_destroy(event);
- nevents++;
- }
- litest_assert_int_eq(nevents, 1);
- libevdev_uinput_destroy(uinput1);
- libinput_unref(li);
- }
- END_TEST
- START_TEST(path_device_gone)
- {
- struct libinput *li;
- struct libinput_device *device;
- struct libevdev_uinput *uinput;
- struct libinput_event *event;
- /* clang-format off */
- uinput = litest_create_uinput_device("test device", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- /* clang-format on */
- li = libinput_path_create_context(&simple_interface, NULL);
- litest_assert_notnull(li);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
- litest_assert_notnull(device);
- litest_drain_events(li);
- libevdev_uinput_destroy(uinput);
- litest_dispatch(li);
- event = libinput_get_event(li);
- litest_assert_notnull(event);
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
- libinput_event_destroy(event);
- libinput_unref(li);
- }
- END_TEST
- START_TEST(path_seat_recycle)
- {
- struct libinput *li;
- struct libevdev_uinput *uinput;
- int rc;
- void *userdata = &rc;
- struct libinput_event *ev;
- struct libinput_device *device;
- struct libinput_seat *saved_seat = NULL;
- struct libinput_seat *seat;
- int data = 0;
- int found = 0;
- void *user_data;
- /* clang-format off */
- uinput = litest_create_uinput_device("test device", NULL,
- EV_KEY, BTN_LEFT,
- EV_KEY, BTN_RIGHT,
- EV_REL, REL_X,
- EV_REL, REL_Y,
- -1);
- /* clang-format on */
- li = libinput_path_create_context(&simple_interface, userdata);
- litest_assert_notnull(li);
- device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput));
- litest_assert_notnull(device);
- litest_dispatch(li);
- ev = libinput_get_event(li);
- litest_assert_notnull(ev);
- litest_assert_event_type(ev, LIBINPUT_EVENT_DEVICE_ADDED);
- device = libinput_event_get_device(ev);
- litest_assert_notnull(device);
- saved_seat = libinput_device_get_seat(device);
- libinput_seat_set_user_data(saved_seat, &data);
- libinput_seat_ref(saved_seat);
- libinput_event_destroy(ev);
- litest_assert_notnull(saved_seat);
- litest_assert_empty_queue(li);
- libinput_suspend(li);
- litest_drain_events(li);
- libinput_resume(li);
- litest_dispatch(li);
- ev = libinput_get_event(li);
- litest_assert_notnull(ev);
- litest_assert_event_type(ev, LIBINPUT_EVENT_DEVICE_ADDED);
- device = libinput_event_get_device(ev);
- litest_assert_notnull(device);
- seat = libinput_device_get_seat(device);
- user_data = libinput_seat_get_user_data(seat);
- if (user_data == &data) {
- found = 1;
- litest_assert(seat == saved_seat);
- }
- libinput_event_destroy(ev);
- litest_assert(found == 1);
- libinput_unref(li);
- libevdev_uinput_destroy(uinput);
- }
- END_TEST
- START_TEST(path_udev_assign_seat)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- int rc;
- litest_set_log_handler_bug(li);
- rc = libinput_udev_assign_seat(li, "foo");
- litest_assert_int_eq(rc, -1);
- litest_restore_log_handler(li);
- }
- END_TEST
- START_TEST(path_ignore_device)
- {
- struct litest_device *dev;
- struct libinput_device *device;
- const char *path;
- dev = litest_create(LITEST_IGNORED_MOUSE, NULL, NULL, NULL, NULL);
- path = libevdev_uinput_get_devnode(dev->uinput);
- litest_assert_notnull(path);
- _litest_context_destroy_ struct libinput *li = litest_create_context();
- device = libinput_path_add_device(li, path);
- litest_assert(device == NULL);
- litest_device_destroy(dev);
- }
- END_TEST
- TEST_COLLECTION(path)
- {
- /* clang-format off */
- litest_add_no_device(path_create_NULL);
- litest_add_no_device(path_create_invalid);
- litest_add_no_device(path_create_invalid_file);
- litest_add_no_device(path_create_invalid_kerneldev);
- litest_add_no_device(path_create_pathmax_file);
- litest_add_no_device(path_create_destroy);
- litest_add(path_force_destroy, LITEST_ANY, LITEST_ANY);
- litest_add_no_device(path_set_user_data);
- litest_add_no_device(path_suspend);
- litest_add_no_device(path_double_suspend);
- litest_add_no_device(path_double_resume);
- litest_add_no_device(path_add_device_suspend_resume);
- litest_add_no_device(path_add_device_suspend_resume_fail);
- litest_add_no_device(path_add_device_suspend_resume_remove_device);
- litest_add_for_device(path_added_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
- litest_add_for_device(path_seat_change, LITEST_SYNAPTICS_CLICKPAD_X220);
- litest_add(path_added_device, LITEST_ANY, LITEST_ANY);
- litest_add(path_device_sysname, LITEST_ANY, LITEST_ANY);
- litest_add_for_device(path_add_device, LITEST_SYNAPTICS_CLICKPAD_X220);
- litest_add_no_device(path_add_invalid_path);
- litest_add_for_device(path_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220);
- litest_add_for_device(path_double_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220);
- litest_add_no_device(path_device_gone);
- litest_add_no_device(path_seat_recycle);
- litest_add_for_device(path_udev_assign_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
- litest_add_no_device(path_ignore_device);
- /* clang-format on */
- }
|