Hotkeys

Differences between revisions 10 and 27 (spanning 17 versions)
Revision 10 as of 2008-10-29 05:26:12
Size: 11737
Editor: c-67-168-235-241
Comment:
Revision 27 as of 2009-07-08 14:31:12
Size: 2395
Editor: pD9EB7542
Comment: removed diagrams, they are obsolete, and Architecture has updated version now
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
----
'' '''NOTE:''' This document is a work in progress. ACPI is a complex subsystem and impossible for any one person to fully understand. Please take a few minutes to improve this document with the bits you know!''
----
== Contents ==
Line 7: Line 5:
== Hotkey Debugging Guide ==  * [[Hotkeys/Troubleshooting|Hotkey Troubleshooting Guide]]
 * [[Hotkeys/Architecture|Hotkeys Architecture Overview]]
Line 9: Line 8:
=== Involved Components === == Todo ==
Line 11: Line 10:
ACPI events cross a lot of different layers, and determining the component that is handling them can take quite a bit of digging. Below is a non-comprehensive list of components which have been known to handle hotkey events:

Most commonly at fault:
 * gnome-power-manager - handles brightness and power hotkeys. Displays a popup 'OCD' display
 * pm-utils
 * hotkey-setup
 * acpi-support
 * xserver-xorg-input-evdev

Less commonly at fault, but sometimes involved:
 * acpid
 * linux kernel
 * gnome-settings-daemon
 * hal
 * xkeyboard-config
 * gdm

Note that the 'acpi' source package is *not* involved in any of this, although many acpi/hotkey issues get (incorrectly) filed against it. 'acpi' is just a command line tool for listing info about acpi devices.

=== Common Classes of Hotkey Issues ===

 * '''Performs no effect''' - Either the event is not being generated, nothing is listening for the event, or something has grabbed the event but failed to act on it.

 * '''Fails when performing action''' - Something is definitely grabbing the event, but either it's the wrong thing to handle it, or is triggering the action in a way that causes a fault somewhere.

 * '''Key doesn't produce balanced KeyPress/KeyRelease events, or produces multiple events''' - Suggests perhaps a kernel issue.

 * '''Performs wrong action''' - Suggests the key is mapped incorrectly. There are several layers where these mappings are done.

=== Useful Information to Collect in Reports ===

 * `lshal -m > lshal.log`
 * `dmesg > dmesg.log`
 * `lsinput > lsinput.log`
 * `xkbcomp -xkb :0 - > xkbcomp.txt`
 * `setxkbmap -print > xkbmap.txt`

=== Troubleshooting Tricks and Tips ===

 * Testing: Before making changes, make a list of all your keys and hit each of them in turn, and record how they work. Repeat this after every change, so you'll know if a change fixed one thing but broke something else.

 * Running acpid in debug mode: acpid -d. This should display output for software events when hitting hotkeys.

 * Disable different suspects. If the issue goes away or changes behavior with one of these turned off, and comes back when it's on, then that strongly points to an issue in that particular component:
  * acpid: /etc/init.d/acpid stop
  * gnome-power-manager: killall gnome-power-manager; gnome-power-manager --verbose --no-daemon > gpm.log
  * hotkey-setup: /etc/init.d/hotkey-setup stop
  * gdm: From console, /etc/init.d/gdm stop; startx

 * Run `acpi_listen`, strike the hotkey, and see what gets printed out.

 * Run `input-events <device-number>` (use lsinput to identify what event devices you have and which to look at)

 * Log out of X to the console and run `showkey -s` to see the low level codes being sent by the keyboard

 * Run gnome-power-manager in verbose mode to get detailed debug info

 * Experiment with the scripts in /etc/acpi/. These come into play only for *some* hardware so may not be relevant for your case.

 * Switch to a virtual terminal and back (e.g. ctrl+alt+F1 ; ctrl+alt+f7) and see if that resets things

 * Switch to the Guest Account and see if the issue can be reproduced.

 * Boot a LiveCD and try reproducing it there. If you can't, it suggests either a modification to your system or a software update not present on the LiveCD.

 * Create a test user account, log out of all sessions and into that one. If you can't reproduce the issue there, then suspect some stored gconf or other settings in your dot files. (This is less likely if you've recently done a fresh install, vs. upgraded from past versions of Ubuntu.)

 * Run `xev` to view the key codes being seen and processed in X. Here's a command that gives cleaner output:
{{{
xev | sed -n 's/^.*state \([0-9].*\), keycode *\([0-9]\+\) *\(.*\), .*$/keycode \2 = \3, state = \1/p'
}}}

 * If the kernel is suspected, try booting an older kernel (e.g. 2.6.26 -> 2.6.24). If the hotkey still does not work then this decreases the likelihood that the kernel is at fault.

 * If X is suspected, log out of X and boot into Recovery Mode and get a root shell. If you can reproduce the problem exactly there, then X is not at fault.

 * If the key used to work properly at one time, and you've narrowed the problem to a specific component, then try testing different past versions of that package to try to bracket where the regression first started. This can help narrow down what patch might have caused the problem.

