2006-08-12 15:24:20

by Magnus Vigerlöf

[permalink] [raw]
Subject: input: evdev.c EVIOCGRAB semantics question

Hi,

What is the purpose of the EVIOCGRAB ioctl in evdev.c? Is it to prevent the
device driver from sending events to other event handlers? Is it to prevent
other applications from receiving events that has the device handler open?
First, last, or both?

I discovered the following behavior when I fired up a second X-server on my
machine with my Wacom tablet connected: The second X-server opened the tablet
as well and everything worked as it should. However when I switched back to
the first X-server the tablet didn't work at all. Only when I stopped the
second X-server did the tablet start working in the first X-server again. If
I changed the code in evdev to ignore the EVIOCGRAB-ioctl the tablet works in
both X-servers, but that caused other problems.

Now, having two X-servers might not be the most common thing to have, but
having other applications that depends on the movement from the tablet might
be more common.

As is it now, it's useless (more or less) to run wacdump to display the tablet
specific events in a understandable manner. An application that generates
events through uinput based on tablet events and some other qualifiers
(mouseemu, simulating mouse scroll wheel) will not work either.

And yes, the X-server must grab the tablet. Otherwise events will go
through /dev/input/mice as well and mess up applications that depend on the
tablet-specific absolute events.

Thanks
Magnus


Subject: Re: input: evdev.c EVIOCGRAB semantics question

On Sat, Aug 12, 2006 at 05:24:16PM +0200, Magnus Vigerl?f wrote:
> Hi,
>
> What is the purpose of the EVIOCGRAB ioctl in evdev.c? Is it to prevent the
> device driver from sending events to other event handlers? Is it to prevent
> other applications from receiving events that has the device handler open?
> First, last, or both?

As things stand, both.
>
> I discovered the following behavior when I fired up a second X-server on my
> machine with my Wacom tablet connected: The second X-server opened the tablet
> as well and everything worked as it should. However when I switched back to
> the first X-server the tablet didn't work at all. Only when I stopped the
> second X-server did the tablet start working in the first X-server again. If
> I changed the code in evdev to ignore the EVIOCGRAB-ioctl the tablet works in
> both X-servers, but that caused other problems.

That is, unusual. Unless each X server has it's own display, then when
switching VCs away from an X server the driver should be turned off, and
the device ungrabbed and possibly closed, at which point the other
should be able to open and grab the device.

The wacom X driver may not be handling that properly though, annoying.
>
> Now, having two X-servers might not be the most common thing to have, but
> having other applications that depends on the movement from the tablet might
> be more common.
>
> As is it now, it's useless (more or less) to run wacdump to display the tablet
> specific events in a understandable manner. An application that generates
> events through uinput based on tablet events and some other qualifiers
> (mouseemu, simulating mouse scroll wheel) will not work either.

That one has been mentioned a few times, but rarely complained about
loudly.

When I drew up the first evdev grab patches I made a masking patch
shortly later which helped divide things, however that never made it
into code and that leaves us here.
>
> And yes, the X-server must grab the tablet. Otherwise events will go
> through /dev/input/mice as well and mess up applications that depend on the
> tablet-specific absolute events.

This is close to the original reason for grabbing, specificly that there
was no safe way to use evdev for the keyboard at all without it.


I can dust off the masking patch sometime here if Dmitry thinks that
he'd be willing to see a second method for this in addition to grabbing,
adding support to xf86-input-evdev would be trivial, and the same could
probably be said for the wacom driver that does grabbing at the moment.

Regards.
Zephaniah E. Hull.
(Original author of the evdev grab patch and xf86-input-evdev
maintainer, among other things.)

--
1024D/E65A7801 Zephaniah E. Hull <[email protected]>
92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801
CCs of replies from mailing lists are requested.

>OK, fine. You're arguing semantics, though.

