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?

  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
    Sep 26 '14 at 8:47
  • 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 Aug 8 '17 at 13:01
  • Why subtract 8? Do you have chapter and verse?
    – Tom Hale
    Sep 2 '19 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
    Jan 15 '20 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. Apr 27 '20 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.