lkml.org 
[lkml]   [2003]   [Jun]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    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/
    \
     
     \ /
      Last update: 2005-03-22 13:36    [from the cache]
    ©2003-2011 Jasper Spaans. Advertise on this site