On Tuesday 15 August 2006 00:49, Magnus Vigerlöf wrote:
[...]
> However, this doesn't address the problem I initially described (I
> think)... What if two application open the same device and one of the
> application do a EVIOCGRAB. Should both applications still get events? With
> the above fix two applications that opens /dev/input/mouse2 resp
> /dev/input/event4 for the same hw and the latter grabs the device, both
> will get events. Using a counter for grab (just like the open-counter) on
> the handler should make them behave the same way in both cases I think.
> Gnnn... I'll make a patch tomorrow (ok today, Tuesday) so you can see what
> I rambling about..
Ok, this is what I mean (in code) if anyone's interested.. It should apply cleanly
on Dmitrys git-tree. It seems to work on my system without any side-effects
regarding the keyboard and Wacom tablet.
/Magnus
---
drivers/input/evdev.c | 41 +++++++++++++++++------------------------
1 files changed, 17 insertions(+), 24 deletions(-)
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 [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]