I have a Thinkpad Edge E130 running Sabayon (a Gentoo-based distro), and I'm fighting the well-know bug Xorg 255 keycodes limit.

My laptop has the Fn+F4 hotkey for Mic Mute/Unmute. This is the problem:

  • showkey -k shows keycode 248 on Fn+F4 keypress
  • showkey -s shows nothing on keypress
  • xev shows nothing on keypress (because 248+8 [added by kernel] is bigger than 255)

If a key has a keycode, it must have a scancode too. With getscancodes program indeed I got 26 as scancode:

# ./Sabayon/getscancodes/getscancodes /dev/input/event6 
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x17aa product 0x5054 version 0x4101
Input device name: "ThinkPad Extra Buttons"
26 (0x1a)
26 (0x1a)

According to this thread, my guess is simply to change the keycode of the hotkey with a smaller, unused one. For example 120 seems to be unused according to my $ xmodmap -pke

I have tried with

# setkeycodes 0x1a 120

but without success, the keycode is always 248 checking with showkey.

How is the proper way to change keycodes?

3 Answers 3

  1. Use showkey to know your key scancode:

    $ sudo showkey -s
    0xe0 0xXX
  2. Kernel will add 8 to you code, use 112 instead 120:

    $ sudo setkeycodes e0XX 112
  3. Use xmodmap to make your key report XF86AudioMute keysym:

    $ xmodmap -e "keycode 120 = XF86AudioMute"
  4. Optional. Press you key when creating shortcut to what you want in the settings of your DE.

  • Actually I switched to Debian Sid and Fn+F4 works out of the box here (maybe just because I have a newer kernel version). But thank you anyway, your solution looks good and I hope will help other people.
    – eang
    Commented Sep 26, 2014 at 8:47
  • 2
    This does not work for USB keyboards, because setkeycodes does not support them. If the system has udev, the keys can be remapped by adding a custom entry to the hardware database. Example here: unix.stackexchange.com/a/384566/245377 Commented Aug 8, 2017 at 13:01
  • Why subtract 8? Do you have chapter and verse?
    – Tom Hale
    Commented Sep 2, 2019 at 12:42
  • Note if you are trying to use showkey -s: it may not report real raw scancodes for use with setkeycodes; as a sanity check, compare the resulting keycodes (shown by showkey [-k]) with what keycode the table for the existing mapping shown by getkeycodes says should be produced for the scancode you got from showkey -s.
    – rakslice
    Commented Jan 15, 2020 at 22:29
  • How to get the scancode if sudo showkey -s doesn't return anything? I'm also in the same scenario, showkey -k returns 248 for me. Commented Apr 27, 2020 at 13:17

What I want to do is that when the "pause" button is pressed, the character "k" is printed. The problem is that the "pause" button has no scan code (showkey -s does not work). I solved this problem like this:

  1. Switch to the console
  2. Use showkey -k to know keycode of "pause" button (425 in my case)
$ showkey -k
keycode 425 press
keycode 425 release
  1. Use getkeycodes to get a table of mapping keycodes to scancodes
e0 68:  128 159 158 157 155 226 225 224
e0 70:    0 192 193 149 148 425 116   0
e0 78:  464 148   0   0   0   0   0   0
  1. In this table find the scancode associated with keycode 425 (e075 in my case)
  2. Switch back to X
  3. Use xmodmap -pke to find keycode you need (you can also modify them) (45 in my case)
keycode  45 = k K Cyrillic_el Cyrillic_EL k K
  1. Subtract 8 to get kernel keycode (45 - 8 = 37)
  2. Use setkeycodes to add association between raw scancode e075 and kernel keycode 37
sudo setkeycodes e075 37
  1. Test it. It should work

step 1: xmodmap -pke will list you keycodes

step 2: xmodmap -e 'keycode 51 = backslash bar' will change that keycode to backslash

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .