Wed, Jul 20, 2022 at 12:34:19PM +0300, Marko Mäkelä wrote:
Mon, Jul 18, 2022 at 09:36:55AM +0300, Marko Mäkelä wrote:
TL;DR: How could I connect VDR to the kernel-provided /dev/lirc0 device? Is there a dummy lircd implementation that would simply open /dev/lirc0 in LIRC_MODE_SCANCODE and relay its contents over a socket?
I wrote a simple converter (attached) that is compatible with vdr --lirc=/dev/shm/lirc. Alas, as far as I can tell, the socket interface does not currently allow any "repeat" flag to be passed explicitly. Instead, lirc.c will detect long keypresses by itself based on some time stamps or timeouts, and then pass the parameter to cRemote::Put().
I took a further step along this path and wrote an experimental patch that makes --lirc=/dev/lirc0 work (while completely breaking compatibility with lircd). The attached patch is only a proof of concept; a final version of this would have to be tied to a dedicated command line option.
I did not clean up the timer logic yet. The lirc_scancode events already contain monotonic timestamps; those could be used in order to reduce the number of system calls.
This patch assumes that the /dev/lirc0 interface is setting the LIRC_SCANCODE_FLAG_REPEAT for subsequent messages sent for a long key press, as in https://patchwork.linuxtv.org/project/linux-media/list/?series=8338 (and before that, only for some RCUs that send special "repeat" messages). The flag could be simulated in userspace by keeping track of the timestamps.
The Linux kernel documentation gave me the impression that the /dev/input/event interface is the modern way to handle any input.
I wonder if a /dev/input/event interface could be implemented natively in the VDR core. It would remove the need for both lircd and vdr-plugin-remote in many typical installations.
It seems that in any case, I'd better write a converter from /dev/lirc0 to /dev/uinput, to have the key events generated in my way, slightly differently from the kernel's built-in /dev/input/event driver.
I experimented with a program that would convert /dev/lirc0 to /dev/uinput, but it quickly got too complex for my taste, starting from the fact that all potential keycodes have to be declared upfront. While searching for information, I learned that lircd could already generate input events: https://www.lirc.org/html/lircd-uinput.html
The /dev/input/event driver in the kernel rc-core has (in my opinion) a design problem that the key-repeat events are triggered by an independent timer and not directly by the reception of IR messages from the RCU. When multiple clock sources are involved, timers will easily get out of sync, and in this case cause input lag: For example, a perceivable time (such as 0.1s) after a button was already released, the independent timer might fire one more key-repeat event.
VDR's existing LIRC interface avoids such input lag by always triggering Put() calls by the reception of IR messages. It merely "filters out" some IR messages by enforcing RcRepeatDelay and RcRepeatDelta.
Best regards,
Marko