[PATCH 001/001] INPUT: new ioctl's to retrieve values of EV_REP and EV_SND event codes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Bauke Jan Douma <[email protected]>

Add two new ioctl's to have the input driver return actual current values for
EV_REP and EV_SND event codes.

Currently there is no ioctl to retrieve EV_REP values, even though they have
actually always been stored in dev->rep.  A new ioctl, EVIOCGREPCODE, retrieves
them.

The existing EVCGSND ioctl has never returned anything meaningful; the relevant
fragment in input.c was missing even a change_bit() call.
The actual EV_SND values are now written in dev->snd.  To make this work,
dev->snd had to be made an int array, and as a consequence the EVICGSND ioctl
became problematic.  I have removed it in this diff, but --even though it never
has returned anything meaningful-- I'm not quite sure that's the right thing to
do, so I would appreciate feedback on this.
Anyway, an EVIOCGSNDCODE ioctl was added to retrieve these values.

I have named the two ioctl's EVIOCGREPCODE and EVIOCGSNDCODE; I didn't want
to use EVIOCGSND for obvious reasons, and since the ioctl's retrieve the value
of an event _code_, I named them in this way, more or less analogue to
EVIOCGKEYCODE -- after all the input driver works with type, code, value, which
is nicely reflected in the naming and argument.  Feedback appreciated though.

The ioctl's btw. currently work analoguous to EVIOCKEYCODE; they must be given
an int[2] argument, where int[0] is exactly one event code (of the appropriate
event type) of which the value is queried; the value will be returned in int[1].


Signed-off-by: Bauke Jan Douma <[email protected]>

---

Patch is against 2.6.16 proper.


diff -uprN a/drivers/input/evdev.c b/drivers/input/evdev.c
--- ./linux/drivers/input/evdev.c.orig	2006-03-22 23:34:42.000000000 +0100
+++ ./linux/drivers/input/evdev.c	2006-04-22 21:31:43.000000000 +0200
@@ -407,6 +407,24 @@ static long evdev_ioctl_handler(struct f
 
 			return 0;
 
+		case EVIOCGREPCODE:
+			if (get_user(t, ip))
+				return -EFAULT;
+			if (t < 0 || t >= REP_MAX + 1)
+				return -EINVAL;
+			if (put_user(dev->rep[t], ip + 1))
+				return -EFAULT;
+			return 0;
+
+		case EVIOCGSNDCODE:
+			if (get_user(t, ip))
+				return -EFAULT;
+			if (t < 0 || t >= SND_MAX + 1)
+				return -EINVAL;
+			if (put_user(dev->snd[t], ip + 1))
+				return -EFAULT;
+			return 0;
+
 		case EVIOCGKEYCODE:
 			if (get_user(t, ip))
 				return -EFAULT;
@@ -513,10 +531,6 @@ static long evdev_ioctl_handler(struct f
 					return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd),
 							    p, compat_mode);
 
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
-					return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd),
-							    p, compat_mode);
-
 				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
 					return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd),
 							    p, compat_mode);
diff -uprN a/drivers/input/input.c b/drivers/input/input.c
--- ./linux/drivers/input/input.c.orig	2006-03-22 23:34:42.000000000 +0100
+++ ./linux/drivers/input/input.c	2006-04-22 21:31:43.000000000 +0200
@@ -153,6 +153,7 @@ void input_event(struct input_dev *dev, 
 			if (code > SND_MAX || !test_bit(code, dev->sndbit))
 				return;
 
+			dev->snd[code] = value;
 			if (dev->event) dev->event(dev, type, code, value);
 
 			break;
diff -uprN a/include/linux/input.h b/include/linux/input.h
--- ./linux/include/linux/input.h.orig	2006-03-22 23:34:50.000000000 +0100
+++ ./linux/include/linux/input.h	2006-04-22 21:31:43.000000000 +0200
@@ -59,6 +59,8 @@ struct input_absinfo {
 #define EVIOCGVERSION		_IOR('E', 0x01, int)			/* get driver version */
 #define EVIOCGID		_IOR('E', 0x02, struct input_id)	/* get device ID */
 #define EVIOCGKEYCODE		_IOR('E', 0x04, int[2])			/* get keycode */
+#define EVIOCGREPCODE		_IOR('E', 0x10, int[2])			/* get an EV_REP setting */
+#define EVIOCGSNDCODE		_IOR('E', 0x11, int[2])			/* get an EV_SND setting */
 #define EVIOCSKEYCODE		_IOW('E', 0x04, int[2])			/* set keycode */
 
 #define EVIOCGNAME(len)		_IOC(_IOC_READ, 'E', 0x06, len)		/* get device name */
@@ -67,7 +69,6 @@ struct input_absinfo {
 
 #define EVIOCGKEY(len)		_IOC(_IOC_READ, 'E', 0x18, len)		/* get global keystate */
 #define EVIOCGLED(len)		_IOC(_IOC_READ, 'E', 0x19, len)		/* get all LEDs */
-#define EVIOCGSND(len)		_IOC(_IOC_READ, 'E', 0x1a, len)		/* get all sounds status */
 #define EVIOCGSW(len)		_IOC(_IOC_READ, 'E', 0x1b, len)		/* get all switch states */
 
 #define EVIOCGBIT(ev,len)	_IOC(_IOC_READ, 'E', 0x20 + ev, len)	/* get event bits */
@@ -908,10 +909,10 @@ struct input_dev {
 
 	int abs[ABS_MAX + 1];
 	int rep[REP_MAX + 1];
+	int snd[SND_MAX + 1];
 
 	unsigned long key[NBITS(KEY_MAX)];
 	unsigned long led[NBITS(LED_MAX)];
-	unsigned long snd[NBITS(SND_MAX)];
 	unsigned long sw[NBITS(SW_MAX)];
 
 	int absmax[ABS_MAX + 1];
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux