Re: [PATCH libinput] tablet: handle custom proximity handling

2015-12-03 Thread Peter Hutterer
On Thu, Dec 03, 2015 at 02:37:26PM +0100, Hans de Goede wrote:
> Hi,
> 
> On 03-12-15 00:57, Peter Hutterer wrote:
> >For the puck/lens cursor tool we need to artificially reduce proximity
> >detection. These tools are usually used in a relative mode (i.e. like a 
> >mouse)
> >and thus require lifting and resetting the tool multiple times to move across
> >the screen. The tablets' distance detection goes too far, requiring the user
> >to lift the device several cm on every move. This is uncomfortable.
> >
> >Introduce an artificial distance threshold for the devices with the default
> >value taken from the X.Org wacom driver. If a tool is in proximity but 
> >outside
> >of this range, fake proximity events accordingly.
> >
> >If a button was pressed while we were out of range we discard that event and
> >send it later when we enter proximity again.
> >
> >This is the simple implementation that only takes one proximity out value 
> >(the
> >one from the wacom driver) and applies it to all. Those devices that support 
> >a
> >button/lens tool and have a different default threshold are well out of date.
> >
> >Signed-off-by: Peter Hutterer 
> 
> Patch looks good to me:
> 
> Reviewed-by: Hans de Goede 
> 
> Regards,
> 
> Hans
> 
> p.s.
> 
> I've a (serial!) graphire tablet, and I'm sure there are also quite a few
> usb graphire tablets out there, so we do need to deal with supporting the
> mouse on the graphire tablet eventually.

maybe. I don't doubt that the tablets are still out there and used, I just
thing that there is only a small number of those tablets being used together
with the mouse :)

Cheers,
   Peter

> >---
> >  src/evdev-tablet.c | 103 -
> >  src/evdev-tablet.h |   3 +
> >  test/litest.c  |  18 +
> >  test/litest.h  |   3 +-
> >  test/tablet.c  | 221 
> > +
> >  5 files changed, 346 insertions(+), 2 deletions(-)
> >
> >diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> >index 7e3298c..777ffad 100644
> >--- a/src/evdev-tablet.c
> >+++ b/src/evdev-tablet.c
> >@@ -67,6 +67,22 @@ tablet_get_released_buttons(struct tablet_dispatch 
> >*tablet,
> > ~(state->stylus_buttons[i]);
> >  }
> >
> >+/* Merge the previous state with the current one so all buttons look like
> >+ * they just got pressed in this frame */
> >+static inline void
> >+tablet_force_button_presses(struct tablet_dispatch *tablet)
> >+{
> >+struct button_state *state = &tablet->button_state,
> >+*prev_state = &tablet->prev_button_state;
> >+size_t i;
> >+
> >+for (i = 0; i < sizeof(state->stylus_buttons); i++) {
> >+state->stylus_buttons[i] = state->stylus_buttons[i] |
> >+prev_state->stylus_buttons[i];
> >+prev_state->stylus_buttons[i] = 0;
> >+}
> >+}
> >+
> >  static int
> >  tablet_device_has_axis(struct tablet_dispatch *tablet,
> >enum libinput_tablet_tool_axis axis)
> >@@ -994,6 +1010,62 @@ sanitize_tablet_axes(struct tablet_dispatch *tablet)
> >  }
> >
> >  static void
> >+tablet_update_proximity_state(struct tablet_dispatch *tablet,
> >+  struct evdev_device *device)
> >+{
> >+const struct input_absinfo *distance;
> >+int dist_max = tablet->cursor_proximity_threshold;
> >+int dist;
> >+
> >+distance = libevdev_get_abs_info(tablet->device->evdev, ABS_DISTANCE);
> >+if (!distance)
> >+return;
> >+
> >+dist = distance->value;
> >+if (dist == 0)
> >+return;
> >+
> >+/* Tool got into permitted range */
> >+if (dist < dist_max &&
> >+(tablet_has_status(tablet, TABLET_TOOL_OUT_OF_RANGE) ||
> >+ tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))) {
> >+tablet_unset_status(tablet,
> >+TABLET_TOOL_OUT_OF_RANGE);
> >+tablet_unset_status(tablet,
> >+TABLET_TOOL_OUT_OF_PROXIMITY);
> >+tablet_set_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY);
> >+tablet_mark_all_axes_changed(tablet, device);
> >+
> >+tablet_set_status(tablet, TABLET_BUTTONS_PRESSED);
> >+tablet_force_button_presses(tablet);
> >+return;
> >+}
> >+
> >+if (dist < dist_max)
> >+return;
> >+
> >+/* Still out of range/proximity */
> >+if (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_RANGE) ||
> >+tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))
> >+return;
> >+
> >+/* Tool entered prox but is outside of permitted range */
> >+if (tablet_has_status(tablet,
> >+  TABLET_TOOL_ENTERING_PROXIMITY)) {
> >+tablet_set_status(tablet,
> >+  TABLET_TOOL_OUT_OF_RANGE);
> >+tablet_unset_status(tablet,
> >+TABLET_TOOL_ENTER

Re: [PATCH libinput] tablet: handle custom proximity handling

2015-12-03 Thread Hans de Goede

Hi,

On 03-12-15 00:57, Peter Hutterer wrote:

For the puck/lens cursor tool we need to artificially reduce proximity
detection. These tools are usually used in a relative mode (i.e. like a mouse)
and thus require lifting and resetting the tool multiple times to move across
the screen. The tablets' distance detection goes too far, requiring the user
to lift the device several cm on every move. This is uncomfortable.

Introduce an artificial distance threshold for the devices with the default
value taken from the X.Org wacom driver. If a tool is in proximity but outside
of this range, fake proximity events accordingly.

If a button was pressed while we were out of range we discard that event and
send it later when we enter proximity again.

This is the simple implementation that only takes one proximity out value (the
one from the wacom driver) and applies it to all. Those devices that support a
button/lens tool and have a different default threshold are well out of date.

Signed-off-by: Peter Hutterer 


Patch looks good to me:

Reviewed-by: Hans de Goede 

Regards,

Hans

p.s.

I've a (serial!) graphire tablet, and I'm sure there are also quite a few
usb graphire tablets out there, so we do need to deal with supporting the
mouse on the graphire tablet eventually.




---
  src/evdev-tablet.c | 103 -
  src/evdev-tablet.h |   3 +
  test/litest.c  |  18 +
  test/litest.h  |   3 +-
  test/tablet.c  | 221 +
  5 files changed, 346 insertions(+), 2 deletions(-)

diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 7e3298c..777ffad 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -67,6 +67,22 @@ tablet_get_released_buttons(struct tablet_dispatch *tablet,
~(state->stylus_buttons[i]);
  }

+/* Merge the previous state with the current one so all buttons look like
+ * they just got pressed in this frame */
+static inline void
+tablet_force_button_presses(struct tablet_dispatch *tablet)
+{
+   struct button_state *state = &tablet->button_state,
+   *prev_state = &tablet->prev_button_state;
+   size_t i;
+
+   for (i = 0; i < sizeof(state->stylus_buttons); i++) {
+   state->stylus_buttons[i] = state->stylus_buttons[i] |
+   prev_state->stylus_buttons[i];
+   prev_state->stylus_buttons[i] = 0;
+   }
+}
+
  static int
  tablet_device_has_axis(struct tablet_dispatch *tablet,
   enum libinput_tablet_tool_axis axis)
@@ -994,6 +1010,62 @@ sanitize_tablet_axes(struct tablet_dispatch *tablet)
  }

  static void
+tablet_update_proximity_state(struct tablet_dispatch *tablet,
+ struct evdev_device *device)
+{
+   const struct input_absinfo *distance;
+   int dist_max = tablet->cursor_proximity_threshold;
+   int dist;
+
+   distance = libevdev_get_abs_info(tablet->device->evdev, ABS_DISTANCE);
+   if (!distance)
+   return;
+
+   dist = distance->value;
+   if (dist == 0)
+   return;
+
+   /* Tool got into permitted range */
+   if (dist < dist_max &&
+   (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_RANGE) ||
+tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))) {
+   tablet_unset_status(tablet,
+   TABLET_TOOL_OUT_OF_RANGE);
+   tablet_unset_status(tablet,
+   TABLET_TOOL_OUT_OF_PROXIMITY);
+   tablet_set_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY);
+   tablet_mark_all_axes_changed(tablet, device);
+
+   tablet_set_status(tablet, TABLET_BUTTONS_PRESSED);
+   tablet_force_button_presses(tablet);
+   return;
+   }
+
+   if (dist < dist_max)
+   return;
+
+   /* Still out of range/proximity */
+   if (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_RANGE) ||
+   tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))
+   return;
+
+   /* Tool entered prox but is outside of permitted range */
+   if (tablet_has_status(tablet,
+ TABLET_TOOL_ENTERING_PROXIMITY)) {
+   tablet_set_status(tablet,
+ TABLET_TOOL_OUT_OF_RANGE);
+   tablet_unset_status(tablet,
+   TABLET_TOOL_ENTERING_PROXIMITY);
+   return;
+   }
+
+   /* Tool was in prox and is now outside of range. Set leaving
+* proximity, on the next event it will be OUT_OF_PROXIMITY and thus
+* caught by the above conditions */
+   tablet_set_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
+}
+
+static void
  tablet_flush(struct tablet_dispatch *tablet,
 struct evdev_device *device,
 uint64_t time)
@@ -1004,7 +1076,12 @@ tablet

Re: [PATCH libinput] tablet: handle custom proximity handling

2015-12-02 Thread Bill Spitzak
On Wed, Dec 2, 2015 at 3:57 PM, Peter Hutterer 
wrote:

