Wednesday, December 20, 2017

Debugging input devices

Having troubles with input devices like mice, touchpads and keyboards or even cameras is hard to debug. Usually one is not sure whether the device is misbehaving or the desktop environment or the application are mishandling the events from the input device.

First check if the driver used for your device is what you expect. For example I had mi x11 libinput driver removed by `dnf autoremove` and had my touchpad taken by `evdev` thus not working.

$ xinput list-props "SynPS/2 Synaptics TouchPad" 
Device 'SynPS/2 Synaptics TouchPad': 
    Device Enabled (140):    1 
    Coordinate Transformation Matrix (142):    1.000000, 0.000000, 0.000000,  0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 
    Device Accel Profile (275):    0 
    Device Accel Constant Deceleration (276):    1.000000 
    Device Accel Adaptive Deceleration (277):    1.000000 
    Device Accel Velocity Scaling (278):    10.000000 
    Device Product ID (262):    2, 7 
    Device Node (263):    "/dev/input/event4" 
    Evdev Axis Inversion (279):    0, 0 
    Evdev Axis Calibration (280):    <no items> 
    Evdev Axes Swap (281):    0 
    Axis Labels (282):    "Abs MT Position X" (302), "Abs MT Position Y"  (303), "Abs MT Pressure" (304), "Abs Tool Width" (301), "None" (0),  "None" (0), "None" (0) 
    Button Labels (283):    "Button Left" (143), "Button Unknown" (265),  "Button Unknown" (265), "Button Wheel Up" (146), "Button Wheel Down" (147) 
    Evdev Scrolling Distance (284):    0, 0, 0 
    Evdev Middle Button Emulation (285):    0 
    Evdev Middle Button Timeout (286):    50 
    Evdev Middle Button Button (287):    2 
    Evdev Third Button Emulation (288):    0 
    Evdev Third Button Emulation Timeout (289):    1000 
    Evdev Third Button Emulation Button (290):    3 
    Evdev Third Button Emulation Threshold (291):    20 
    Evdev Wheel Emulation (292):    0 
    Evdev Wheel Emulation Axes (293):    0, 0, 4, 5 
    Evdev Wheel Emulation Inertia (294):    10 
    Evdev Wheel Emulation Timeout (295):    200 
    Evdev Wheel Emulation Button (296):    4 
    Evdev Drag Lock Buttons (297):    0

Usually you'd expect to see `libinput` (synaptics is now abandoned).

...
    libinput Send Events Mode Enabled (266):    0, 0
    libinput Send Events Mode Enabled Default (267):    0, 0
...

Fortunately there is a tool to help understand what is device sending to the computer. This works for libinput devices.

$ sudo dnf install evemu

Then we can see
$ ls /usr/bin/evemu-*
/usr/bin/evemu-describe  /usr/bin/evemu-event  /usr/bin/evemu-record
/usr/bin/evemu-device    /usr/bin/evemu-play

These executable files can be used to inspect, record and replay the events sent by any connected device.

$ sudo evemu-record
Available devices:
/dev/input/event0: Lid Switch
/dev/input/event1: Sleep Button
/dev/input/event2: Power Button
/dev/input/event3: AT Translated Set 2 keyboard
/dev/input/event4: SynPS/2 Synaptics TouchPad
/dev/input/event5: Video Bus
/dev/input/event6: Video Bus
/dev/input/event7: TPPS/2 IBM TrackPoint
/dev/input/event8: Logitech MX Anywhere 2
/dev/input/event9: ThinkPad Extra Buttons
/dev/input/event10: HDA Intel PCH Dock Mic
/dev/input/event11: HDA Intel PCH Mic
/dev/input/event12: HDA Intel PCH Dock Headphone
/dev/input/event13: HDA Intel PCH Headphone
/dev/input/event14: HDA Intel PCH HDMI/DP,pcm=3
/dev/input/event15: HDA Intel PCH HDMI/DP,pcm=7
/dev/input/event16: HDA Intel PCH HDMI/DP,pcm=8
/dev/input/event17: HDA Intel PCH HDMI/DP,pcm=9
/dev/input/event18: HDA Intel PCH HDMI/DP,pcm=10
/dev/input/event19: Integrated Camera: Integrated C
Select the device event number [0-19]: 8 
# EVEMU 1.3
# Kernel: 4.14.5-300.fc27.x86_64
# DMI: dmi:bvnLENOVO:bvrR07ET63W(2.03):bd03/15/2016:svnLENOVO:pn20FXS0BB14:pvrThinkPadT460p:rvnLENOVO:rn20FXS0BB14:rvrNotDefined:cvnLENOVO:ct10:cvrNone:
# Input device name: "Logitech MX Anywhere 2"
# Input device ID: bus 0x03 vendor 0x46d product 0x4063 version 0x111
# Supported events:
#   Event type 0 (EV_SYN)
#     Event code 0 (SYN_REPORT)
#     Event code 1 (SYN_CONFIG)
...
B: 15 00 00 00 00 00 00 00 00
A: 20 1 652 0 0 0
################################
#      Waiting for events      #
################################
E: 0.000001 0002 0000 0001 # EV_REL / REL_X                1
E: 0.000001 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +0ms
E: 0.013561 0002 0000 0001 # EV_REL / REL_X                1
E: 0.013561 0002 0001 0001 # EV_REL / REL_Y                1
E: 0.013561 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +13ms
E: 0.039808 0002 0000 0001 # EV_REL / REL_X                1
E: 0.039808 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +26ms
E: 0.063578 0002 0000 0001 # EV_REL / REL_X                1
E: 0.063578 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +24ms
E: 0.071790 0002 0000 0001 # EV_REL / REL_X                1
E: 0.071790 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +8ms
E: 0.087586 0002 0000 0001 # EV_REL / REL_X                1
E: 0.087586 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +16ms
E: 0.111578 0002 0001 0001 # EV_REL / REL_Y                1
E: 0.111578 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +24ms
...

Decoding those would be left for another post or as an exercise for the reader. At the very least one can prepare logs while things are misbehaving and then report bugs to the affected projects with the logs attached. Make sure to read `man evemu-record` to check for a common issues preventing event capturing.

-- thanks to Peter Hutterer for pointing me at this tool

1 comment: