[PATCH libevdev 2/4] Put a warning in the documentation about disabling/enabling event types/codes

Peter Hutterer peter.hutterer at who-t.net
Mon Apr 25 23:34:53 UTC 2016


On Fri, Apr 22, 2016 at 10:37:14AM +0200, David Herrmann wrote:
> Hi
> 
> On Thu, Apr 21, 2016 at 11:59 PM, Peter Hutterer
> <peter.hutterer at who-t.net> wrote:
> > If a client disables a code halfway through an MT interaction the touch up
> > events are lost. If it re-enables a code it may get weird event sequences.
> > That's something the client has to deal with though because without getting
> > events a client cannot know the current state of a device.
> 
> I always thought we cache the state and discard anything that does not
> involve a state-change? So if a key-down is "not known" to us, a
> following "key up" event is silently discarded? According to your
> comments here, this is not the case, right? Or is this only related to
> ABS slots?
> I should refresh my memory on evdev more often...

no, we do cache the state of the device for EV_KEY, EV_LED, EV_SW and
EV_ABS (and of course mt slots on top of that), mostly so that we can
correctly handle a SYN_DROPPED events and generate the required events. and
libevdev_get_event_value() will return the current state for that code/type.
however, there are a few behaviours that are a result of the implementation:
* we update (and sync) the state even for disabled event *codes*, but we
  don't so so if the *type* is disabled.
* libevdev_next_event() won't return an event if it's disabled.
* libevdev_get_event_value() returns 0 when the type or code is disabled

So there's a weird niche case where you can call
    libevdev_disable_event_code()
    libevdev_next_event()      <- event happens here
    libevdev_get_event_value() <- returns 0
    libevdev_enable_event_code()
    libevdev_get_event_value() <- returns correct value

versus
    libevdev_disable_event_type()
    libevdev_next_event()      <- event happens here
    libevdev_get_event_value() <- returns 0
    libevdev_enable_event_type()
    libevdev_get_event_value() <- returns previously buffered value

That behaviour is admittedly a bit quirky.

Cheers,
   Peter

> > Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> > ---
> >  libevdev/libevdev.h | 22 ++++++++++++++++++++++
> >  1 file changed, 22 insertions(+)
> >
> > diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h
> > index 3edc3ae..856aeb9 100644
> > --- a/libevdev/libevdev.h
> > +++ b/libevdev/libevdev.h
> > @@ -1751,6 +1751,12 @@ void libevdev_set_abs_info(struct libevdev *dev, unsigned int code, const struct
> >   * This is a local modification only affecting only this representation of
> >   * this device.
> >   *
> > + * @note If a caller has previously invoked libevdev_disable_event_code() or
> > + * libevdev_disable_event_type(), re-enabling an event type may cause
> > + * unexpected event sequences. For example, re-enabling an event type while a
> > + * touch is down may cause a touch end to be passed to the caller without a
> > + * preceding touch down event.
> > + *
> >   * @param dev The evdev device, already initialized with libevdev_set_fd()
> >   * @param type The event type to enable (EV_ABS, EV_KEY, ...)
> >   *
> > @@ -1778,6 +1784,11 @@ int libevdev_enable_event_type(struct libevdev *dev, unsigned int type);
> >   * This is a local modification only affecting only this representation of
> >   * this device.
> >   *
> > + * @note This function should only be invoked when the respective event type
> > + * is in a neutral state. Otherwise, a caller may get unexpected event
> > + * sequences. For example, disabling an event type while a touch is down may
> > + * cause the touch end event to be discarded.
> > + *
> >   * @param dev The evdev device, already initialized with libevdev_set_fd()
> >   * @param type The event type to disable (EV_ABS, EV_KEY, ...)
> >   *
> > @@ -1811,6 +1822,12 @@ int libevdev_disable_event_type(struct libevdev *dev, unsigned int type);
> >   * that already has the given event code enabled, the values in data
> >   * overwrite the previous values.
> >   *
> > + * @note If a caller has previously invoked libevdev_disable_event_code() or
> > + * libevdev_disable_event_type(), re-enabling an event code may cause
> > + * unexpected event sequences. For example, re-enabling an event code while a
> > + * touch is down may cause a touch end to be passed to the caller without a
> > + * preceding touch down event.
> > + *
> >   * @param dev The evdev device, already initialized with libevdev_set_fd()
> >   * @param type The event type to enable (EV_ABS, EV_KEY, ...)
> >   * @param code The event code to enable (ABS_X, REL_X, etc.)
> > @@ -1841,6 +1858,11 @@ int libevdev_enable_event_code(struct libevdev *dev, unsigned int type, unsigned
> >   * Disabling codes of type EV_SYN will not work. Don't shoot yourself in the
> >   * foot. It hurts.
> >   *
> > + * @note This function should only be invoked when the respective event type
> > + * is in a neutral state. Otherwise, a caller may get unexpected event
> > + * sequences. For example, disabling an event code while a touch is down may
> > + * cause the touch end event to be discarded.
> > + *
> >   * @param dev The evdev device, already initialized with libevdev_set_fd()
> >   * @param type The event type to disable (EV_ABS, EV_KEY, ...)
> >   * @param code The event code to disable (ABS_X, REL_X, etc.)
> > --
> > 2.7.3
> >
> > _______________________________________________
> > Input-tools mailing list
> > Input-tools at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/input-tools


More information about the Input-tools mailing list