Program to remap keys on the Sun-2 (sunkeys)

Praveen Kumar phaedrus at eneevax.UUCP
Thu Aug 1 06:30:42 AEST 1985


Sunkeys is a program to remap keys on a Sun-2 keyboard.  It is
intended to be used on the function keys but it can be used on any key.

**WARNING**

If you don't use sunkeys correctly, it will positively screw up your
keyboard.  If this does happen, you'll have to reboot or reset the
machine.  So, I urge you to test it out first.  So, without further
ado, is sunkeys.

#---------------------------cut here--------------------------------------
#! /bin/sh
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
all=FALSE
if [ $1x = -ax ]; then
	all=TRUE
fi
/bin/echo 'Extracting sunkeys.1l'
sed 's/^X//' <<'//go.sysin dd *' >sunkeys.1l
X.TH SUNKEYS 1L "19-June-1985"
X.UC
X.SH NAME
sunkeys \- program Sun2 keyboard
X.SH SYNOPSIS
X.B sunkeys
[
X.B \-fl
] [ <key> <key definition>] or [file]
X.SH DESCRIPTION
X.I sunkeys
Can program the entire Sun2 black and white console keyboard
X.IR key
is any key on the keyboard, plus the control and shifted version
of the keys as well.  The "C", and "S" are special characters
If a "C" is put in front of a key then, the control-key is to be defined.
For example
X.sp
X.I sunkeys
X.IR -c
X.IR St
X.IR \\001
X.sp
programs the shift-t key to send out the "^A" character.
X.IR key definition
is an arbitrary string with "\\" and "0x" as special strings. The (\\)
backslash operates like it does in the C language.  The (0x) means the
numbers following "0x" are to be interpreted as a hexadecimal
representation of an ASCII character.  For example,
X.sp
X.I sunkey
X.IR -c
X.IR l10
X.IR 0x20
X.sp
programs the l10 key to transmit the space character.
The
X.B -f
option tells sunkeys to read in
X.IR file
as a list of key definitions.  They are in the same format as for the
command line (i.e., <key> <key definition>) but, only one definition
is allowed per line.
X.PP
The list of key names may be generated with
X.B "sunkeys -l."
Most of the names are obvious (e.g. l2, f4, Cf6, , Sr4, return); 
X.SH AUTHOR
Pravin Kumar (phaedrus at eneevax or {allegra,seismo}!umcp-cs!eneevax!phaedrus)
X.SH FILES
X.SH "SEE ALSO"
X/usr/include/sun/fbio.h
X/usr/include/sundev/kbio.h
X/usr/include/sundev/kbd.h
X.SH DIAGNOSTICS
These should be self-explanatory.
X.SH BUGS
Of course, there aren't any.  I wrote it didn't I?  :-)
X.sp
Seriously, there is one. There really should be a way to do meta keys.
So, if anyone figures out a way to do these, pleae, mail me your code.
If you happen to find any other bugs, please mail details/fixes to me.
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
	/bin/chmod 644 sunkeys.1l
	/bin/echo -n '	'; /bin/ls -ld sunkeys.1l
fi
/bin/echo 'Extracting sunkeys.c'
sed 's/^X//' <<'//go.sysin dd *' >sunkeys.c
#ifndef lint
static char sccsid[] = "@(#)kbd.c	U of Md EE Dept. PK 3-Jun-1985";
#endif
X/*
 *	Sunkeys - reprogams the SUN2 keyboard
 *
 *	This is program maybe freely distributed to other UNIX sites but,
 *	comment/header must remain intact.
 *
 *	Author:  Pravin Kumar umcp-cs!eneevax!phaedrus
 *
 *
 %	cc -O -o sunkeys sunkeys.c
 */

#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sun/fbio.h>
#include <sundev/kbio.h>
#include <sundev/kbd.h>

#define		TRUE		1
#define		FALSE		0
#define		BACKSLASH	0x5C
#define		BACKSPACE	0x08
#define		NEWLINE		0x0A
#define		RETURN		0x0D
#define		TAB		0x09
#define		MAX_keydefs	(sizeof (k_board)/sizeof (*k_board))
#define		MAXLEN		80

FILE * fp, *fopen ();

