Difference between revisions of "How to get special keys to work"

From ThinkWiki
Jump to: navigation, search
m (ACPI events from the button module)
m (Weblinks: add category)
 
(11 intermediate revisions by 8 users not shown)
Line 16: Line 16:
 
| {{key|Fn}}{{key|F5}} || switch bluetooth || [[thinkpad-acpi]] || full || in models starting from 2002
 
| {{key|Fn}}{{key|F5}} || switch bluetooth || [[thinkpad-acpi]] || full || in models starting from 2002
 
|-
 
|-
| {{key|Fn}}{{key|F6}} || - || [[thinkpad-acpi]] || full ||
+
| {{key|Fn}}{{key|F6}} || Video conference || || || Starting with the T400s (icon of a camera and a headset)
 
|-
 
|-
 
| {{key|Fn}}{{key|F7}} || toggle display || [[thinkpad-acpi]], [[#tpb configuration|tpb]] || additional actions || [[Sample Fn-F7 script]]
 
| {{key|Fn}}{{key|F7}} || toggle display || [[thinkpad-acpi]], [[#tpb configuration|tpb]] || additional actions || [[Sample Fn-F7 script]]
Line 71: Line 71:
 
|-
 
|-
 
| {{ibmkey|Volume mute|#494949}} || mute volume || [[thinkpad-acpi]], [[#tpb configuration|tpb]], [[KMilo]] || additional actions ||
 
| {{ibmkey|Volume mute|#494949}} || mute volume || [[thinkpad-acpi]], [[#tpb configuration|tpb]], [[KMilo]] || additional actions ||
 +
|-
 +
| {{ibmkey|Microphone mute|#494949}} || Microphone volume || || || Starting with the T400s
 
|-
 
|-
 
| {{ibmkey|Play/Pause|#494949}} || start/pause playback  || [[#xmodmap configuration|xmodmap]] || full || {{X60s}} (Fn+Arrow Down)
 
| {{ibmkey|Play/Pause|#494949}} || start/pause playback  || [[#xmodmap configuration|xmodmap]] || full || {{X60s}} (Fn+Arrow Down)
Line 118: Line 120:
  
 
These events can be used to configure HAL or [[How to configure acpid|acpid]].
 
These events can be used to configure HAL or [[How to configure acpid|acpid]].
 +
 +
{{WARN|The below list of ACPI key events seems to have been invalidated on some platforms by a recent update (March 2013) - for details, see  [[Talk:Thinkpad-acpi#Problem_with_ACPI_key_event_codes_in_OpenSuse_12.3|Problem with ACPI key event codes in OpenSuse 12.3]].}}
  
 
{| {{prettytable}}
 
{| {{prettytable}}
Line 166: Line 170:
 
|-
 
|-
 
| {{ibmkey|Volume mute|#494949}} || ibm/hotkey HKEY 00000080 00001017 || 0x16:mute || 0x16:mute
 
| {{ibmkey|Volume mute|#494949}} || ibm/hotkey HKEY 00000080 00001017 || 0x16:mute || 0x16:mute
 +
|-
 +
| {{ibmkey|Microphone mute|#494949}} || ibm/hotkey HKEY 00000080 0000101b || ||
 
|-
 
|-
 
| {{ibmkey|Access IBM|#495988}} or {{ibmkey|ThinkPad|#494949}} or {{ibmkey|ThinkVantage|#495988}} || ibm/hotkey HKEY 00000080 00001018 || 0x17:prog1 || 0x17:prog1
 
| {{ibmkey|Access IBM|#495988}} or {{ibmkey|ThinkPad|#494949}} or {{ibmkey|ThinkVantage|#495988}} || ibm/hotkey HKEY 00000080 00001018 || 0x17:prog1 || 0x17:prog1
Line 182: Line 188:
 
=== ACPI events from the <tt>button</tt> module===
 
=== ACPI events from the <tt>button</tt> module===
  
A few keys can generate ACPI events that result from the <tt>button</tt> kernel module, as long as they are masked off in the /<tt>thinkpad-acpi</tt> hotkey's mask or the hotkey function of the latter module is disabled.
+
A few keys can generate ACPI events that result from the <tt>button</tt> kernel module, as long as they are masked off in the <tt>thinkpad-acpi</tt> hotkey's mask or the hotkey function of the latter module is disabled.
  
If you want the ThinkPad's BIOS and ACPI methods to know about these keys being pressed, you probably want to leave them masked out from ibm-acpi, and use their non-HKEY events listed below, instead.
+
If you want the ThinkPad's BIOS and ACPI methods to know about these keys being pressed, you probably want to leave them masked out from thinkpad-acpi, and use their non-HKEY events listed below, instead.
  
 
{| {{prettytable}}
 
{| {{prettytable}}
Line 204: Line 210:
 
====Xorg problems====
 
====Xorg problems====
 
You may find that by default some buttons will work in Xorg and others will not (e.g. Fn-Space). The reason for this is that Xorg is limited to 255 different key codes, and some keys are mapped to key codes that are out of range for Xorg. The Xorg developers are aware of this issue and plan to fix it in XKB2. Unfortunately support for XKB2 has slipped and is now planned for Xorg 1.8, sometime in 2010.
 
You may find that by default some buttons will work in Xorg and others will not (e.g. Fn-Space). The reason for this is that Xorg is limited to 255 different key codes, and some keys are mapped to key codes that are out of range for Xorg. The Xorg developers are aware of this issue and plan to fix it in XKB2. Unfortunately support for XKB2 has slipped and is now planned for Xorg 1.8, sometime in 2010.
 +
 +
{{HINT|You can get Fn-Space working via ACPI events. Here is a practical [http://www.thinkwiki.org/wiki/Installing_Ubuntu_10.04_(Lucid_Lynx)_on_a_ThinkPad_Z61m#Make_Fn-Space_.28Screen_Magnify.29_work HOWTO] for Ubuntu 10.04 Lucid}}
  
 
Default HAL config files are located in {{path|/usr/share/hal/fdi}}. If you create any custom files you should instead place them in {{path|/etc/hal/fdi}} to prevent them from getting overwritten by the next hal-info package update of your distribution.
 
Default HAL config files are located in {{path|/usr/share/hal/fdi}}. If you create any custom files you should instead place them in {{path|/etc/hal/fdi}} to prevent them from getting overwritten by the next hal-info package update of your distribution.
Line 225: Line 233:
 
     <!-- Warning: /etc/sudoers must be configured to let 'halevt' user
 
     <!-- Warning: /etc/sudoers must be configured to let 'halevt' user
 
         runs the given command ! -->
 
         runs the given command ! -->
     <halevt:Condition name="ButtonPressed" detail="wlan" exec="sudo /usr/local/sbin/toggle_wlan"/>
+
     <halevt:Condition name="ButtonPressed" value="wlan" exec="sudo /usr/local/sbin/toggle_wlan"/>
 
   </halevt:Device>
 
   </halevt:Device>
 
   </nowiki>
 
   </nowiki>
Line 237: Line 245:
 
===inputlirc configuration===
 
===inputlirc configuration===
  
An alternative to halevt is inputlirc. After installation of the packages inputlirc and lirc, you can test it with the irw command. To run custom scripts you need a configuration for the irexec daemon ('''/etc/lirc/lircrc''') :
+
An alternative to halevt is inputlirc [http://ajoute.org/wiki/doc/linux/inputlirc]. After installation of the packages inputlirc [http://packages.debian.org/search?keywords=inputlirc] and lirc, you can test it with the irw command. To run custom scripts you need a configuration for the irexec daemon ('''/etc/lirc/lircrc''') :
  
 
   <nowiki>
 
   <nowiki>
Line 592: Line 600:
 
<br><code># printf 'keycode 234 = XF86Back\nkeycode 233 = XF86Forward' >> /etc/X11/Xmodmap</code><br>
 
<br><code># printf 'keycode 234 = XF86Back\nkeycode 233 = XF86Forward' >> /etc/X11/Xmodmap</code><br>
 
And to make this take effect immediately (i.e., without having to log out and log in again), as a regular user run:
 
And to make this take effect immediately (i.e., without having to log out and log in again), as a regular user run:
<br><code>{{cmduser|Xmodmap /etc/X11/Xmodmap}}</code>
+
<br>{{cmduser|Xmodmap /etc/X11/Xmodmap}}
  
 
For Hardy Heron, the xmodmap command is all lowercase. Also, the /etc/X11/Xmodmap file is not being read on boot. I've added the command to my .bashrc to have it called on startup.
 
For Hardy Heron, the xmodmap command is all lowercase. Also, the /etc/X11/Xmodmap file is not being read on boot. I've added the command to my .bashrc to have it called on startup.
Line 612: Line 620:
 
To get them switch through your tabs, you could use the extension from [http://crashman.homelinux.org/~andre/public/epiphany%20extensions/thinkpad%20browserkeys/ here]
 
To get them switch through your tabs, you could use the extension from [http://crashman.homelinux.org/~andre/public/epiphany%20extensions/thinkpad%20browserkeys/ here]
 
You just need to edit your Xmodmap like described for Firefox < 3.0 (bind the keys on F19 and F20)
 
You just need to edit your Xmodmap like described for Firefox < 3.0 (bind the keys on F19 and F20)
 +
 +
====W3M (under Emacs)====
 +
I'm not sure that I want to use the back and forward keys all the time in Emacs, but while browsing the web it is useful to have them.
 +
 +
On my X61s running Fedora 13, I've found that by adding the following lines to my .emacs, I'm able to do just that:
 +
 +
<code>(eval-after-load "w3m"<br>'(progn<br>(define-key w3m-mode-map [XF86Back] 'w3m-view-previous-page)<br>  (define-key w3m-mode-map [XF86Forward] 'w3m-view-next-page)))</code>
  
 
===Open an application===
 
===Open an application===
Line 752: Line 767:
 
#Thanks go to Ryan Barrett for writing the [http://snarfed.org/space/thinkpad+keys+in+firefox little howto] on [http://snarfed.org/space/start his blog].
 
#Thanks go to Ryan Barrett for writing the [http://snarfed.org/space/thinkpad+keys+in+firefox little howto] on [http://snarfed.org/space/start his blog].
 
}}
 
}}
 +
 +
== Weblinks ==
 +
* http://www.freedesktop.org/wiki/Software/XKeyboardConfig
 +
 +
[[Category:HOWTOs]]

Latest revision as of 02:13, 15 February 2016

Overview

The following table gives an overview over the special keys found on ThinkPads and what is needed to make them work.

key standard function1 tools supporting key2 configurability3 remarks
Fn - xmodmap, tpb full on release without completed key combination
FnF1 - thinkpad-acpi full
FnF2 lock screen thinkpad-acpi full in models from T/X/Z 60 onwards
FnF3 blank screen thinkpad-acpi full
FnF4 suspend to ram thinkpad-acpi full may generate ACPI event when not enabled in the thinkpad-acpi hotkey mask
FnF5 switch bluetooth thinkpad-acpi full in models starting from 2002
FnF6 Video conference Starting with the T400s (icon of a camera and a headset)
FnF7 toggle display thinkpad-acpi, tpb additional actions Sample Fn-F7 script
FnF8 toggle trackpoint/touchpad thinkpad-acpi, tpb additional actions
FnF9 eject from dock thinkpad-acpi full
FnF10 - thinkpad-acpi full
FnF11 - thinkpad-acpi full
FnF12 hibernate thinkpad-acpi full may generate ACPI event when not enabled in the thinkpad-acpi hotkey mask
FnHome / FnPos1 brightness up thinkpad-acpi, tpb, KMilo additional actions
FnEnd brightness down thinkpad-acpi, tpb, KMilo additional actions
FnPageUp toggle thinklight thinkpad-acpi, tpb, KMilo additional actions
FnSpace toggle zoom thinkpad-acpi, tpb, KMilo full
FnIns - thinkpad-acpi full
FnDel - thinkpad-acpi full
FnBackspace - thinkpad-acpi full
NumLock - xmodmap make working
Windows - xmodmap remapping
Access IBM or ThinkPad or ThinkVantage help application thinkpad-acpi,tpb, KMilo full
Home open web browser xmodmap, tpb, KMilo full only A30, A30p, A31, A31p and ext. keyboards
Search open search application xmodmap, tpb, KMilo full only A30, A30p, A31, A31p and ext. keyboards
Mail open mail application xmodmap, tpb, KMilo full only A30, A30p, A31, A31p and ext. keyboards
Favorites open favorites xmodmap, tpb full only A30, A30p, A31, A31p and ext. keyboards
Reload reload web page xmodmap, tpb full only A30, A30p, A31, A31p and ext. keyboards
Abort abort loading page xmodmap, tpb full only A30, A30p, A31, A31p and ext. keyboards
Backward previous page xmodmap, tpb full ext. keyboards and ThinkPads starting from 2002
Forward next page xmodmap, tpb full ext. keyboards and ThinkPads starting from 2002
Volume up volume up thinkpad-acpi, tpb, KMilo additional actions
Volume down volume down thinkpad-acpi, tpb, KMilo additional actions
Volume mute mute volume thinkpad-acpi, tpb, KMilo additional actions
Microphone mute Microphone volume Starting with the T400s
Play/Pause start/pause playback xmodmap full X60s (Fn+Arrow Down)
Stop stop playback xmodmap full X60s (Fn+Arrow Up)
Next play next xmodmap full X60s (Fn+Arrow Right)
Previous play previous xmodmap full X60s (Fn+Arrow Left)
Power shutdown thinkpad-acpi full triggered on pressing 3secs, but notebook goes off on 5sec press
Display lid blank screen acpi video full
Ultrabay eject announce ultrabay change acpi bay full
Dock eject eject from dock acpi dock full
Tablet power shutdown thinkpad-acpi full triggered on pressing 3secs, but notebook goes off on 5sec press
Tablet orientation rotates screen setkeycodes full
Tablet shortcut shortcut menu setkeycodes full
Tablet Esc esc key setkeycodes full
Tablet Enter enter key setkeycodes full
Tablet Up up key setkeycodes full
Tablet Down down key setkeycodes full
Tablet (unlabeled) down key setkeycodes full

For completeness, note that the WiFi enable/disable switch is located (on the X61 and other models that have it) just under the front edge of the base of the machine. You should see a small horizontal slider switch. Enable by sliding it rightwards, disable by sliding it leftwards.

Tablet buttons vary with model. See Tablet Hardware Buttons.

Triggering key events

thinkpad_acpi events

The thinkpad_acpi driver should automatically select an appropriate mask for your machine. But on a rare occasions you might need to change the hotkey mask for key events to happen. In that case, read the recommended hotkey_mask from hotkey_recommended_mask, set the extra bits you need, and write the result to hotkey_mask. These files (actually, "sysfs attributes") can be found on sys/devices/platform/thinkpad_acpi

These events can be used to configure HAL or acpid.

ATTENTION!
The below list of ACPI key events seems to have been invalidated on some platforms by a recent update (March 2013) - for details, see Problem with ACPI key event codes in OpenSuse 12.3.
events triggered by thinkpad-acpi. May vary on different models.
key acpi event IBM ThinkPad hal event Lenovo ThinkPad hal event
FnF1 ibm/hotkey HKEY 00000080 00001001
FnF2 ibm/hotkey HKEY 00000080 00001002 0x01:battery 0x01:screenlock
FnF3 ibm/hotkey HKEY 00000080 00001003 0x02:screenlock 0x02:battery
FnF4 ibm/hotkey HKEY 00000080 00001004 0x03:sleep 0x03:sleep
FnF5 ibm/hotkey HKEY 00000080 00001005 0x04:radio 0x04:radio
FnF6 ibm/hotkey HKEY 00000080 00001006
FnF7 ibm/hotkey HKEY 00000080 00001007 0x06:switchvideomode 0x06:switchvideomode
FnF8 ibm/hotkey HKEY 00000080 00001008 0x07:zoom 0x07:f22
FnF9 ibm/hotkey HKEY 00000080 00001009 0x08:f24 0x08:f24
FnF10 ibm/hotkey HKEY 00000080 0000100a
FnF11 ibm/hotkey HKEY 00000080 0000100b
FnF12 ibm/hotkey HKEY 00000080 0000100c 0x0b:suspend 0x0b:suspend
FnBackspace ibm/hotkey HKEY 00000080 0000100d
FnIns ibm/hotkey HKEY 00000080 0000100e
FnDel ibm/hotkey HKEY 00000080 0000100f
FnHome/FnPos1 ibm/hotkey HKEY 00000080 00001010 0x0f:brightnessup 0x0f:brightnessup
FnEnd ibm/hotkey HKEY 00000080 00001011 0x10:brightnessdown 0x10:brightnessdown
FnPgUp ibm/hotkey HKEY 00000080 00001012 0x11:kbdillumtoggle 0x11:kbdillumtoggle
FnSpace ibm/hotkey HKEY 00000080 00001014 0x13:zoom 0x13:zoom
Volume up ibm/hotkey HKEY 00000080 00001015 0x14:volumeup 0x14:volumeup
Volume down ibm/hotkey HKEY 00000080 00001016 0x15:volumedown 0x15:volumedown
Volume mute ibm/hotkey HKEY 00000080 00001017 0x16:mute 0x16:mute
Microphone mute ibm/hotkey HKEY 00000080 0000101b
Access IBM or ThinkPad or ThinkVantage ibm/hotkey HKEY 00000080 00001018 0x17:prog1 0x17:prog1
Ultrabay eject ibm/bay MSTR 00000003 00000000
Ultrabay inserted ibm/bay MSTR 00000001 00000000
Dock eject ibm/dock GDCK 00000003 00000001
Wireless switch ibm/hotkey HKEY 00000080 00007000

By disassembling and editing the DSDT, more events can be added. HKEY events are triggered by calls to the MKHQ function, e.g. \_SB.PCI0.LPC.EC.HKEY.MHKQ(0×1007) will trigger "ibm/hotkey HKEY 00000080 00001007". Most of these can be found in _Qxx methods within the DSDT, which are executed on embedded controller events, e.g. _Q10 is triggered by pressing Fn-F7. You can add a call to MKHQ into an existing _Qxx method to get it recognized by thinkpad-acpi as well as creating new _Qxx methods, which if you're lucky will correspond to an EC event that IBM never used (e.g. A 770 will send Fn-Home/End/PgUp/PgDn to thinkpad-acpi if hacked in this fashion). For example, this is a modified block of DSDT for a G40.

ACPI events from the button module

A few keys can generate ACPI events that result from the button kernel module, as long as they are masked off in the thinkpad-acpi hotkey's mask or the hotkey function of the latter module is disabled.

If you want the ThinkPad's BIOS and ACPI methods to know about these keys being pressed, you probably want to leave them masked out from thinkpad-acpi, and use their non-HKEY events listed below, instead.

events triggered by ACPI when hotkey is masked out or disabled.
key event T60 event
Power button/power PWRF 00000080 xxxxxxxx button/power PWRF 00000080 00000001
FnF4 button/sleep SLPB 00000080 00000001 button/sleep SLPB 00000080 00000001
Display lid button/lid LID 00000080 xxxxxxxx button/lid LID 00000080 00000001

Configuration using HAL

Modern distributions like Ubuntu 8.10 and Fedora 10 use HAL to configure the kernel input devices. Xorg in turn gets these key events through the evdev driver and will no longer try to take control of the input devices away from the kernel.

But before you get started on this you should make sure you have all the updates applied from your distro vendor as both Ubuntu 8.10 and Fedora 10 require some additional fixes that you might need.

Xorg problems

You may find that by default some buttons will work in Xorg and others will not (e.g. Fn-Space). The reason for this is that Xorg is limited to 255 different key codes, and some keys are mapped to key codes that are out of range for Xorg. The Xorg developers are aware of this issue and plan to fix it in XKB2. Unfortunately support for XKB2 has slipped and is now planned for Xorg 1.8, sometime in 2010.

Hint:
You can get Fn-Space working via ACPI events. Here is a practical HOWTO for Ubuntu 10.04 Lucid

Default HAL config files are located in /usr/share/hal/fdi. If you create any custom files you should instead place them in /etc/hal/fdi to prevent them from getting overwritten by the next hal-info package update of your distribution.

You can see for instance the mapping between /usr/share/hal/fdi/information/10freedesktop/30-keymap-module-thinkpad-acpi.fdi and that of the kernel input.h header file.

keyboard events defined in input.h in the 0x100 range and above will be ignored by current Xorg. If you want to work around this you can change the hal config file such that for instance the Fn-F5 key no longer maps to radio (0x181) but to wlan (238) or bluetooth (237).

Have a look at the HAL documentation for samples on how to configure your own events [1].

To check if a key is being handled by Xorg, start xev and press the key. If you do not see any output from the keypress it is not handled. If it is handled you can configure the key in Gnome with gnome-keybinding-properties (kde??).

bypassing Xorg

Since the keys are handled by the kernel and passed through hal, we can bypass Xorg and have a key run a specific task. This is useful if Xorg cannot handle the key (out of range, or X doesn't matter this input key), or if your not running X. This can be done with the halevt program (located at [2] ; for Debian systems, use a version >= 0.1.5-1). This program can react to some events detected by HAL such a special key press. For example, to run a custom script when Fn-F5 (Radio toggle) is pressed, you could put a stanza in halevt's configuration file (/etc/halevt/halevt.xml, in XML format) :

 
  <halevt:Device match="hal.info.category = input">
    <!-- Warning: /etc/sudoers must be configured to let 'halevt' user
         runs the given command ! -->
    <halevt:Condition name="ButtonPressed" value="wlan" exec="sudo /usr/local/sbin/toggle_wlan"/>
  </halevt:Device>
  

Here, sudo is used as the halevt daemon runs with its own user, which don't have required rights to do the work in the custom script /usr/local/sbin/toggle_wlan, so in /etc/sudoers, we have :

 halevt  ALL = NOPASSWD: /usr/local/sbin/toggle_wlan

Be careful when writing halevt configuration, as the daemon isn't very verbose about what it does or not : you don't get error messages when command run fails…

inputlirc configuration

An alternative to halevt is inputlirc [3]. After installation of the packages inputlirc [4] and lirc, you can test it with the irw command. To run custom scripts you need a configuration for the irexec daemon (/etc/lirc/lircrc) :

  
   begin
    prog = irexec
    button = KEY_RADIO
    config = /etc/acpi/wireless.sh
   end

   begin
    prog = irexec
    button = KEY_SCREENLOCK
    config = /etc/acpi/thinkpad-lockorbattery.sh
   end
   

tpb configuration

configuration keywords for tpb (to put in /etc/tpbrc)
key config keyword
Access IBM or ThinkPad THINKPAD
Home HOME
Search SEARCH
Mail MAIL
Favorites FAVORITES
Reload RELOAD
Abort ABORT
Backward BACKWARD
Forward FORWARD
Fn FN
FnSpace CALLBACK (zoom on/off)
FnPageUp CALLBACK (thinklight on/off)
FnF7 CALLBACK (display lcd/crt/both)
FnF8 CALLBACK (expand on/off)
FnHome / FnPos1 CALLBACK (brightness <percent>)
FnEnd CALLBACK (brightness <percent>)
Volume up CALLBACK (volume <percent>)
Volume down CALLBACK (volume <percent>)
Volume mute CALLBACK (mute on/off)

To all parameter keywords should be assigned the full path to the executables supposed to be started on key press. The exectable provided for the CALLBACK keyword should take the parameters given in parentheses and act according to them. If you want to use xmodmap for the HOME, SEARCH, MAIL, FAVORITES, RELOAD, ABORT, BACKWARD, FORWARD and FN keys you should provide a XEVENTS OFF in your /etc/tpbrc. You can use an appropriate executable to inject fake keystrokes.

For Debian users, tpb is started from /etc/X11/Xsession.d/90tpb.

Sound Button configuration

Note: Tested on T60p with Ubuntu 6.06 LTS

Most Thinkpads have a hardware sound mixer, thus the volumes buttons should work without configuration. However, this change is not reflected in the software mixer. tpb has a switch to enable software mixer support via OSS. The manual recommends this only for devices without a hardware mixer, but it also works for other hadware mixer enabled devices, even with the ALSA system. Just put MIXER ON in your /etc/tpbrc file and you can see the effect immediately in any ALSA mixer (e.g. kmix). For this to work you need write permissions to /dev/nvram.

Note: Tested on X21 with Ubuntu 6.06 LTS

On the ThinkPad X21 (and maybe some other older models) ACPI causes problems with tpb. On an X21 using acpi the volume buttons would work occasionally, and the OSD for tpb functions would rarely work. If a volume buttons was pressed too often, sometimes the computer would enter a low power (unplugged state) and would require a reboot. The solution is to use APM instead of ACPI. Instructions can be found in How_to_make_APM_work.

KMilo configuration

The programs to be executed by KMilo are configured via the KDE Control Center (kcontrol), under System Administration --> IBM Thinkpad Laptop. Note that you can use appropriate commands to inject fake keystrokes.

xmodmap configuration

xmodmap enables you to edit the modifier map and keymap tables that are used to translate keycodes into keysyms. Understood? Well, basically it allows you to give the X server a dictionary for the translation of keycodes like "97" into more human readable synonyms like "Home". This way xmodmap allows you to make the special keys of your keyboard known to X applications.

To discover the keycode that a certain keypress produces, use the tool $ xev

Usually you should write your keycode-keysym associations into the file ~/.Xmodmap. This file is usually read by the X session startup scripts of your system, so that the mappings automatically get included everytime you run the X server.

The ~/.Xmodmap lines for our purpose are in the form of

keycode <keycode> = <keysym>

Load the assocation using the command

$ xmodmap ~/.Xmodmap

(some configurations do this automatically upon X startup).

The following table shows the keycodes generated by the ThinkPad special keys and sensible keysyms to assign them to.

keycodes and recommended keysyms
key keycode keysym
Access IBM or ThinkPad 159 XF86LaunchA
Backward 234 XF86Back or F19
Forward 233 XF86Forward or F20
Play/Pause 162 XF86AudioPlay
Stop 164 XF86AudioStop
Next 153 XF86AudioNext
Previous 144 XF86AudioPrev
Home 178 XF86HomePage
Search 229 XF86Search
Mail 236 XF86Mail
Favorites 230 XF86AddFavorite or XF86Favorites
Reload 231 XF86Reload
Abort 232 XF86Stop
Fn 227 F35

Note: You can also use xkeycaps (an X tool to display and edit the X keyboard mapping) to generate proper .Xmodmap.

Note: if you are running tpb you might need to add the line XEVENTS=off into your tpbrc to stop it from grabbing the key events and allow them to get through to X instead. See [[5]] for more detailed instruction on how to use tpb and xmodmap.

Note: XF86Forward and XF86Back do not work correctly in Firefox. You may want to map them to F19 and F20 instead if you use Firefox.

Note: The "XF86AudioPlay" etc. just works with a few programs. To make it work with more multimedia programs you have map the key to use something like ReMoot. ReMoot is a command line wrapper that control 18 of the most common multimedia applications.

Enabling the Windows and Menu Keys

On some systems the Windows and Menu keys may not be recognized. You can enable then by making the following changes:

       keycode 115 = F13
       keycode 227 = F35

F13 and F35 are used for the Windows and and Menu keys respectively. Labelling keycpode 227 as "Menu" may conflict with the right-mouse-click event.

Using Caps Lock as Super L (Windows key)

You can easily use Caps Lock as Win key by adding the following in your ~/.Xmodmap:

       ! No Caps Lock
       clear lock
       ! Caps Lock as Win key
       add mod4 = Caps_Lock
NumLock

On the ThinkPad 600, T20, T21, T22, T30, X20, X21, X31, X40, T42p, T43, R51, R52 and possibly other models, X does not recognize the keycode for NumLk = Shift+ScrLk. To fix this, add the following to ~/.Xmodmap in your home directory or /etc/X11/Xmodmap and run xmodmap, ex: xmodmap ~/.Xmodmap:

keycode 77 = Num_Lock

The following might work better for you:

 keycode 77 = Num_Lock Num_Lock

because you will only get keycode 77 together with Shift (at least on the T43)

This configuration also enables the respective LED.

Please note, pressing the Shift+ScrLk key combination, without first following the above configuration, will start an accessibility feature, which will allow the numeric keypad to maneuver the mouse pointer. Starting this accessibility feature and subsequently running xmodmap, as described above, results in the accessibility feature and the numeric lock LED functioning simultaneously. As such, the above configuration should be completed before the accessibility feature is started in order to produce numbers.

T60 (and possibly others)

It seems that on the T60, PrtSc, ScrLk and Pause all generate the correct keycodes, however Fn-PrtSc (labelled as SysRq) generates keycode 64 (Alt_L) followed by the expected 111 (Sys_Req) on down and the same thing in the opposite order on release. Fn-ScrLk (labelled as NmLk) does indeed toggle the Numlock, but only seems to register as an X event the first time it is engaged. The above solution does not appear to work. This is perhaps because the Numlock toggle is built into the firmware rather than controlled by the kernel. Finally, Fn-Pause (labelled as Break) generates keycode 37 (Control_L) followed by the expected keycode 110 (Break) on down and the same thing in reverse order on release.

NumPad (KeyPad) keys access by a key combination

The current state is that you have to switch NumLock on via Fn+ScrLk and then e.g. type u to get a KP_4 (NumPad 4). To get back to normal keyboard, you have to type Fn+ScrLk again.

Some people (including me) are missing on recent Thinkpads the option to have Fn as a modifier key to access the NumPad instead, i.e. and e.g. Fn+u gives you KP_4.

There is currently no way to make this work in a simple way (pleeeease correct me if I am wrong!), though there is a work-around. Instead of using Fn for accessing the NumPad, CapsLock can get this function by being mapped as Mode_switch (the AltGr on international keyboards). The Fn can be remapped to be Caps_Lock - while at the same time retaining its function to access the special laptop functions (e.g. Fn+F4 for sleep}}, by using .Xmodmap.

So on my R60 running fvwm@Slackware 12.1 the .Xmodmap would look like this:

! Make the forward and back buttons work
   keycode 233 = XF86Forward
   keycode 234 = XF86Back
! Make the WIN key to Super modifier
   keycode 115 = Super_L
! Set the Caps_Lock physical key to Mode_switch (like AltGr on intl. keyboards)
   keycode 66 = Mode_switch
! Set the Fn key to work as Caps_Lock now. The special key combos like Fn-F4 for "sleep" still work then
   keycode 227 = Caps_Lock
   clear lock
   add lock = Caps_Lock
! Now we activate those new keys. Find some free mod slots (xmodmap) and put them there.
   clear mod4
   clear mod5
   add mod4 = Super_L
   add mod3 = Mode_switch
! It's time to add the keypad keys to the third position of the key definition (pure shift mode_switch shift+mode_switch)
   keycode 16 = 7 ampersand KP_7
   keycode 17 = 8 asterisk KP_8
   keycode 18 = 9 parenleft KP_9
     keycode 19 = 0 parenright KP_Divide
   keycode 30 = u U KP_4
   keycode 31 = i I KP_5
   keycode 32 = o O KP_6
     keycode 33 = p P KP_Multiply
   keycode 44 = j J KP_1
   keycode 45 = k K KP_2
   keycode 46 = l L KP_3
     keycode 47 = semicolon colon KP_Subtract
   keycode 58 = m M KP_0
! ... I have to use the coma key, too, on the keypad...so I set it to be F20 (which is not existing on normal keyboards and thus is free... check for side effects in programmes accepting F12+ keys!)
   keycode 59 = comma less F20 
   keycode 60 = period greater KP_Decimal    
     keycode  61 = slash question KP_Add
ATTENTION!
Your keycodes might be different as well as your mod# settings.

Use $ xmodmap and $ xmodmap -pke to check your ModMap, and the tool $ xev to obtain your exact key codes.

Mapping keys with setkeycodes

You can use the setkeycodes command to remap certain keys. I.e. you can use # setkeycodes 6e 109 6d 104 69 28 6b 1 to map the Tablets Up and Down keys to the standard PageUp and PageDown keys and Tablet Escape and Enter to their respective keys.

The following table shows the scancodes generated by the ThinkPad keys. They vary with model - see Tablet Hardware Buttons.

scancodes
key scancode
Tablet orientation 0x6c
Tablet Shortcut 0x68
Tablet Esc 0x6b
Tablet Enter 0x69
Tablet Up 0x6d
Tablet Down 0x6e
Tablet (unlabeled) 0x67

acpi_fakekey

You can turn acpi events into user-level xevents by putting acpi_fakekey commands into the acpi action scripts. There are several layers involved in using acpi keys in this way, so I'll go through the example of using the ThinkVantage button to open xmms.

My ThinkVantage button generates an acpi event "ibm/hotkey HKEY 00000080 00001018", so we have the event file /etc/acpi/events/ThinkVantage for it which executes the script /etc/acpi/actions/fakekey-macro.sh.

event=ibm/hotkey HKEY 00000080 00001018
action=/etc/acpi/actions/fakekey-macro.sh

In turn, the executable /etc/acpi/actions/fakekey-macro.sh script calls acpi_fakekey with the key number defined in /usr/share/acpi-support/key-constants as $KEY_MACRO which is 112 (you could just as well choose an other key number, just make sure that it doesn't belong to something else like the "j" key or something).

#!/bin/sh
. /usr/share/acpi-support/key-constants
acpi_fakekey $KEY_MACRO 

I have no idea how this actually corresponds to which xevent is generated, so I can find out out by running the program xev and hitting the ThinkVantage button while the mouse is in the xev window (remember to /etc/init.d/acpid restart first if you just created the /etc/acpi/events/ThinkVantage file). I get something popping up in the terminal where I ran xev that looks like this:

KeyPress event, serial 30, synthetic NO, window 0x2800001,
    root 0x6a, subw 0x0, time 2000522842, (138,83), root:(781,500),
    state 0x0, keycode 239 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 30, synthetic NO, window 0x2800001,
    root 0x6a, subw 0x0, time 2000522842, (138,83), root:(781,500),
    state 0x0, keycode 239 (keysym 0x0, NoSymbol), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

This tells me that the acpi_fakekey 112 as executed by hitting the ThinkVantage button generates KeyPress event followed by a KeyRelease event with keycode 239 and that this keycode has been assigned no corresponding keysym. Thus, I am free to assign the keycode to any keysym I want. You can find a list of available keysyms in /usr/share/X11/XKeysymDB. Again try and pick one that is not likely to have already been taken by something, such as XF86LaunchA. To assign this keysym to keycode 239, you can either edit ~/.Xmodmap on an individual user basis, or edit the systemwide /etc/X11/Xmodmap file to contain the line

keycode 239 = XF86LaunchA

If you choose to go with the former, you may need to run xmodmap ~/.Xmodmap for every login session in order to read in your ~/.Xmodmap file if your window manager does not do it for you. Regardless of which option you choose, you can run xmodmap <file> to read in the updated Xmodmap file without logging out and logging back in.

You should now find that hitting the ThinkVantage button creates the following output from xev:

KeyPress event, serial 55, synthetic NO, window 0x2800001,
    root 0x6a, subw 0x0, time 2001286078, (0,106), root:(643,523),
    state 0x0, keycode 239 (keysym 0x1008ff4a, XF86LaunchA), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 55, synthetic NO, window 0x2800001,
    root 0x6a, subw 0x0, time 2001286078, (0,106), root:(643,523),
    state 0x0, keycode 239 (keysym 0x1008ff4a, XF86LaunchA), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

Note the change of (keysym 0x0, NoSymbol) to (keysym 0x1008ff4a, XF86LaunchA).

You're now ready to map XF86LaunchA to executing xmms. This is highly dependent on what keygrabber you decide to use. For openbox, I edit my ~/.config/openbox/rc.xml file and add the following entry in the <keyboard> section:

    <keybind key="XF86LaunchA">
      <action name="Execute">
        <startupnotify>
          <enabled>true</enabled>
        </startupnotify>
        <command>
	  xmms
	</command>
      </action>
    </keybind>

After, right clicking on the desktop and selecting the "Reconfigure" menu option, you should then have xmms pop up when you hit the ThinkVantage key.

Example Applications

Web Browsers

Firefox (<3.0)

There are various ways to assign actions to the browser keys. The easiest way is to install keyconfig.xpi from http://mozilla.dorando.at, which adds a menu entry Tools->Keyconfig. Then you can assign any action you want to the F19/F20 keys (you still need to create ~/.Xmodmap as explained above).


The remaining discussion gives you various more complicated ways to achieve the same thing. To have firefox make use of the browser keys you need to modify one of its files4. To do this you will first need to extract it from the browser.jar archive. Do...

Step 1: Edit .Xmodmap and add entries for F19 and F20 as explained above.

Step 2:

Note: <firefox-directory> is probably /usr/lib/firefox. Use your version so, if you have 3.0.1 or 3.0.2 use /usr/lib/firefox-3.0.1

# cd <firefox-directory>/chrome
# unzip browser.jar

The file of interest is content/browser/browser.xul. Edit it {and don't forget to make a backup copy first}...

# vi content/browser/browser.xul

Look for the <keyset id="mainKeyset"> section and add the following lines within...

<key id="goBackKb" keycode="VK_F19" command="Browser:Back" />
<key id="goForwardKb" keycode="VK_F20" command="Browser:Forward" />

The Command you need for Next Tab

<key id="goBackTabKb" keycode="VK_F19" oncommand="gBrowser.mTabContainer.advanceSelectedTab(-1)" />

For the Previous Tab

<key id="goForwardTabKb" keycode="VK_F20" oncommand="gBrowser.mTabContainer.advanceSelectedTab(1)" />

Now save the file and repackage the browser.jar archive...

# zip -rD0 browser.jar content/browser/

That's it.

Step 3: Restart Firefox.

Hint:
Outdated: Another interesting Page on Firefox is http://dqd.com/~mayoff/notes/thinkpad/dqdnavkeys/ It uses different key mappings (F19 resp. F20) but a ready .xpi is provided which is pretty comfortable. However, this xpi file does not install on Firefox 1.5. or later.
Hint:
You can also use the keyconfig extension to configure custom keys. This extension works with Firefox 1.5 and also with Firefox 2.0. The Command you need for Next Tab is gBrowser.mTabContainer.advanceSelectedTab(1,true); For Previous Tab its gBrowser.mTabContainer.advanceSelectedTab(-1,true); You can alternatively install the functions for keyconfig and set the variable f4kc_NextTab to F20 and f4kc_PrevTab to F19.

.

Firefox 3.0

Thankfully the people at Mozilla decided to include the expected functionality for the XF86Back and XF86Forward keysyms in the new release so all you need to do is
# printf 'keycode 234 = XF86Back\nkeycode 233 = XF86Forward' >> /etc/X11/Xmodmap
And to make this take effect immediately (i.e., without having to log out and log in again), as a regular user run:
$ Xmodmap /etc/X11/Xmodmap

For Hardy Heron, the xmodmap command is all lowercase. Also, the /etc/X11/Xmodmap file is not being read on boot. I've added the command to my .bashrc to have it called on startup.

Konqueror

KDE allows you set key mappings for KDE applications (Go to KMenu > System > Control Center > Regional & Accessibility > Keyboard Shortcuts). By default (at least in KDE 3.5), XF86Back and XF86Forward are set as alternatives to Alt-Left and Alt-Right, and are mapped to KDE Back and Forward navigation actions.

If you use Konqueror as your only browser, you only need to set up ~/.Xmodmap as described above to assign ThinkPad back/forward keys to the symbols XF86Back/XF86Forward. This also make these keys work for other KDE applications such as Quanta Plus, KPackage and so on (not all KDE applications honor this setting, e.g. KDE help system doesn't).

If you want to use Firefox, however, the above settings do not work. You will have to map ThinkPad back/forward keys to F19/F20 as described above, and change KDE navigation key settings to use F19/F20 instead of the default.

Opera

However this isn't a simple configration file, you can set your browser manually.
Go to Tool > Settings > Mouse and keyboard > Keyboard settings > Edit > Browser Window. There add F19 - Back and F20 - Forward. Now you can surf using your TP keys ;-)

Epiphany

By default, the back/forward keys, when bound to XF86Back/XF86Forward, successfully navigate through the history.

To get them switch through your tabs, you could use the extension from here You just need to edit your Xmodmap like described for Firefox < 3.0 (bind the keys on F19 and F20)

W3M (under Emacs)

I'm not sure that I want to use the back and forward keys all the time in Emacs, but while browsing the web it is useful to have them.

On my X61s running Fedora 13, I've found that by adding the following lines to my .emacs, I'm able to do just that:

(eval-after-load "w3m"
'(progn
(define-key w3m-mode-map [XF86Back] 'w3m-view-previous-page)
(define-key w3m-mode-map [XF86Forward] 'w3m-view-next-page)))

Open an application

To configure the ThinkVantage button to open a terminal window in Gnome:

Step 1: Use xev to find the keycode generated by the button on your machine. In my case is is 159.

Step 2: Create an entry in .Xmodmap like so

keycode 159 = XF86LaunchA

replacing 159 by the keycode found in step 1. Load the map using

{{{2}}} xmodmap ~/.Xmodmap

Step 3: Configure the required function (e.g. open terminal window) in System->Preferences->Keyboard shortcuts

Window Managers

fvwm

To get the Forward and Backward keys to cycle through pages in the virtual desktop, add this to your ~/.fvwmrc:

Key    XF86Back     A      A   Scroll     -100000   0
Key    XF86Forward  A      A   Scroll     +100000   0

If you use multiple virtual desktops, you could instead use the keys to flip between them by using GotoDesk.

fluxbox

To get the keys to cycle through pages in the virtual desktop, add this to your ~/.fluxbox/keys:

None F19 :PrevWorkspace
None F20 :NextWorkspace

pekwm configuration

You can make the two browser keys switch workspaces in pekwm, by adding the following two lines to the ~/.pekwm/keys file:

KeyPress = "Mod1 XF86Back" { Actions = "GoToWorkspace prev" }
KeyPress = "Mod1 XF86Forward" { Actions = "GoToWorkspace next" }

pwm

Another example how to use these two keys to switch between pwm tabs. These two lines should be added to ~/.pwm/keys-default.conf or /etc/pwm/keys-default.conf:

kbind "Back", "switch_rot", -1
kbind "Forward", "switch_rot", 1

IceWM

To make IceWM cycle workspaces using the Forward and Backward keys, change these two options in ~/.icewm/preferences (Provided you assigned keysyms F19 and F20 with xmodmap):

# "Previous workspace" shortcut
KeySysWorkspacePrev="F19"
# "Next workspace" shortcut
KeySysWorkspaceNext="F20"

Gnome/metacity

On Debian Lenny, using Gnome 2.22.2, once the acpid and acpi-support packages are installed, most Fn keys do the right thing out of the box.

For more advanced configuration, follow the Ubuntu guide.

Other Uses

Console tools configuraton

To make the Forward and Backward keys useful in console, add this to your keymap (/etc/console/boottime.kmap.gz in Debian):

keycode 158 = Decr_Console
keycode 159 = Incr_Console

Alternatively you can load this script (perhaps on system startup) to enable Backward/Forward button console (VT) switch:

#!/bin/sh
echo keycode 158 = Decr_Console | loadkeys
echo keycode 159 = Incr_Console | loadkeys

It should work with any distro.

Cycling through tabs

In Gnome and Xfce4, Ctrl-PageUp/Ctrl-PageDown move to the previous/following open tab in all applications that have tabbed user interfaces (terminal emulator, web browser, ...). To make use of the Forward and Backward keys for this task, there're two possibilities.

For both ways, you should map the keycodes 233 and 234 to XF86Back and XF86Forward as described in xmodmap configuration.

Using xautomation

xautomation can be found here.

Create two files with permissions 755:

/usr/local/bin/tp_back: <bash>

  1. !/bin/bash

/usr/bin/xte 'keydown Control_L' 'keydown Page_Up' 'keyup Page_Up' 'keyup Control_L' </bash>

/usr/local/bin/tp_forward: <bash>

  1. !/bin/bash

/usr/bin/xte 'keydown Control_L' 'keydown Page_Down' 'keyup Page_Down' 'keyup Control_L' </bash>

Use your desktop's keyboard shortcut editor to assign XF86Back as a shortcut for tp_back and XF86Forward as a shortcut for tp_forward.

This should work in all distros and with all window managers (you might have to use other key combinations than Ctrl-PageUp and Ctrl-PageDown).

Redirecting XF86Back/XF86Forward

Create /etc/X11/xkb/compat/thinkpad:

// $XFree86$
//  XFree86 special keysyms
default partial xkb_compatibility "basic"  {
    interpret.repeat= True;

    interpret  XF86Back {
        action = Redirect(Key=<PGUP>, modifiers=Control);
    };
    interpret  XF86Forward {
        action = Redirect(Key=<PGDN>, modifiers=Control);
    };
};

Edit /etc/X11/xkb/compat/complete and add augment "thinkpad" so that it looks similar to the following:

// $XKeyboardConfig: xkbdesc/compat/complete,v 1.3 2005/10/17 00:42:11 svu Exp $
// $Xorg: complete,v 1.3 2000/08/17 19:54:34 cpqbld Exp $
default xkb_compatibility "complete"  {
    include "basic"
    augment "iso9995"
    augment "mousekeys"
    augment "accessx(full)"
    augment "misc"
    augment "xfree86"
    augment "level5"
    augment "thinkpad"
};

External Sources


FOOTNOTES [Δ]
  1. Note that the associated functionality for Fn-F* key combinations is not consistent amongst all ThinkPads. We are maintaining a table of associated meanings.
  2. if there are more than one tool listed, one is sufficient
  3. 'full' means you can completely reassign any action to be triggered by the key, 'additional actions' means you can trigger actions in addition to the standard function of the key, which can not be changed.
  4. Thanks go to Ryan Barrett for writing the little howto on his blog.

Weblinks