"arguing semantics" is not the same as "arguing nomenclature". My DI
was very good at arguing semantics. He had this funny idea that an
"unloaded" weapon was one that you had personally inspected and that
the semantic difference mattered. Something about not wanting to do
the paperwork of one of us killed someone with an unloaded weapon.
Most technical debates are ultimately about semantics, but that
doesn't mean that they are unimportant.
-- Shmuel Metz and Steve Sobol on ASR.


Attachments:
(No filename) (3.31 kB)
signature.asc (189.00 B)
Digital signature
Download all attachments

2006-08-12 21:08:06

by Magnus Vigerlöf

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

On Saturday 12 August 2006 18:52, Zephaniah E. Hull wrote:
> On Sat, Aug 12, 2006 at 05:24:16PM +0200, Magnus Vigerl?f wrote:
> > Hi,
> >
> > What is the purpose of the EVIOCGRAB ioctl in evdev.c? Is it to prevent
> > the device driver from sending events to other event handlers? Is it to
> > prevent other applications from receiving events that has the device
> > handler open? First, last, or both?
>
> As things stand, both.

Ok, Wacom tablets needs the first one. But no harm appears to be done if the
second one is skipped. What that means for other kinds of devices, I don't
know.

> > I discovered the following behavior when I fired up a second X-server on
> > my machine with my Wacom tablet connected: The second X-server opened the
> > tablet as well and everything worked as it should. However when I
> > switched back to the first X-server the tablet didn't work at all. Only
> > when I stopped the second X-server did the tablet start working in the
> > first X-server again. If I changed the code in evdev to ignore the
> > EVIOCGRAB-ioctl the tablet works in both X-servers, but that caused other
> > problems.
>
> That is, unusual. Unless each X server has it's own display, then when
> switching VCs away from an X server the driver should be turned off, and
> the device ungrabbed and possibly closed, at which point the other
> should be able to open and grab the device.
>
> The wacom X driver may not be handling that properly though, annoying.

Well, with only one X-server running I'd say it looks all right, but when I
start two things starts to get strange. Don't know what happends really. But
that was how I saw this, and...

> > Now, having two X-servers might not be the most common thing to have, but
> > having other applications that depends on the movement from the tablet
> > might be more common.

...this is a bigger problem when apps need the data directly from the
event?-device and not from the XInput-device.

A mail was sent to the linuxwacom list where a guy tried to use mouseemu to
emulate the scroll button of a mouse with the stylus and a keyboard
qualifier. Nice idea and I would probably use if it works, however since the
X-server grabs the device no event will ever be sent so this could work.
Pity.

> > As is it now, it's useless (more or less) to run wacdump to display the
> > tablet specific events in a understandable manner. An application that
> > generates events through uinput based on tablet events and some other
> > qualifiers (mouseemu, simulating mouse scroll wheel) will not work
> > either.
>
> That one has been mentioned a few times, but rarely complained about
> loudly.
>
> When I drew up the first evdev grab patches I made a masking patch
> shortly later which helped divide things, however that never made it
> into code and that leaves us here.
>
> > And yes, the X-server must grab the tablet. Otherwise events will go
> > through /dev/input/mice as well and mess up applications that depend on
> > the tablet-specific absolute events.
>
> This is close to the original reason for grabbing, specificly that there
> was no safe way to use evdev for the keyboard at all without it.

Does safe in this case mean 'noone will be able to see what I'm typing', or is
the reason the same as for the Wacom tablets?

Hmm.. What I'm asking is; Would there be a problem if grabbing only means that
only that evdev-device will receive the input events, but all applications
that has this device open will receive event whether or not if they have
grabbed the device.

> I can dust off the masking patch sometime here if Dmitry thinks that
> he'd be willing to see a second method for this in addition to grabbing,
> adding support to xf86-input-evdev would be trivial, and the same could
> probably be said for the wacom driver that does grabbing at the moment.

I wouldn't mind having a look on the patch. It would be nice to see other ways
of how this little could be solved as I don't know what 'masking' in this
case would mean. It's not a problem if I can't apply it to the latest
source..

