Changing your keyboard mapping
When you are sitting at the computer, typing away at the keyboard, you don’t give much thought to the process of how those simple strokes translate into characters on the screen. Well, if you do, then you shouldn’t be reading this article. You are probably familiar with the ASCII codes. The codes are just one part of that process.
The goal here is to disable certain keys to in order to make life easier for a particular user. This person is
constantly confused by certain keys (
Print Scrn and
Scroll Lock) and, from time to time, accidently
winds up on a different virtual console. Education is not a solution in this case. It is easier for me to
disable those keys.
NOTE this article deals only with the system console and not with X-Windows or with ssh connections.
I come seeking knowledge
I asked this question in an IRC channel:
What should I be reading if I want to disable PRINT SCREEN and SCROLL LOCK? Possibly just for one user [who gets confused when those keys are accidentally pressed].And the answer was:
I’m sure most of you will find those man pages as interesting as I did. They are useful when you know what you are doing, but the first time around, they are very difficult to interpret. I’ll try to give a very basic outline of the concepts.
The basics of key mapping
Each key on your keyboard has a scancode associated with it. These scancodes can vary from one type of keyboard
to another and from one region to another (different languages have different characters).
Those scan code numbers are most likely not
ASCII codes. It is the responsibility of the syscons driver to translate the keycodes to ASCII codes.
To do this translation, syscons(4)
uses a keyboard map file. kbdmap(5)
defines the map file layout. A
kbdmap file describes how the keys on a keyboard should behave.
The keyboard map file layout is pretty simple, once you understand it (isn’t everything?). To view your current mappings, issue the following command (you don’t have to be root to do any of this):
$ kbdcontrol -d # alt # scan cntrl alt alt cntrl lock # code base shift cntrl shift alt shift cntrl shift state # ------------------------------------------------------------------ 000 nop nop nop nop nop nop nop nop O 001 esc esc esc esc esc esc debug esc O 002 '1' '!' nop nop '1' '!' nop nop O 003 '2' '@' nul nul '2' '@' nul nul O [ the rest of the output has been snipped ]
Comments start with a #. So let’s concentrate on the second non-comment line. The first column is the scancode for the key.
On this keyboard, the escape key has a scan code of 001. If it is pressed, it is mapped
esc character. The remaining columns show what should happen if the shift, control, and ALT
keys are used in combination with the esc key. In most cases, the keystrokes are mapped to
However, if you press ALT-CONTROL-ESC, that invokes the debugger. See kbdmap(5) for detail.
NOTE: You should issue the above command at the console. If you issue this command from an ssh shell, you’ll get something like this:
$ kbdcontrol -d kbdcontrol: getting keymap: Inappropriate ioctl for device
Loading a new key mapping
As mentioned above, you can dump the existing keyboard map file with the following command:
kbdcontrol -d > ~/mykeys
kbdcontrolis one of those well designed commands which will accept its output as its input. Therefore it would be perfectly valid to do this:
You would wind up with the same key mappings you had before. We are going to take advantage of this after we map a few keys.
kbdcontrol -l ~/mykeys
Changing the key mappingMy goal is to disable a few keys. First, I will take a backup of the original keys:
Then I started working on ~/mykeys. Here is a diff which demonstrates the changes:
cp ~/mykeys ~/mykeys.original
The changes above are:$ diff original-keyboard-mappings my-keyboard-mappings 64,73c64,73 < 059 fkey01 fkey13 fkey25 fkey37 scr01 scr11 scr01 scr11 O < 060 fkey02 fkey14 fkey26 fkey38 scr02 scr12 scr02 scr12 O < 061 fkey03 fkey15 fkey27 fkey39 scr03 scr13 scr03 scr13 O < 062 fkey04 fkey16 fkey28 fkey40 scr04 scr14 scr04 scr14 O < 063 fkey05 fkey17 fkey29 fkey41 scr05 scr15 scr05 scr15 O < 064 fkey06 fkey18 fkey30 fkey42 scr06 scr16 scr06 scr16 O < 065 fkey07 fkey19 fkey31 fkey43 scr07 scr07 scr07 scr07 O < 066 fkey08 fkey20 fkey32 fkey44 scr08 scr08 scr08 scr08 O < 067 fkey09 fkey21 fkey33 fkey45 scr09 scr09 scr09 scr09 O < 068 fkey10 fkey22 fkey34 fkey46 scr10 scr10 scr10 scr10 O --- > 059 fkey01 fkey13 fkey25 fkey37 nop scr11 scr01 scr11 O > 060 fkey02 fkey14 fkey26 fkey38 nop scr12 scr02 scr12 O > 061 fkey03 fkey15 fkey27 fkey39 nop scr13 scr03 scr13 O > 062 fkey04 fkey16 fkey28 fkey40 nop scr14 scr04 scr14 O > 063 fkey05 fkey17 fkey29 fkey41 nop scr15 scr05 scr15 O > 064 fkey06 fkey18 fkey30 fkey42 nop scr16 scr06 scr16 O > 065 fkey07 fkey19 fkey31 fkey43 nop scr07 scr07 scr07 O > 066 fkey08 fkey20 fkey32 fkey44 nop scr08 scr08 scr08 O > 067 fkey09 fkey21 fkey33 fkey45 nop scr09 scr09 scr09 O > 068 fkey10 fkey22 fkey34 fkey46 nop scr10 scr10 scr10 O 75c75 < 070 slock slock slock slock slock slock slock slock O --- > 070 nop nop nop nop nop nop nop nop O 97c97 < 092 nscr nscr debug debug nop nop nop nop O --- > 092 nop nop nop nop nop nop nop nop O
- I have changed the actions of the functions keys so that when ALT is pressed,
nothing happens (
nop). But I can still get to the virtual screens by pressing ALT-CONTROL-Fn instead of just ALT-Fn. 059-068.
- When the SHIFT LOCK key is pressed, nothing happens. Ever. 070.
- When Print Screen is pressed, nothing happens. Ever. 092.
Making it happen at login timeI wanted these keyboard mappings to be used whenever this person logged in. The user in question uses the bash shell. So I added this to
When the user logs out, the mappings are removed by this entry added to
/usr/sbin/kbdcontrol -l ~/my-keyboard-mappings
/usr/sbin/kbdcontrol -l ~/mykeys.original
Other improvementsI’m not happy with using ~/mykeys.original within
~/.bash_logout. I think I’d prefer to do something better. Such as using one of the entries from
/usr/share/syscons/keymaps/. Or perhaps saving the keymap at login time and then restoring that at logout.
Your favorite strings
One feature of
kbdcontrol is the ability to make a function key emit your
favorite string. Here’s the example from the man page:
The following command will make the function key 10 emit "telnet myhost".
kbdcontrol -f 10 "telnet myhost"
Huh? What about /etc/ttys?
Before you bright sparks jump in and suggest that I modify
and remove my virtual terminals, I’ll explain my choice of the keymap solution.
I wanted access to the virtual terminals but wanted to make it more difficult for the user
to accidentally wind up on a different terminal. Modification of
was not an option in this case.