[PATCH libinput 2/8] evdev: Add middle button scrolling for trackpoints

2014-09-16 Thread Hans de Goede
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 
Reviewed-by: Peter Hutterer 
---
 include/linux/input.h|  1 +
 src/evdev.c  | 56 
 src/evdev.h  |  5 +
 test/litest-trackpoint.c |  2 ++
 test/pointer.c   |  4 +++-
 5 files changed, 67 insertions(+), 1 deletion(-)

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_TOPBUTTONPAD0x04/* 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 45020ba..85e4d71 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -41,6 +41,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,
@@ -203,6 +204,15 @@ evdev_flush_pending_event(struct evdev_device *device, 
uint64_t time)
device->rel.dx = 0;
device->rel.dy = 0;
 
+   /* Use unaccelerated deltas for pointing stick scroll */
+   if (device->scroll.has_middle_button_scroll &&
+   hw_is_key_down(device, BTN_MIDDLE)) {
+   if (device->scroll.middle_button_scroll_active)
+   evdev_post_scroll(device, time,
+ motion.dx, motion.dy);
+   break;
+   }
+
/* Apply pointer acceleration. */
filter_dispatch(device->pointer.filter, &motion, device, time);
 
@@ -346,6 +356,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 is_press)
+{
+   if (is_press) {
+   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 quickly enough emit the
+* 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)
 {
@@ -405,6 +446,12 @@ evdev_process_key(struct evdev_device *device,
   LIBINPUT_KEY_STATE_RELEASED);
break;
case EVDEV_KEY_TYPE_BUTTON:
+   if (device->scroll.has_middle_button_scroll &&
+   e->code == BTN_MIDDLE) {
+   evdev_middle_button_scroll_button(device, time,
+ e->value);
+   break;
+   }
evdev_pointer_notify_button(
device,
time,
@@ -946,6 +993,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.has_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 311dddc..e1506d2 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -26,10 +26,12 @@
 
 #include 

Re: [PATCH libinput 2/8] evdev: Add middle button scrolling for trackpoints

2014-09-17 Thread Peter Hutterer
On Tue, Sep 16, 2014 at 04:22:36PM +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 
> Reviewed-by: Peter Hutterer 
> ---
>  include/linux/input.h|  1 +
>  src/evdev.c  | 56 
> 
>  src/evdev.h  |  5 +
>  test/litest-trackpoint.c |  2 ++
>  test/pointer.c   |  4 +++-
>  5 files changed, 67 insertions(+), 1 deletion(-)
> 
> 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_STICK0x05/* 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 45020ba..85e4d71 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -41,6 +41,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,
> @@ -203,6 +204,15 @@ evdev_flush_pending_event(struct evdev_device *device, 
> uint64_t time)
>   device->rel.dx = 0;
>   device->rel.dy = 0;
>  
> + /* Use unaccelerated deltas for pointing stick scroll */
> + if (device->scroll.has_middle_button_scroll &&
> + hw_is_key_down(device, BTN_MIDDLE)) {
> + if (device->scroll.middle_button_scroll_active)
> + evdev_post_scroll(device, time,
> +   motion.dx, motion.dy);
> + break;
> + }
> +

Just to verify: the behaviour here is that the scrolling does not activate
until after the timeout, regardless of the number of motion events during
the timeout period. Is this intentional, or do we need a threshold here?

Cheers,
   Peter


>   /* Apply pointer acceleration. */
>   filter_dispatch(device->pointer.filter, &motion, device, time);
>  
> @@ -346,6 +356,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 is_press)
> +{
> + if (is_press) {
> + 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 quickly enough emit the
> +  * 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)
>  {
> @@ -405,6 +446,12 @@ evdev_process_key(struct evdev_device *device,
>  LIBINPUT_KEY_STATE_RELEASED);
>   break;
>   case EVDEV_KEY_TYPE_BUTTON:
> + if (device->scroll.has_middle_button_scroll &&
> + e->code == BTN_MIDDLE) {
> + evdev_middle_button_scroll_button(device, time,
> +   e->value);
> + break;
> + }
>   evdev_pointer_notify_button(
>   device,
>   time,
> @@ -946,6 +993,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_

Re: [PATCH libinput 2/8] evdev: Add middle button scrolling for trackpoints

2014-09-18 Thread Hans de Goede
Hi,

On 09/18/2014 03:49 AM, Peter Hutterer wrote:
> On Tue, Sep 16, 2014 at 04:22:36PM +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 
>> Reviewed-by: Peter Hutterer 
>> ---
>>  include/linux/input.h|  1 +
>>  src/evdev.c  | 56 
>> 
>>  src/evdev.h  |  5 +
>>  test/litest-trackpoint.c |  2 ++
>>  test/pointer.c   |  4 +++-
>>  5 files changed, 67 insertions(+), 1 deletion(-)
>>
>> 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_BUTTONPAD0x02/* 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 45020ba..85e4d71 100644
>> --- a/src/evdev.c
>> +++ b/src/evdev.c
>> @@ -41,6 +41,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,
>> @@ -203,6 +204,15 @@ evdev_flush_pending_event(struct evdev_device *device, 
>> uint64_t time)
>>  device->rel.dx = 0;
>>  device->rel.dy = 0;
>>  
>> +/* Use unaccelerated deltas for pointing stick scroll */
>> +if (device->scroll.has_middle_button_scroll &&
>> +hw_is_key_down(device, BTN_MIDDLE)) {
>> +if (device->scroll.middle_button_scroll_active)
>> +evdev_post_scroll(device, time,
>> +  motion.dx, motion.dy);
>> +break;
>> +}
>> +
> 
> Just to verify: the behaviour here is that the scrolling does not activate
> until after the timeout, regardless of the number of motion events during
> the timeout period. Is this intentional, or do we need a threshold here?

This behavior is copied from the xf86-input-evdev driver, and so far in
my testing scrolling through web-pages and pdfs I've not noticed the timeout
being an issue. So my vote goes to the KISS approach of keeping this as is.

Regards,

Hans




> 
> Cheers,
>Peter
> 
> 
>>  /* Apply pointer acceleration. */
>>  filter_dispatch(device->pointer.filter, &motion, device, time);
>>  
>> @@ -346,6 +356,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 is_press)
>> +{
>> +if (is_press) {
>> +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 quickly enough emit the
>> + * 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)
>>  {
>> @@ -405,6 +446,12 @@ evdev_process_key(struct evdev_device *device,
>> LIBINPUT_KEY_STATE_RELEASED);
>>  break;
>>  case EVDEV_KEY_TYPE_BUTTON:
>> +if (device->scroll.has_middle_button_scroll &&
>> +e->code == BTN_MIDDLE) {
>> +evdev_middle_button_scroll_button(device, time,
>> +  e->value);
>> +break;
>> +}
>>  evdev_pointer_notify_button(
>>  device,
>>  time,
>> @@ -946,6 +993