From 1cf0c6e69e396538615153056605aaafab11935a Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 6 Feb 2012 08:49:25 +0100 Subject: Input: Add EVIOC mechanism for MT slots This patch adds the ability to extract MT slot data via a new ioctl, EVIOCGMTSLOTS. The function returns an array of slot values for the specified ABS_MT event type. Example of user space usage: struct { unsigned code; int values[64]; } req; req.code = ABS_MT_POSITION_X; if (ioctl(fd, EVIOCGMTSLOTS(sizeof(req)), &req) < 0) return -1; for (i = 0; i < 64; i++) printf("slot %d: %d\n", i, req.values[i]); Reviewed-by: Chase Douglas Signed-off-by: Henrik Rydberg --- drivers/input/evdev.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'drivers/input/evdev.c') diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 76457d50bc34..e4cad161be9d 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include "input-compat.h" @@ -623,6 +623,28 @@ static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) return input_set_keycode(dev, &ke); } +static int evdev_handle_mt_request(struct input_dev *dev, + unsigned int size, + int __user *ip) +{ + const struct input_mt_slot *mt = dev->mt; + unsigned int code; + int max_slots; + int i; + + if (get_user(code, &ip[0])) + return -EFAULT; + if (!input_is_mt_value(code)) + return -EINVAL; + + max_slots = (size - sizeof(__u32)) / sizeof(__s32); + for (i = 0; i < dev->mtsize && i < max_slots; i++) + if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i])) + return -EFAULT; + + return 0; +} + static long evdev_do_ioctl(struct file *file, unsigned int cmd, void __user *p, int compat_mode) { @@ -708,6 +730,9 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, return bits_to_user(dev->propbit, INPUT_PROP_MAX, size, p, compat_mode); + case EVIOCGMTSLOTS(0): + return evdev_handle_mt_request(dev, size, ip); + case EVIOCGKEY(0): return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); -- cgit