2010/11/2 Juan Jesús García de Soria Lucena <skandalfo@...>:
> Hello everybody.
> I just set up my new media center, to find that the uinput support seems to
> be just difficult to get working in an acceptable way. What I mean is that
> it's easy to make it work, but then the results aren't very pleasant.
> I'm trying to just map the remote to standard and multimedia keys. X just
> picks them up. The main problem is with repeats.
> I just can use the keyboard preferences in the GNOME control panel (I'm on
> Ubuntu 10.10) so that the repeat start threshold is rather long, and then
> reduce the repeat rate to a minimum, and it begins getting better. But then
> I'll have to do that for every user that wants to be able to use the remote
> keys, and the settings will affect the repeat threshold/rates of actual
> keyboards too.
> I've done a little analysis of how lircd decoding and uinput feeding works.
> Let's say we have a stream of messages for a given button and this mapping:
> LIRC EVENT UINPUT EVENT
> ========== ============
> BUTTON_A(REP=0) KEY_A(PRESSED, VALUE=1)
> BUTTON_A(REP=1) KEY_A(REPEAT, VALUE=2)
> BUTTON_A(RELEASE) KEY_A(RELEASED, VALUE=0)
> It seems that, at least for X (based on my experiments), there's no
> difference among values 1 (pressed) and 2 (repeat), so what X sees is a key
> that gets pressed in the first LIRC event, and gets released at the last
> LIRC event.
> This would make sense, but we have to take into account timing
> considerations and the fact that keyboards and remotes are very different
> With an usual PS/2 or USB keyboard, a scancode release packet is sent to the
> PC when a key gets released, with a reasonable latency.
> Most remotes, on the other hand, just send "key is pressed" codes more or
> less continuously while the key is being pressed. My specific MCE remote
> does so, for instance. And they insert a rather long gap between code
> repetitions. I guess the gap just makes decoding easier, and also helps
> reducing power usage at the remote side. The fact is that the
> BUTTON_A(RELEASE) event above has to be synthesized by lircd.
> And the only two ways for lircd to notice that a key isn't pressed anymore
> are either to begin receiving the code for a different button, or (more
> often) not receiving any further code during a period of time (the timeout).
> Looking at the code, it would seem that the time it waits before declaring a
> "release" uses the following formula:
> timeout = max_code_length_without_gap + max(2 * gap_time, 100 ms) + 10 ms
> In my case, the timeout above must be in the order of magnitude of 235 ms.
> That means that if I just press a remote key for as short a time as I can
> (ideally 0 ms), the earlier time lircd will notice will be after 235 ms
> after the first, single code has been completely transmitted by the remote.
> This value may well be above the default key repeat threshold time that X
> Even if I just configure a longer keyboard repeat threshold in X, a latency
> problem still exists with repetitions. Just suppose I mapped the backspace
> key to a remote button, and I'm trying to delete "the last word" in a text
> field. The backspace repetition can stop as late as 235 ms after I release
> the remote key. This means that many times I'll just delete too much text
> unless I configure the minimum keyboard repeat rate (once again affecting
> every actual keyboard connected to the X session).
> I guess the temporal resolution of IR devices is just too coarse for this
> kind of usage.
> I want to propose a different approach to this problem, that won't require
> users fiddling with keyboard settings. See the following event mapping:
> LIRC EVENT UINPUT EVENT
> ========== ============
> BUTTON_A(REP=0) KEY_A(PRESSED, VALUE=1) + KEY_A(RELEASED, VALUE=0)
> BUTTON_A(REP=3) KEY_A(PRESSED, VALUE=1) + KEY_A(RELEASED, VALUE=0)
> BUTTON_A(REP=N-1) KEY_A(PRESSED, VALUE=1) + KEY_A(RELEASED, VALUE=0)
> BUTTON_A(REP=N) KEY_A(PRESSED, VALUE=1) + KEY_A(RELEASED, VALUE=0)
> Now we just simulate an instantaneous press+release pair of events for each
> actual IR code received. We won't trigger any X repeat, since the keys
> remain pressed "0 milliseconds". We will implement repeats ourselves more or
> less in the same way that they can be filtered in .lircrc. For instance, in
> the example above, we will repeat for REP = 3 + n. We could easily make it
> configurable as REP = a + b * n so that users can configure the repeat
> threshold and rate for remotes differently than for keyboards. Moreover, we
> won't have any latency problem with the time between the two last LIRC
> Of course this is philosophically less correct than the existing approach
> (it makes for "funny keyboards" from the point of view of the input layer).
> And at least there'll be one actual downside: it won't be possible to use
> remotes "like joysticks" this way. But I think it will make for a way better
> user experience in the common case. If there are people depending on the old
> behavior, this new one could be selected by using a new lircd option.
> I'm just running a version of lircd I hacked in this way, and I personally
> find the results far more usable.
> What do you think of this proposal? I can produce a patch if the change is
> deemed desirable.
I think I'm fine with the idea. I don't use uinput support much
myself, since I'm simply rewriting drivers to be input layer devices
natively though. ;)