[PATCH libevdev 6/8] Work around missing EVIOCGMTSLOTS ioctl

Peter Hutterer peter.hutterer at who-t.net
Mon Oct 21 03:28:51 PDT 2013


On Mon, Oct 21, 2013 at 10:48:27AM +0200, David Herrmann wrote:
> Hi
> 
> On Mon, Oct 14, 2013 at 8:14 AM, Peter Hutterer
> <peter.hutterer at who-t.net> wrote:
> > Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> > ---
> >  libevdev/libevdev.c | 14 ++++++++++++--
> >  1 file changed, 12 insertions(+), 2 deletions(-)
> >
> > diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c
> > index 29640f4..6f203e2 100644
> > --- a/libevdev/libevdev.c
> > +++ b/libevdev/libevdev.c
> > @@ -498,11 +498,14 @@ sync_mt_state(struct libevdev *dev, int create_events)
> >  {
> >         int rc;
> >         int i;
> > +       int ioctl_success = 0;
> >         struct mt_state {
> >                 int code;
> >                 int val[MAX_SLOTS];
> >         } mt_state[ABS_MT_CNT];
> >
> > +       memset(&mt_state, 0, sizeof(mt_state));
> > +
> >         for (i = ABS_MT_MIN; i <= ABS_MT_MAX; i++) {
> >                 int idx;
> >                 if (i == ABS_MT_SLOT)
> > @@ -514,8 +517,15 @@ sync_mt_state(struct libevdev *dev, int create_events)
> >                 idx = i - ABS_MT_MIN;
> >                 mt_state[idx].code = i;
> >                 rc = ioctl(dev->fd, EVIOCGMTSLOTS(sizeof(struct mt_state)), &mt_state[idx]);
> > -               if (rc < 0)
> > -                       goto out;
> > +               if (rc < 0) {
> > +                       /* if the first ioctl fails with -EINVAL, chances are the kernel
> > +                          doesn't support the ioctl. Simply continue */
> > +                       if (errno == -EINVAL && !ioctl_success) {
> > +                               rc = 0;
> 
> Why not check whether dev->num_slots is 0? Or isn't this guaranteed?
> If it's not, you need to clear mt_state here.

yeah, that's a separate issue that Benjamin brought up but I haven't been
able to fix yet: there are some devices that simply have all bits set.
for those, we need to unset num_slots to avoid issues, especially when this
ioctl is missing.

the code will be something like this:
if (has_bit(ABS_MT_SLOT - 1)) /* undefined by the kernel */
   set num_slots to 0, disable MT

it's a corner case, but needed. And once it's in, checking for num-slots and
ABS_MT_SLOT - 1 is likely more confusing to read than the ioctl guard above.

Cheers,
   Peter
> 
> > +                       } else /* if the second, ... ioctl fails, really fail */
> > +                               goto out;
> > +               } else if (ioctl_success == 0)
> > +                       ioctl_success = 1;
> >         }
> >
> >         for (i = 0; i < dev->num_slots; i++) {
> > --
> > 1.8.3.1
> >
> > _______________________________________________
> > Input-tools mailing list
> > Input-tools at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/input-tools


More information about the Input-tools mailing list