[comp.emacs] source for making Alt key work as a Meta under AT&T SVr3.2 on AT boxen

eric@snark.uu.net (Eric S. Raymond) (07/25/89)

RMS: care to drop this in the gnumacs /etc as unsupported code?

---- CUT HERE -------- CUT HERE -------- CUT HERE -------- CUT HERE --------
/****************************************************************************

NAME
   alter -- remap 6386WGS console so the Alt key becomes a real meta key

SYNOPSIS
   alter [-adr]

DESCRIPTION
   When run from root, this program will remap the console keyboard on
an AT&T 6386WGS so that the Alt key acts as a meta key when combined with
any printable character, or any shift-control modification of a printable;
that is, it turns on the high (0x80) bit of the character. Function keys and
control-character keys and other special keys are not affected.

   This is useful with GNU EMACS. To see why, run it, pull up an EMACS, set
the meta-flag global to non-nil, type ALT-x, and notice that it works!

   To arrange this behavior by default, put an `alter -a' in a initialization
script under /etc/rc2.d to be executed whenever the system enters multiuser
mode.

   The -a flag enables Alt. The -r flag restores the default key bindings.
The -d flag dumps a C-compilable version of the current keyboard table. These
flags may be used in any combination and will be trigger actions in the order
they are given.

NOTE
   The ISTRIP bit must be off in your termio structure for this to work. GNU
EMACS does this; for other applications you may need to do an explicit
stty -istrip or TCSETA{W} ioctl.

   This code will probably work on any AT/ISA/EISA box running an un-munged
port of AT&T UNIX at release 3.2 or later, including XENIX.

BUGS
   Due to the absence of a reset ioctl(), the `defaults' that -r resets to
come from a table dumped out of 3.2u and hardwired into the code. If you have
reason to suspect that the system defaults have changed, you can replace the
sydefault initializer with the output of an `alter -d'.

AUTHOR
   Eric S. Raymond (eric@snark.uu.net), July 24 1989

*****************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/at_ansi.h>
#include <sys/kd.h>
#include <ctype.h>

extern void exit();
extern void perror();

static keymap_t sysdefault =
{
    128,
    {
/* 000 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 001 */  {{0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b}, 0x00, 0x00},
/* 002 */  {{0x31,0x21,0x31,0x31,0x7d,0x95,0x00,0x95}, 0x0f, 0x00},
/* 003 */  {{0x32,0x40,0x32,0x00,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 004 */  {{0x33,0x23,0x33,0x33,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 005 */  {{0x34,0x24,0x34,0x34,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 006 */  {{0x35,0x25,0x35,0x35,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 007 */  {{0x36,0x5e,0x36,0x1e,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 008 */  {{0x37,0x26,0x37,0x37,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 009 */  {{0x38,0x2a,0x38,0x38,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 010 */  {{0x39,0x28,0x39,0x39,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 011 */  {{0x30,0x29,0x30,0x30,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 012 */  {{0x2d,0x5f,0x2d,0x1f,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 013 */  {{0x3d,0x2b,0x3d,0x3d,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 014 */  {{0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08}, 0x00, 0x00},
/* 015 */  {{0x09,0x1d,0x09,0x1d,0x09,0x1d,0x09,0x1d}, 0x00, 0x00},
/* 016 */  {{0x71,0x51,0x11,0x11,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 017 */  {{0x77,0x57,0x17,0x17,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 018 */  {{0x65,0x45,0x05,0x05,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 019 */  {{0x72,0x52,0x12,0x12,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 020 */  {{0x74,0x54,0x14,0x14,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 021 */  {{0x79,0x59,0x19,0x19,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 022 */  {{0x75,0x55,0x15,0x15,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 023 */  {{0x69,0x49,0x09,0x09,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 024 */  {{0x6f,0x4f,0x0f,0x0f,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 025 */  {{0x70,0x50,0x10,0x10,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 026 */  {{0x5b,0x7b,0x1b,0x00,0x7d,0x7d,0x00,0x00}, 0x1f, 0x00},
/* 027 */  {{0x5d,0x7d,0x1d,0x00,0x7d,0x7d,0x00,0x00}, 0x1f, 0x00},
/* 028 */  {{0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d}, 0x00, 0x00},
/* 029 */  {{0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c}, 0xff, 0x00},
/* 030 */  {{0x61,0x41,0x01,0x01,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 031 */  {{0x73,0x53,0x13,0x13,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 032 */  {{0x64,0x44,0x04,0x04,0x7d,0x7d,0x81,0x00}, 0x0f, 0x01},
/* 033 */  {{0x66,0x46,0x06,0x06,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 034 */  {{0x67,0x47,0x07,0x07,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 035 */  {{0x68,0x48,0x08,0x08,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 036 */  {{0x6a,0x4a,0x0a,0x0a,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 037 */  {{0x6b,0x4b,0x0b,0x0b,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 038 */  {{0x6c,0x4c,0x0c,0x0c,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 039 */  {{0x3b,0x3a,0x3b,0x3a,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 040 */  {{0x27,0x22,0x27,0x22,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 041 */  {{0x60,0x7e,0x60,0x7e,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 042 */  {{0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}, 0xff, 0x00},
/* 043 */  {{0x5c,0x7c,0x1c,0x7c,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 044 */  {{0x7a,0x5a,0x1a,0x1a,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 045 */  {{0x78,0x58,0x18,0x18,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 046 */  {{0x63,0x43,0x03,0x03,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 047 */  {{0x76,0x56,0x16,0x16,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 048 */  {{0x62,0x42,0x02,0x02,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 049 */  {{0x6e,0x4e,0x0e,0x0e,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 050 */  {{0x6d,0x4d,0x0d,0x0d,0x7d,0x7d,0x00,0x00}, 0x0f, 0x01},
/* 051 */  {{0x2c,0x3c,0x2c,0x3c,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 052 */  {{0x2e,0x3e,0x2e,0x3e,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 053 */  {{0x2f,0x3f,0x2f,0x1f,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 054 */  {{0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03}, 0xff, 0x00},
/* 055 */  {{0x2a,0x2a,0x2a,0x2a,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 056 */  {{0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a}, 0xff, 0x00},
/* 057 */  {{0x20,0x20,0x00,0x00,0x7d,0x7d,0x00,0x00}, 0x0f, 0x00},
/* 058 */  {{0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04}, 0xff, 0x00},
/* 059 */  {{0x1b,0x27,0x33,0x3f,0x1b,0x27,0x33,0x3f}, 0xff, 0x00},
/* 060 */  {{0x1c,0x28,0x34,0x40,0x1c,0x28,0x34,0x40}, 0xff, 0x00},
/* 061 */  {{0x1d,0x29,0x35,0x41,0x1d,0x29,0x35,0x41}, 0xff, 0x00},
/* 062 */  {{0x1e,0x2a,0x36,0x42,0x1e,0x2a,0x36,0x42}, 0xff, 0x00},
/* 063 */  {{0x1f,0x2b,0x37,0x43,0x1f,0x2b,0x37,0x43}, 0xff, 0x00},
/* 064 */  {{0x20,0x2c,0x38,0x44,0x20,0x2c,0x38,0x44}, 0xff, 0x00},
/* 065 */  {{0x21,0x2d,0x39,0x45,0x21,0x2d,0x39,0x45}, 0xff, 0x00},
/* 066 */  {{0x22,0x2e,0x3a,0x46,0x22,0x2e,0x3a,0x46}, 0xff, 0x00},
/* 067 */  {{0x23,0x2f,0x3b,0x47,0x23,0x2f,0x3b,0x47}, 0xff, 0x00},
/* 068 */  {{0x24,0x30,0x3c,0x48,0x24,0x30,0x3c,0x48}, 0xff, 0x00},
/* 069 */  {{0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05}, 0xff, 0x00},
/* 070 */  {{0x06,0x06,0x7c,0x7c,0x06,0x06,0x7c,0x7c}, 0xff, 0x00},
/* 071 */  {{0x4b,0x37,0x4b,0x37,0x4b,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 072 */  {{0x4c,0x38,0x4c,0x38,0x4c,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 073 */  {{0x4d,0x39,0x4d,0x39,0x4d,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 074 */  {{0x4e,0x2d,0x4e,0x2d,0x4e,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 075 */  {{0x4f,0x34,0x4f,0x34,0x4f,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 076 */  {{0x50,0x35,0x50,0x35,0x50,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 077 */  {{0x51,0x36,0x51,0x36,0x51,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 078 */  {{0x52,0x2b,0x52,0x2b,0x52,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 079 */  {{0x53,0x31,0x53,0x31,0x53,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 080 */  {{0x54,0x32,0x54,0x32,0x54,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 081 */  {{0x55,0x33,0x55,0x33,0x55,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 082 */  {{0x56,0x30,0x56,0x30,0x56,0x7d,0x00,0x00}, 0xaf, 0x02},
/* 083 */  {{0x7f,0x2e,0x7f,0x2e,0x7f,0x7d,0x80,0x00}, 0x07, 0x02},
/* 084 */  {{0x56,0x34,0x56,0x00,0x7b,0x7b,0x7b,0x7b}, 0xff, 0x00},
/* 085 */  {{0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54}, 0xff, 0x00},
/* 086 */  {{0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f}, 0xff, 0x00},
/* 087 */  {{0x25,0x31,0x3d,0x49,0x25,0x31,0x3d,0x49}, 0xff, 0x00},
/* 088 */  {{0x26,0x32,0x3e,0x4a,0x26,0x32,0x3e,0x4a}, 0xff, 0x00},
/* 089 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 090 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 091 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 092 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 093 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 094 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 095 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 096 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 097 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 098 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 099 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 100 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 101 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 102 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 103 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 104 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 105 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 106 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 107 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 108 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 109 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 110 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 111 */  {{0x4d,0x4d,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 112 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 113 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 114 */  {{0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b}, 0xff, 0x00},
/* 115 */  {{0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d}, 0xff, 0x00},
/* 116 */  {{0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a}, 0x00, 0x00},
/* 117 */  {{0x2f,0x2f,0x00,0x00,0x7d,0x7d,0x00,0x00}, 0x3f, 0x00},
/* 118 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 119 */  {{0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c}, 0xff, 0x00},
/* 120 */  {{0x4c,0x4c,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 121 */  {{0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f}, 0x00, 0x00},
/* 122 */  {{0x53,0x53,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 123 */  {{0x56,0x56,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 124 */  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 125 */  {{0x51,0x51,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 126 */  {{0x55,0x55,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
/* 127 */  {{0x4b,0x4b,0x00,0x00,0x00,0x00,0x00,0x00}, 0xff, 0x00},
    }
};
static keymap_t keymap;

static void enable_alt()
{
    struct key_t *kp;

    /* for each non-special key that is ASCII printable in base state */
    for (kp = &(keymap.key[0]); kp < &(keymap.key[keymap.n_keys]); kp++)
	if (!(kp->spcl & 0x80) && isprint(kp->map[0]))
	{
	    kp->spcl &=~ 0xf; /* turn off specialness for alt maps */

	    /* set appropriate values in alt maps */
	    kp->map[ALTED] 	= (kp->map[0] + 128);
	    kp->map[ALTSHF]	= (kp->map[0] + 96);
	    kp->map[ALTCTL]	= (kp->map[0] + 128) & 0xf0;
	    kp->map[ALTSHFCTL]	= (kp->map[0] + 96) & 0xf0;
	}
}

static void dump_keymap()
{
    struct key_t *kp;

    (void) printf("{\n           %d,\n    {\n", keymap.n_keys);

    for (kp = &(keymap.key[0]); kp < &(keymap.key[keymap.n_keys]); kp++)
	(void) printf(
	     "/* %03d */  {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}, 0x%02x, 0x%02x},\n",
	     kp - &(keymap.key[0]),
	     kp->map[0], kp->map[1], kp->map[2], kp->map[3], 
	     kp->map[4], kp->map[5], kp->map[6], kp->map[7],
	     kp->spcl, kp->flgs);

    (void) printf("    }\n};");
}

static void restore_defaults()
{
    (void) memcpy(&keymap, &sysdefault, sizeof(keymap_t));
}

main(argc, argv)
int argc;
char **argv;
{
    int c, modified = 0;

    if (ioctl(0, GIO_KEYMAP, &keymap) == -1)
    {
	perror("alter: GIO_KEYMAP ioctl failed");
	exit(1);
    }

    while ((c = getopt(argc, argv, "adr")) != -1)
	switch(c)
	{
	case 'a':
	    enable_alt();
	    modified++;
	    break;

	case 'd':
	    dump_keymap();
	    break;

	case 'r':
	    restore_defaults();
	    modified++;
	    break;
	}

    if (modified)
	if (ioctl(0, PIO_KEYMAP, &keymap) == -1)
	{
	    perror("alter: SIO_KEYMAP ioctl failed");
	    exit(1);
	}

    exit(0);    
}

/* alter.c ends here */
---- CUT HERE -------- CUT HERE -------- CUT HERE -------- CUT HERE --------
-- 
      Eric S. Raymond = eric@snark.uu.net    (mad mastermind of TMN-Netnews)