Friday, November 22, 2013

evtest is dead. long live evemu

No, don't worry, evtest isn't actually dead. I'll keep maintaining it (it's not a lot of work, after all). But I'll discourage its use and in the future you should be using evemu instead.

evtest is a tool that prints out a human-readable description of an evdev kernel device and its events. evemu does the same, but it also records the events in a format that can be parsed and re-played easily on another machine, making it possible to reproduce bugs easily.

evemu was originally written by Henrik Rydberg, had a stint on launchpad and moved to freedesktop.org earlier this year. Since then, Benjamin Tissoires and I have been working quite a bit on it, trying to make improve on the usability. We're still polishing a few things, but since version 1.1 we have a UI that I'm now reasonably happy with it. And Benjamin we just released 1.2.

evemu has two modes: recording mode and replaying mode. In recording mode, evemu records the bits that the kernel exports for a device and writes them into a file. This includes both the device description and the events (if any) from the device. In replaying mode, evemu creates a virtual (uinput) device that looks exactly the same as the original file [1] and replays the events in the same order and timeframe. The result is that if you record your device and send it to me, chances are I can reproduce the bug without having the hardware. And of course, for the nastier bugs having a recording that reliably reproduces something is great for testing.

Let's look at it in more detail. The first step for a reporter is evemu-record [2].

$> 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: PIXART USB OPTICAL MOUSE
/dev/input/event6: Microsoft Microsoft® Digital Media Keyboard
/dev/input/event7: Video Bus
/dev/input/event8: TPPS/2 IBM TrackPoint
/dev/input/event9: Wacom ISDv4 E6 Pen
/dev/input/event10: Wacom ISDv4 E6 Finger
/dev/input/event11: Microsoft Microsoft® Digital Media Keyboard
/dev/input/event12: Integrated Camera
/dev/input/event13: ThinkPad Extra Buttons
/dev/input/event14: HDA Intel PCH HDMI/DP,pcm=8
/dev/input/event15: HDA Intel PCH HDMI/DP,pcm=7
/dev/input/event16: HDA Intel PCH HDMI/DP,pcm=3
Select the device event number [0-16]: 
This is obviously the list of devices on my machine, selecting a number will record that device (e.g. 4 will start recording the touchpad). Recording the output produces a bunch of comments describing the device in human-readable form, followed by the bits that we use within evemu.
# EVEMU 1.2
# Input device name: "SynPS/2 Synaptics TouchPad"
# Input device ID: bus 0x11 vendor 0x02 product 0x07 version 0x1b1
# Supported events:
#   Event type 0 (EV_SYN)
#     Event code 0 (SYN_REPORT)
#     Event code 1 (SYN_CONFIG)
#     Event code 3 (SYN_DROPPED)
#   Event type 1 (EV_KEY)
#     Event code 272 (BTN_LEFT)
#     Event code 325 (BTN_TOOL_FINGER)
#     Event code 328 (BTN_TOOL_QUINTTAP)
#     Event code 330 (BTN_TOUCH)
#     Event code 333 (BTN_TOOL_DOUBLETAP)
#     Event code 334 (BTN_TOOL_TRIPLETAP)
#     Event code 335 (BTN_TOOL_QUADTAP)
#   Event type 3 (EV_ABS)
#     Event code 0 (ABS_X)
#       Value   2680
#       Min     1472
#       Max     5472
#       Fuzz       0
#       Flat       0
#       Resolution 75
#     Event code 1 (ABS_Y)
#       Value   4550
#       Min     1408
#       Max     4448
#       Fuzz       0
#       Flat       0
#       Resolution 129
#     Event code 24 (ABS_PRESSURE)
#       Value      0
#       Min        0
#       Max      255
#       Fuzz       0
#       Flat       0
#       Resolution 0

[...]

N: SynPS/2 Synaptics TouchPad
I: 0011 0002 0007 01b1
P: 05 00 00 00 00 00 00 00
B: 00 0b 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 01 00 00 00 00 00
B: 01 20 e5 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 02 00 00 00 00 00 00 00 00
B: 03 03 00 00 11 00 80 60 06
B: 04 00 00 00 00 00 00 00 00
B: 05 00 00 00 00 00 00 00 00
B: 11 00 00 00 00 00 00 00 00
B: 12 00 00 00 00 00 00 00 00
B: 15 00 00 00 00 00 00 00 00
B: 15 00 00 00 00 00 00 00 00
A: 00 1472 5472 0 0 75
A: 01 1408 4448 0 0 129
[...]
And that is followed by events that look something like this:
E: 1382571966.639767 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
E: 1382571966.650972 0003 0036 4044 # EV_ABS / ABS_MT_POSITION_Y    4044
E: 1382571966.650972 0003 003a 0041 # EV_ABS / ABS_MT_PRESSURE      41
E: 1382571966.650972 0003 0001 4044 # EV_ABS / ABS_Y                4044
E: 1382571966.650972 0003 0018 0041 # EV_ABS / ABS_PRESSURE         41
E: 1382571966.650972 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
E: 1382571966.663486 0003 0039 -001 # EV_ABS / ABS_MT_TRACKING_ID   -1
E: 1382571966.663486 0001 014a 0000 # EV_KEY / BTN_TOUCH            0
E: 1382571966.663486 0003 0018 0000 # EV_ABS / ABS_PRESSURE         0
E: 1382571966.663486 0001 0145 0000 # EV_KEY / BTN_TOOL_FINGER      0
E: 1382571966.663486 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
With the bits we need to replay on the left, and comments for humans on the right.

