On Fri, Mar 27, 2015 at 02:52:15PM -0700, Jason Gerecke wrote:
> Did some practical testing of these patches and noticed two issues with the
> touchstrips:
> 
> On 3/17/2015 11:58 PM, Peter Hutterer wrote:
> >From: Benjamin Tissoires <benjamin.tissoi...@gmail.com>
> >
> >Same approach as evdev-tablet (started as copy/paste), with axis and buttons
> >adjusted. Wacom's handling of pad devices requires a lot of non-obvious
> >handling, e.g. ABS_THROTTLE is the second ring, ABS_RX is the strip, etc.
> >
> >This is not generic buttonset code, if we start supporting other devices for
> >buttonsets we'll factor out a couple of the functions.
> >
> >The wheel and strip events are a bit of a problem: Wacom sends a 0 event on 
> >the
> >axis when the finger is released. We can detect this if there is an ABS_MISC > >0
> >present in the same event and suppress it.  Won't work if any finger is down
> >on any other wheel, strip or button but that's a kernel bug we'll fix once we
> >figure out how.
> >
> >Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@redhat.com>
> >Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
> >---
> >  src/Makefile.am             |   2 +
> >  src/evdev-buttonset-wacom.c | 533 
> > ++++++++++++++++++++++++++++++++++++++++++++
> >  src/evdev-buttonset-wacom.h |  63 ++++++
> >  src/evdev.c                 |  18 +-
> >  src/evdev.h                 |   3 +
> >  src/libinput-private.h      |  16 ++
> >  src/libinput.c              |  65 ++++++
> >  7 files changed, 691 insertions(+), 9 deletions(-)
> >  create mode 100644 src/evdev-buttonset-wacom.c
> >  create mode 100644 src/evdev-buttonset-wacom.h
> >
> >[...]
> >
> >+static inline double
> >+normalize_strip(const struct input_absinfo *absinfo)
> >+{
> >+    /* strip axes don't use a proper value, they just shift the bit left
> >+     * for each position. 0 isn't a real value either, it's only sent on
> >+     * finger release */
> >+    double min = 1,
> 
> Min should be set to 0 (i.e., log2(1)) here.

fixed, thanks.
 
> >+           max = log2(absinfo->maximum);
> >+    double range = max - min;
> >+    double value = (log2(absinfo->value) - min) / range;
> >+
> >+    return value;
> >+}
> >+
> >+/* Detect ring wraparound, current and old are normalized to [0, 1[ */
> >+static inline double
> >+guess_ring_delta(double current, double old)
> >+{
> >+    double d1, d2, d3;
> >+
> >+    d1 = current - old;
> >+    d2 = (current + 1) - old;
> >+    d3 = current - (old + 1);
> >+
> >+    if (fabs(d2) < fabs(d1))
> >+            d1 = d2;
> >+
> >+    if (fabs(d3) < fabs(d1))
> >+            d1 = d3;
> >+
> >+    return d1;
> >+}
> >+
> >+static void
> >+buttonset_check_notify_axes(struct buttonset_dispatch *buttonset,
> >+                        struct evdev_device *device,
> >+                        uint32_t time)
> >+{
> >+    struct libinput_device *base = &device->base;
> >+    bool axis_update_needed = false;
> >+    double deltas[LIBINPUT_BUTTONSET_MAX_NUM_AXES] = {0};
> >+    double deltas_discrete[LIBINPUT_BUTTONSET_MAX_NUM_AXES] = {0};
> >+    unsigned int a;
> >+    unsigned int code;
> >+
> >+    for (a = 0; a <= buttonset->naxes; a++) {
> >+            const struct input_absinfo *absinfo;
> >+
> >+            if (!bit_is_set(buttonset->changed_axes, a))
> >+                    continue;
> >+
> >+            code = buttonset->axis_map[a];
> >+            assert(code != 0);
> >+            absinfo = libevdev_get_abs_info(device->evdev, code);
> >+            assert(absinfo);
> >+
> >+            switch (buttonset->types[a]) {
> >+            case LIBINPUT_BUTTONSET_AXIS_RING:
> >+                    buttonset->axes[a] = normalize_ring(absinfo);
> >+                    deltas[a] = guess_ring_delta(buttonset->axes[a],
> >+                                                 buttonset->axes_prev[a]);
> >+                    deltas_discrete[a] = unnormalize_ring_value(absinfo,
> >+                                                                deltas[a]);
> >+                    break;
> >+            case LIBINPUT_BUTTONSET_AXIS_STRIP:
> >+                    buttonset->axes[a] = normalize_strip(absinfo);
> >+                    deltas[a] = buttonset->axes[a] - 
> >buttonset->axes_prev[a];
> >+                    break;
> 
> When a touch goes up, normalize_strip will return a normalized value of
> negative infinity. You should add suppression logic like for the ABS_MISC
> case since it isn't a real value.

added, thanks.

Cheers,
   Peter

> 
> >+            default:
> >+                    log_bug_libinput(device->base.seat->libinput,
> >+                                     "Invalid axis update: %u\n", a);
> >+                    break;
> >+            }
> >+
> >+            if (buttonset->have_abs_misc_terminator) {
> >+                    /* Suppress the reset to 0 on finger up. See the
> >+                       comment in buttonset_process_absolute */
> >+                    if (libevdev_get_event_value(device->evdev,
> >+                                                 EV_ABS,
> >+                                                 ABS_MISC) == 0) {
> >+                            clear_bit(buttonset->changed_axes, a);
> >+                            buttonset->axes[a] = buttonset->axes_prev[a];
> >+                            continue;
> >+                    /* on finger down, reset the delta to 0 */
> >+                    } else {
> >+                            deltas[a] = 0;
> >+                            deltas_discrete[a] = 0;
> >+                    }
> >+            }
> >+
> >+            axis_update_needed = true;
> >+    }
> >+
> >+    if (axis_update_needed)
> >+            buttonset_notify_axis(base,
> >+                                  time,
> >+                                  LIBINPUT_BUTTONSET_AXIS_SOURCE_UNKNOWN,
> >+                                  buttonset->changed_axes,
> >+                                  buttonset->axes,
> >+                                  deltas,
> >+                                  deltas_discrete);
> >+
> >+    memset(buttonset->changed_axes, 0, sizeof(buttonset->changed_axes));
> >+    memcpy(buttonset->axes_prev,
> >+           buttonset->axes,
> >+           sizeof(buttonset->axes_prev));
> >+    buttonset->have_abs_misc_terminator = false;
> >+}
> >+
> >[...]
> >
> 
> -- 
> Jason
> ---
> Now instead of four in the eights place /
> you’ve got three, ‘Cause you added one /
> (That is to say, eight) to the two, /
> But you can’t take seven from three, /
> So you look at the sixty-fours....
_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to