[PATCH 3/3] evdev: Add middle buttton scrolling for trackpoints

Peter Hutterer peter.hutterer at who-t.net
Tue Sep 2 20:57:58 PDT 2014


On Tue, Sep 02, 2014 at 04:34:50PM +0200, Hans de Goede wrote:
> Most trackpoint users want to be able to scroll using the trackpoint with
> the middle button pressed, add support for this.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

yes, but I'd like to wait for dmitry to merge the INPUT_PROP_POINTING_STICK
patch before we rely on it.

> ---
>  include/linux/input.h |  1 +
>  src/evdev.c           | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/evdev.h           |  5 +++++
>  3 files changed, 61 insertions(+)
> 
> diff --git a/include/linux/input.h b/include/linux/input.h
> index aa98ce7..39b550b 100644
> --- a/include/linux/input.h
> +++ b/include/linux/input.h
> @@ -163,6 +163,7 @@ struct input_keymap_entry {
>  #define INPUT_PROP_BUTTONPAD		0x02	/* has button(s) under pad */
>  #define INPUT_PROP_SEMI_MT		0x03	/* touch rectangle only */
>  #define INPUT_PROP_TOPBUTTONPAD		0x04	/* softbuttons at top of pad */
> +#define INPUT_PROP_POINTING_STICK	0x05	/* is a pointing stick */
>  
>  #define INPUT_PROP_MAX			0x1f
>  #define INPUT_PROP_CNT			(INPUT_PROP_MAX + 1)
> diff --git a/src/evdev.c b/src/evdev.c
> index b45f7ec..f013362 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -40,6 +40,7 @@
>  #include "libinput-private.h"
>  
>  #define DEFAULT_AXIS_STEP_DISTANCE 10
> +#define DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT 200
>  
>  enum evdev_key_type {
>  	EVDEV_KEY_TYPE_NONE,
> @@ -208,6 +209,14 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
>  		if (motion.dx == 0.0 && motion.dy == 0.0)
>  			break;
>  
> +		if (device->scroll.middle_button_scroll &&
> +		    is_key_down(device, BTN_MIDDLE)) {
> +			if (device->scroll.middle_button_scroll_active)
> +				evdev_post_scroll(device, time,
> +						  motion.dx, motion.dy, 5.0);
> +			break;
> +		}
> +
>  		pointer_notify_motion(base, time, motion.dx, motion.dy);
>  		break;
>  	case EVDEV_ABSOLUTE_MT_DOWN:
> @@ -345,6 +354,37 @@ get_key_type(uint16_t code)
>  }
>  
>  static void
> +evdev_middle_button_scroll_timeout(uint64_t time, void *data)
> +{
> +	struct evdev_device *device = data;
> +
> +	device->scroll.middle_button_scroll_active = true;
> +}
> +
> +static void
> +evdev_middle_button_scroll_button(struct evdev_device *device,
> +				 uint64_t time, int value)
> +{
> +	if (value) {
> +		libinput_timer_set(&device->scroll.timer,
> +				time + DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT);
> +	} else {
> +		libinput_timer_cancel(&device->scroll.timer);
> +		if (device->scroll.middle_button_scroll_active) {
> +			evdev_stop_scroll(device, time);
> +			device->scroll.middle_button_scroll_active = false;
> +		} else {
> +			/* If the button is released early enough emit the

s/early/quickly/

Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
otherwise.

Cheers,
   Peter


> +			 * button press/release events. */
> +			evdev_pointer_notify_button(device, time, BTN_MIDDLE,
> +					LIBINPUT_BUTTON_STATE_PRESSED);
> +			evdev_pointer_notify_button(device, time, BTN_MIDDLE,
> +					LIBINPUT_BUTTON_STATE_RELEASED);
> +		}
> +	}
> +}
> +
> +static void
>  evdev_process_touch_button(struct evdev_device *device,
>  			   uint64_t time, int value)
>  {
> @@ -404,6 +444,12 @@ evdev_process_key(struct evdev_device *device,
>  				   LIBINPUT_KEY_STATE_RELEASED);
>  		break;
>  	case EVDEV_KEY_TYPE_BUTTON:
> +		if (device->scroll.middle_button_scroll &&
> +		    e->code == BTN_MIDDLE) {
> +			evdev_middle_button_scroll_button(device, time,
> +							  e->value);
> +			break;
> +		}
>  		evdev_pointer_notify_button(
>  			device,
>  			time,
> @@ -836,6 +882,15 @@ evdev_configure_device(struct evdev_device *device)
>  			device->mt.slot = active_slot;
>  		}
>  	}
> +
> +	if (libevdev_has_property(evdev, INPUT_PROP_POINTING_STICK)) {
> +		libinput_timer_init(&device->scroll.timer,
> +				    device->base.seat->libinput,
> +				    evdev_middle_button_scroll_timeout,
> +				    device);
> +		device->scroll.middle_button_scroll = true;
> +	}
> +
>  	if (libevdev_has_event_code(evdev, EV_REL, REL_X) ||
>  	    libevdev_has_event_code(evdev, EV_REL, REL_Y))
>  		has_rel = 1;
> diff --git a/src/evdev.h b/src/evdev.h
> index 1cb6bea..2617b7f 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -26,10 +26,12 @@
>  
>  #include "config.h"
>  
> +#include <stdbool.h>
>  #include "linux/input.h"
>  #include <libevdev/libevdev.h>
>  
>  #include "libinput-private.h"
> +#include "timer.h"
>  
>  enum evdev_event_type {
>  	EVDEV_NONE,
> @@ -90,6 +92,9 @@ struct evdev_device {
>  	} rel;
>  
>  	struct {
> +		struct libinput_timer timer;
> +		bool middle_button_scroll;
> +		bool middle_button_scroll_active;
>  		int32_t direction;
>  	} scroll;
>  
> -- 
> 2.1.0


More information about the wayland-devel mailing list