> Regards.
> Zephaniah E. Hull.
> (Original author of the evdev grab patch and xf86-input-evdev
> maintainer, among other things.)

Thanks
Magnus

2006-08-13 00:00:51

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

On Saturday 12 August 2006 12:52, Zephaniah E. Hull wrote:
> I can dust off the masking patch sometime here if Dmitry thinks that
> he'd be willing to see a second method for this in addition to grabbing,
> adding support to xf86-input-evdev would be trivial, and the same could
> probably be said for the wacom driver that does grabbing at the moment.
>

I would not mind if we get it working right ;) Do we need to turn off
"undesirable" handlers or do we want to limit output to one particular
handler? I'd prefer the former, if possible. Do we keep a counter or
set of counters so several processes can mask output, etc. Can we keep
event delivery somewhat fast?

--
Dmitry

Subject: Re: input: evdev.c EVIOCGRAB semantics question

On Sat, Aug 12, 2006 at 08:00:47PM -0400, Dmitry Torokhov wrote:
> On Saturday 12 August 2006 12:52, Zephaniah E. Hull wrote:
> > I can dust off the masking patch sometime here if Dmitry thinks that
> > he'd be willing to see a second method for this in addition to grabbing,
> > adding support to xf86-input-evdev would be trivial, and the same could
> > probably be said for the wacom driver that does grabbing at the moment.
> >
>
> I would not mind if we get it working right ;) Do we need to turn off
> "undesirable" handlers or do we want to limit output to one particular
> handler? I'd prefer the former, if possible. Do we keep a counter or
> set of counters so several processes can mask output, etc. Can we keep
> event delivery somewhat fast?

EVIOCGRAB provides for the latter, though it seems to go too far and
mess with sysrq as well.

My old old EVIOCMASK patch just added a long (or was it an int? It's
been a while) to each device struct, and to each handler struct, and if
they had bits set in common then they received the events, and if not
they did not.

That was the cost of a quick & operation and a branch in the input event
path, so not too expensive, though my memory seems to indicate that I
tried to play some evil games to invert the bits first to allow things
to be zero inited.

I'd definitely want to just rewrite it these days, but that approach is
fast, and if we define it something along the lines of 'bit 0 is the
kernel console layer, bit 1 is any further handlers in the kernel like
/dev/input/mice or the joystick interface, the rest belong to userspace'
that gives userspace plenty of bits for odd policy decisions.

One obvious catch is that programs would have to be careful to reset the
mask when leaving, though having the sysrq handler always present and
adding controls for 'reset input device masks' would be one escape
route for X masking keyboard events from the kernel, then crashing
messily.

We probably don't want to automaticly reset on close by a program that
did the masking, as I can see some cases where someone might want to use
a utility that adjusts the masks on input devices.


On a side note, if we mess with sysrq for the masking, we should add a
'ungrab all input devices' one as well.

Zephaniah E. Hull.

--
1024D/E65A7801 Zephaniah E. Hull <[email protected]>
92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801
CCs of replies from mailing lists are requested.

<aj> ``Who killed the server at the colo site?'' ``Weasel killed the
server at the colo site'' ``Not me'' ``Then who?'' ``m2 killed the
server at the colo site'' ...


Attachments:
(No filename) (2.56 kB)
signature.asc (189.00 B)
Digital signature
Download all attachments

2006-08-14 14:20:14

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

