Keys & Consoles
Of Keyboards and Consoles...(The following article was submitted to the Linux Journal for publication and is being presented here with the permission of the publisher of the Linux Journal -- John M. Fisk)
"It's a GUI, GUI, GUI, GUI world!" -- or so the major OS manufacturers would have you belief. Truth is, that while this is increasingly the case, there are times when the command line interface (CLI) is still a very good choice for getting things done. It's fast, generally efficient, and is a good choice on memory or CPU constrained machines. And don't forget that there are still a lot of very nifty things that can be done "at the console."
In this spirit, I'd like to start by following up on a delightful and informative article written by Allesandro Rubini entitled "The Best Without X" that appeared in the November, 1995 (Issue 19) edition of the Linux Journal. Among a wealth of helpful ideas, Allesandro suggested converting the numeric keypad into a "console-switch scratch pad" to allow single key switching from one virtual terminal (VT) to another. We'll begin by looking at how this can be done. We'll also look at:
By the time that you get through tinkering around with these things I think you'll agree that the CLI isn't such a bad place after all :-) Also, the good news is that the programs you'll need for this are standard inclusions in most recent Linux distributions and include:
A listing of Linux FTP archives where these may be found is included at the end of this article.
The numeric keypad is an ideal candidate for remapping into a virtual terminal (VT) switching scratch pad as most of us have never learned to "touch type" using the keypad. In addition, on a 101-key keyboard, its non-numeric functions are already duplicated by the Home, End, Page Up, Page Down, Insert, Delete, and arrow keys. Since there may be occasions in which we still want to use the keypad for numeric input let's see how to set it up as a VT switcher while retaining numeric input ability.
To do this you'll need to have the kbd package installed on your system. The two programs we'll be using for this are the 'showkey' and 'loadkey' programs. To check whether they are installed on your system you can type in:
% type loadkeys showkey
if you're using the BASH shell, or:
% which loadkeys showkey
The 'which' program or the BASH shell built-in function 'type' will both print the path to the executable if they exist in the PATH search path. On my machine this produces:
~$ type showkey loadkeys
showkey is /usr/bin/showkey
loadkeys is /usr/bin/loadkeys
~$ which showkey loadkeys
/usr/bin/showkey
/usr/bin/loadkeys
If you don't have these programs installed you'll need to get the sources for the kbd package and install it yourself. (This comes as source only but installation is as simple as unachiving it into a temporary directory and typing in 'make && make install').
Converting the keypad into VT switcher involves defining a keyboard mapping and then using loadkeys to actually load this information into the kernel keyboard translation tables. It's a whole lot easier than it sounds although you must keep in mind that indiscriminate tinkering can render your keyboard useless (requiring one of those dreaded cold reboots) and that changing the keyboard translation tables affects ALL VT's, not just the one you're working on.
The kbd package default installation location is under /usr/lib/kbd with the key mapping files in the keytables subdirectory. Change to this directory and make a copy of the defkeymap.map file. This is the default keyboard mapping and is a useful place to start. You can call the new file anything you'd like - e.g.,
cp defkeymap.map custom.map
Use your favorite editor and load up this file. At this point it's probably helpful to stop for a moment and have a look around. It's rather like visiting one of those fine old curio shops -- look, but don't touch! The first few lines may look something like this:
keycode 1 = Escape Escape
alt keycode 1 = Meta_Escape
keycode 2 = one exclam
alt keycode 2 = Meta_one
shift alt keycode 2 = Meta_exclam
keycode 3 = two at at
control keycode 3 = nul
shift control keycode 3 = nul
alt keycode 3 = Meta_two
shift alt keycode 3 = Meta_at
I won't go into all the gory details of how to remap the keyboard except to say that the basic format that we'll use is:
keycode keynumber = keysym
modifier keycode keynumber = keysym
in which 'keynumber' is the internal identification number of the key and 'keysym' represents the action to take. Now before you bail out on me let's put this into simple terms. Each key on the keyboard is identified by a unique number which is represented by 'keynumber'. When a key is pressed or released these events are passed to the operating system which responds by performing the appropriate action -- represented here by 'keysym'. The 'modifier' is a key which is held down at the same time that the key is pressed. These 'modifier' keys include the well known control, alt, and shift keys. Being able to define multi-key combinations extends the mapping available for each key.
So, using the example above, pressing the key associated with keynumber 3 actually causes the number '2' to be printed to the screen. If the shift key is held down at the same time as the key is pressed, the '@' sign is printed to the screen, and if the three key combination Shift+Alt+keynumber 3 is pressed, the output is the Meta_at (whatever one of those looks like).
Getting back to the task at hand, what we want to do is change to a specified VT when we press one of the keypad keys: pressing keypad 1 should switch to VT number 1, pressing keypad 2 should switch to VT number 2, and so forth. In your customized key map file find the section that defines the keypad keys -- it should look similar to this:
keycode 71 = KP_7
alt keycode 71 = Ascii_7
keycode 72 = KP_8
alt keycode 72 = Ascii_8
keycode 73 = KP_9
alt keycode 73 = Ascii_9
[...]
Now, edit this section so that it reads something like:
# NUMERIC KEYPAD MAPPING
#
# The section remaps the keypad keys so that they act as a
# VT-switcher: keypad 1 switches to VT 1, keypad 2 to VT 2,
# and so forth. Note that pressing Shift+key switches to a VT
# which is 10+ the number of the key (Shift+3 = VT 13) and that
# pressing Alt+key (when Num Lock is on) causes numeric output.
#
# Keypad number 7
#
keycode 71 = Console_7
shift keycode 71 = Console_17
alt keycode 71 = KP_7
alt control keycode 71 = Console_7
#
# Keypad number 8
#
keycode 72 = Console_8
shift keycode 72 = Console_18
alt keycode 72 = KP_8
alt control keycode 72 = Console_8
#
# Keypad number 9
#
keycode 73 = Console_9
shift keycode 73 = Console_19
alt keycode 73 = KP_9
alt control keycode 73 = Console_9
keycode 74 = KP_Subtract
#
# Keypad number 4
#
keycode 75 = Console_4
shift keycode 75 = Console_14
alt keycode 75 = KP_4
alt control keycode 75 = Console_4
#
# Keypad number 5
#
keycode 76 = Console_5
shift keycode 76 = Console_15
alt keycode 76 = KP_5
alt control keycode 76 = Console_5
#
# Keypad number 6
#
keycode 77 = Console_6
shift keycode 77 = Console_16
alt keycode 77 = KP_6
alt control keycode 77 = Console_6
keycode 78 = KP_Add
#
# Keypad number 1
#
keycode 79 = Console_1
shift keycode 79 = Console_11
alt keycode 79 = KP_1
alt control keycode 79 = Console_1
#
# Keypad number 2
#
keycode 80 = Console_2
shift keycode 80 = Console_12
alt keycode 80 = KP_2
alt control keycode 80 = Console_2
#
# Keypad number 3
#
keycode 81 = Console_3
shift keycode 81 = Console_13
alt keycode 81 = KP_3
alt control keycode 81 = Console_3
#
# Keypad number 0
#
keycode 82 = Last_Console
shift keycode 82 = Console_10
alt keycode 82 = KP_0
#
# Keypad '.' key
#
keycode 83 = KP_Period
altgr control keycode 83 = Boot
control alt keycode 83 = Boot
keycode 84 = Last_Console
Before going on let's make a couple observations. First, it's not a bad idea to comment the file as you go. What's seems so clear and obvious now quickly fades into obscurity as the weeks pass. Adding comments will help prevent your having to pour back over manual pages, program documentation, and magazine articles looking for the correct syntax or usage.
Second, notice that with each entry there are "sub-stanzas" if you will, that begin with the words "alt keycode" "shift keycode" etc. These are the stanzas that define multi-key combinations in which a "modifier" key is pressed at the same time as the key being defined. A common example of this is the "Ctrl-C" combination that is used to terminate a program in execution.
Finally, you may be asking yourself how you're supposed to know which keynumber is associated with a key. Anyone know off hand what keynumber goes with the " key? The way you find this out is using the 'showkey' program. After you invoke the program, showkey prints the keynumber for any key that you hit (and quits after 10 seconds of no input). So, now that we've already edited the pertinent section in the 'custom.map' file, let's see how we'd arrive at this "from scratch."
The basic steps we'd need to take would be to:
To do this, let's begin by using the 'showkey' program which can be invoked using:
% showkey
Now, any key that you press causes showkey to print the keynumber. On my machine, invoking showkey and pressing keypad keys 1 through 9 results in the following output:
~$ showkey kb mode was XLATE press any key (program terminates after 10s of last key press)... keycode 79 press keycode 79 release keycode 80 press keycode 80 release keycode 81 press keycode 81 release keycode 75 press keycode 75 release keycode 76 press keycode 76 release keycode 77 press keycode 77 release keycode 71 press keycode 71 release keycode 72 press keycode 72 release keycode 73 press keycode 73 release
You can see that both key press and key release events are detected. Also note that the numbering of the keypad keys is not sequential. The numeric keys have the following format:
Actual Key: Keynumber: 7 8 9 71 72 73 4 5 6 75 76 77 1 2 3 79 80 81
So that keypad number 1 has keynumber 79, keypad number 2 has keynumber 80, and so forth. Knowing this, we can now set up the appropriate key map entry for each of these keys. The keysym event that we're interested in is Console_x, in which 'x' is the number of the VT to which the view is s asection in the 'custom.map' file, let's see how we'd arrive at this "from scratch."
The basic steps we'd need to take would be to:
To do this, let's begin by using the 'showkey' program which can be invoked using:
% showkey
Now, any key that you press causes showkey to print the keynumber. On my machine, invoking showkey and pressing keypad keys 1 through 9 results in the following output:
~$ showkey kb mode was XLATE press any key (program terminates after 10s of last key press)... keycode 79 press keycode 79 release keycode 80 press keycode 80 release keycode 81 press keycode 81 release keycode 75 press keycode 75 release keycode 76 press keycode 76 release keycode 77 press keycode 77 release keycode 71 press keycode 71 release keycode 72 press keycode 72 release keycode 73 press keycode 73 release
You can see that both key press and key release events are detected. Also note that the numbering of the keypad keys is not sequential. The numeric keys have the following format:
Actual Key: Keynumber: 7 8 9 71 72 73 4 5 6 75 76 77 1 2 3 79 80 81
So that keypad number 1 has keynumber 79, keypad number 2 has keynumber 80, and so forth. Knowing this, we can now set up the appropriate key map entry for each of these keys. The keysym event that we're interested in is Console_x, in which 'x' is the number of the VT to which the view is s asection in the 'custom.map' file, let's see how we'd arrive at this "from scratch."
The basic steps we'd need to take would be to:
To do this, let's begin by using the 'showkey' program which can be invoked using:
% showkey
Now, any key that you press causes showkey to print the keynumber. On my machine, invoking showkey and pressing keypad keys 1 through 9 results in the following output:
~$ showkey kb mode was XLATE press any key (program terminates after 10s of last key press)... keycode 79 press keycode 79 release keycode 80 press keycode 80 release keycode 81 press keycode 81 release keycode 75 press keycode 75 release keycode 76 press keycode 76 release keycode 77 press keycode 77 release keycode 71 press keycode 71 release keycode 72 press keycode 72 release keycode 73 press keycode 73 release
You can see that both key press and key release events are detected. Also note that the numbering of the keypad keys is not sequential. The numeric keys have the following format:
Actual Key: Keynumber: 7 8 9 71 72 73 4 5 6 75 76 77 1 2 3 79 80 81
So that keypad number 1 has keynumber 79, keypad number 2 has keynumber 80, and so forth. Knowing this, we can now set up the appropriate key map entry for each of these keys. The keysym event that we're interested in is Console_x, in which 'x' is the number of the VT to which the view is s asection in the 'custom.map' file, let's see how we'd arrive at this "from scratch."
The basic steps we'd need to take would be to:
To do this, let's begin by using the 'showkey' program which can be invoked using:
% showkey
Now, any key that you press causes showkey to print the keynumber. On my machine, invoking showkey and pressing keypad keys 1 through 9 results in the following output:
~$ showkey kb mode was XLATE press any key (program terminates after 10s of last key press)... keycode 79 press keycode 79 release keycode 80 press keycode 80 release keycode 81 press keycode 81 release keycode 75 press keycode 75 release keycode 76 press keycode 76 release keycode 77 press keycode 77 release keycode 71 press keycode 71 release keycode 72 press keycode 72 release keycode 73 press keycode 73 release
You can see that both key press and key release events are detected. Also note that the numbering of the keypad keys is not sequential. The numeric keys have the following format:
Actual Key: Keynumber: 7 8 9 71 72 73 4 5 6 75 76 77 1 2 3 79 80 81
So that keypad number 1 has keynumber 79, keypad number 2 has keynumber 80, and so forth. Knowing this, we can now set up the appropriate key map entry for each of these keys. The keysym event that we're interested in is Console_x, in which 'x' is the number of the VT to which the view is s asection in the 'custom.map' file, let's see how we'd arrive at this "from scratch."
The basic steps we'd need to take would be to:
To do this, let's begin by using the 'showkey' program which can be invoked using:
% showkey
Now, any key that you press causes showkey to print the keynumber. On my machine, invoking showkey and pressing keypad keys 1 through 9 results in the following output:
~$ showkey kb mode was XLATE press any key (program terminates after 10s of last key press)... keycode 79 press keycode 79 release keycode 80 press keycode 80 release keycode 81 press keycode 81 release keycode 75 press keycode 75 release keycode 76 press keycode 76 release keycode 77 press keycode 77 release keycode 71 press keycode 71 release keycode 72 press keycode 72 release keycode 73 press keycode 73 release
You can see that both key press and key release events are detected. Also note that the numbering of the keypad keys is not sequential. The numeric keys have the following format:
Actual Key: Keynumber: 7 8 9 71 72 73 4 5 6 75 76 77 1 2 3 79 80 81
So that keypad number 1 has keynumber 79, keypad number 2 has keynumber 80, and so forth. Knowing this, we can now set up the appropriate key map entry for each of these keys. The keysym event that we're interested in is Console_x, in which 'x' is the number of the VT to which the view is s asection in the 'custom.map' file, let's see how we'd arrive at this "from scratch."
The basic steps we'd need to take would be to:
To do this, let's begin by using the 'showkey' program which can be invoked using:
% showkey
Now, any key that you press causes showkey to print the keynumber. On my machine, invoking showkey and pressing keypad keys 1 through 9 results in the following output:
~$ showkey kb mode was XLATE press any key (program terminates after 10s of last key press)... keycode 79 press keycode 79 release keycode 80 press keycode 80 release keycode 81 press keycode 81 release keycode 75 press keycode 75 release keycode 76 press keycode 76 release keycode 77 press keycode 77 release keycode 71 press keycode 71 release keycode 72 press keycode 72 release keycode 73 press keycode 73 release
You can see that both key press and key release events are detected. Also note that the numbering of the keypad keys is not sequential. The numeric keys have the following format:
Actual Key: Keynumber: 7 8 9 71 72 73 4 5 6 75 76 77 1 2 3 79 80 81
So that keypad number 1 has keynumber 79, keypad number 2 has keynumber 80, and so forth. Knowing this, we can now set up the appropriate key map entry for each of these keys. The keysym event that we're interested in is Console_x, in which 'x' is the number of the VT to which the view is s asection in the 'custom.map' file, let's see how we'd arrive at this "from scratch."
The basic steps we'd need to take would be to:
To do this, let's begin by using the 'showkey' program which can be invoked using:
% showkey
Now, any key that you press causes showkey to print the keynumber. On my machine, invoking showkey and pressing keypad keys 1 through 9 results in the following output:
~$ showkey kb mode was XLATE press any key (program terminates after 10s of last key press)... keycode 79 press keycode 79 release keycode 80 press keycode 80 release keycode 81 press keycode 81 release keycode 75 press keycode 75 release keycode 76 press keycode 76 release keycode 77 press keycode 77 release keycode 71 press keycode 71 release keycode 72 press keycode 72 release keycode 73 press keycode 73 release
You can see that both key press and key release events are detected. Also note that the numbering of the keypad keys is not sequential. The numeric keys have the following format:
Actual Key: Keynumber: 7 8 9 71 72 73 4 5 6 75 76 77 1 2 3 79 80 81
So that keypad number 1 has keynumber 79, keypad number 2 has keynumber 80, and so forth. Knowing this, we can now set up the appropriate key map entry for each of these keys. The keysym event that we're interested in is Console_x, in which 'x' is the number of the VT to which the view is s asection in the 'custom.map' file, let's see how we'd arrive at this "from scratch."
The basic steps we'd need to take would be to:
To do this, let's begin by using the 'showkey' program which can be invoked using:
% showkey
Now, any key that you press causes showkey to print the keynumber. On my machine, invoking showkey and pressing keypad keys 1 through 9 results in the following output:
~$ showkey kb mode was XLATE press any key (program terminates after 10s of last key press)... keycode 79 press keycode 79 release keycode 80 press keycode 80 release keycode 81 press keycode 81 release keycode 75 press keycode 75 release keycode 76 press keycode 76 release keycode 77 press keycode 77 release keycode 71 press keycode 71 release keycode 72 press keycode 72 release keycode 73 press keycode 73 release
You can see that both key press and key release events are detected. Also note that the numbering of the keypad keys is not sequential. The numeric keys have the following format:
Actual Key: Keynumber: 7 8 9 71 72 73 4 5 6 75 76 77 1 2 3 79 80 81
So that keypad number 1 has keynumber 79, keypad number 2 has keynumber 80, and so forth. Knowing this, we can now set up the appropriate key map entry for each of these keys. The keysym event that we're interested in is Console_x, in which 'x' is the number of the VT to which the view is s asection in the 'custom.map' fi