Bug #951


Keyboard not working with Media, Player or Kiosk modes

Added by Hammel 2 months ago. Updated about 1 month ago.

Start date:
26 Mar 2023
Due date:
% Done:


Estimated time:
01 - Critical


Tested on RPi 1 with desktop display using wired and wireless keyboards: arrow keys do not support navigation.
Tested on RPi 2 and 3 after RM #957 resolved: still broken.

This has to be fixed before the 2.0 release.

Actions #1

Updated by Hammel 2 months ago

  • Status changed from New to In Progress
  • % Done changed from 0 to 10
Might be due to two recently fixed problems
  1. RM #949: If a touchscreen is identified, then the launcher keyboard was disabled.
  2. RM #955: Recognized touchscreens was not working correctly.

So this needs to be retested with the updates and see if those fixes address this issue.

Actions #2

Updated by Hammel 2 months ago

  • % Done changed from 10 to 20

Still broken with those fixes. But the whole keyboard mapping problem is broken too.

In pmsui, there is src/config/etc/X11/xinitrc, which includes a test for a specific USB vendor/product pair for the FAVI keyboards. If found, then xmodmap is used to map the keys. This isn't very flexible, to say the least.

The more modern way of handling keyboards is XKB. This sets the keyboard type in the xorg.conf. There are a variety of configurations (see wiki doc on XKB) that can be seen in /usr/share/X11/xkb/rules/base. And these can be changed at runtime with setxkbdmap.

So there are a couple of things to update here.
  1. Add setxkbdmap to dev platform buildroot config.
  2. Change pmsui's xinitrc to read a config file and run setxkbmap instead of using xmodmap and checking for usb identifiers.
  3. Default to using pc104, us keyboard types, as in:
Section "InputClass" 
    Identifier "keyboard defaults" 
    MatchIsKeyboard "on" 

    Option "XkbModel" "pc104" 
    Option "XkbLayout" "us" 
    Option "XKbOptions" "" 

But we don't do this in the xinitrc. Instead we use the setxkbdmap utility in the xinitrc in pmsui.

I think that may fix all my generic keyboard problems, though it's not international. Users can then change the config file, call it /etc/xkb.cfg, with a model/layout to use at boot time.

I need to manually try this to verify it works. I have an RPi1 running Kiosk that I can use to verify it.

Actions #3

Updated by Hammel about 2 months ago

  • Description updated (diff)
Actions #4

Updated by Hammel about 2 months ago

  • Subject changed from Keyboard not working with Kiosk mode to Keyboard not working with Media, Player or Kiosk modes
  • Description updated (diff)
Actions #5

Updated by Hammel about 2 months ago

I added a test configuration with pc104 to a conf file for, but that didn't change anything. The shows the configuration was accepted, however.

I tested with evtest using both the Sino Wealth and Favi keyboards. evtest reports key left and key right the same way and correctly. So the problem is something else.

Actions #6

Updated by Hammel about 2 months ago

Okay, I added debug code to see what keyval was being presented (because it was showing "NULL" when translated to GDK) and now it just works. Can't seem to get it to fail again.

I'll keep trying it with different models and reboots. Maybe this is an intermittent problem? Or maybe I just fixed it with the icon pre-scaling/color icons fixes?

Actions #7

Updated by Hammel about 2 months ago

Tried it on a RPi2 this time. The Sino keyboard only was plugged in and didn't work. Added config and rebooted. Still didn't work.
Plugged in the Favi keyboard. Neither worked.
Rebooted. Both keyboards worked.
Removed Favi keyboard. Rebooted. Sino keyboard doesn't work.

So this may have something to do with the way the xinitrc is structured to support Favi keyboards. Try the following.
  1. Remove the favi keyboard config.
  2. Add setxkbmap to xinitrc without the favi config.
Actions #8

Updated by Hammel about 2 months ago

  • % Done changed from 20 to 50

Use of xkb didn't seem to help any, at least not without lots of customization. The technique used in pmsui's xinitrc is simpler, and as it turns out extensible.

That bit of code at the start that is looking specifically for FAVI usb ids should be changed to this:

# Load a keyboard file.  This might load more than one if there
# are multiple keyboards installed - be careful!
rm -f "/etc/X11/kbd/active" 
while read line; do
    usbid="$(echo ${line} | cut -f1 -d" ")" 
    kbdfile="$(echo ${line} | cut -f2 -d" ")" 
    kbd="$(lsusb | grep "${usbid}")" 
    if [ -n "${kbd}" ]
        sh "/etc/X11/kbd/${kbdfile}" 
        echo "Keyboard: ${usbid} /etc/X11/kbd/${kbdfile}" >> "/etc/X11/kbd/active" 
done < /etc/X11/kbd/kbd.list