== Hotkey Architecture ==

Here is the birds-eye view of how key mapping works: The kernel recognizes the key and establishes a raw scancode and maps it to an arbitrary kernel keycode (e.g. e06d -> 120). Xorg reads the kernel's keycode table, and generates it's own list of X keycodes (e.g. 120 -> 136). X then maps each X keycode to a keysym (e.g. 136 -> XF86AudioMedia). Finally, the window manager maps the keysym to a desired window manager shortcut action or an application command (e.g. XF86AudioMedia -> rhythmbox).

=== Part A: Kernel keyboard mapping ===

Find the "raw scancode" of the key in question. Typically for PS/2 keyboards this can be done from a tty console by hitting the key, and looking at {{{dmesg}}} output. For instance, if we are hitting the 'Media' key on a Dell Inspiron, we might see:

{{{
        atkbd.c: Unknown key pressed (translated set 2, code ... on isa0060/serio0).
        atkbd.c: Use 'setkeycodes e06d <keycode>' to make it known.
}}}

In the above, {{{e06d}}} is what we're looking for.

Another way to get the kernel keycodes is to shutdown X and hotkey-setup (e.g. {{{/etc/init.d/gdm stop ; /etc/init.d/hotkey-setup stop}}}) and then run {{{showkey -s}}} for raw scancodes or {{{showkey -k}}} for keycodes. Then restart hotkey-setup and gdm. This will give output for Media on a Dell Inspiron 1505N like:

{{{
0x9c
0x00 0x80 0xe2
0x80 0x81 0xe2
}}}

For USB controlled keys, an alternate approach is to run {{{lshal -m}}} from a console window and then hit the key. This should return something like:

{{{
    17:51:47.996: platform_i8042_i8042_KBD_port_logicaldev_input condition ButtonPressed = media
}}}
 
In this case, {{{media}}} is the key we're interested in. If ButtonPressed shows up as undefined, then the USB driver needs to be updated to support mapping this key to a Linux keycode (currently these are all compiled into the USB driver).

In some cases, your keys may be generating ACPI events instead of standard keycodes. To check this, run {{{sudo tail -f /var/log/acpid}}} and then hit the key. You should see something like:

{{{
received event "ibm/hotkey HKEY 00000080 00001010"
}}}

The interesting bits here is the part between the quotes. [What do we do with this info?]

On IBM/Lenovo laptops, some keys are only accessible via {{{/dev/nvram}}}.

Identify the kernel keycode to use by referring to {{{/usr/share/hotkey-setup/key-constants}}}. For example, browsing through the file we find KEY_MEDIA:

{{{
...
KEY_BRIGHTNESSDOWN=224
KEY_BRIGHTNESSUP=225
KEY_MEDIA=226
KEY_SWITCHVIDEOMODE=227
KEY_KBDILLUMTOGGLE=228
...
}}}

These codes are defined in {{{/usr/include/linux/input.h}}}.

=== Part B: Hal ===

