diff --git a/proto/ei.proto b/proto/ei.proto index 954984a..51338b3 100644 --- a/proto/ei.proto +++ b/proto/ei.proto @@ -208,6 +208,9 @@ message DeviceAdded { uint32 capabilities = 2; string name = 6; uint32 seatid = 7; + uint32 type = 8; + uint32 width = 9; + uint32 height = 10; } message DeviceKeymap { diff --git a/src/libei-device.c b/src/libei-device.c index ca531e2..a7d8467 100644 --- a/src/libei-device.c +++ b/src/libei-device.c @@ -87,6 +87,8 @@ OBJECT_IMPLEMENT_CREATE(ei_device); static OBJECT_IMPLEMENT_PARENT(ei_device, ei_seat); _public_ +OBJECT_IMPLEMENT_GETTER(ei_device, type, enum ei_device_type); +_public_ OBJECT_IMPLEMENT_GETTER(ei_device, name, const char *); _public_ OBJECT_IMPLEMENT_GETTER(ei_device, user_data, void *); @@ -294,6 +296,29 @@ ei_device_added(struct ei_device *device) { } +void +ei_device_set_type(struct ei_device *device, enum ei_device_type type) +{ + switch(type) { + case EI_DEVICE_TYPE_PHYSICAL: + case EI_DEVICE_TYPE_VIRTUAL: + device->type = type; + break; + default: + log_bug(ei_device_get_context(device), "Invalid device type %u\n", type); + break; + } +} + +void +ei_device_set_size(struct ei_device *device, uint32_t width, uint32_t height) +{ + if (device->type == EI_DEVICE_TYPE_PHYSICAL) { + device->width = width; + device->height = height; + } +} + void ei_device_set_name(struct ei_device *device, const char *name) { diff --git a/src/libei-private.h b/src/libei-private.h index 13aa4c8..0f1e3cb 100644 --- a/src/libei-private.h +++ b/src/libei-private.h @@ -127,6 +127,9 @@ struct ei_device { enum ei_device_state state; uint32_t capabilities; char *name; + enum ei_device_type type; + + uint32_t width, height; struct list regions; @@ -429,6 +432,12 @@ ei_device_paused(struct ei_device *device); void ei_device_resumed(struct ei_device *device); +void +ei_device_set_type(struct ei_device *device, enum ei_device_type type); + +void +ei_device_set_size(struct ei_device *device, uint32_t width, uint32_t height); + void ei_device_set_name(struct ei_device *device, const char *name); diff --git a/src/libei-proto.c b/src/libei-proto.c index d28fbc8..d6d426d 100644 --- a/src/libei-proto.c +++ b/src/libei-proto.c @@ -80,7 +80,10 @@ ei_proto_handle_message(struct ei *ei, proto->device_added->deviceid, proto->device_added->seatid, proto->device_added->name, - proto->device_added->capabilities); + proto->device_added->capabilities, + proto->device_added->type, + proto->device_added->width, + proto->device_added->height); break; case SERVER_MESSAGE__MSG_DEVICE_DONE: rc = call(device_done, ei, diff --git a/src/libei-proto.h b/src/libei-proto.h index d97f279..37bf193 100644 --- a/src/libei-proto.h +++ b/src/libei-proto.h @@ -40,7 +40,8 @@ struct ei_proto_interface { const char *name, uint32_t capabilities); int (*seat_removed)(struct ei *ei, uint32_t seatid); int (*device_added)(struct ei *ei, uint32_t deviceid, uint32_t seatid, - const char *name, uint32_t capabilities); + const char *name, uint32_t capabilities, uint32_t type, + uint32_t width, uint32_t height); int (*device_removed)(struct ei *ei, uint32_t deviceid); int (*device_paused)(struct ei *ei, uint32_t deviceid); int (*device_resumed)(struct ei *ei, uint32_t deviceid); diff --git a/src/libei.c b/src/libei.c index cac44a8..98dfcc4 100644 --- a/src/libei.c +++ b/src/libei.c @@ -576,7 +576,8 @@ handle_msg_seat_removed(struct ei *ei, uint32_t seatid) static int handle_msg_device_added(struct ei *ei, uint32_t deviceid, uint32_t seatid, - const char *name, uint32_t capabilities) + const char *name, uint32_t capabilities, uint32_t type, + uint32_t width, uint32_t height) { struct ei_seat *seat = ei_find_seat(ei, seatid); @@ -595,7 +596,19 @@ handle_msg_device_added(struct ei *ei, uint32_t deviceid, uint32_t seatid, return -EINVAL; } + switch (type) { + case EI_DEVICE_TYPE_PHYSICAL: + case EI_DEVICE_TYPE_VIRTUAL: + break; + default: + log_error(ei, "Server sent invalid device type %u\n", type); + return -EINVAL; + } + _unref_(ei_device) *device = ei_device_new(seat, deviceid); + ei_device_set_type(device, type); + if (type == EI_DEVICE_TYPE_PHYSICAL) + ei_device_set_size(device, width, height); ei_device_set_name(device, name); ei_device_set_capabilities(device, capabilities); ei_device_added(device); diff --git a/src/libei.h b/src/libei.h index 760ef9f..202d4ef 100644 --- a/src/libei.h +++ b/src/libei.h @@ -126,6 +126,32 @@ struct ei_keymap; */ struct ei_region; +/** + * @enum ei_device_type + * + * The device type determines what the device represents. + * + * If the device type is @ref EI_DEVICE_TYPE_VIRTUAL, the device is a + * virtual device representing input as applied on the EIS implementation's + * screen. A relative virtual device generates input events in logical pixels, + * an absolute virtual device generates input events in logical pixels on one + * of the device's regions. Virtual devices do not have a size. + * + * If the device type is @ref EI_DEVICE_TYPE_PHYSICAL, the device is a + * representation of a physical device as if connected to the EIS + * implementation's host computer. A relative physical device generates input + * events in mm, an absolute physical device generates input events in mm + * within the device's specified physical size. Physical devices do not have + * regions. + * + * @see eis_device_get_width + * @see eis_device_get_height + */ +enum ei_device_type { + EI_DEVICE_TYPE_VIRTUAL = 1, + EI_DEVICE_TYPE_PHYSICAL +}; + /** * @enum ei_device_capability * @@ -908,6 +934,20 @@ ei_device_close(struct ei_device *device); const char * ei_device_get_name(struct ei_device *device); +/** + * The device type of the device is determined by the type of the ei + * context. If the client context was created with ei_new_active(), the device + * type defaults to @ref EI_DEVICE_TYPE_VIRTUAL. If the client context was + * created with ei_new_passive(), the device type defaults to @ref + * EI_DEVICE_TYPE_PHYSICAL. + * + * libei does not currently support virtual devices on a passive context or + * physical devices on an active context. This may change in the future, + * applications should not rely on the type being fixed. + */ +enum ei_device_type +ei_device_get_type(struct ei_device *device); + /** * Return true if the device has the requested capability. Device * capabilities are constant. @@ -918,9 +958,9 @@ ei_device_has_capability(struct ei_device *device, /** - * Obtain a region from the device. The number of regions is constant for a - * device and the indices of any region remains the same for the lifetime of - * the device. + * Obtain a region from a device of type @ref EI_DEVICE_TYPE_VIRTUAL. The + * number of regions is constant for a device and the indices of any region + * remains the same for the lifetime of the device. * * Regions are shared between all capabilities. Where two capabilities need * different regions, the EIS implementation must create multiple devices with @@ -933,6 +973,8 @@ ei_device_has_capability(struct ei_device *device, * * This does not increase the refcount of the region. Use ei_region_ref() to * keep a reference beyond the immediate scope. + * + * Devices of type @ref EI_DEVICE_TYPE_PHYSICAL do not have regions. */ struct ei_region * ei_device_get_region(struct ei_device *device, size_t index); @@ -1397,28 +1439,28 @@ ei_event_property_get_permissions(struct ei_event *event); /** * For an event of type @ref EI_EVENT_POINTER_MOTION return the relative x - * movement in logical pixels. + * movement in logical pixels or mm, depending on the device type. */ double ei_event_pointer_get_dx(struct ei_event *event); /** * For an event of type @ref EI_EVENT_POINTER_MOTION return the relative y - * movement in logical pixels. + * movement in logical pixels or mm, depending on the device type. */ double ei_event_pointer_get_dy(struct ei_event *event); /** * For an event of type @ref EI_EVENT_POINTER_MOTION_ABSOLUTE return the x - * position in logical pixels. + * position in logical pixels or mm, depending on the device type. */ double ei_event_pointer_get_absolute_x(struct ei_event *event); /** * For an event of type @ref EI_EVENT_POINTER_MOTION_ABSOLUTE return the y - * position in logical pixels. + * position in logical pixels or mm, depending on the device type. */ double ei_event_pointer_get_absolute_y(struct ei_event *event); @@ -1439,14 +1481,14 @@ ei_event_pointer_get_button_is_press(struct ei_event *event); /** * For an event of type @ref EI_EVENT_POINTER_SCROLL return the x scroll - * distance in logical pixels. + * distance in logical pixels or mm, depending on the device type. */ double ei_event_pointer_get_scroll_x(struct ei_event *event); /** * For an event of type @ref EI_EVENT_POINTER_SCROLL return the y scroll - * distance in logical pixels. + * distance in logical pixels or mm, depending on the device type. */ double ei_event_pointer_get_scroll_y(struct ei_event *event); @@ -1508,14 +1550,16 @@ ei_event_touch_get_id(struct ei_event *event); /** * For an event of type @ref EI_EVENT_TOUCH_DOWN, or @ref - * EI_EVENT_TOUCH_MOTION, return the x coordinate of the touch. + * EI_EVENT_TOUCH_MOTION, return the x coordinate of the touch + * in logical pixels or mm, depending on the device type. */ double ei_event_touch_get_x(struct ei_event *event); /** * For an event of type @ref EI_EVENT_TOUCH_DOWN, or @ref - * EI_EVENT_TOUCH_MOTION, return the y coordinate of the touch. + * EI_EVENT_TOUCH_MOTION, return the y coordinate of the touch + * in logical pixels or mm, depending on the device type. */ double ei_event_touch_get_y(struct ei_event *event); diff --git a/src/libeis-client.c b/src/libeis-client.c index e257f9a..2ec40d2 100644 --- a/src/libeis-client.c +++ b/src/libeis-client.c @@ -151,7 +151,7 @@ client_send_device_added(struct eis_client *client, struct eis_device *device) if (rc >= 0 && device->keymap) rc = eis->requests->device_keymap(device); - if (rc >= 0) { + if (rc >= 0 && device->type == EIS_DEVICE_TYPE_VIRTUAL) { struct eis_region *r; list_for_each(r, &device->regions, link) { rc = eis->requests->device_region(device, r); diff --git a/src/libeis-device.c b/src/libeis-device.c index f41e2b6..7a7129a 100644 --- a/src/libeis-device.c +++ b/src/libeis-device.c @@ -152,6 +152,12 @@ _public_ OBJECT_IMPLEMENT_SETTER(eis_device, user_data, void *); _public_ OBJECT_IMPLEMENT_GETTER(eis_device, name, const char *); +_public_ +OBJECT_IMPLEMENT_GETTER(eis_device, type, enum eis_device_type); +_public_ +OBJECT_IMPLEMENT_GETTER(eis_device, width, uint32_t); +_public_ +OBJECT_IMPLEMENT_GETTER(eis_device, height, uint32_t); _public_ struct eis_seat * eis_device_get_seat(struct eis_device *device) @@ -181,6 +187,7 @@ eis_seat_new_device(struct eis_seat *seat) device->name = xstrdup("unnamed device"); device->capabilities = 0; device->state = EIS_DEVICE_STATE_NEW; + device->type = EIS_DEVICE_TYPE_VIRTUAL; list_init(&device->regions); list_init(&device->regions_new); @@ -189,6 +196,24 @@ eis_seat_new_device(struct eis_seat *seat) return eis_device_ref(device); } +_public_ void +eis_device_configure_type(struct eis_device *device, enum eis_device_type type) +{ + if (device->state != EIS_DEVICE_STATE_NEW) + return; + + switch (type) { + case EIS_DEVICE_TYPE_VIRTUAL: + case EIS_DEVICE_TYPE_PHYSICAL: + break; + default: + log_bug_client(eis_device_get_context(device), "Invalid device type %u\n", type); + return; + } + + device->type = type; +} + _public_ void eis_device_configure_name(struct eis_device *device, const char *name) { @@ -211,6 +236,21 @@ eis_device_configure_capability(struct eis_device *device, enum eis_device_capab flag_set(device->capabilities, cap); } +_public_ void +eis_device_configure_size(struct eis_device *device, uint32_t width, uint32_t height) +{ + if (device->type != EIS_DEVICE_TYPE_PHYSICAL) { + log_bug_client(eis_device_get_context(device), "Device type physical requird for size\n"); + return; + } + + if (width > 2000 || height > 2000) + log_warn(eis_device_get_context(device), "Suspicious device size: %ux%umm\n", width, height); + + device->width = width; + device->height = height; +} + _public_ void eis_device_add(struct eis_device *device) { diff --git a/src/libeis-private.h b/src/libeis-private.h index bac8457..b746e2a 100644 --- a/src/libeis-private.h +++ b/src/libeis-private.h @@ -133,6 +133,9 @@ struct eis_device { enum eis_device_state state; uint32_t capabilities; void *user_data; + enum eis_device_type type; + + uint32_t width, height; struct list regions; struct list regions_new; /* not yet added */ diff --git a/src/libeis-proto.c b/src/libeis-proto.c index 790af37..5288d03 100644 --- a/src/libeis-proto.c +++ b/src/libeis-proto.c @@ -177,6 +177,9 @@ eis_proto_send_device_added(struct eis_device *device) device_added.seatid = seat->id; device_added.name = device->name; device_added.capabilities = device->capabilities; + device_added.type = device->type; + device_added.width = device->width; + device_added.height = device->height; return eis_proto_send_msg(eis_device_get_client(device), &msg); } diff --git a/src/libeis-region.c b/src/libeis-region.c index c35c06c..7795042 100644 --- a/src/libeis-region.c +++ b/src/libeis-region.c @@ -57,6 +57,14 @@ OBJECT_IMPLEMENT_CREATE(eis_region); _public_ struct eis_region * eis_device_new_region(struct eis_device *device) { + switch (device->type) { + case EIS_DEVICE_TYPE_VIRTUAL: + break; + case EIS_DEVICE_TYPE_PHYSICAL: + log_bug_client(eis_device_get_context(device), "Regions on physical devices are not supported\n"); + return NULL; + } + struct eis_region *region = eis_region_create(NULL); region->device = eis_device_ref(device); diff --git a/src/libeis.h b/src/libeis.h index bffa615..661e58c 100644 --- a/src/libeis.h +++ b/src/libeis.h @@ -65,6 +65,8 @@ struct eis_touch; /** * @struct eis_region * + * Regions are only available on devices of type @ref EIS_DEVICE_TYPE_VIRTUAL. + * * A rectangular region, defined by an x/y offset and a width and a height. * A region defines the area on an EIS desktop layout that is accessible by * this device - this region may not be the full area of the desktop. @@ -89,6 +91,32 @@ struct eis_touch; */ struct eis_region; +/** + * @enum eis_device_type + * + * The device type determines what the device represents. + * + * If the device type is @ref EIS_DEVICE_TYPE_VIRTUAL, the device is a + * virtual device representing input as applied on the EIS implementation's + * screen. A relative virtual device generates input events in logical pixels, + * an absolute virtual device generates input events in logical pixels on one + * of the device's regions. Virtual devices do not have a size. + * + * If the device type is @ref EIS_DEVICE_TYPE_PHYSICAL, the device is a + * representation of a physical device as if connected to the EIS + * implementation's host computer. A relative physical device generates input + * events in mm, an absolute physical device generates input events in mm + * within the device's specified physical size. Physical devices do not have + * regions. + * + * @see eis_device_get_width + * @see eis_device_get_height + */ +enum eis_device_type { + EIS_DEVICE_TYPE_VIRTUAL = 1, + EIS_DEVICE_TYPE_PHYSICAL +}; + enum eis_device_capability { EIS_DEVICE_CAP_POINTER = 1, EIS_DEVICE_CAP_POINTER_ABSOLUTE, @@ -185,12 +213,13 @@ enum eis_event_type { /* These events are only generated on a passive EIS context */ /** - * A relative motion event with delta coordinates + * A relative motion event with delta coordinates in logical pixels or + * mm, depending on the device type. */ EIS_EVENT_POINTER_MOTION = 300, /** * An absolute motion event with absolute position within the device's - * regions. + * regions or size, depending on the device type. */ EIS_EVENT_POINTER_MOTION_ABSOLUTE, /** @@ -199,7 +228,7 @@ enum eis_event_type { EIS_EVENT_POINTER_BUTTON, /** * A vertical and/or horizontal scroll event with logical-pixels - * precision. + * or mm precision, depending on the device type. */ EIS_EVENT_POINTER_SCROLL, /** @@ -611,6 +640,20 @@ bool eis_device_has_capability(struct eis_device *device, enum eis_device_capability cap); +/** + * Return the width in mm of a device of type @ref EIS_DEVICE_TYPE_PHYSICAL, + * or zero otherwise. + */ +uint32_t +eis_device_get_width(struct eis_device *device); + +/** + * Return the height in mm of a device of type @ref EIS_DEVICE_TYPE_PHYSICAL, + * or zero otherwise. + */ +uint32_t +eis_device_get_height(struct eis_device *device); + /** * Create a new device on the seat. This device is not immediately active, use * eis_device_add() to notify the client of it's availability. @@ -620,14 +663,29 @@ eis_device_has_capability(struct eis_device *device, * * Before calling eis_device_add(), use the following functions to set up the * device: + * - eis_device_configure_type() * - eis_device_configure_name() * - eis_device_configure_capability() * - eis_device_new_region() * - eis_device_new_keymap() + * + * The device type of the device defaults to @ref EIS_DEVICE_TYPE_VIRTUAL. */ struct eis_device * eis_seat_new_device(struct eis_seat *seat); +/** + * Set the device type for this device. It is recommended that that the device + * type is the first call to configure the device as the device type + * influences which other properties on the device can be set and/or will + * trigger warnings if invoked with wrong arguments. + */ +void +eis_device_configure_type(struct eis_device *device, enum eis_device_type type); + +enum eis_device_type +eis_device_get_type(struct eis_device *device); + void eis_device_configure_name(struct eis_device *device, const char *name); @@ -635,10 +693,29 @@ void eis_device_configure_capability(struct eis_device *device, enum eis_device_capability cap); /** - * Create a new region on the device with an initial refcount of 1. - * Use eis_region_add() to properly add the region to the device. + * Configure the size in mm of a device of type @ref EIS_DEVICE_TYPE_PHYSICAL. + * + * Device with relative-only capabilities does not require a size. A device + * with capability @ref EIS_DEVICE_CAP_POINTER_ABSOLUTE or @ref + * EIS_DEVICE_CAP_TOUCH must have a size. + * + * This function has no effect if called on a device of type other than @ref + * EIS_DEVICE_TYPE_PHYSICAL. + * + * This function has no effect if called after ei_device_add() + */ +void +eis_device_configure_size(struct eis_device *device, uint32_t width, uint32_t height); + +/** + * Create a new region on the device of type @ref EIS_DEVICE_TYPE_VIRTUAL with + * an initial refcount of 1. Use eis_region_add() to properly add the region + * to the device. * * A region **must** have a size to be valid, see eis_region_set_size(). + * + * For a device of type @ref EIS_DEVICE_TYPE_PHYSICAL this function returns + * NULL. */ struct eis_region * eis_device_new_region(struct eis_device *device); @@ -966,28 +1043,28 @@ eis_event_get_device(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_MOTION return the relative x - * movement in logical pixels. + * movement in logical pixels or mm, depending on the device type. */ double eis_event_pointer_get_dx(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_MOTION return the relative y - * movement in logical pixels. + * movement in logical pixels or mm, depending on the device type. */ double eis_event_pointer_get_dy(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_MOTION_ABSOLUTE return the x - * position in logical pixels. + * position in logical pixels or mm, depending on the device type. */ double eis_event_pointer_get_absolute_x(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_MOTION_ABSOLUTE return the y - * position in logical pixels. + * position in logical pixels or mm, depending on the device type. */ double eis_event_pointer_get_absolute_y(struct eis_event *event); @@ -1008,14 +1085,14 @@ eis_event_pointer_get_button_is_press(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_SCROLL return the x scroll - * distance in logical pixels. + * distance in logical pixels or mm, depending on the device type. */ double eis_event_pointer_get_scroll_x(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_SCROLL return the y scroll - * distance in logical pixels. + * distance in logical pixels or mm, depending on the device type. */ double eis_event_pointer_get_scroll_y(struct eis_event *event); @@ -1083,14 +1160,16 @@ eis_event_touch_get_id(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_TOUCH_DOWN, or @ref - * EIS_EVENT_TOUCH_MOTION, return the x coordinate of the touch. + * EIS_EVENT_TOUCH_MOTION, return the x coordinate of the touch + * in logical pixels or mm, depending on the device type. */ double eis_event_touch_get_x(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_TOUCH_DOWN, or @ref - * EIS_EVENT_TOUCH_MOTION, return the y coordinate of the touch. + * EIS_EVENT_TOUCH_MOTION, return the y coordinate of the touch + * in logical pixels or mm, depending on the device type. */ double eis_event_touch_get_y(struct eis_event *event); diff --git a/test/test-ei-device.c b/test/test-ei-device.c index c265c6a..861a1b5 100644 --- a/test/test-ei-device.c +++ b/test/test-ei-device.c @@ -48,6 +48,9 @@ MUNIT_TEST(test_ei_device_basics) struct eis_seat *seat = peck_eis_get_default_seat(peck); _unref_(eis_device) *device = eis_seat_new_device(seat); + /* The default value */ + munit_assert_int(eis_device_get_type(device), ==, EIS_DEVICE_TYPE_VIRTUAL); + eis_device_configure_name(device, "string is freed"); munit_assert_string_equal(eis_device_get_name(device), "string is freed"); @@ -83,6 +86,7 @@ MUNIT_TEST(test_ei_device_basics) struct ei_device *device = ei_event_get_device(event); munit_assert_not_null(device); + munit_assert_int(ei_device_get_type(device), ==, EI_DEVICE_TYPE_VIRTUAL); munit_assert_string_equal(ei_device_get_name(device), __func__); munit_assert_true(ei_device_has_capability(device, EI_DEVICE_CAP_POINTER)); @@ -94,6 +98,48 @@ MUNIT_TEST(test_ei_device_basics) return MUNIT_OK; } +MUNIT_TEST(test_passive_ei_device_type) +{ + _unref_(peck) *peck = peck_new(); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL); + peck_dispatch_until_stable(peck); + + with_server(peck) { + struct eis_seat *seat = peck_eis_get_default_seat(peck); + _unref_(eis_device) *phys = eis_seat_new_device(seat); + + eis_device_configure_type(phys, EIS_DEVICE_TYPE_PHYSICAL); + munit_assert_int(eis_device_get_type(phys), ==, EIS_DEVICE_TYPE_PHYSICAL); + eis_device_add(phys); + + /* noop after add */ + eis_device_configure_type(phys, EIS_DEVICE_TYPE_VIRTUAL); + + _unref_(eis_device) *virt = eis_seat_new_device(seat); + eis_device_configure_type(virt, EIS_DEVICE_TYPE_VIRTUAL); + munit_assert_int(eis_device_get_type(virt), ==, EIS_DEVICE_TYPE_VIRTUAL); + eis_device_add(virt); + + /* noop after add */ + eis_device_configure_type(virt, EIS_DEVICE_TYPE_PHYSICAL); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _unref_(ei_event) *event_phys = peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED); + struct ei_device *phys = ei_event_get_device(event_phys); + munit_assert_int(ei_device_get_type(phys), ==, EI_DEVICE_TYPE_PHYSICAL); + + _unref_(ei_event) *event_virt = peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED); + struct ei_device *virt = ei_event_get_device(event_virt); + munit_assert_int(ei_device_get_type(virt), ==, EI_DEVICE_TYPE_VIRTUAL); + } + + return MUNIT_OK; +} + MUNIT_TEST(test_ei_device_set_name_multiple_devices) { _unref_(peck) *peck = peck_new();