[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