char *progname;

int     fbdes,
        kb;

static int  str_cnt = STRING + 0x05;

struct fbtype   fb;

struct key_id_num {
	char *name;
	int id_num;
	} k_board [] = {
	{"'", 87},
	{",", 107},
	{"-", 40},
	{".", 108},
	{"/", 109},
	{"0", 39},
	{"1", 30},
	{"2", 31},
	{"3", 32},
	{"4", 33},
	{"5", 34},
	{"6", 35},
	{"7", 36},
	{"8", 37},
	{"9", 38},
	{";", 86},
	{"=", 41},
	{"break", 19},
	{"bs", 43},
	{"del", 66},
	{"esc", 29},
	{"l1", 1},
	{"l10", 97},
	{"l2", 3},
	{"l3", 25},
	{"l4", 26},
	{"l5", 49},
	{"l6", 51},
	{"l7", 72},
	{"l8", 73},
	{"l9", 95},
	{"lf", 111},
	{"r1", 21},
	{"r10", 91},
	{"r11", 92},
	{"r12", 93},
	{"r13", 112},
	{"r14", 113},
	{"r15", 114},
	{"r2", 22},
	{"r3", 23},
	{"r4", 45},
	{"r5", 46},
	{"r6", 47},
	{"r7", 68},
	{"r8", 69},
	{"r9", 70},
	{"ret", 89},
	{"f1", 5},
	{"f2", 6},
	{"f3", 8},
	{"f4", 10},
	{"f5", 12},
	{"f6", 14},
	{"f7", 16},
	{"f8", 17},
	{"f9", 18},
	{"tab", 53},
	{"[", 64},
	{"\\", 88},
	{"]", 65},
	{"`", 42},
	{"a", 77},
	{"b", 104},
	{"c", 102},
	{"d", 79},
	{"e", 56},
	{"f", 80},
	{"g", 81},
	{"h", 82},
	{"i", 61},
	{"j", 83},
	{"k", 84},
	{"l", 85},
	{"m", 106},
	{"n", 105},
	{"o", 62},
	{"p", 63},
	{"q", 54},
	{"r", 57},
	{"s", 78},
	{"t", 58},
	{"u", 60},
	{"v", 103},
	{"w", 55},
	{"x", 101},
	{"y", 59},
	{"z", 100}
};

main (argc, argv)
int argc;
char **argv;
{

    char    key[6],
            keydef[10],
            line[MAXLEN + 1];

    int     i;

    progname = *argv;

    while (argc > 1) {
	++argv;
	--argc;
	switch (*(++*argv)) {
	    case 'c': 
		strcpy (key, *++argv);
		strcpy (keydef, *++argv);
		argc -= 2;
		prep_kbd ();	/* prepare keyboard */

		printf ("Remapping ");
		switch (*key) {
		    case 'C': 
			printf ("`ctrl-%s' ", &key[1]);
			break;
		    case 'M': 
			printf ("`meta-%s' ", &key[1]);
			break;
		    case 'S': 
			printf ("`shift-%s' ", &key[1]);
			break;
		    default: 
			printf ("`%s' ", key);
			break;
		}
		printf ("...\n");

		set_key (key, keydef);
		break;
	    case 'f': 
		if ((fp = fopen (*++argv, "r")) == NULL) {
		    fprintf (stderr, "%s: couldn't open `%s'\n", progname, *argv);
		    exit (1);
		}
		--argc;
		printf ("Remapping Sun2 keyboard...\n");
		prep_kbd ();
		while (fgets (line, MAXLEN, fp) != NULL) {
		    xlate_line (line, key, keydef);
		    set_key (key, keydef);
		}
		fclose (fp);
		break;
	    case 'l': 
		for (i = 0; i < MAX_keydefs; i++) {
		    printf ("%s%c", k_board[i].name,
			    ((i + 1) % 4) ? '\t' : '\n');
		}
		break;
	    default: 
		usage ();
		break;
	}
    }
    exit (0);
}