On 8/12/06, Zephaniah E. Hull <[email protected]> wrote:
> On Sat, Aug 12, 2006 at 08:00:47PM -0400, Dmitry Torokhov wrote:
> > On Saturday 12 August 2006 12:52, Zephaniah E. Hull wrote:
> > > I can dust off the masking patch sometime here if Dmitry thinks that
> > > he'd be willing to see a second method for this in addition to grabbing,
> > > adding support to xf86-input-evdev would be trivial, and the same could
> > > probably be said for the wacom driver that does grabbing at the moment.
> > >
> >
> > I would not mind if we get it working right ;) Do we need to turn off
> > "undesirable" handlers or do we want to limit output to one particular
> > handler? I'd prefer the former, if possible. Do we keep a counter or
> > set of counters so several processes can mask output, etc. Can we keep
> > event delivery somewhat fast?
>
> EVIOCGRAB provides for the latter, though it seems to go too far and
> mess with sysrq as well.
>
> My old old EVIOCMASK patch just added a long (or was it an int? It's
> been a while) to each device struct, and to each handler struct, and if
> they had bits set in common then they received the events, and if not
> they did not.
>
> That was the cost of a quick & operation and a branch in the input event
> path, so not too expensive, though my memory seems to indicate that I
> tried to play some evil games to invert the bits first to allow things
> to be zero inited.
>
> I'd definitely want to just rewrite it these days, but that approach is
> fast, and if we define it something along the lines of 'bit 0 is the
> kernel console layer, bit 1 is any further handlers in the kernel like
> /dev/input/mice or the joystick interface, the rest belong to userspace'
> that gives userspace plenty of bits for odd policy decisions.
>
> One obvious catch is that programs would have to be careful to reset the
> mask when leaving, though having the sysrq handler always present and
> adding controls for 'reset input device masks' would be one escape
> route for X masking keyboard events from the kernel, then crashing
> messily.
>
> We probably don't want to automaticly reset on close by a program that
> did the masking, as I can see some cases where someone might want to use
> a utility that adjusts the masks on input devices.
>
>
> On a side note, if we mess with sysrq for the masking, we should add a
> 'ungrab all input devices' one as well.
>

I've been thinking about all of this and all of it is very fragile and
unwieldy and I am not sure that we really need another ioctl after
all. The only issue we have right now is that mousedev delivers
undesirable events through /dev/input/mice while there is better
driver listening to /dev/input/eventX and they clash with each other.
Still, /dev/input/mice is nice for dealing with hotplugging of simple
USB mice. So can't we make mousedev only multiplex devices that are
not opened directly (where directly is one of mouseX, jsX, tsX, or
evdevX)? We could even control this behavior through a module
parameter. Then noone (normally) would need to use EVIOCGRAB.

--
Dmitry

Subject: Re: input: evdev.c EVIOCGRAB semantics question

On Mon, Aug 14, 2006 at 10:20:09AM -0400, Dmitry Torokhov wrote:
> On 8/12/06, Zephaniah E. Hull <[email protected]> wrote:
> >On Sat, Aug 12, 2006 at 08:00:47PM -0400, Dmitry Torokhov wrote:
> >> On Saturday 12 August 2006 12:52, Zephaniah E. Hull wrote:
> >> > I can dust off the masking patch sometime here if Dmitry thinks that
> >> > he'd be willing to see a second method for this in addition to
> >grabbing,
> >> > adding support to xf86-input-evdev would be trivial, and the same could
> >> > probably be said for the wacom driver that does grabbing at the moment.
> >> >
> >>
> >> I would not mind if we get it working right ;) Do we need to turn off
> >> "undesirable" handlers or do we want to limit output to one particular
> >> handler? I'd prefer the former, if possible. Do we keep a counter or
> >> set of counters so several processes can mask output, etc. Can we keep
> >> event delivery somewhat fast?
> >
> >EVIOCGRAB provides for the latter, though it seems to go too far and
> >mess with sysrq as well.
> >
> >My old old EVIOCMASK patch just added a long (or was it an int? It's
> >been a while) to each device struct, and to each handler struct, and if
> >they had bits set in common then they received the events, and if not
> >they did not.
> >
> >That was the cost of a quick & operation and a branch in the input event
> >path, so not too expensive, though my memory seems to indicate that I
> >tried to play some evil games to invert the bits first to allow things
> >to be zero inited.
> >
> >I'd definitely want to just rewrite it these days, but that approach is
> >fast, and if we define it something along the lines of 'bit 0 is the
> >kernel console layer, bit 1 is any further handlers in the kernel like
> >/dev/input/mice or the joystick interface, the rest belong to userspace'
> >that gives userspace plenty of bits for odd policy decisions.
> >
> >One obvious catch is that programs would have to be careful to reset the
> >mask when leaving, though having the sysrq handler always present and
> >adding controls for 'reset input device masks' would be one escape
> >route for X masking keyboard events from the kernel, then crashing
> >messily.
> >
> >We probably don't want to automaticly reset on close by a program that
> >did the masking, as I can see some cases where someone might want to use
> >a utility that adjusts the masks on input devices.
> >
> >
> >On a side note, if we mess with sysrq for the masking, we should add a
> >'ungrab all input devices' one as well.
> >
>
> I've been thinking about all of this and all of it is very fragile and
> unwieldy and I am not sure that we really need another ioctl after
> all. The only issue we have right now is that mousedev delivers
> undesirable events through /dev/input/mice while there is better
> driver listening to /dev/input/eventX and they clash with each other.
> Still, /dev/input/mice is nice for dealing with hotplugging of simple
> USB mice. So can't we make mousedev only multiplex devices that are
> not opened directly (where directly is one of mouseX, jsX, tsX, or
> evdevX)? We could even control this behavior through a module
> parameter. Then noone (normally) would need to use EVIOCGRAB.

