Hi!

This patch adds some needed ioctls to evdev.c, so that userland programs
can read some of the input_dev structures, namely the bitfields. It's
not complete, more ioctls will follow later.

-- 
Vojtech Pavlik
SuSE Labs
diff -urN linux-2.3.99-pre3-old/drivers/usb/evdev.c linux/drivers/usb/evdev.c
--- linux-2.3.99-pre3-old/drivers/usb/evdev.c   Wed Mar 29 13:18:16 2000
+++ linux/drivers/usb/evdev.c   Thu Mar 30 17:35:41 2000
@@ -192,12 +192,59 @@
        return 0;
 }
 
+static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 
+unsigned long arg)
+{
+       struct evdev_list *list = file->private_data;
+       struct evdev *evdev = list->evdev;
+       struct input_dev *dev = evdev->handle.dev;
+
+       switch (cmd) {
+
+               case EVIOCGVERSION:
+                       return put_user(EV_VERSION, (__u32 *) arg);
+               case EVIOCGID:
+                       return copy_to_user(&dev->id, (void *) arg,
+                                               sizeof(struct input_id)) ? -EFAULT : 0;
+               default:
+
+                       if (_IOC_TYPE(cmd) != 'E' || _IOC_DIR(cmd) != _IOC_READ)
+                               return -EINVAL;
+
+                       if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
+
+                               long *bits = NULL;
+                               int len = 0;
+
+                               switch (_IOC_NR(cmd) & EV_MAX) {
+                                       case      0: bits = dev->evbit;  len = EV_MAX; 
+ break;
+                                       case EV_KEY: bits = dev->keybit; len = 
+KEY_MAX; break;
+                                       case EV_REL: bits = dev->relbit; len = 
+REL_MAX; break;
+                                       case EV_ABS: bits = dev->absbit; len = 
+ABS_MAX; break;
+                                       case EV_LED: bits = dev->ledbit; len = 
+LED_MAX; break;
+                                       case EV_SND: bits = dev->sndbit; len = 
+SND_MAX; break;
+                                       default: return -EINVAL;
+                               }
+                               len = NBITS(len) * sizeof(long);
+                               if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+                               return copy_to_user((void *) arg, bits, len) ? -EFAULT 
+: len;
+                       }
+
+                       if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
+                               int len = strlen(dev->name) + 1;
+                               if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+                               return copy_to_user((char *) arg, dev->name, len) ? 
+-EFAULT : len;
+                       }
+       }
+       return -EINVAL;
+}
+
 static struct file_operations evdev_fops = {
        read:           evdev_read,
        write:          evdev_write,
        poll:           evdev_poll,
        open:           evdev_open,
        release:        evdev_release,
+       ioctl:          evdev_ioctl,
        fasync:         evdev_fasync,
 };
 
diff -urN linux-2.3.99-pre3-old/include/linux/input.h linux/include/linux/input.h
--- linux-2.3.99-pre3-old/include/linux/input.h Wed Mar 29 13:18:16 2000
+++ linux/include/linux/input.h Thu Mar 30 17:28:36 2000
@@ -47,6 +47,32 @@
 };
 
 /*
+ * The device ID structure;
+ */
+
+struct input_id {
+       __u16 bus;
+       __u16 vendor;
+       __u16 product;
+};
+
+/*
+ * Protocol version.
+ */
+
+#define EV_VERSION             0x010000
+
+/*
+ * IOCTLs (0x00 - 0x7f)
+ */
+
+#define EVIOCGVERSION          _IOR('E', 0x01, __u32)                  /* get driver 
+version */
+#define EVIOCGID               _IOR('E', 0x02, struct input_id)        /* get device 
+ID */
+#define EVIOCGNAME(len)                _IOC(_IOC_READ, 'E', 0x03, len)         /* get 
+device name */
+#define EVIOCGBIT(ev,len)      _IOC(_IOC_READ, 'E', 0x20 + ev, len)    /* get event 
+bits */
+#define EVIOCGABSLIM(num)      _IOR('E', 0x40 + num, 4 * sizeof(int))  /* get abs 
+event limits */ 
+
+/*
  * Event types
  */
 
@@ -394,6 +420,8 @@
        void *private;
 
        int number;
+       char *name;
+       struct input_id id;
 
        unsigned long evbit[NBITS(EV_MAX)];
        unsigned long keybit[NBITS(KEY_MAX)];

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to