]> Pileus Git - ~andy/linux/blobdiff - drivers/input/evdev.c
Input: Add EVIOC mechanism for MT slots
[~andy/linux] / drivers / input / evdev.c
index 76457d50bc3493e351c40fbe5b667d1b2e33ff6a..e4cad161be9d832d5baeaabe047024c2dbe4332e 100644 (file)
@@ -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);