Sadly, the case of using EVIOCGRAB for mice to stop the use of
/dev/input/mice is actually not the primary usage.

xf86-input-evdev will more or less happily continue talking to a mouse
that it can't grab, however things become somewhat more problematic when
it comes to keyboards.

X needs to keep the keyboard driver from receiving events while it has
it open, however that being the default behavior would be, ah,
undesirable because just running evtest on the event node of the
keyboard could abruptly make it unkillable. (Single keyboard system.)

An alternative would be to either redefine the semantics of EVIOCGRAB,
add another value to it, or another ioctl entirely, which explicitly
tells the kernel to stop listening for the console keyboard handler,
the multiplexer, etc.

I'm not horribly attached to any specific means for doing it, except
that it needs to either explicitly fail or fallback to 'X has this
keyboard, the kernel does not' if we don't support it. (Trying it on a
2.4 kernel or a current 2.6 kernel, for example.)

Quite simply, having the X server killed when someone hits ctrl-C in an
xterm is entirely unacceptable, and so we need to make sure that it
can't happen. Beyond that, throwing support in for a less exclusive
grab is fairly trivial.

Zephaniah E. Hull.

--
1024D/E65A7801 Zephaniah E. Hull <[email protected]>
92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801
CCs of replies from mailing lists are requested.

"And now, little kittens, we're going to run across red-hot
motherboards, with our bare feet." -- Buzh.


Attachments:
(No filename) (4.67 kB)
signature.asc (189.00 B)
Digital signature
Download all attachments

2006-08-14 15:00:57

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

On 8/14/06, Zephaniah E. Hull <[email protected]> wrote:
> On Mon, Aug 14, 2006 at 10:20:09AM -0400, Dmitry Torokhov wrote:
> >
> > I've been thinking about all of this and all of it is very fragile and
> > unwieldy and I am not sure that we really need another ioctl after
> > all. The only issue we have right now is that mousedev delivers
> > undesirable events through /dev/input/mice while there is better
> > driver listening to /dev/input/eventX and they clash with each other.
> > Still, /dev/input/mice is nice for dealing with hotplugging of simple
> > USB mice. So can't we make mousedev only multiplex devices that are
> > not opened directly (where directly is one of mouseX, jsX, tsX, or
> > evdevX)? We could even control this behavior through a module
> > parameter. Then noone (normally) would need to use EVIOCGRAB.
>
> Sadly, the case of using EVIOCGRAB for mice to stop the use of
> /dev/input/mice is actually not the primary usage.
>
> xf86-input-evdev will more or less happily continue talking to a mouse
> that it can't grab, however things become somewhat more problematic when
> it comes to keyboards.
>
> X needs to keep the keyboard driver from receiving events while it has
> it open

