[comp.emacs] 'remapping the keyboard'

zorat@ziggy.UUCP (Alessandro Zorat) (11/08/88)

I have read some the suggestions that were offered to Jon Zeeff about
using the ALT key as a meta key.  While that is a quite simple cure to
the fact that the ALT+key sends ESC N key, I preferred to have the
ALT+key actually send a REAL meta code, that is with the eighth bit on.
So I remapped the keyboard with the following program mapkeys.c.
Since it might be of some use to others as well, I post it here.

One of the things mapkeys does is to set the 8-th bit to codes obtained while
the META (ALT) key is pressed.
While I was at it, I also changed the backspace key to send a delete
(0177) char.  Finally, I was tired of the strange layout of my compaq
keyboard and mapped a control key to the key that has the shift-lock
(if I want to really do a shift-lock, I have to press both the ususal
shift-lock and the shift key - this because the shift shift-lock entry
has NOT been remapped.)

The compiled program mapkeys is executed by placing an appropriate
entry for it in the /etc/rc script.
In my case I remap only when entering multi-user state, so I put the
call to mapkeys in /etc/rc2 and the relevant fragment looks like this:

if [ "${BOOT}" = "yes" -a $7 = "2" ]
then
	/etc/mapkey
	echo 'The system is ready.'
elif [ $7 = "2" ]
then
	echo 'Change to state 2 has been completed.'
fi
__________ end of fragment of /etc/rc2__________________


Here is the program mapkeys.c
____________________________ cut here __________________
/*
	mapkeys.c:	the keyboard so that the META key sends a META
			character.  Also map a DEL on the backspace key
			and a CNTRL. on the shift-lock
*/

#include <sys/kd_info.h>
#include <stdio.h>
#include <fcntl.h>

#define BS_INDEX		14 	/* the index of the backspace key */
#define DEL_VALUE		0x007F	/* the value of DELETE */
#define DEL_ALTVALUE		0x00FF	/* the value of "Meta-delete" */

#define	CAPS_LOCK_INDEX		58	/* the index of the cap_lock key */
#define CNTRL_VAL		0x0104	/* the value of CNTRL */

#ifdef DEBUG
# define	msg(arg)	printf arg
#else
# define	msg(arg)
#endif

struct kbentry {
	unsigned char		kb_table;
	unsigned char		kb_index;
	unsigned short		kb_value;
};

int				fd;
struct kbentry			kbtbl;

/*
	Map the single character of index "index" in table "table"
	to the new value "value"
*/
map_a_key(table, index, value)
	unsigned short	table;
	unsigned short	index;
	unsigned short	value;
{
	kbtbl.kb_index = index;
	kbtbl.kb_table = table;
	if (ioctl(fd, KDGKBENT, &kbtbl) < 0) {
		perror("failed in the ioctl call\n");
		fflush(stdout);
	}
	kbtbl.kb_value = value;
	if (ioctl(fd, KDSKBENT, &kbtbl) < 0) {
		perror("failed in the ioctl call\n");
		fflush(stdout);
	}
}

/*
	Map the alphanumeric keys of table "to_table" within indices "low" and
	"high" to have the value of the corresponding entry in the "from_table",
	but with the eight-th bit set to one, so that they become "meta" chars.
	Also, wipe out the upper byte (flags).
*/
map_to_meta(from_table, to_table, low, high)
	unsigned short	from_table, to_table;
	short		low, high;
{
	register int		i;
	unsigned short		outval;

	for (i=low; i<=high; i++) {
		kbtbl.kb_index = i;
		kbtbl.kb_table = from_table;

		msg(("\nfrom_tbl %1d, to_tbl %1d:  entry %3d", 
				from_table, to_table, i));
		if (ioctl(fd, KDGKBENT, &kbtbl) < 0) {
			perror("failed in the ioctl call\n");
			fflush(stdout);
		}
		outval = 0x00FF&kbtbl.kb_value;
		msg(("   had the value 0x%04x", kbtbl.kb_value));

		if ((outval >= 0x20) && (outval < 0x7F)) {
			msg((" = %c", outval));

			kbtbl.kb_value |= 0x80;
			kbtbl.kb_value &= 0x00FF;
			kbtbl.kb_table = to_table;
			if (ioctl(fd, KDSKBENT, &kbtbl) < 0) {
				perror("failed in the ioctl call\n");
				fflush(stdout);
			}
			msg(("   and has been set to 0x%x",kbtbl.kb_value));
		}
	}
}

main()
{
	register int 		i;

	fd = open("/dev/console", "r");
	if (fd < 0) {
		perror("Error - could not open /dev/console for reading\n");
		exit(-1);
	}
	msg(("Setting the backspace key to delete\n"));
	map_a_key(K_NORMTAB, BS_INDEX, DEL_VALUE);
	msg(("Setting the ALT-backspace key to META-delete\n"));
	map_a_key(K_ALTTAB, BS_INDEX, DEL_ALTVALUE);

	msg(("Setting the CAPS-LOCK to CNTRL\n"));
	map_a_key(K_NORMTAB, CAPS_LOCK_INDEX, CNTRL_VAL);

	msg(("Changing the Alt table to be Meta\n"));
	map_to_meta(K_NORMTAB, K_ALTTAB, 2, 53);
	msg(("Changing the Shift-Alt table to be Meta\n"));
	map_to_meta(K_SHIFTTAB, K_ALTSHIFTTAB, 2, 53);
}