summaryrefslogtreecommitdiffstats
path: root/drivers/input/evdev.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2012-02-06 08:49:25 +0100
committerHenrik Rydberg <rydberg@euromail.se>2012-02-09 09:40:57 +0100
commit1cf0c6e69e396538615153056605aaafab11935a (patch)
treec414962f0047548765778132a3a988d48d7034b5 /drivers/input/evdev.c
parentb89529a10c954f14191367355da2a6053c49abb9 (diff)
downloadlinux-1cf0c6e69e396538615153056605aaafab11935a.tar.bz2
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 <chase.douglas@canonical.com> Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r--drivers/input/evdev.c27
1 files changed, 26 insertions, 1 deletions
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 <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/input.h>
+#include <linux/input/mt.h>
#include <linux/major.h>
#include <linux/device.h>
#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);