diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 12c7ab8..c7e741b 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -29,7 +29,7 @@ struct evdev { char name[16]; struct input_handle handle; wait_queue_head_t wait; - struct evdev_list *grab; + int grab; struct list_head list; }; @@ -37,6 +37,7 @@ struct evdev_list { struct input_event buffer[EVDEV_BUFFER_SIZE]; int head; int tail; + int grab; struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; @@ -49,8 +50,7 @@ static void evdev_event(struct input_han struct evdev *evdev = handle->private; struct evdev_list *list; - if (evdev->grab) { - list = evdev->grab; + list_for_each_entry(list, &evdev->list, node) { do_gettimeofday(&list->buffer[list->head].time); list->buffer[list->head].type = type; @@ -59,17 +59,7 @@ static void evdev_event(struct input_han 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); } @@ -104,9 +94,10 @@ static int evdev_release(struct inode * { struct evdev_list *list = file->private_data; - if (list->evdev->grab == list) { - input_release_device(&list->evdev->handle); - list->evdev->grab = NULL; + if (list->grab) { + if(!--list->evdev->grab && list->evdev->exist) + input_release_device(&list->evdev->handle); + list->grab = 0; } evdev_fasync(-1, file, 0); @@ -483,17 +474,19 @@ static long evdev_ioctl_handler(struct f case EVIOCGRAB: if (p) { - if (evdev->grab) - return -EBUSY; - if (input_grab_device(&evdev->handle)) + if (list->grab) return -EBUSY; - evdev->grab = list; + if (!evdev->grab++) + if (input_grab_device(&evdev->handle)) + return -EBUSY; + list->grab = 0; return 0; } else { - if (evdev->grab != list) + if (!list->grab) return -EINVAL; - input_release_device(&evdev->handle); - evdev->grab = NULL; + if (!--evdev->grab) + input_release_device(&evdev->handle); + list->grab = 0; return 0; } - 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/