The FreeBSD Diary

The FreeBSD Diary (TM)

Providing practical examples since 1998

If you buy from Amazon USA, please support us by using this link.
[ HOME | TOPICS | INDEX | WEB RESOURCES | BOOKS | CONTRIBUTE | SEARCH | FEEDBACK | FAQ | FORUMS ]
Changing your keyboard mapping 20 September 2002
Need more help on this topic? Click here
This article has 1 comment
Show me similar articles

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:
kbdcontrol(1), kbdmap(5)

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 to the 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 esc. 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
Fortunately, kbdcontrol is one of those well designed commands which will accept its output as its input. Therefore it would be perfectly valid to do this:
kbdcontrol -l ~/mykeys
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.
Changing the key mapping
My goal is to disable a few keys. First, I will take a backup of the original keys:
cp ~/mykeys ~/mykeys.original
Then I started working on ~/mykeys. Here is a diff which demonstrates the changes:

$ 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
The changes above are:
  • 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.
These changes can be loaded with the command specified in the previous section.
Making it happen at login time
I 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 ~/.bash_profile:
/usr/sbin/kbdcontrol -l ~/my-keyboard-mappings
When the user logs out, the mappings are removed by this entry added to ~/.bash_logout:
/usr/sbin/kbdcontrol -l ~/mykeys.original
Other improvements
I'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 /etc/ttys 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 /etc/ttys was not an option in this case.

There you go....
That's it. I'll get no more requests for help based on virtual terminal or scroll lock problems. These may not be problems in your environment, but you may have other needs for specific key mappings. But have fun.

Need more help on this topic? Click here
This article has 1 comment
Show me similar articles