int prep_kbd()
{
    if ((fbdes = open ("/dev/fb", 2)) < 0) {
	fprintf (stderr, "%s: couldn't open framebuffer\n", progname);
	exit (2);
    }

    if (ioctl (fbdes, FBIOGTYPE, &fb) < 0) {
	fprintf (stderr, "%s: couldn't get the fb struct\n", progname);
	exit (2);
    }

    if (fb.fb_type != FBTYPE_SUN2BW) {
	fprintf (stderr, "Sorry, I only do Sun2s\n", progname);
	exit (2);
    }

    if ((kb = open ("/dev/kbd", 2)) < 0) {
	fprintf (stderr, "%s: couldn't open keyboard\n", progname);
	exit (2);
    }
    return;
}

int set_key(key, keydef)
char *key, *keydef;
{
    int     found_key = FALSE,
            i;

    struct kiockey  this_key;
    struct kiockey *pk = &this_key;


    switch (*key) {
	case 'C': 
	    pk -> kio_tablemask = CTRLMASK;
	    key++;
	    break;
	case 'S': 
	    pk -> kio_tablemask = SHIFTMASK;
	    key++;
	    break;
	default: 
	    pk -> kio_tablemask = 0;
	    break;
    }


    for (i = 0; i < MAX_keydefs; i++) {
	if (strncmp (key, k_board[i].name, 3) == 0) {
	    found_key = TRUE;
	    break;
	}
    }

    if (!found_key) {
	fprintf (stderr, "%s: couldn't find `%s' key\n", progname, key);
	exit (2);
    }

    pk -> kio_station = k_board[i].id_num;

X/*    pk -> kio_tablemask = 0; */

    if (strlen (keydef) > 1) {
	if (keydef[0] == BACKSLASH) {
	    pk -> kio_string[0] = 0;
	    switch (keydef[1]) {
		case 'b': 
		    pk -> kio_entry = BACKSPACE;
		    break;
		case 'n': 
		    pk -> kio_entry = NEWLINE;
		    break;
		case 'r': 
		    pk -> kio_entry = RETURN;
		    break;
		case 't': 
		    pk -> kio_entry = TAB;
		    break;
		default: 
		    if (!isdigit (keydef[1])) {
			fprintf (stderr, "%s: don't know what `%s' is\n", progname, keydef);
			exit (2);
		    }
		    sscanf (&keydef[1], "%o", &i);
		    pk -> kio_entry = i;
		    break;
	    }
	}
	else if (strncmp (keydef, "0x", 2) == 0) {
	    pk -> kio_string[0] == 0;
	    sscanf (&keydef[2], "%x", &i);
	    pk -> kio_entry = i;
	}
	else {
	    if (++str_cnt > STRING + 0x0F) {
		fprintf (stderr, "%s: OOPS! only 10 string defs allowed.\n", progname);
		exit (2);
	    }
	    else {
		pk -> kio_entry = str_cnt;
		strcpy (pk -> kio_string, keydef);
	    }
	}
    }
    else {
	pk -> kio_string[0] = 0;
	pk -> kio_entry = toascii (keydef[0]);
    }

X/* define key */

    if (ioctl (kb, KIOCSETKEY, pk) < 0) {
	fprintf (stderr, "%s: couldn't define the `%s' key\n", progname, key);
	exit (2);
    }
    return;
}

int usage ()			/* routine to output usage message */
{
    fprintf (stderr, "usage: %s [-cfl] [key definition] or [file]\n", progname, progname);
    exit (2);
}

int xlate_line (buff, key, keydef)
char *buff,
     *key,
     *keydef;
{

    while (*buff != ' ' && *buff != '\t') {
	*key++ = *buff++;
    }
    *key = NULL;
    while (*buff == ' ' || *buff == '\t') {
	buff++;
    }
    if (strlen (buff) > 9) {
	fprintf (stderr, "%s: `%s' too long; must be < 10 chars\n", progname, keydef);
	exit (2);
    }
    strncpy (keydef, buff, 10);
    return;
}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
	/bin/chmod 644 sunkeys.c
	/bin/echo -n '	'; /bin/ls -ld sunkeys.c
fi
-- 


			Praveen Kumar

Don't bother me! I'm on an emergency third rail power trip.

phaedrus at eneevax.arpa or {seismo,allegra}!umcp-cs!eneevax!phaedrus



More information about the Comp.sources.unix mailing list