Keyboard... can't X just ignore data from old keyboard driver while
evdev-based keyboard driver is used?

--
Dmitry

2006-08-14 15:02:52

by Mattia Dongili

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

Hello Dmitry,

On Mon, Aug 14, 2006 at 10:20:09AM -0400, Dmitry Torokhov wrote:
[...]
> I've been thinking about all of this and all of it is very fragile and
> unwieldy and I am not sure that we really need another ioctl after
> all. The only issue we have right now is that mousedev delivers
> undesirable events through /dev/input/mice while there is better
> driver listening to /dev/input/eventX and they clash with each other.
> Still, /dev/input/mice is nice for dealing with hotplugging of simple
> USB mice. So can't we make mousedev only multiplex devices that are
> not opened directly (where directly is one of mouseX, jsX, tsX, or
> evdevX)? We could even control this behavior through a module
> parameter. Then noone (normally) would need to use EVIOCGRAB.

there's one more use case (don't know how much it's relevant but still
worth mentioning): pbbuttonsd v/s synaptics (x driver).

pbbuttonsd is a nice utility that (between the other things) monitors
keyboard and mouse activity and eventually sends the laptop to sleep.
The synaptics driver uses EVIOCGRAB and they don't work nice together
(eg: laptop goes to sleep even if actively using your touchpad)...

Now, with your proposal a user not using the synaptics driver and would
lose multiplexing to /dev/input/mice.

So why not just make EVIOCGRAB mean "don't send events to
mousedev but still report data to others opening the device"?

--
mattia
:wq!

2006-08-14 15:15:26

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

Hi Mattia,

On 8/14/06, Mattia Dongili <[email protected]> wrote:
>
> pbbuttonsd is a nice utility that (between the other things) monitors
> keyboard and mouse activity and eventually sends the laptop to sleep.
> The synaptics driver uses EVIOCGRAB and they don't work nice together
> (eg: laptop goes to sleep even if actively using your touchpad)...
>
> Now, with your proposal a user not using the synaptics driver and would
> lose multiplexing to /dev/input/mice.
>

Yes, you are right, it won't work.

> So why not just make EVIOCGRAB mean "don't send events to
> mousedev but still report data to others opening the device"?
>

That darn layering thing. We don't want evdev to know about all other
handlers there are.

--
Dmitry

2006-08-14 16:05:56

by Ian Stirling

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

Dmitry Torokhov wrote:
> On 8/14/06, Zephaniah E. Hull <[email protected]> wrote:
>> On Mon, Aug 14, 2006 at 10:20:09AM -0400, Dmitry Torokhov wrote:
>> >

>> xf86-input-evdev will more or less happily continue talking to a mouse
>> that it can't grab, however things become somewhat more problematic when
>> it comes to keyboards.
>>
>> X needs to keep the keyboard driver from receiving events while it has
>> it open
>
> Keyboard... can't X just ignore data from old keyboard driver while
> evdev-based keyboard driver is used?

Apart from the other issues, it'd be nice to be able to have some way to
disable 'keyboards'.

For example, I have some CM108 based audio USB cards, which come with 3
(event generating) keys. These generate events for F13,F14,'help'.
Of course I can do something in my X wm config to get them to do stuff -
but this is hardly ideal, especially for headless machines, or whatever.
And it utterly breaks if I want to distinguish between 'F13' being
pressed on the audio device in the kitchen, and the one in the lounge,
or I want to stop X.
evdev works just fine for this. I'd love to have some way to say 'this
should never be a core keyboard' - and have it generate no keyboard
events, only output stuff on evdev. As another example - I might like to
have an unsecured keyboard, to which I can point X - but I never want it
to allow magic sysrq, or to generate console events if the system isn't
running X.

The lack of unique per-device IDs is of course really annoying in this case.

