[PATCH v2 libinput] Restore capability events

Jonas Ådahl jadahl at gmail.com
Tue Jan 27 15:57:06 PST 2015


On Wed, Jan 28, 2015 at 09:45:31AM +1000, Peter Hutterer wrote:
> This reverts commit ab9260c5c70b95779f39069b31646ff5cf8970ad, with a bunch of
> changes on top.
> 
> First change is different naming, the events are now DEVICE_CAPABILITY_ADDED
> and DEVICE_CAPABILITY_REMOVED for consistency with the device events.
> 
> The behaviour of capability events is as previously, the event sequence is
> always: DEVICE_ADDED
> 	DEVICE_CAPABILITY_ADDED
> 	DEVICE_CAPABILITY_ADDED
> 	...
> 	DEVICE_CAPABILITY_REMOVED
> 	DEVICE_CAPABILITY_REMOVED
> 	DEVICE_REMOVED
> 
> Disabling a device does not send capablity events, but suspending a libinput
> context does (since it removes the device).
> 
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

Reviewed-by: Jonas Ådahl <jadahl at gmail.com>

> ---
> Changes to v1:
> - rename device_register_capability to device_notify_capability_added, same
>   for removed
> - add/split out evdev_device_notify_capability_removed from
>   evdev_device_suspend (instead of the previous boolean flag)
> - rename evdev_register_device_capabilities to
>   evdev_device_notify_capability_added
> 
>  src/evdev.c            |  36 +++++++++++++
>  src/libinput-private.h |   8 +++
>  src/libinput.c         |  82 ++++++++++++++++++++++++++++++
>  src/libinput.h         |  44 ++++++++++++++++
>  src/libinput.sym       |   3 ++
>  test/keyboard.c        |   3 ++
>  test/litest.c          |   6 +++
>  test/path.c            | 133 +++++++++++++++++++++++++++++++------------------
>  test/pointer.c         |   3 ++
>  test/udev.c            |   8 ++-
>  tools/event-debug.c    |  48 ++++++++++++++----
>  tools/event-gui.c      |   3 ++
>  12 files changed, 317 insertions(+), 60 deletions(-)
> 
> diff --git a/src/evdev.c b/src/evdev.c
> index 24d30e0..f4b7f85 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -1559,6 +1559,23 @@ out:
>  	return rc;
>  }
>  
> +static void
> +evdev_device_notify_capability_added(struct evdev_device *device)
> +{
> +	if (device->seat_caps & EVDEV_DEVICE_POINTER) {
> +		device_notify_capability_added(&device->base,
> +					       LIBINPUT_DEVICE_CAP_POINTER);
> +	}
> +	if (device->seat_caps & EVDEV_DEVICE_KEYBOARD) {
> +		device_notify_capability_added(&device->base,
> +					       LIBINPUT_DEVICE_CAP_KEYBOARD);
> +	}
> +	if (device->seat_caps & EVDEV_DEVICE_TOUCH) {
> +		device_notify_capability_added(&device->base,
> +					       LIBINPUT_DEVICE_CAP_TOUCH);
> +	}
> +}
> +
>  struct evdev_device *
>  evdev_device_create(struct libinput_seat *seat,
>  		    struct udev_device *udev_device)
> @@ -1643,6 +1660,7 @@ evdev_device_create(struct libinput_seat *seat,
>  
>  	evdev_tag_device(device);
>  	evdev_notify_added_device(device);
> +	evdev_device_notify_capability_added(device);
>  
>  	return device;
>  
> @@ -2082,6 +2100,23 @@ evdev_device_resume(struct evdev_device *device)
>  	return 0;
>  }
>  
> +static void
> +evdev_device_notify_capability_removed(struct evdev_device *device)
> +{
> +	if (device->seat_caps & EVDEV_DEVICE_POINTER) {
> +		device_notify_capability_removed(&device->base,
> +						 LIBINPUT_DEVICE_CAP_POINTER);
> +	}
> +	if (device->seat_caps & EVDEV_DEVICE_KEYBOARD) {
> +		device_notify_capability_removed(&device->base,
> +						 LIBINPUT_DEVICE_CAP_KEYBOARD);
> +	}
> +	if (device->seat_caps & EVDEV_DEVICE_TOUCH) {
> +		device_notify_capability_removed(&device->base,
> +						 LIBINPUT_DEVICE_CAP_TOUCH);
> +	}
> +}
> +
>  void
>  evdev_device_remove(struct evdev_device *device)
>  {
> @@ -2096,6 +2131,7 @@ evdev_device_remove(struct evdev_device *device)
>  			d->dispatch->interface->device_removed(d, device);
>  	}
>  
> +	evdev_device_notify_capability_removed(device);
>  	evdev_device_suspend(device);
>  
>  	if (device->dispatch->interface->remove)
> diff --git a/src/libinput-private.h b/src/libinput-private.h
> index b938ed0..b9a877b 100644
> --- a/src/libinput-private.h
> +++ b/src/libinput-private.h
> @@ -259,6 +259,14 @@ void
>  notify_removed_device(struct libinput_device *device);
>  
>  void
> +device_notify_capability_added(struct libinput_device *device,
> +			       enum libinput_device_capability capability);
> +
> +void
> +device_notify_capability_removed(struct libinput_device *device,
> +				 enum libinput_device_capability capability);
> +
> +void
>  keyboard_notify_key(struct libinput_device *device,
>  		    uint64_t time,
>  		    uint32_t key,
> diff --git a/src/libinput.c b/src/libinput.c
> index 951698a..39c4ef6 100644
> --- a/src/libinput.c
> +++ b/src/libinput.c
> @@ -46,6 +46,11 @@ struct libinput_event_device_notify {
>  	struct libinput_event base;
>  };
>  
> +struct libinput_event_device_capability {
> +	struct libinput_event base;
> +	enum libinput_device_capability capability;
> +};
> +
>  struct libinput_event_keyboard {
>  	struct libinput_event base;
>  	uint32_t time;
> @@ -170,6 +175,8 @@ libinput_event_get_pointer_event(struct libinput_event *event)
>  		abort(); /* not used as actual event type */
>  	case LIBINPUT_EVENT_DEVICE_ADDED:
>  	case LIBINPUT_EVENT_DEVICE_REMOVED:
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED:
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED:
>  	case LIBINPUT_EVENT_KEYBOARD_KEY:
>  		break;
>  	case LIBINPUT_EVENT_POINTER_MOTION:
> @@ -196,6 +203,8 @@ libinput_event_get_keyboard_event(struct libinput_event *event)
>  		abort(); /* not used as actual event type */
>  	case LIBINPUT_EVENT_DEVICE_ADDED:
>  	case LIBINPUT_EVENT_DEVICE_REMOVED:
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED:
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED:
>  		break;
>  	case LIBINPUT_EVENT_KEYBOARD_KEY:
>  		return (struct libinput_event_keyboard *) event;
> @@ -222,6 +231,8 @@ libinput_event_get_touch_event(struct libinput_event *event)
>  		abort(); /* not used as actual event type */
>  	case LIBINPUT_EVENT_DEVICE_ADDED:
>  	case LIBINPUT_EVENT_DEVICE_REMOVED:
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED:
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED:
>  	case LIBINPUT_EVENT_KEYBOARD_KEY:
>  	case LIBINPUT_EVENT_POINTER_MOTION:
>  	case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
> @@ -248,6 +259,8 @@ libinput_event_get_device_notify_event(struct libinput_event *event)
>  	case LIBINPUT_EVENT_DEVICE_ADDED:
>  	case LIBINPUT_EVENT_DEVICE_REMOVED:
>  		return (struct libinput_event_device_notify *) event;
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED:
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED:
>  	case LIBINPUT_EVENT_KEYBOARD_KEY:
>  	case LIBINPUT_EVENT_POINTER_MOTION:
>  	case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
> @@ -264,6 +277,41 @@ libinput_event_get_device_notify_event(struct libinput_event *event)
>  	return NULL;
>  }
>  
> +LIBINPUT_EXPORT struct libinput_event_device_capability *
> +libinput_event_get_device_capability_event(struct libinput_event *event)
> +{
> +	switch (event->type) {
> +	case LIBINPUT_EVENT_NONE:
> +		abort(); /* not used as actual event type */
> +	case LIBINPUT_EVENT_DEVICE_ADDED:
> +	case LIBINPUT_EVENT_DEVICE_REMOVED:
> +		break;
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED:
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED:
> +		return (struct libinput_event_device_capability *) event;
> +	case LIBINPUT_EVENT_KEYBOARD_KEY:
> +	case LIBINPUT_EVENT_POINTER_MOTION:
> +	case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
> +	case LIBINPUT_EVENT_POINTER_BUTTON:
> +	case LIBINPUT_EVENT_POINTER_AXIS:
> +	case LIBINPUT_EVENT_TOUCH_DOWN:
> +	case LIBINPUT_EVENT_TOUCH_UP:
> +	case LIBINPUT_EVENT_TOUCH_MOTION:
> +	case LIBINPUT_EVENT_TOUCH_CANCEL:
> +	case LIBINPUT_EVENT_TOUCH_FRAME:
> +		break;
> +	}
> +
> +	return NULL;
> +}
> +
> +LIBINPUT_EXPORT enum libinput_device_capability
> +libinput_event_device_capability_get_capability(
> +	struct libinput_event_device_capability *event)
> +{
> +	return event->capability;
> +}
> +
>  LIBINPUT_EXPORT uint32_t
>  libinput_event_keyboard_get_time(struct libinput_event_keyboard *event)
>  {
> @@ -932,6 +980,40 @@ notify_removed_device(struct libinput_device *device)
>  }
>  
>  void
> +device_notify_capability_added(struct libinput_device *device,
> +			       enum libinput_device_capability capability)
> +{
> +	struct libinput_event_device_capability *capability_event;
> +
> +	capability_event = malloc(sizeof *capability_event);
> +
> +	*capability_event = (struct libinput_event_device_capability) {
> +		.capability = capability,
> +	};
> +
> +	post_base_event(device,
> +			LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED,
> +			&capability_event->base);
> +}
> +
> +void
> +device_notify_capability_removed(struct libinput_device *device,
> +				 enum libinput_device_capability capability)
> +{
> +	struct libinput_event_device_capability *capability_event;
> +
> +	capability_event = malloc(sizeof *capability_event);
> +
> +	*capability_event = (struct libinput_event_device_capability) {
> +		.capability = capability,
> +	};
> +
> +	post_base_event(device,
> +			LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED,
> +			&capability_event->base);
> +}
> +
> +void
>  keyboard_notify_key(struct libinput_device *device,
>  		    uint64_t time,
>  		    uint32_t key,
> diff --git a/src/libinput.h b/src/libinput.h
> index 7b7a2db..50bedc8 100644
> --- a/src/libinput.h
> +++ b/src/libinput.h
> @@ -158,6 +158,9 @@ enum libinput_event_type {
>  	 */
>  	LIBINPUT_EVENT_DEVICE_REMOVED,
>  
> +	LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED = 200,
> +	LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED,
> +
>  	LIBINPUT_EVENT_KEYBOARD_KEY = 300,
>  
>  	LIBINPUT_EVENT_POINTER_MOTION = 400,
> @@ -224,6 +227,15 @@ struct libinput_event;
>  struct libinput_event_device_notify;
>  
>  /**
> + * @ingroup event
> + * @struct libinput_event_device_capability
> + *
> + * An event notifying the caller of a device capability being added or
> + * removed
> + */
> +struct libinput_event_device_capability;
> +
> +/**
>   * @ingroup event_keyboard
>   * @struct libinput_event_keyboard
>   *
> @@ -370,6 +382,38 @@ struct libinput_event *
>  libinput_event_device_notify_get_base_event(struct libinput_event_device_notify *event);
>  
>  /**
> + * @ingroup event
> + *
> + * Return the capability event that is this input event. If the event type
> + * does not match the capability event types, this function returns NULL.
> + *
> + * The inverse of this function is
> + * libinput_event_device_capability_get_base_event().
> + *
> + * @return A capability event, or NULL for other events
> + */
> +struct libinput_event_device_capability *
> +libinput_event_get_device_capability_event(struct libinput_event *event);
> +
> +/**
> + * @ingroup event
> + *
> + * @return The capability registered or unregistered from this device
> + */
> +enum libinput_device_capability
> +libinput_event_device_capability_get_capability(
> +	struct libinput_event_device_capability *event);
> +
> +/**
> + * @ingroup event
> + *
> + * @return The generic libinput_event of this event
> + */
> +struct libinput_event *
> +libinput_event_device_capability_get_base_event(
> +			struct libinput_event_device_capability *event);
> +
> +/**
>   * @defgroup event_keyboard Keyboard events
>   *
>   * Key events are generated when a key changes its logical state, usually by
> diff --git a/src/libinput.sym b/src/libinput.sym
> index 77fccb8..671930e 100644
> --- a/src/libinput.sym
> +++ b/src/libinput.sym
> @@ -121,8 +121,11 @@ local:
>  
>  LIBINPUT_0.9.0 {
>  global:
> +	libinput_event_device_capability_get_capability;
> +	libinput_event_device_capability_get_base_event;
>  	libinput_device_config_click_get_default_method;
>  	libinput_device_config_click_get_method;
>  	libinput_device_config_click_get_methods;
>  	libinput_device_config_click_set_method;
> +	libinput_event_get_device_capability_event;
>  } LIBINPUT_0.8.0;
> diff --git a/test/keyboard.c b/test/keyboard.c
> index 4563ce6..022edd4 100644
> --- a/test/keyboard.c
> +++ b/test/keyboard.c
> @@ -261,6 +261,9 @@ START_TEST(keyboard_key_auto_release)
>  		if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
>  			libinput_event_destroy(event);
>  			break;
> +		} else if (type == LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED) {
> +			libinput_event_destroy(event);
> +			continue;
>  		}
>  
>  		ck_assert_int_eq(type, LIBINPUT_EVENT_KEYBOARD_KEY);
> diff --git a/test/litest.c b/test/litest.c
> index 643c168..92ed4ce 100644
> --- a/test/litest.c
> +++ b/test/litest.c
> @@ -958,6 +958,12 @@ litest_event_type_str(struct libinput_event *event)
>  	case LIBINPUT_EVENT_DEVICE_REMOVED:
>  		str = "REMOVED";
>  		break;
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED:
> +		str = "CAPABILITY ADDED";
> +		break;
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED:
> +		str = "CAPABILITY REMOVED";
> +		break;
>  	case LIBINPUT_EVENT_KEYBOARD_KEY:
>  		str = "KEY";
>  		break;
> diff --git a/test/path.c b/test/path.c
> index 243edd7..1dbae46 100644
> --- a/test/path.c
> +++ b/test/path.c
> @@ -211,6 +211,10 @@ START_TEST(path_seat_change)
>  
>  	libinput_dispatch(li);
>  
> +	litest_drain_typed_events(li,
> +				  LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED,
> +				  -1);
> +
>  	event = libinput_get_event(li);
>  	ck_assert(event != NULL);
>  
> @@ -354,14 +358,14 @@ START_TEST(path_device_sysname)
>  	libinput_dispatch(dev->libinput);
>  
>  	while ((ev = libinput_get_event(dev->libinput))) {
> -		if (libinput_event_get_type(ev) != LIBINPUT_EVENT_DEVICE_ADDED)
> -			continue;
> -
> -		device = libinput_event_get_device(ev);
> -		sysname = libinput_device_get_sysname(device);
> -		ck_assert(sysname != NULL && strlen(sysname) > 1);
> -		ck_assert(strchr(sysname, '/') == NULL);
> -		ck_assert_int_eq(strncmp(sysname, "event", 5), 0);
> +		if (libinput_event_get_type(ev) ==
> +			    LIBINPUT_EVENT_DEVICE_ADDED) {
> +			device = libinput_event_get_device(ev);
> +			sysname = libinput_device_get_sysname(device);
> +			ck_assert(sysname != NULL && strlen(sysname) > 1);
> +			ck_assert(strchr(sysname, '/') == NULL);
> +			ck_assert_int_eq(strncmp(sysname, "event", 5), 0);
> +		}
>  
>  		libinput_event_destroy(ev);
>  	}
> @@ -537,7 +541,7 @@ START_TEST(path_add_device_suspend_resume)
>  	struct libinput_event *event;
>  	struct libevdev_uinput *uinput1, *uinput2;
>  	int rc;
> -	int nevents;
> +	int ndevices;
>  	void *userdata = &rc;
>  
>  	uinput1 = litest_create_uinput_device("test device", NULL,
> @@ -564,44 +568,53 @@ START_TEST(path_add_device_suspend_resume)
>  
>  	libinput_dispatch(li);
>  
> -	nevents = 0;
> +	ndevices = 0;
>  	while ((event = libinput_get_event(li))) {
>  		enum libinput_event_type type;
>  		type = libinput_event_get_type(event);
> -		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
> +		if (type != LIBINPUT_EVENT_DEVICE_ADDED &&
> +		    type != LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED)
> +			ck_assert_msg(type, "Expected device/capability added");
>  		libinput_event_destroy(event);
> -		nevents++;
> +		if (type == LIBINPUT_EVENT_DEVICE_ADDED)
> +			ndevices++;
>  	}
>  
> -	ck_assert_int_eq(nevents, 2);
> +	ck_assert_int_eq(ndevices, 2);
>  
>  	libinput_suspend(li);
>  	libinput_dispatch(li);
>  
> -	nevents = 0;
> +	ndevices = 0;
>  	while ((event = libinput_get_event(li))) {
>  		enum libinput_event_type type;
>  		type = libinput_event_get_type(event);
> -		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED);
> +		if (type != LIBINPUT_EVENT_DEVICE_REMOVED &&
> +		    type != LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED)
> +			ck_assert_msg(type, "Expected device/capability removed");
>  		libinput_event_destroy(event);
> -		nevents++;
> +		if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
> +			ndevices++;
>  	}
>  
> -	ck_assert_int_eq(nevents, 2);
> +	ck_assert_int_eq(ndevices, 2);
>  
>  	libinput_resume(li);
>  	libinput_dispatch(li);
>  
> -	nevents = 0;
> +	ndevices = 0;
>  	while ((event = libinput_get_event(li))) {
>  		enum libinput_event_type type;
>  		type = libinput_event_get_type(event);
> -		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
> +		if (type != LIBINPUT_EVENT_DEVICE_ADDED &&
> +		    type != LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED)
> +			ck_assert_msg(type, "Expected device/capability added");
>  		libinput_event_destroy(event);
> -		nevents++;
> +		if (type == LIBINPUT_EVENT_DEVICE_ADDED)
> +			ndevices++;
>  	}
>  
> -	ck_assert_int_eq(nevents, 2);
> +	ck_assert_int_eq(ndevices, 2);
>  
>  	libevdev_uinput_destroy(uinput1);
>  	libevdev_uinput_destroy(uinput2);
> @@ -619,7 +632,7 @@ START_TEST(path_add_device_suspend_resume_fail)
>  	struct libinput_event *event;
>  	struct libevdev_uinput *uinput1, *uinput2;
>  	int rc;
> -	int nevents;
> +	int ndevices;
>  	void *userdata = &rc;
>  
>  	uinput1 = litest_create_uinput_device("test device", NULL,
> @@ -647,30 +660,36 @@ START_TEST(path_add_device_suspend_resume_fail)
>  
>  	libinput_dispatch(li);
>  
> -	nevents = 0;
> +	ndevices = 0;
>  	while ((event = libinput_get_event(li))) {
>  		enum libinput_event_type type;
>  		type = libinput_event_get_type(event);
> -		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
> +		if (type != LIBINPUT_EVENT_DEVICE_ADDED &&
> +		    type != LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED)
> +			ck_assert_msg(type, "Expected device/capability added");
>  		libinput_event_destroy(event);
> -		nevents++;
> +		if (type == LIBINPUT_EVENT_DEVICE_ADDED)
> +			ndevices++;
>  	}
>  
> -	ck_assert_int_eq(nevents, 2);
> +	ck_assert_int_eq(ndevices, 2);
>  
>  	libinput_suspend(li);
>  	libinput_dispatch(li);
>  
> -	nevents = 0;
> +	ndevices = 0;
>  	while ((event = libinput_get_event(li))) {
>  		enum libinput_event_type type;
>  		type = libinput_event_get_type(event);
> -		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED);
> +		if (type != LIBINPUT_EVENT_DEVICE_REMOVED &&
> +		    type != LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED)
> +			ck_assert_msg(type, "Expected device/capability removed");
>  		libinput_event_destroy(event);
> -		nevents++;
> +		if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
> +			ndevices++;
>  	}
>  
> -	ck_assert_int_eq(nevents, 2);
> +	ck_assert_int_eq(ndevices, 2);
>  
>  	/* now drop one of the devices */
>  	libevdev_uinput_destroy(uinput1);
> @@ -679,20 +698,27 @@ START_TEST(path_add_device_suspend_resume_fail)
>  
>  	libinput_dispatch(li);
>  
> -	nevents = 0;
> +	ndevices = 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)
> +		switch(type) {
> +		case LIBINPUT_EVENT_DEVICE_ADDED:
> +		case LIBINPUT_EVENT_DEVICE_REMOVED:
> +			ndevices++;
> +			break;
> +		case LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED:
> +		case LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED:
> +			break;
> +		default:
>  			ck_abort();
> +		}
>  		libinput_event_destroy(event);
> -		nevents++;
>  	}
>  
> -	ck_assert_int_eq(nevents, 2);
> +	ck_assert_int_eq(ndevices, 2);
>  
>  	libevdev_uinput_destroy(uinput2);
>  	libinput_unref(li);
> @@ -709,7 +735,7 @@ START_TEST(path_add_device_suspend_resume_remove_device)
>  	struct libinput_event *event;
>  	struct libevdev_uinput *uinput1, *uinput2;
>  	int rc;
> -	int nevents;
> +	int ndevices;
>  	void *userdata = &rc;
>  
>  	uinput1 = litest_create_uinput_device("test device", NULL,
> @@ -737,30 +763,36 @@ START_TEST(path_add_device_suspend_resume_remove_device)
>  	libinput_device_ref(device);
>  	libinput_dispatch(li);
>  
> -	nevents = 0;
> +	ndevices = 0;
>  	while ((event = libinput_get_event(li))) {
>  		enum libinput_event_type type;
>  		type = libinput_event_get_type(event);
> -		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
> +		if (type != LIBINPUT_EVENT_DEVICE_ADDED &&
> +		    type != LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED)
> +			ck_assert_msg(type, "Expected device/capability added");
>  		libinput_event_destroy(event);
> -		nevents++;
> +		if (type == LIBINPUT_EVENT_DEVICE_ADDED)
> +			ndevices++;
>  	}
>  
> -	ck_assert_int_eq(nevents, 2);
> +	ck_assert_int_eq(ndevices, 2);
>  
>  	libinput_suspend(li);
>  	libinput_dispatch(li);
>  
> -	nevents = 0;
> +	ndevices = 0;
>  	while ((event = libinput_get_event(li))) {
>  		enum libinput_event_type type;
>  		type = libinput_event_get_type(event);
> -		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED);
> +		if (type != LIBINPUT_EVENT_DEVICE_REMOVED &&
> +		    type != LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED)
> +			ck_assert_msg(type, "Expected device/capability removed");
>  		libinput_event_destroy(event);
> -		nevents++;
> +		if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
> +			ndevices++;
>  	}
>  
> -	ck_assert_int_eq(nevents, 2);
> +	ck_assert_int_eq(ndevices, 2);
>  
>  	/* now drop and remove one of the devices */
>  	libevdev_uinput_destroy(uinput2);
> @@ -772,16 +804,19 @@ START_TEST(path_add_device_suspend_resume_remove_device)
>  
>  	libinput_dispatch(li);
>  
> -	nevents = 0;
> +	ndevices = 0;
>  	while ((event = libinput_get_event(li))) {
>  		enum libinput_event_type type;
>  		type = libinput_event_get_type(event);
> -		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
> +		if (type != LIBINPUT_EVENT_DEVICE_ADDED &&
> +		    type != LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED)
> +			ck_assert_msg(type, "Expected device/capability added");
>  		libinput_event_destroy(event);
> -		nevents++;
> +		if (type == LIBINPUT_EVENT_DEVICE_ADDED)
> +			ndevices++;
>  	}
>  
> -	ck_assert_int_eq(nevents, 1);
> +	ck_assert_int_eq(ndevices, 1);
>  
>  	libevdev_uinput_destroy(uinput1);
>  	libinput_unref(li);
> @@ -889,10 +924,12 @@ main(int argc, char **argv)
>  	litest_add_no_device("path:suspend", path_add_device_suspend_resume);
>  	litest_add_no_device("path:suspend", path_add_device_suspend_resume_fail);
>  	litest_add_no_device("path:suspend", path_add_device_suspend_resume_remove_device);
> +
>  	litest_add_for_device("path:seat", path_added_seat, LITEST_SYNAPTICS_CLICKPAD);
>  	litest_add_for_device("path:seat", path_seat_change, LITEST_SYNAPTICS_CLICKPAD);
>  	litest_add("path:device events", path_added_device, LITEST_ANY, LITEST_ANY);
>  	litest_add("path:device events", path_device_sysname, LITEST_ANY, LITEST_ANY);
> +
>  	litest_add_for_device("path:device events", path_add_device, LITEST_SYNAPTICS_CLICKPAD);
>  	litest_add_no_device("path:device events", path_add_invalid_path);
>  	litest_add_for_device("path:device events", path_remove_device, LITEST_SYNAPTICS_CLICKPAD);
> diff --git a/test/pointer.c b/test/pointer.c
> index 45e0d57..c3dedb2 100644
> --- a/test/pointer.c
> +++ b/test/pointer.c
> @@ -313,6 +313,9 @@ START_TEST(pointer_button_auto_release)
>  		if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
>  			libinput_event_destroy(event);
>  			break;
> +		} else if (type == LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED) {
> +			libinput_event_destroy(event);
> +			continue;
>  		}
>  
>  		ck_assert_int_eq(type, LIBINPUT_EVENT_POINTER_BUTTON);
> diff --git a/test/udev.c b/test/udev.c
> index c351bed..44a12c2 100644
> --- a/test/udev.c
> +++ b/test/udev.c
> @@ -241,6 +241,10 @@ START_TEST(udev_change_seat)
>  
>  	libinput_dispatch(li);
>  
> +	litest_drain_typed_events(li,
> +				  LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED,
> +				  -1);
> +
>  	event = libinput_get_event(li);
>  	ck_assert_int_eq(libinput_event_get_type(event),
>  			 LIBINPUT_EVENT_DEVICE_REMOVED);
> @@ -411,8 +415,10 @@ START_TEST(udev_device_sysname)
>  	libinput_dispatch(li);
>  
>  	while ((ev = libinput_get_event(li))) {
> -		if (libinput_event_get_type(ev) != LIBINPUT_EVENT_DEVICE_ADDED)
> +		if (libinput_event_get_type(ev) != LIBINPUT_EVENT_DEVICE_ADDED) {
> +			libinput_event_destroy(ev);
>  			continue;
> +		}
>  
>  		device = libinput_event_get_device(ev);
>  		sysname = libinput_device_get_sysname(device);
> diff --git a/tools/event-debug.c b/tools/event-debug.c
> index 297e47d..48f7a62 100644
> --- a/tools/event-debug.c
> +++ b/tools/event-debug.c
> @@ -76,6 +76,12 @@ print_event_header(struct libinput_event *ev)
>  	case LIBINPUT_EVENT_DEVICE_REMOVED:
>  		type = "DEVICE_REMOVED";
>  		break;
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED:
> +		type = "CAPABILITY_ADDED";
> +		break;
> +	case LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED:
> +		type = "CAPABILITY_REMOVED";
> +		break;
>  	case LIBINPUT_EVENT_KEYBOARD_KEY:
>  		type = "KEYBOARD_KEY";
>  		break;
> @@ -130,17 +136,6 @@ print_device_notify(struct libinput_event *ev)
>  	       libinput_seat_get_physical_name(seat),
>  	       libinput_seat_get_logical_name(seat));
>  
> -	printf(" cap:");
> -	if (libinput_device_has_capability(dev,
> -					   LIBINPUT_DEVICE_CAP_KEYBOARD))
> -		printf("k");
> -	if (libinput_device_has_capability(dev,
> -					   LIBINPUT_DEVICE_CAP_POINTER))
> -		printf("p");
> -	if (libinput_device_has_capability(dev,
> -					   LIBINPUT_DEVICE_CAP_TOUCH))
> -		printf("t");
> -
>  	if (libinput_device_get_size(dev, &w, &h) == 0)
>  		printf("\tsize %.2f/%.2fmm", w, h);
>  
> @@ -169,6 +164,33 @@ print_device_notify(struct libinput_event *ev)
>  }
>  
>  static void
> +print_device_capability(struct libinput_event *ev)
> +{
> +	struct libinput_event_device_capability *c =
> +		libinput_event_get_device_capability_event(ev);
> +	const char *cap, *mode;
> +
> +	switch (libinput_event_device_capability_get_capability(c)) {
> +	case LIBINPUT_DEVICE_CAP_KEYBOARD:
> +		cap = "keyboard";
> +		break;
> +	case LIBINPUT_DEVICE_CAP_POINTER:
> +		cap = "pointer";
> +		break;
> +	case LIBINPUT_DEVICE_CAP_TOUCH:
> +		cap = "touch";
> +		break;
> +	}
> +
> +	if (libinput_event_get_type(ev) == LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED)
> +		mode = "added";
> +	else
> +		mode = "removed";
> +
> +	printf(" capability %s: %s\n", mode, cap);
> +}
> +
> +static void
>  print_key_event(struct libinput_event *ev)
>  {
>  	struct libinput_event_keyboard *k = libinput_event_get_keyboard_event(ev);
> @@ -285,6 +307,10 @@ handle_and_print_events(struct libinput *li)
>  			tools_device_apply_config(libinput_event_get_device(ev),
>  						  &options);
>  			break;
> +		case LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED:
> +		case LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED:
> +			print_device_capability(ev);
> +			break;
>  		case LIBINPUT_EVENT_KEYBOARD_KEY:
>  			print_key_event(ev);
>  			break;
> diff --git a/tools/event-gui.c b/tools/event-gui.c
> index 70dd854..10a5fa3 100644
> --- a/tools/event-gui.c
> +++ b/tools/event-gui.c
> @@ -443,6 +443,9 @@ handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data)
>  		case LIBINPUT_EVENT_DEVICE_REMOVED:
>  			handle_event_device_notify(ev);
>  			break;
> +		case LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED:
> +		case LIBINPUT_EVENT_DEVICE_CAPABILITY_REMOVED:
> +			break;
>  		case LIBINPUT_EVENT_POINTER_MOTION:
>  			handle_event_motion(ev, w);
>  			break;
> -- 
> 2.1.0
> 


More information about the wayland-devel mailing list