The comments with the human-readable description are new in version 1.1.0 which makes it finally useful as a replacement for evtest. Previously I had to either replay a device and look at the replay with evtest to make sense of something. But then again, previously the evemu repo was on launchpad, so having to use two tools was less painful than working with bzr...

To replay a device, you'll need two tools: evemu-device and evemu-play. The former creates a device based on the device description. The latter pumps the events into the newly created device.

$> sudo evemu-device my-device-recording.txt
CyPS/2 Cypress Trackpad: /dev/input/event17
$> sudo evemu-play /dev/input/event17 < my-device-recording.txt
And that's it. You've created a new device and that device now spits out the events as recorded. evemu-play will replay the events so that the timing is as close as possible to the original recording, meaning that you can reproduce most bugs.

Speaking of bugs: if you have an input-related bug that is triggered by a given event sequence, record your device. Make sure the recording reproduces the bug and attach the file to the bugreport. I almost always ask for an evemu recording anyway, so having that ready just speeds up the process.

[1] uinput doesn't let you set some fields but that is fine for 95% of the use cases
[2] There used to be evemu-describe, but that's a symlink to evemu-record now

Friday, November 1, 2013

Neues deutsches Tastaturlayout (Changes to the German keyboard layout)

Ich hab's zuerst nicht bemerkt, darum kommt diese Warnung etwas spät. Dennoch: seit Fedora 19 (xkeyboard-config 2.8) gibt es eine kleine Änderung im deutschen Tastaturlayout.

Die Tilde taste ("~"), zu finden neben der Entertaste, betätigt mit AltGr und "+" war ein sogenannter dead key. Solche dead keys ermöglichen es mit mehreren Eingaben Buchstaben wie etwa "ñ" zu erzeugen (tilde + n). dead key hieß allerdings auch dass, um eine tatsächliche Tilde einzugeben, "~", die Taste zweimal betätigt werden musste. Dieses Layout war anders als die DIN und das Standardlayout in Windows und wurde daher geändert. Siehe (fdo bug 9753). Die neue Belegung ist Tilde, ohne dead key Funktionalität.

Falls das alte Layout bevorzugt wird, muss das Layout auf Deutsch(veraltet) gestellt werden. Dies kann entweder über setxkbmap -layout "de(legacy)" bzw. setxkbmap -layout "de" -variant "legacy" geändert werden, bzw in GNOME über eine etwas versteckte Option. Im "Region und Sprache" Dialog den "+" Button betätigen, danach die drei vertikalen Punkte anklicken. Das öffnet das Suchfenster, wo dann nach Deutsch(veraltet) gesucht werden kann. Diesen Eintrag wählen und fertig.

Actually typed this in English first and then felt a bit silly. Anyway, here's the English version:

Ok, I'm a bit late here because I didn't notice and apparently most Fedora users with a German keyboard layout didn't either. Nevertheless, a PSA: the keyboard has changed upstream in version 2.8 which is the one we're shipping in Fedora 19 and thus later versions as well.

The tilde "~" key, on AltGr and the + key, left of the Enter key, used to be a dead key. Dead keys allow multi-key combinations. In this specific case the dead key tilde followed by n would produce ñ. It also means that to type an actual "~" the tilde key had to be typed twice. This layout was against the DIN norm and differed from the default Windows layout too, so it was changed to a normal tilde (see fdo bug 9753, opened in 2007!).

If you prefer the old workings, you'll need to switch to the German(legacy) variant. If you configure with setxkbmap, simply use setxkbmap -layout "de(legacy)" or setxkbmap -layout "de" -variant "legacy". If you're using GNOME, the configuration is a little hidden. Fire up the "Region & Language" dialog in the control center ("Region und Sprache"), hit the little + button and then the three vertical dots which open up the search field.

Search for "legacy" and you'll see German(legacy) pop up. Select it and you're good to go. If you have your desktop in German, the entry to search for "Deutsch (veraltet)".