patch-2.4.10 linux/drivers/input/evdev.c
Next file: linux/drivers/input/input.c
Previous file: linux/drivers/input/Config.in
Back to the patch index
Back to the overall index
- Lines: 166
- Date:
Wed Sep 12 15:34:06 2001
- Orig file:
v2.4.9/linux/drivers/input/evdev.c
- Orig date:
Fri Feb 9 11:30:23 2001
diff -u --recursive --new-file v2.4.9/linux/drivers/input/evdev.c linux/drivers/input/evdev.c
@@ -1,7 +1,7 @@
/*
- * $Id: evdev.c,v 1.10 2000/06/23 09:23:00 vojtech Exp $
+ * $Id: evdev.c,v 1.27 2001/05/28 09:06:44 vojtech Exp $
*
- * Copyright (c) 1999-2000 Vojtech Pavlik
+ * Copyright (c) 1999-2001 Vojtech Pavlik
*
* Event char devices, giving access to raw input device events.
*
@@ -11,18 +11,18 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
@@ -72,7 +72,7 @@
list->buffer[list->head].code = code;
list->buffer[list->head].value = value;
list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1);
-
+
kill_fasync(&list->fasync, SIGIO, POLL_IN);
list = list->next;
@@ -104,7 +104,7 @@
if (!--list->evdev->open) {
if (list->evdev->exist) {
- input_close_device(&list->evdev->handle);
+ input_close_device(&list->evdev->handle);
} else {
input_unregister_minor(list->evdev->devfs);
evdev_table[list->evdev->minor] = NULL;
@@ -138,14 +138,26 @@
if (!list->evdev->open++)
if (list->evdev->exist)
- input_open_device(&list->evdev->handle);
+ input_open_device(&list->evdev->handle);
return 0;
}
static ssize_t evdev_write(struct file * file, const char * buffer, size_t count, loff_t *ppos)
{
- return -EINVAL;
+ struct evdev_list *list = file->private_data;
+ struct input_event event;
+ int retval = 0;
+
+ while (retval < count) {
+
+ if (copy_from_user(&event, buffer + retval, sizeof(struct input_event)))
+ return -EFAULT;
+ input_event(list->evdev->handle.dev, event.type, event.code, event.value);
+ retval += sizeof(struct input_event);
+ }
+
+ return retval;
}
static ssize_t evdev_read(struct file * file, char * buffer, size_t count, loff_t *ppos)
@@ -161,6 +173,10 @@
while (list->head == list->tail) {
+ if (!list->evdev->exist) {
+ retval = -ENODEV;
+ break;
+ }
if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
break;
@@ -187,7 +203,7 @@
retval += sizeof(struct input_event);
}
- return retval;
+ return retval;
}
/* No kernel lock - fine */
@@ -219,6 +235,32 @@
if ((retval = put_user(dev->idversion, ((short *) arg) + 3))) return retval;
return 0;
+ case EVIOCSFF:
+ if (dev->upload_effect) {
+ struct ff_effect effect;
+ int err;
+
+ if (copy_from_user((void*)(&effect), (void*)arg, sizeof(effect))) {
+ return -EINVAL;
+ }
+ err = dev->upload_effect(dev, &effect);
+ if (put_user(effect.id, &(((struct ff_effect*)arg)->id))) {
+ return -EINVAL;
+ }
+ return err;
+ }
+ else return -ENOSYS;
+
+ case EVIOCRMFF:
+ if (dev->erase_effect) {
+ return dev->erase_effect(dev, (int)arg);
+ }
+ else return -ENOSYS;
+
+ case EVIOCGEFFECTS:
+ put_user(dev->ff_effects_max, (int*) arg);
+ return 0;
+
default:
if (_IOC_TYPE(cmd) != 'E' || _IOC_DIR(cmd) != _IOC_READ)
@@ -236,6 +278,7 @@
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;
+ case EV_FF: bits = dev->ffbit; len = FF_MAX; break;
default: return -EINVAL;
}
len = NBITS(len) * sizeof(long);
@@ -310,7 +353,7 @@
evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE);
- printk(KERN_INFO "event%d: Event device for input%d\n", minor, dev->number);
+// printk(KERN_INFO "event%d: Event device for input%d\n", minor, dev->number);
return &evdev->handle;
}
@@ -323,13 +366,14 @@
if (evdev->open) {
input_close_device(handle);
+ wake_up_interruptible(&evdev->wait);
} else {
input_unregister_minor(evdev->devfs);
evdev_table[evdev->minor] = NULL;
kfree(evdev);
}
}
-
+
static struct input_handler evdev_handler = {
event: evdev_event,
connect: evdev_connect,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)