Things look quiet here. But I've been doing a lot of blogging at
dan.langille.org because I prefer WordPress now.
Not all my posts there are FreeBSD related.
I am in the midst of migrating The FreeBSD Diary over to WordPress
(and you can read about that here).
Once the migration is completed, I'll move the FreeBSD posts into the
new FreeBSD Diary website.
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:
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.