Subject: Re: input: evdev.c EVIOCGRAB semantics question

On Mon, Aug 14, 2006 at 11:00:55AM -0400, Dmitry Torokhov wrote:
> On 8/14/06, Zephaniah E. Hull <[email protected]> wrote:
> >On Mon, Aug 14, 2006 at 10:20:09AM -0400, Dmitry Torokhov wrote:
> >>
> >> I've been thinking about all of this and all of it is very fragile and
> >> unwieldy and I am not sure that we really need another ioctl after
> >> all. The only issue we have right now is that mousedev delivers
> >> undesirable events through /dev/input/mice while there is better
> >> driver listening to /dev/input/eventX and they clash with each other.
> >> Still, /dev/input/mice is nice for dealing with hotplugging of simple
> >> USB mice. So can't we make mousedev only multiplex devices that are
> >> not opened directly (where directly is one of mouseX, jsX, tsX, or
> >> evdevX)? We could even control this behavior through a module
> >> parameter. Then noone (normally) would need to use EVIOCGRAB.
> >
> >Sadly, the case of using EVIOCGRAB for mice to stop the use of
> >/dev/input/mice is actually not the primary usage.
> >
> >xf86-input-evdev will more or less happily continue talking to a mouse
> >that it can't grab, however things become somewhat more problematic when
> >it comes to keyboards.
> >
> >X needs to keep the keyboard driver from receiving events while it has
> >it open
>
> Keyboard... can't X just ignore data from old keyboard driver while
> evdev-based keyboard driver is used?

The problem is that without xf86-input-keyboard X ignores the keyboard
entirely, which means that the console driver gets it, so ctrl-C sends
signals, alt-F<n> switches consoles on you, etc.

Additional code to open the console, put the keyboard in raw mode, and
throw everything away would be problematic for a few reasons, one of
which being that people have managed, with grab, to keep X from being
attached to an actual console. (Used for multiple X sessions running at
once for instance.)

It also would mean that xf86-input-evdev would have to touch stuff that
otherwise it wouldn't have to come anywhere near.

Zephaniah E. Hull.

--
1024D/E65A7801 Zephaniah E. Hull <[email protected]>
92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801
CCs of replies from mailing lists are requested.

I've always taken the position that if you can't find anything bad to
say about a language or an operating system then you don't understand
it. I also agree with you about the advocacy. AHS. ASS.
-- Shmuel (Seymour J.) Metz in the Scary Devil Monastery.


Attachments:
(No filename) (2.42 kB)
signature.asc (189.00 B)
Digital signature
Download all attachments

2006-08-14 16:22:05

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

On 8/14/06, Zephaniah E. Hull <[email protected]> wrote:
> On Mon, Aug 14, 2006 at 11:00:55AM -0400, Dmitry Torokhov wrote:
> > On 8/14/06, Zephaniah E. Hull <[email protected]> wrote:
> > >On Mon, Aug 14, 2006 at 10:20:09AM -0400, Dmitry Torokhov wrote:
> > >>
> > >> I've been thinking about all of this and all of it is very fragile and
> > >> unwieldy and I am not sure that we really need another ioctl after
> > >> all. The only issue we have right now is that mousedev delivers
> > >> undesirable events through /dev/input/mice while there is better
> > >> driver listening to /dev/input/eventX and they clash with each other.
> > >> Still, /dev/input/mice is nice for dealing with hotplugging of simple
> > >> USB mice. So can't we make mousedev only multiplex devices that are
> > >> not opened directly (where directly is one of mouseX, jsX, tsX, or
> > >> evdevX)? We could even control this behavior through a module
> > >> parameter. Then noone (normally) would need to use EVIOCGRAB.
> > >
> > >Sadly, the case of using EVIOCGRAB for mice to stop the use of
> > >/dev/input/mice is actually not the primary usage.
> > >
> > >xf86-input-evdev will more or less happily continue talking to a mouse
> > >that it can't grab, however things become somewhat more problematic when
> > >it comes to keyboards.
> > >
> > >X needs to keep the keyboard driver from receiving events while it has
> > >it open
> >
> > Keyboard... can't X just ignore data from old keyboard driver while
> > evdev-based keyboard driver is used?
>
> The problem is that without xf86-input-keyboard X ignores the keyboard
> entirely, which means that the console driver gets it, so ctrl-C sends
> signals, alt-F<n> switches consoles on you, etc.
>
> Additional code to open the console, put the keyboard in raw mode, and
> throw everything away would be problematic for a few reasons, one of
> which being that people have managed, with grab, to keep X from being
> attached to an actual console. (Used for multiple X sessions running at
> once for instance.)
>
> It also would mean that xf86-input-evdev would have to touch stuff that
> otherwise it wouldn't have to come anywhere near.
>

