[PATCH libinput 2/4] evdev: Keep track of button/key press count per device

Peter Hutterer peter.hutterer at who-t.net
Sun Aug 3 22:15:28 PDT 2014


On Sun, Jul 27, 2014 at 11:28:29PM +0200, Jonas Ådahl wrote:
> Keep track of the number of times a given button or key is pressed on a
> device. For regular mouse devices or keyboard devices, such a count will
> never exceed 1, but counting button presses could help when button
> presses with the same code can originate from different sources. One could
> for example implement overlapping tap-drags with button presses by
> having them deal with their own life-time independently, sorting out
> when the user should receive button presses or not depending on the
> pressed count.
> 
> Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
> ---
>  src/evdev-mt-touchpad-buttons.c | 30 +++++++++++++------------
>  src/evdev-mt-touchpad-tap.c     |  8 +++----
>  src/evdev.c                     | 49 +++++++++++++++++++++++++++++++++++++----
>  src/evdev.h                     | 13 +++++++++++
>  4 files changed, 78 insertions(+), 22 deletions(-)
> 
> diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
> index fe33d0b..8a28054 100644
> --- a/src/evdev-mt-touchpad-buttons.c
> +++ b/src/evdev-mt-touchpad-buttons.c
> @@ -606,11 +606,12 @@ tp_post_clickfinger_buttons(struct tp_dispatch *tp, uint64_t time)
>  		state = LIBINPUT_BUTTON_STATE_RELEASED;
>  	}
>  
> -	if (button)
> -		pointer_notify_button(&tp->device->base,
> -				      time,
> -				      button,
> -				      state);
> +	if (button) {
> +		evdev_pointer_notify_button(tp->device,
> +					    time,
> +					    button,
> +					    state);
> +	}
>  	return 1;
>  }
>  
> @@ -632,10 +633,10 @@ tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
>  			else
>  				state = LIBINPUT_BUTTON_STATE_RELEASED;
>  
> -			pointer_notify_button(&tp->device->base,
> -					      time,
> -					      button,
> -					      state);
> +			evdev_pointer_notify_button(tp->device,
> +						    time,
> +						    button,
> +						    state);
>  		}
>  
>  		button++;
> @@ -707,11 +708,12 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
>  
>  	tp->buttons.click_pending = false;
>  
> -	if (button)
> -		pointer_notify_button(&tp->device->base,
> -				      time,
> -				      button,
> -				      state);
> +	if (button) {
> +		evdev_pointer_notify_button(tp->device,
> +					    time,
> +					    button,
> +					    state);
> +	}
>  	return 1;
>  }
>  
> diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
> index 6008507..64801a8 100644
> --- a/src/evdev-mt-touchpad-tap.c
> +++ b/src/evdev-mt-touchpad-tap.c
> @@ -113,10 +113,10 @@ tp_tap_notify(struct tp_dispatch *tp,
>  		return;
>  	}
>  
> -	pointer_notify_button(&tp->device->base,
> -			      time,
> -			      button,
> -			      state);
> +	evdev_pointer_notify_button(tp->device,
> +				    time,
> +				    button,
> +				    state);
>  }
>  
>  static void
> diff --git a/src/evdev.c b/src/evdev.c
> index 0f4874c..f656a5e 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -59,6 +59,47 @@ is_key_pressed(struct evdev_device *device, int code)
>  	return long_bit_is_set(device->key_mask, code);
>  }
>  
> +static int
> +update_key_pressed_count(struct evdev_device *device, int code, int pressed)

see my "pressed" vs "down" comment in the previous email, update if you
updated the other one

> +{
> +	assert(code >= 0 && code < KEY_CNT);
> +
> +	if (pressed) {
> +		return ++device->key_count[code];

want to add checks for == 255? or tbh, a log_bug for something like 32 or 64
seems a sensible thing to do too.

> +	} else {
> +		assert(device->key_count[code] > 0);
> +		return --device->key_count[code];
> +	}
> +}
> +
> +void
> +evdev_keyboard_notify_key(struct evdev_device *device,
> +			  uint32_t time,
> +			  int key,
> +			  enum libinput_key_state state)
> +{
> +	int pressed_count;
> +
> +	pressed_count = update_key_pressed_count(device, key, state);
> +
> +	if ((state && pressed_count == 1) || (!state && pressed_count == 0))

please use the enum symbolic names LIBINPUT_KEY_STATE_PRESSED etc. for the
states.

> +		keyboard_notify_key(&device->base, time, key, state);
> +}
> +
> +void
> +evdev_pointer_notify_button(struct evdev_device *device,
> +			    uint32_t time,
> +			    int button,
> +			    enum libinput_button_state state)
> +{
> +	int pressed_count;
> +
> +	pressed_count = update_key_pressed_count(device, button, state);
> +
> +	if ((state && pressed_count == 1) || (!state && pressed_count == 0))
> +		pointer_notify_button(&device->base, time, button, state);

here too, with that Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

Cheers,
   Peter

> +}
> +
>  void
>  evdev_device_led_update(struct evdev_device *device, enum libinput_led leds)
>  {
> @@ -341,16 +382,16 @@ evdev_process_key(struct evdev_device *device,
>  	case EVDEV_KEY_TYPE_NONE:
>  		break;
>  	case EVDEV_KEY_TYPE_KEY:
> -		keyboard_notify_key(
> -			&device->base,
> +		evdev_keyboard_notify_key(
> +			device,
>  			time,
>  			e->code,
>  			e->value ? LIBINPUT_KEY_STATE_PRESSED :
>  				   LIBINPUT_KEY_STATE_RELEASED);
>  		break;
>  	case EVDEV_KEY_TYPE_BUTTON:
> -		pointer_notify_button(
> -			&device->base,
> +		evdev_pointer_notify_button(
> +			device,
>  			time,
>  			e->code,
>  			e->value ? LIBINPUT_BUTTON_STATE_PRESSED :
> diff --git a/src/evdev.h b/src/evdev.h
> index f71d387..1819ae8 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -96,6 +96,7 @@ struct evdev_device {
>  	} pointer;
>  
>  	unsigned long key_mask[NLONGS(KEY_CNT)];
> +	uint8_t key_count[KEY_CNT];
>  };
>  
>  #define EVDEV_UNHANDLED_DEVICE ((struct evdev_device *) 1)
> @@ -175,6 +176,18 @@ evdev_device_transform_y(struct evdev_device *device,
>  			 uint32_t height);
>  
>  void
> +evdev_keyboard_notify_key(struct evdev_device *device,
> +			  uint32_t time,
> +			  int key,
> +			  enum libinput_key_state state);
> +
> +void
> +evdev_pointer_notify_button(struct evdev_device *device,
> +			    uint32_t time,
> +			    int button,
> +			    enum libinput_button_state state);
> +
> +void
>  evdev_device_remove(struct evdev_device *device);
>  
>  void
> -- 
> 1.8.5.1
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> 


More information about the wayland-devel mailing list