Messages in this thread Patch in this message | ![/](/images/icornerl.gif) | | Date | Sat, 14 Jun 2003 22:35:13 +0200 | From | Vojtech Pavlik <> | Subject | [patch] input: Implement device grabbing [1/13] |
| |
Hi!
This is a batch of already very much overdue fixes and needed improvements. The most significant changes are Synaptics pad support (although that code will still develop a bit), and fixes and quirk additions in USB HID driver.
You can pull this changeset from: bk://kernel.bkbits.net/vojtech/input
===================================================================
ChangeSet@1.1215.104.18, 2003-06-09 13:45:46+02:00, warp@mercury.d2dc.net input: Implement input device grabbing so that it is possible to steal an input device from other handlers and have an exclusive access to events.
drivers/input/evdev.c | 37 +++++++++++++++++++++++++++++++++++-- drivers/input/input.c | 27 ++++++++++++++++++++++++--- include/linux/input.h | 7 +++++++ 3 files changed, 66 insertions(+), 5 deletions(-)
===================================================================
diff -Nru a/drivers/input/evdev.c b/drivers/input/evdev.c --- a/drivers/input/evdev.c Sat Jun 14 22:21:24 2003 +++ b/drivers/input/evdev.c Sat Jun 14 22:21:24 2003 @@ -29,6 +29,7 @@ char name[16]; struct input_handle handle; wait_queue_head_t wait; + struct evdev_list *grab; struct list_head list; }; @@ -48,7 +49,8 @@ struct evdev *evdev = handle->private; struct evdev_list *list; - list_for_each_entry(list, &evdev->list, node) { + if (evdev->grab) { + list = evdev->grab; do_gettimeofday(&list->buffer[list->head].time); list->buffer[list->head].type = type; @@ -57,7 +59,17 @@ list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1); kill_fasync(&list->fasync, SIGIO, POLL_IN); - } + } else + list_for_each_entry(list, &evdev->list, node) { + + do_gettimeofday(&list->buffer[list->head].time); + list->buffer[list->head].type = type; + 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); + } wake_up_interruptible(&evdev->wait); } @@ -88,6 +100,11 @@ { struct evdev_list *list = file->private_data; + if (list->evdev->grab == list) { + input_release_device(&list->evdev->handle); + list->evdev->grab = NULL; + } + evdev_fasync(-1, file, 0); list_del(&list->node); @@ -256,6 +273,22 @@ if (put_user(dev->ff_effects_max, (int*) arg)) return -EFAULT; return 0; + + case EVIOCGRAB: + if (arg) { + if (evdev->grab) + return -EBUSY; + if (input_grab_device(&evdev->handle)) + return -EBUSY; + evdev->grab = list; + return 0; + } else { + if (evdev->grab != list) + return -EINVAL; + input_release_device(&evdev->handle); + evdev->grab = NULL; + return 0; + } default: diff -Nru a/drivers/input/input.c b/drivers/input/input.c --- a/drivers/input/input.c Sat Jun 14 22:21:24 2003 +++ b/drivers/input/input.c Sat Jun 14 22:21:24 2003 @@ -33,6 +33,8 @@ EXPORT_SYMBOL(input_unregister_device); EXPORT_SYMBOL(input_register_handler); EXPORT_SYMBOL(input_unregister_handler); +EXPORT_SYMBOL(input_grab_device); +EXPORT_SYMBOL(input_release_device); EXPORT_SYMBOL(input_open_device); EXPORT_SYMBOL(input_close_device); EXPORT_SYMBOL(input_accept_process); @@ -175,9 +177,12 @@ if (type != EV_SYN) dev->sync = 0; - list_for_each_entry(handle, &dev->h_list, d_node) - if (handle->open) - handle->handler->event(handle, type, code, value); + if (dev->grab) + dev->grab->handler->event(dev->grab, type, code, value); + else + list_for_each_entry(handle, &dev->h_list, d_node) + if (handle->open) + handle->handler->event(handle, type, code, value); } static void input_repeat_key(unsigned long data) @@ -201,6 +206,21 @@ return 0; } +int input_grab_device(struct input_handle *handle) +{ + if (handle->dev->grab) + return -EBUSY; + + handle->dev->grab = handle; + return 0; +} + +void input_release_device(struct input_handle *handle) +{ + if (handle->dev->grab == handle) + handle->dev->grab = NULL; +} + int input_open_device(struct input_handle *handle) { if (handle->dev->pm_dev) @@ -221,6 +241,7 @@ void input_close_device(struct input_handle *handle) { + input_release_device(handle); if (handle->dev->pm_dev) pm_dev_idle(handle->dev->pm_dev); if (handle->dev->close) diff -Nru a/include/linux/input.h b/include/linux/input.h --- a/include/linux/input.h Sat Jun 14 22:21:24 2003 +++ b/include/linux/input.h Sat Jun 14 22:21:24 2003 @@ -77,6 +77,8 @@ #define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */ #define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */ +#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */ + /* * Event types */ @@ -798,6 +800,8 @@ int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect); int (*erase_effect)(struct input_dev *dev, int effect_id); + struct input_handle *grab; + struct list_head h_list; struct list_head node; }; @@ -887,6 +891,9 @@ void input_register_handler(struct input_handler *); void input_unregister_handler(struct input_handler *); + +int input_grab_device(struct input_handle *); +void input_release_device(struct input_handle *); int input_open_device(struct input_handle *); void input_close_device(struct input_handle *); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| ![\](/images/icornerr.gif) |