I can see that. Unfortunately any form of "grabbing" just makes it all
worse in the long run. The problem is that some programs rely on X to
deliver events while others use device nodes (eventX, mouseX, or
super-new blahX) for their data. When X server grabs the devices it
interferes with other programs running on the same box making them
dependent on X configuration. I have the feeling that best course
would be for X to work out its own input handling and any
filtering/asking that is necessary.

--
Dmitry

2006-08-14 22:50:05

by Magnus Vigerlöf

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

On Monday 14 August 2006 17:15, Dmitry Torokhov wrote:
[...]
> > So why not just make EVIOCGRAB mean "don't send events to
> > mousedev but still report data to others opening the device"?
>
> That darn layering thing. We don't want evdev to know about all other
> handlers there are.

Nonono... I think the layers is a good thingy, even in this case..

What if you turn the whole thing around? Let the handler that should not get
the events in case someone grabs the device (/dev/input/mice, more devices?)
say it's so. And when the event is forwarded through the input-layer, check
if the device is grabbed and in that case skip those handlers that shouldn't
get any.

It would require an additional field in the input_handle struct that should be
set to non-zero for mousedev and a change in the event-propagation code to
send events to all handlers except to those with a non-zero value if grabbed
(I'd estimate it to be less than 5-10 lines that has to be added/changed).

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..

Won't EVIOCGRAB be quite misnamed (not that I propose a change...) if we make
a change like this though?

/Magnus

2006-08-15 11:52:07

by Magnus Vigerlöf

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

On Tuesday 15 August 2006 00:49, Magnus Vigerl?f wrote:
> On Monday 14 August 2006 17:15, Dmitry Torokhov wrote:
> [...]
>
> > > So why not just make EVIOCGRAB mean "don't send events to
> > > mousedev but still report data to others opening the device"?
> >
> > That darn layering thing. We don't want evdev to know about all other
> > handlers there are.
>
> Nonono... I think the layers is a good thingy, even in this case..
>
> What if you turn the whole thing around? Let the handler that should not
> get the events in case someone grabs the device (/dev/input/mice, more
> devices?) say it's so. And when the event is forwarded through the
> input-layer, check if the device is grabbed and in that case skip those
> handlers that shouldn't get any.
>
> It would require an additional field in the input_handle struct that should
> be set to non-zero for mousedev and a change in the event-propagation code
> to send events to all handlers except to those with a non-zero value if
> grabbed (I'd estimate it to be less than 5-10 lines that has to be
> added/changed).

And since /dev/input/mice does not have an own handler, but leeches the events
from the handlers for /dev/input/mouse* this won't work as easily as I
wrote.. Though if it get its own handler then it should be a simple thing...
A few more lines of code that needs to be changed though, and the event loop
will probably cost a little more to run.

> 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..
>
> Won't EVIOCGRAB be quite misnamed (not that I propose a change...) if we
> make a change like this though?
>
> /Magnus
/Magnus

2006-08-15 23:20:25

by Magnus Vigerlöf

[permalink] [raw]
Subject: Re: input: evdev.c EVIOCGRAB semantics question

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;
}