From: Jarod W. <ja...@wi...> - 2010-11-02 20:06:43
|
2010/11/2 Juan Jesús García de Soria Lucena <ska...@gm...>: > 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(REP=2) > BUTTON_A(REP=3) > ... > BUTTON_A(REP=N-1) > BUTTON_A(REP=N) > 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 > devices. > > 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 > uses. > > 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=1) > BUTTON_A(REP=2) > 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) > BUTTON_A(RELEASE) > > 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 > events. > > 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. ;) -- Jarod Wilson ja...@wi... |