For this to work we need to add the following pieces to the dev platform (or maybe pmsui, but probably dev):
  1. mkdir /etc/X11/kbd
  2. new file: /etc/X11/kbd/kbd.list
  3. Add to kbd.list for each supported input device
    1. <usbid pair> <filename>
  4. Add to /etc/X11/kbd
    1. One file for each entry in kbd.list that contains the xmodmap's for the keys of interest (usually arrow keys)

Then I just need to run xev for each keyboard and get their keycodes for the arrow keys and create a new /etc/X11/kbd/<file> for that keyboard.

Yes, this is clumsy, but it's easy to extend for the DIY'ers and that's kinda what PiBox is all about.

One thing this doesn't do, as written: you can't plug in a keyboard after boot and have it work. The way around this problem is to make that new bit of code a shell script and tie it to mdev.conf's inputdev handling. That may or may not work. I may have to experiment with that.

Actions #9

Updated by Hammel about 2 months ago

So this will work to handle plug events for new keyboards.

  • Change /etc/mdev.conf from
    input/event[0-9]*   root:root 644   */lib/mdev/inputdev

    input/event[0-9]*   root:root 640   @/usr/bin/
  • /usr/bin/ should call the script that loads the xmodmaps (see previous comment on this issue) and make use of the following env vars passed from mdev
        ACTION      = add
        SEQNUM      = 939
        MAJOR       = 13
        MDEV        = input/event0
        DEVPATH     = /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/0003:258A:0001.0005/input/input7/event0
        DEVNAME     = input/event0
        SUBSYSTEM   = input
        MINOR       = 64
        PHYSDEVPATH = 
        PHYSDEVBUS  = 
        PWD         = /dev

    The important one is extracting the usb id from DEVPATH, which are in reverse order:
ids="$(echo ${DEVPATH} | cut -f10 -d"/")" 
echo "USB ID: $(echo ${ids} | cut -f2 -d":"):$(echo ${ids}|cut -f1 -d":")" 

Another important issue is that the shell script can be called repeatedly with no guarantee that the first call completes before the second is made. I'll need a way to serialize this.

One final thing: the script can be called multiple times (multiple input/event* devices from a single keyboard). The script should be run each time but rather only once since the same USB IDs are used for each input event.


  • The first step in this is to make sure that an mdev event can update the X server. The xmodmap frontend needs to set DISPLAY=unix:0.0 before calling the xmodmap backend script for the given usb id pair.
    • Just write the front end as a script and call it from /usr/bin/ on plug event for a keyboard and see if the arrow keys work. If so, then setting DISPLAY is all that's required.
  • Serializing could be done by having piboxd run the xmodmap frontend script. /usr/bin/ uses nc to send a new message type, MT_KEYBOARD, that causes piboxd to run the xmodmap front end.
  • piboxd can read /etc/X11/kdb/active to see if the usb id pair has already been run, skipping the mdev event if it has.
Actions #10

Updated by Hammel about 2 months ago

I've tested the two scripts I need:
  1. - called via mdev to send a pibox protocol message (MT_SYS, MA_KEYB) to piboxd.
  2. - called by piboxd and xinitrc to configured keyboard arrow keys.

I've also added the code to piboxd to handle this new message type and added the new MA_KEYB action for MA_SYS to libpibox:pmsg.h.

Now I need to rebuild libpibox in the dev platform, then I can build piboxd. The former will require rebuilding the SD card so I'll just push a new version of piboxd with that. Since the shell scripts are in pmsui I'll also build and push a new version of that for testing.

So that means
  • Test compile libpibox
  • Push libpibox
  • Rebuild dev platform w/updated libpibox
  • Build piboxd
  • Build pmsui
  • Rebuild SD card
  • Push meta to SD card
  • Push piboxd to SD card
  • Push pmsui to SD card

Assuming this works then I should update the wiki with the new MA_KEYB action so I don't forget it later.

I'm still not happy with this solution - Xorg should really be doing this. Terminals recognize arrow keys. I'm not sure why Xorg doesn't.

Actions #11

Updated by Hammel about 1 month ago

  • Status changed from In Progress to Closed
  • % Done changed from 50 to 100

Tested on Media System with all updates - works fine.
Tested on Player System - works fine.
Tested on Kiosk System - fails

All repo updates commited and pushed:
  1. pibox
  2. libpibox
  3. piboxd
  4. pmsui

The kiosk problem

The mdev.conf update breaks the launcher on touchscreens. The problem is that I changed the permissions on the input devices to 640 but for the touchscreen to work it needs to be 644.

Actions #12

Updated by Hammel about 1 month ago

  • Status changed from Closed to In Progress
  • % Done changed from 100 to 90
Actions #13

Updated by Hammel about 1 month ago

Change to mdev.conf pushed. Still needs a hardware test but I have little doubt it will work because I made the same change manually and it worked.

Actions #14

Updated by Hammel about 1 month ago

  • Status changed from In Progress to Closed
  • % Done changed from 90 to 100

Verified working on kiosk.

All code committed and pushed.

Closing issue.


Also available in: Atom PDF