[PATCH libinput v2 3/5] Add evdev_dispatch interface for lid switch

Peter Hutterer peter.hutterer at who-t.net
Thu Jan 12 03:21:37 UTC 2017


On Tue, Jan 10, 2017 at 12:24:23PM +1100, James Ye wrote:
> Create a lid_switch_interface to handle lid switch events, so the touchpad can
> be disabled when lid is closed.
> 
> Signed-off-by: James Ye <jye836 at gmail.com>
> ---
> Changes since v1:
>  - style and text fixes
> 
>  src/evdev.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  src/evdev.h |  8 ++++++
>  2 files changed, 100 insertions(+), 2 deletions(-)
> 
> diff --git a/src/evdev.c b/src/evdev.c
> index c06daa6..56586af 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -68,6 +68,7 @@ enum evdev_device_udev_tags {
>          EVDEV_UDEV_TAG_TABLET_PAD = (1 << 8),
>          EVDEV_UDEV_TAG_POINTINGSTICK = (1 << 9),
>          EVDEV_UDEV_TAG_TRACKBALL = (1 << 10),
> +        EVDEV_UDEV_TAG_SWITCH = (1 << 11),
>  };
>  
>  struct evdev_udev_tag_match {
> @@ -88,6 +89,7 @@ static const struct evdev_udev_tag_match evdev_udev_tag_matches[] = {
>  	{"ID_INPUT_ACCELEROMETER",	EVDEV_UDEV_TAG_ACCELEROMETER},
>  	{"ID_INPUT_POINTINGSTICK",	EVDEV_UDEV_TAG_POINTINGSTICK},
>  	{"ID_INPUT_TRACKBALL",		EVDEV_UDEV_TAG_TRACKBALL},
> +	{"ID_INPUT_SWITCH",		EVDEV_UDEV_TAG_SWITCH},
>  
>  	/* sentinel value */
>  	{ 0 },
> @@ -1072,6 +1074,13 @@ evdev_tag_keyboard(struct evdev_device *device,
>  }
>  
>  static void
> +evdev_tag_lid_switch(struct evdev_device *device,
> +		     struct udev_device *udev_device)
> +{
> +	device->tags |= EVDEV_TAG_LID_SWITCH;
> +}
> +
> +static void
>  fallback_process(struct evdev_dispatch *evdev_dispatch,
>  		 struct evdev_device *device,
>  		 struct input_event *event,
> @@ -1113,6 +1122,32 @@ fallback_process(struct evdev_dispatch *evdev_dispatch,
>  }
>  
>  static void
> +lid_switch_process(struct evdev_dispatch *evdev_dispatch,
> +		   struct evdev_device *device,
> +		   struct input_event *event,
> +		   uint64_t time)
> +{
> +	struct lid_switch_dispatch *dispatch =
> +		(struct lid_switch_dispatch*)evdev_dispatch;
> +
> +	switch (event->type) {
> +	case EV_SW:
> +		dispatch->lid_is_closed = !!event->value;
> +
> +		switch_notify_toggle(&device->base,
> +				     time,
> +				     LIBINPUT_SWITCH_LID,
> +				     dispatch->lid_is_closed);

doh. not sure how I missed this in the first one, but this needs an extra
check for the event code too, otherwise we'll be sending switch lid events
for any switch on the device.

We filter for SW_LID but if a device happens to have switch and tablet mode
on the same node, then we do the wrong thing here. So I'd say, the easiest
here is have a lid_switch_process_switch() for EV_SW and move that condition
into a switch() statement in there (similar-ish to what the touchpad code
does for example).

I'm also relatively hesitant to merge the tablet mode switch enum value
unless we have an implementation for it. That's easy to remove though.

the rest is good now, thanks.

Cheers,
   Peter

> +		break;
> +	case EV_SYN:
> +		break;
> +	default:
> +		assert(0 && "Unknown event type");
> +		break;
> +	}
> +}
> +
> +static void
>  release_touches(struct fallback_dispatch *dispatch,
>  		struct evdev_device *device,
>  		uint64_t time)
> @@ -1237,6 +1272,15 @@ fallback_destroy(struct evdev_dispatch *evdev_dispatch)
>  	free(dispatch);
>  }
>  
> +static void
> +lid_switch_destroy(struct evdev_dispatch *evdev_dispatch)
> +{
> +	struct lid_switch_dispatch *dispatch =
> +		(struct lid_switch_dispatch*)evdev_dispatch;
> +
> +	free(dispatch);
> +}
> +
>  static int
>  evdev_calibration_has_matrix(struct libinput_device *libinput_device)
>  {
> @@ -1291,6 +1335,19 @@ struct evdev_dispatch_interface fallback_interface = {
>  	fallback_toggle_touch, /* toggle_touch */
>  };
>  
> +struct evdev_dispatch_interface lid_switch_interface = {
> +	lid_switch_process,
> +	NULL, /* suspend */
> +	NULL, /* remove */
> +	lid_switch_destroy,
> +	NULL, /* device_added */
> +	NULL, /* device_removed */
> +	NULL, /* device_suspended */
> +	NULL, /* device_resumed */
> +	NULL, /* post_added */
> +	NULL, /* toggle_touch */
> +};
> +
>  static uint32_t
>  evdev_sendevents_get_modes(struct libinput_device *device)
>  {
> @@ -1800,6 +1857,25 @@ fallback_dispatch_create(struct libinput_device *device)
>  	return &dispatch->base;
>  }
>  
> +static struct evdev_dispatch *
> +lid_switch_dispatch_create(struct libinput_device *device)
> +{
> +	struct lid_switch_dispatch *dispatch = zalloc(sizeof *dispatch);
> +	struct evdev_device *lid_device = (struct evdev_device *)device;
> +
> +	if (dispatch == NULL)
> +		return NULL;
> +
> +	dispatch->base.interface = &lid_switch_interface;
> +
> +	evdev_init_sendevents(lid_device, &dispatch->base);
> +
> +	dispatch->lid_is_closed = false;
> +
> +	return &dispatch->base;
> +}
> +
> +
>  static inline void
>  evdev_process_event(struct evdev_device *device, struct input_event *e)
>  {
> @@ -2508,7 +2584,7 @@ evdev_configure_device(struct evdev_device *device)
>  	}
>  
>  	log_info(libinput,
> -		 "input device '%s', %s is tagged by udev as:%s%s%s%s%s%s%s%s%s%s\n",
> +		 "input device '%s', %s is tagged by udev as:%s%s%s%s%s%s%s%s%s%s%s\n",
>  		 device->devname, devnode,
>  		 udev_tags & EVDEV_UDEV_TAG_KEYBOARD ? " Keyboard" : "",
>  		 udev_tags & EVDEV_UDEV_TAG_MOUSE ? " Mouse" : "",
> @@ -2519,7 +2595,8 @@ evdev_configure_device(struct evdev_device *device)
>  		 udev_tags & EVDEV_UDEV_TAG_JOYSTICK ? " Joystick" : "",
>  		 udev_tags & EVDEV_UDEV_TAG_ACCELEROMETER ? " Accelerometer" : "",
>  		 udev_tags & EVDEV_UDEV_TAG_TABLET_PAD ? " TabletPad" : "",
> -		 udev_tags & EVDEV_UDEV_TAG_TRACKBALL ? " Trackball" : "");
> +		 udev_tags & EVDEV_UDEV_TAG_TRACKBALL ? " Trackball" : "",
> +		 udev_tags & EVDEV_UDEV_TAG_SWITCH ? " Switch" : "");
>  
>  	if (udev_tags & EVDEV_UDEV_TAG_ACCELEROMETER) {
>  		log_info(libinput,
> @@ -2631,6 +2708,17 @@ evdev_configure_device(struct evdev_device *device)
>  			 device->devname, devnode);
>  	}
>  
> +	if (udev_tags & EVDEV_UDEV_TAG_SWITCH &&
> +	    libevdev_has_event_code(evdev, EV_SW, SW_LID)) {
> +		dispatch = lid_switch_dispatch_create(&device->base);
> +		device->seat_caps |= EVDEV_DEVICE_SWITCH;
> +		evdev_tag_lid_switch(device, device->udev_device);
> +		log_info(libinput,
> +			 "input device '%s', %s is a switch device\n",
> +			 device->devname, devnode);
> +		return dispatch;
> +	}
> +
>  	if (device->seat_caps & EVDEV_DEVICE_POINTER &&
>  	    libevdev_has_event_code(evdev, EV_REL, REL_X) &&
>  	    libevdev_has_event_code(evdev, EV_REL, REL_Y) &&
> @@ -3062,6 +3150,8 @@ evdev_device_has_capability(struct evdev_device *device,
>  		return !!(device->seat_caps & EVDEV_DEVICE_TABLET);
>  	case LIBINPUT_DEVICE_CAP_TABLET_PAD:
>  		return !!(device->seat_caps & EVDEV_DEVICE_TABLET_PAD);
> +	case LIBINPUT_DEVICE_CAP_SWITCH:
> +		return !!(device->seat_caps & EVDEV_DEVICE_SWITCH);
>  	default:
>  		return false;
>  	}
> diff --git a/src/evdev.h b/src/evdev.h
> index c07b09f..d65510c 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -63,6 +63,7 @@ enum evdev_device_seat_capability {
>  	EVDEV_DEVICE_TABLET = (1 << 3),
>  	EVDEV_DEVICE_TABLET_PAD = (1 << 4),
>  	EVDEV_DEVICE_GESTURE = (1 << 5),
> +	EVDEV_DEVICE_SWITCH = (1 << 6),
>  };
>  
>  enum evdev_device_tags {
> @@ -71,6 +72,7 @@ enum evdev_device_tags {
>  	EVDEV_TAG_EXTERNAL_TOUCHPAD = (1 << 2),
>  	EVDEV_TAG_TRACKPOINT = (1 << 3),
>  	EVDEV_TAG_KEYBOARD = (1 << 4),
> +	EVDEV_TAG_LID_SWITCH = (1 << 5),
>  };
>  
>  enum evdev_middlebutton_state {
> @@ -332,6 +334,12 @@ struct fallback_dispatch {
>  	bool ignore_events;
>  };
>  
> +struct lid_switch_dispatch {
> +	struct evdev_dispatch base;
> +
> +	bool lid_is_closed;
> +};
> +
>  struct evdev_device *
>  evdev_device_create(struct libinput_seat *seat,
>  		    struct udev_device *device);
> -- 
> 2.9.3
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel
> 


More information about the wayland-devel mailing list