From 306f856f67be8eca0a1bae3db9fd70752aae05d4 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 8 Oct 2013 14:21:14 +1000 Subject: [PATCH] Work around missing EVIOCGMTSLOTS ioctl Signed-off-by: Peter Hutterer --- 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; + } 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++) { -- 2.7.4