Set up the kernel keycode mapping for the keyboard layout. These can be set up via HAL quirks. See [[http://people.freedesktop.org/~hughsient/quirk/quirk-keymap-try.html|Keymap Quirk Debugger]] for details. Essentially, you need to add or update a section in the appropriate FDI file in {{{/usr/share/hal/fdi/information/10freedesktop/}}}, such as {{{30-keymap-dell.fdi}}} for a Dell Inspiron 1505N:

{{{
...
 <!-- Dell Inspiron 9400, 640m, E1505/6400 -->
        <match key="/org/freedesktop/Hal/devices/computer:system.hardware.product" prefix_outof="MP061;MXC061;MM061">
          <append key="input.keymap.data" type="strlist">e005:brightnessdown</append> <!-- Fn+Down arrow Brightness Down -->
          <append key="input.keymap.data" type="strlist">e006:brightnessup</append> <!-- Fn+Up arrow Brightness Up -->
          <append key="input.keymap.data" type="strlist">e007:battery</append> <!-- Fn+F3 battery icon -->
          <append key="input.keymap.data" type="strlist">e008:wlan</append> <!-- Fn+F2 Toggle WiFi -->
          <append key="input.keymap.data" type="strlist">e008:bluetooth</append> <!-- FIXME Bluetooth switch (same as wireless) -->
          <append key="input.keymap.data" type="strlist">e009:ejectclosecd</append> <!-- Fn+F10 Eject CD -->
          <append key="input.keymap.data" type="strlist">e00a:suspend</append> <!-- Fn+F1 hibernate -->
          <append key="input.keymap.data" type="strlist">e00b:switchvideomode</append> <!-- Fn+F8 CRT/LCD -->
          <append key="input.keymap.data" type="strlist">e012:media</append> <!-- MediaDirect button (house icon) -->
          <append key="info.capabilities" type="strlist">input.keymap</append>
        </match>
...
}}}

So for instance, to support the {{{e06d}}} code we found before, we'd create a new section like the above, substituting in {{{e06d}}} for {{{e012}}} (and any other codes that need remapping), into a new product section.

Use {{{lshal | grep system.hardware.product}}} and {{{lshal | grep system.hardware.vendor}}} to determine the product name and vendor of your laptop.

To see if hal has picked up your keymaps, restart the hal daemon and use {{{lshal | grep keymap}}}, which gives output like:

{{{
  info.callouts.add = {'hal-setup-keymap'} (string list)
  info.capabilities = {'input', 'input.keyboard', 'input.keypad', 'input.keys', 'input.keymap', 'button'} (string list)
  input.keymap.data = {'e005:brightnessdown', 'e006:brightnessup', 'e007:battery', 'e008:wlan', 'e008:bluetooth', 'e009:ejectclosecd', 'e00a:suspend', 'e00b:switchvideomode', 'e012:media'} (string list)
}}}


=== Part C: Gnome/KDE hotkey mapping ===

At this point, {{{gnome-keybinding-properties}}} should now be able to detect your key. Check this by setting it for "Launch help browser" for example.
 * Move mis-filed hotkey bugs into more correct packages:
   * https://bugs.edge.launchpad.net/ubuntu/+source/hotkeys
   * https://bugs.edge.launchpad.net/ubuntu/+source/acpi
   * https://bugs.edge.launchpad.net/ubuntu/+source/hotkey-setup
   * (DONE) https://bugs.edge.launchpad.net/ubuntu/+source/xorg
   * (DONE) https://bugs.edge.launchpad.net/ubuntu/+source/xkeyboard-config
   * https://bugs.edge.launchpad.net/ubuntu/+source/xserver-xorg-input-keyboard
 * Work through Hotkeys/Troubleshooting a few times to make sure it gives good guidance
 * Cleanup and improve Hotkeys/Architecture
 * Migrate key support out of acpid to more appropriate packages
 * Migrate key support out of acpi-support to appropriate proper packages
 * Migrate key support out of hotkey-setup to appropriate proper packages
Line 199: Line 38:
 * [[http://rdist.root.org/2008/10/17/all-about-acpi/|All About ACPI]]

Laptops have special functions such as sleep or brightness that are implemented through either buttons outside the main keyboard or key combinations using the Fn key. These are called "hotkeys", and are typically implemented in the laptop hardware and BIOS via the Advanced Configuration and Power Interface (ACPI).

Contents

Todo

See Also

Hotkeys (last edited 2009-07-08 14:31:12 by pD9EB7542)