Sleep Quirk Debugger

Back to the main keymap page

Trying keymaps by editing FDI files

If the quirks are added to a local fdi data file, then the quirks get used automatically when starting the system.

Editing a local fdi file to test

Now we can edit an fdi file for a fictional IBM laptop.

[root@localhost ~]# cd /usr/share/hal/fdi/information/10freedesktop
[root@localhost 10freedesktop]# ls 30-keymap-*
30-keymap-lenovo.fdi
[root@localhost 10freedesktop]# gedit 30-keymap-lenovo.fdi

Now the following XML is displayed:

...
    <match key="system.hardware.vendor" prefix="LENOVO">
      <match key="system.hardware.version" contains="3000">
        <append key="input.keymap.data" type="strlist">e016:wifi</append> <!-- Fn+F5 Wireless -->
        <append key="input.keymap.data" type="strlist">e017:sleep</append> <!-- Fn+F4 Suspend -->
        <append key="input.keymap.data" type="strlist">e018:suspend</append> <!-- Fn+F12 Hibernate -->
        <append key="info.capabilities" type="strlist">input.keymap</append>
      </match>
    </match>
...

This means, match any vendor that starts with LENOVO and any machine with 3000 in the version string. So basically this rule matches Lenovo laptops in the 3000 range.

The input.keymap.data is the actual mapping data. The second line actually means 'Take the hex scancode e017 and make it activate key wifi. The bit after the last tag is just a comment, so other people know what key combination to press to get this scancode. In this case, we have to press the Fn key and then F4, which has got a little yellow suspend symbol above it.

Random Numbers?

But hey, how did I choose the magic number e017 and wifi? The attentive amongst you will recognize the e017 from the dmesg output - this is the scancode of the FnF4 button and should be unique for each of the unmapped buttons. The other number is the keycode name in lower case, and these can be found in the file /usr/include/linux/input.h. There is a list sorted by name available here.

[NOTE]

What do I do if there are two separate keycodes for the same key?

It's probably emulating a toggle key. We have no good solution for this now, just include both in the FDI file with a comment and we can fix this later.

We want to a description that explains what the button is doing. For instance, on multimedia keyboards you might want to use volumedown or power.

This is where it gets slightly tricky for suspend and hibernate. There is quite some confusion about sleep states between input and userspace. The keys used in input.h are badly named, but we have to keep these to maintain compatibility.

ActionKernel Input Key Name
Suspendsleep
Hibernatesuspend

Other common keys not present in input.h are defined as follows:

ActionKernel Input Key Name
Rotate Screenf21
Touchpad togglef22
Undockf24
Auto Brightnessf23

If you are using one of the substituted keys above, please note in the FDI file what you think the button should be (for instance rotatescreen and then when input.h is updated we change all the files automatically.

Keys that are difficult to map (but agreed upon) are defined as follows:

ActionKernel Input Key Name
Lockscreenlock
Take a picturecamera
Internetwww
Wifi togglewlan
Wifi and bluetooth toggleradio

If you really cannot find a name for a really oddball key (a make button for instance) then please use prog1 and add a note in the XML.

Matching

So, now we know where to get the scancode and the keyname from. Now we have to make rules up for our machine type so we can match it.

[NOTE]

Do I add keys where the event if done in hardware?

Yes, as we may need to tell userspace to do something, for instance show an on screen display or re-read the register state.

Keys you should be using are as follows:

system.hardware.product
system.hardware.vendor
system.hardware.version
system.firmware.version
system.chassis.manufacturer

The values of these can be found with lshal or gnome-device-manager. It is a lot easier if you just modify an existing entry or copy and paste the match tags. For instance, if there was a Lenovo 4000 range of laptops, I would copy the Lenovo 3000 match section and change the number.

[NOTE]

On some IBM and Lenovo hardware the suspend and hibernate keys generate key up and key down events. They do not generate subsequent events until the hardware has been suspended, hibernated or rebooted.

We think this is a firmware feature (bug?) and no known workaround is currently known.

Now, hypothetically, we want to add a Lenovo ThinkPad X41. We can find the values of system.hardware.* using:

[root@localhost 10freedesktop]# lshal | grep system.hardware
  system.hardware.product = '1807Y8J'  (string)
  system.hardware.serial = 'xxxxxxx'  (string)
  system.hardware.uuid = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'  (string)
  system.hardware.vendor = 'LENOVO'  (string)
  system.hardware.version = 'ThinkPad X41'  (string)

We need to restart HAL to set the new keymap using either:

[root@localhost ~]# /sbin/service haldaemon restart
Stopping HAL daemon:                                       [  OK  ]
Starting HAL daemon:                                       [  OK  ]

or:

sudo /etc/init.d/hal restart

To check the quirk has been detected and is present you can do:

lshal | grep keymap

Hopefully then pressing the keys should have a response in xev. When the new key is pressed you should be notified of the key up and the key down event with the correct keycode. This will allow you to use gnome-keybindings-properties to assign an action for the key. Please take the few extra steps to submit this data so that keymap just works for less technical users.

Back to the main keymap page