> For the puck/lens cursor tool we need to artificially reduce proximity
> detection. These tools are usually used in a relative mode (i.e. like a
> mouse)
> and thus require lifting and resetting the tool multiple times to move
> across
> the screen. The tablets' distance detection goes too far, requiring the
> user
> to lift the device several cm on every move. This is uncomfortable.
>
> Introduce an artificial distance threshold for the devices with the default
> value taken from the X.Org wacom driver. If a tool is in proximity but
> outside
> of this range, fake proximity events accordingly.
>
>
You will want something like this for pens and all other tools, as it is
possible to use them in a relative mode (very common if the tablet is
smaller than the screen). I think rather than typing this to the type of
tool, you need to tie it to whether relative motion is being used or not.
Not sure where in libinput or wayland that would be, though.
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH libinput] tablet: handle custom proximity handling

2015-12-02 Thread Peter Hutterer
For the puck/lens cursor tool we need to artificially reduce proximity
detection. These tools are usually used in a relative mode (i.e. like a mouse)
and thus require lifting and resetting the tool multiple times to move across
the screen. The tablets' distance detection goes too far, requiring the user
to lift the device several cm on every move. This is uncomfortable.

Introduce an artificial distance threshold for the devices with the default
value taken from the X.Org wacom driver. If a tool is in proximity but outside
of this range, fake proximity events accordingly.

If a button was pressed while we were out of range we discard that event and
send it later when we enter proximity again.

This is the simple implementation that only takes one proximity out value (the
one from the wacom driver) and applies it to all. Those devices that support a
button/lens tool and have a different default threshold are well out of date.

Signed-off-by: Peter Hutterer 
---
 src/evdev-tablet.c | 103 -
 src/evdev-tablet.h |   3 +
 test/litest.c  |  18 +
 test/litest.h  |   3 +-
 test/tablet.c  | 221 +
 5 files changed, 346 insertions(+), 2 deletions(-)

diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 7e3298c..777ffad 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -67,6 +67,22 @@ tablet_get_released_buttons(struct tablet_dispatch *tablet,
~(state->stylus_buttons[i]);
 }
 
+/* Merge the previous state with the current one so all buttons look like
+ * they just got pressed in this frame */
+static inline void
+tablet_force_button_presses(struct tablet_dispatch *tablet)
+{
+   struct button_state *state = &tablet->button_state,
+   *prev_state = &tablet->prev_button_state;
+   size_t i;
+
+   for (i = 0; i < sizeof(state->stylus_buttons); i++) {
+   state->stylus_buttons[i] = state->stylus_buttons[i] |
+   prev_state->stylus_buttons[i];
+   prev_state->stylus_buttons[i] = 0;
+   }
+}
+
 static int
 tablet_device_has_axis(struct tablet_dispatch *tablet,
   enum libinput_tablet_tool_axis axis)
@@ -994,6 +1010,62 @@ sanitize_tablet_axes(struct tablet_dispatch *tablet)
 }
 
 static void
+tablet_update_proximity_state(struct tablet_dispatch *tablet,
+ struct evdev_device *device)
+{
+   const struct input_absinfo *distance;
+   int dist_max = tablet->cursor_proximity_threshold;
+   int dist;
+
+   distance = libevdev_get_abs_info(tablet->device->evdev, ABS_DISTANCE);
+   if (!distance)
+   return;
+
+   dist = distance->value;
+   if (dist == 0)
+   return;
+
+   /* Tool got into permitted range */
+   if (dist < dist_max &&
+   (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_RANGE) ||
+tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))) {
+   tablet_unset_status(tablet,
+   TABLET_TOOL_OUT_OF_RANGE);
+   tablet_unset_status(tablet,
+   TABLET_TOOL_OUT_OF_PROXIMITY);
+   tablet_set_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY);
+   tablet_mark_all_axes_changed(tablet, device);
+
+   tablet_set_status(tablet, TABLET_BUTTONS_PRESSED);
+   tablet_force_button_presses(tablet);
+   return;
+   }
+
+   if (dist < dist_max)
+   return;
+
+   /* Still out of range/proximity */
+   if (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_RANGE) ||
+   tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))
+   return;
+
+   /* Tool entered prox but is outside of permitted range */
+   if (tablet_has_status(tablet,
+ TABLET_TOOL_ENTERING_PROXIMITY)) {
+   tablet_set_status(tablet,
+ TABLET_TOOL_OUT_OF_RANGE);
+   tablet_unset_status(tablet,
+   TABLET_TOOL_ENTERING_PROXIMITY);
+   return;
+   }
+
+   /* Tool was in prox and is now outside of range. Set leaving
+* proximity, on the next event it will be OUT_OF_PROXIMITY and thus
+* caught by the above conditions */
+   tablet_set_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
+}
+
+static void
 tablet_flush(struct tablet_dispatch *tablet,
 struct evdev_device *device,
 uint64_t time)
@@ -1004,7 +1076,12 @@ tablet_flush(struct tablet_dispatch *tablet,
tablet->current_tool_id,
tablet->current_tool_serial);
 
-   if (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))
+   if (tool->type == LIBINPUT_TABLET_TOOL_TYPE_MOUSE ||
+   tool->type == LIBINPUT_TABL