home *** CD-ROM | disk | FTP | other *** search
- Path: wuarchive!uwm.edu!cs.utexas.edu!uunet!bbn.com!rsalz
- From: rsalz@uunet.uu.net (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v20i081: Rebind the console keyboard in Xenix or System Vr3.2.1+
- Message-ID: <2098@papaya.bbn.com>
- Date: 27 Oct 89 17:27:21 GMT
- Lines: 1912
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Eric S. Raymond <eric@snark.uu.net>
- Posting-number: Volume 20, Issue 81
- Archive-name: keybind
-
- [ I have not even tried to compile this this. /r$ ]
-
- This program is an editor/minilanguage that lets you tweak the tables in
- the XENIX or System Vr3.2.1+ console keyboard driver for fun and profit.
-
- It is particularly useful if you use GNU EMACS or anything else that likes
- to have a real Meta key; see the -m option and `meta' directive. You can
- also map your virtual terminal selector functions to more convenient
- places than the bizarre Alt-cokebottle-foobar sequences they default to.
-
- Some may also find klex[12].l and kgram.y interesting as a simple but
- nontrivial example of lex/yacc usage, illustrating how to build a
- minilanguage with per-line error recovery.
-
- This release adds the capability to `precompile' keyboard mappings using
- the -o option; the binary dump files produced can be loaded by subsequent
- keybind runs, avoiding the interpreter's lexer and parser overhead.
-
- #!/bin/sh
- : "This is a shell archive, meaning: "
- : "1. Remove everything above the #! /bin/sh line. "
- : "2. Save the resulting test in a file. "
- : "3. Execute the file with /bin/sh (not csh) to create the files:"
- : " READ.ME"
- : " Makefile"
- : " keybind.c"
- : " kgram.y"
- : " klex1.l"
- : " klex2.l"
- : " kdefaults.h"
- : " keycaps"
- : " keybind.1"
- : " sample.kmf"
- echo file: READ.ME
- sed 's/^X//' >READ.ME << 'END-of-READ.ME'
- X Release 1.1 notes -- August 1, 1989
- X
- XThis program is an editor/minilanguage that lets you tweak the tables in the
- XXENIX or System Vr3.2.1+ console keyboard driver for fun and profit.
- X
- XIt is particularly useful if you use GNU EMACS or anything else that likes
- Xto have a real Meta key; see the -m option and `meta' directive. You can also
- Xmap your virtual terminal selector functions to more convenient places than
- Xthe bizarre Alt-cokebottle-foobar sequences they default to.
- X
- XSome may also find klex[12].l and kgram.y interesting as a simple but
- Xnontrivial example of lex/yacc usage, illustrating how to build a minilanguage
- Xwith per-line error recovery.
- X
- XThis replaces and extends the `alter' program I posted a couple of weeks ago;
- Xyou can throw that out now.
- X
- X Release 1.2 notes -- August 14 1989
- X
- XThis release adds the capability to `precompile' keyboard mappings using
- Xthe -o option; the binary dump files produced can be loaded by subsequent
- Xkeybind runs, avoiding the interpreter's lexer and parser overhead.
- X
- X Eric S. Raymond (eric@snark.uu.net)
- END-of-READ.ME
- echo file: Makefile
- sed 's/^X//' >Makefile << 'END-of-Makefile'
- X# Makefile for the key mapper utility
- X#
- X# @(#)Makefile 1.2
- X#
- X# Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
- X# You may use, modify or redistribute this code freely, but do not delete
- X# this notice. Check with me before you make money with it.
- X#
- X# Note: if you are running 3.2.1 rather than 3.2u, you have only 256 bytes of
- X# string definition space per tty, and you need to add -DMAXSTRINGS=256 to your
- X# compile flags. Otherwise it will be assumed that you have 512 bytes of
- X# string space per tty.
- X#
- XCFLAGS = -O # -g -DYYDEBUG # -DMAXSTRINGS=256
- XLDFLAGS = -s
- XYFLAGS = -v
- X
- Xkeybind: keybind.o kgram.o klex.o
- X $(CC) $(LDFLAGS) keybind.o kgram.o klex.o -ll -o keybind
- X
- Xkeybind.o: keybind.c kdefaults.h keycaps.h keybind.h
- Xkgram.o: kgram.c keybind.h
- Xklex.o: klex.c y.tab.h
- X
- Xklex.l: klex1.l keycaps.l klex2.l
- X cat klex1.l keycaps.l klex2.l >klex.l
- X
- Xkdefaults.h:
- X keybind -c >kdefaults.h
- X
- X# keycaps.h is the keycaps include file for C programs
- XCFILTER = '/^\([^ ]*\).*/s//"@\1",/p'
- Xkeycaps.h:
- X sed -n -e '/^#/d' -e $(CFILTER) <keycaps >keycaps.h
- X
- X# keycaps.l is the keycaps include file for lex programs
- XLFILTER = '/\(.*\) \(.*\)/s//"@\1" {yylval=\2;yytokno++;return(SCANCODE);}/'
- Xkeycaps.l:
- X tr <keycaps "[A-Z]" "[a-z]" | sort -r | sed -e '/^#/d' -e $(LFILTER) >keycaps.l
- X
- Xkgram.c y.tab.h: kgram.y
- X @echo expect conflicts: 3 shift/reduce
- X yacc -d $(YFLAGS) kgram.y
- X mv y.tab.c kgram.c
- X
- X# This is a lexical analyzer tester
- Xklex: klex.c y.tab.h
- X $(CC) $(CFLAGS) -DMAIN klex.c -ll -o klex
- X
- Xlint: keybind.c kgram.c klex.c
- X lint keybind.c kgram.c klex.c
- X
- Xkeybind.lpr:
- X nroff -T$(LPT) -man keybind.1 $(REGS) >$keybind.lpr
- X
- Xhelp:
- X @nroff -e -man keybind.1 | more
- X
- XSOURCES = keybind.c kgram.y klex[12].l kdefaults.h keycaps
- Xshar:
- X shar READ.ME Makefile $(SOURCES) keybind.1 sample.kmf >keybind.shar
- X
- Xclean:
- X rm -f kgram.c klex.c y.tab.h y.output klex keybind *.o *~
- X rm -f keycaps.h keycaps.l klex.[lc] keybind.shar
- END-of-Makefile
- echo file: keybind.c
- sed 's/^X//' >keybind.c << 'END-of-keybind.c'
- X/*
- X * keybind -- console/virtual tty keyboard remapper for 6386WGS systems
- X *
- X * @(#)keybind.c 1.2
- X *
- X * Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
- X * You may use, modify or redistribute this code freely, but do not delete
- X * this notice. Check with me before you make money with it.
- X */
- X#ifndef lint
- Xstatic char *sccsid = "@(#)keybind.c 1.2";
- X#endif /* lint */
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X#include <sys/types.h>
- X#include <sys/at_ansi.h>
- X#include <sys/kd.h>
- X#include <ctype.h>
- X#include <sys/ascii.h>
- X#include "keybind.h"
- X
- X#ifndef MAXSTRINGS
- X#define MAXSTRINGS STRTABLN
- X#endif /* MAXSTRINGS */
- X
- Xextern FILE *yyin;
- X#ifdef YYDEBUG
- Xextern int yydebug;
- X#endif /* YYDEBUG */
- X
- Xextern void exit();
- Xextern void perror();
- X
- X#define M(c) (0x80 | (c))
- X#define F(n) ((n) + K_FUNF - 1)
- X#define VTK(n) ((n) + K_VTF)
- X#define IS_VTKEY(c) (((c) >= K_VTF) && ((c) <= K_VTL))
- X#define MGR(n) ((n) + K_MGRF)
- X#define IS_MGRKEY(c) (((c) >= K_MGRF) && ((c) <= K_MGRL))
- X#define PFX(n) ((n) + K_PFXF)
- X#define IS_PFXKEY(c) (((c) >= K_PFXF) && ((c) <= K_PFXL))
- X
- X#define META 0x80
- X#define PSPECIAL(p,i) (p->spcl & (0x80>>(i)))
- X
- Xtypedef struct
- X{
- X int val;
- X char *name;
- X}
- Xsymbol;
- X
- Xtypedef struct
- X{
- X int val;
- X char *aname;
- X char *mname;
- X}
- Xtriple;
- X
- Xkbd_t kbd = {KBDHDMAGIC}; /* our workspace */
- X
- Xstatic char funkeys[NSTRKEYS][MAXFK+1]; /* function key strings */
- Xstatic int mapmods = 0; /* count map table changes */
- Xstatic int stringmods = 0; /* count string key changes */
- Xstatic int ttyfd; /* fd of console */
- X
- X/*
- X * The name table for printout of keycaps is generated from the master
- X * keycaps table.
- X */
- Xstatic char *keycaps[] =
- X{
- X#include "keycaps.h"
- X};
- X
- X/*
- X * Defaults tables -- regen defaults.h with keybind -c output if the system
- X * defaults ever change. Be sure to do this *before* you let vtlmgr run!
- X */
- X#include "kdefaults.h"
- X
- Xstatic triple specvals[] =
- X/* note: the second-column token have to match up with the lexical analyzer */
- X{
- X K_NOP, "nop", "NOP", /* Keys with no function */
- X K_LSH, "lshft", "LSH", /* Left shift */
- X K_RSH, "rshft", "RSH", /* Right shift */
- X K_CLK, "clock", "CLK", /* Caps lock */
- X K_NLK, "nlock", "NLK", /* Num lock */
- X K_SLK, "slock", "SLK", /* Scroll lock */
- X K_ALT, "alt", "ALT", /* Alt */
- X K_BTAB, "btab", "BTAB", /* Back tab */
- X K_CTL, "ctl", "CTL", /* Control */
- X K_LAL, "lalt", "LAL", /* Left alt */
- X K_RAL, "ralt", "RAL", /* Right alt */
- X K_LCT, "lctrl", "LCT", /* Left control */
- X K_RCT, "rctrl", "RCT", /* Right control */
- X K_SRQ, "sysreq", "SRQ", /* System request */
- X K_BRK, "break", "BRK", /* Break */
- X K_ESN, "escn", "ESN", /* <ESC> N <unalt'd value> sequence */
- X K_ESO, "esco", "ESO", /* <ESC> O <unalt'd value> sequence */
- X K_ESL, "escl", "ESL", /* <ESC> L <unalt'd value> sequence */
- X K_RBT, "reboot", "RBT", /* Reboot system */
- X K_DBG, "debug", "DBG", /* Invoke debugger */
- X K_NEXT, "next", "NEXT", /* Next virtual terminal */
- X K_PREV, "prev", "PREV", /* Previous virtual terminal */
- X K_FRCNEXT, "frcnext", "FRCNEXT",
- X K_FRCPREV, "frcprev", "FRCPREV",
- X -1
- X};
- X
- X#ifdef REGEN
- X/*
- X * This enables us to regenerate the defaults
- X */
- Xstatic void cdump_keymap()
- X{
- X int j;
- X
- X static char *mascii[] = /* use Microsoft's IBM-style NL/HT */
- X {
- X "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
- X "BS", "HT", "NL", "VT", "FF", "CR", "SO", "SI",
- X "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
- X "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US",
- X };
- X
- X struct key_t *kp;
- X
- X (void) printf("static keymap_t keydefaults[] = \n{\n %d,\n {\n",
- X kbd.keymap.n_keys);
- X
- X for (kp = &(kbd.keymap.key[0]); kp < &(kbd.keymap.key[kbd.keymap.n_keys]); kp++)
- X {
- X char repbuf[10];
- X
- X (void) printf("/*%03d*/{{", kp - &(kbd.keymap.key[0]));
- X for (j = 0; j < NUM_STATES; j++)
- X {
- X int c = kp->map[j];
- X
- X if (PSPECIAL(kp, j))
- X {
- X triple *sp;
- X
- X for (sp = specvals; sp->val != -1; sp++)
- X if (sp->val == c)
- X {
- X (void) strcpy(repbuf, "K_");
- X (void) strcat(repbuf, sp->mname);
- X break;
- X }
- X if (sp->val == -1)
- X if (IS_FUNKEY(c))
- X (void) sprintf(repbuf, "F(%d)", c - K_FUNF + 1);
- X else if (IS_VTKEY(c))
- X (void) sprintf(repbuf, "VTK(%d)", c - K_VTF + 1);
- X else if (IS_MGRKEY(c))
- X (void) sprintf(repbuf, "MGR(%d)", c - K_MGRF + 1);
- X else if (IS_PFXKEY(c))
- X (void) sprintf(repbuf, "PFX(%d)", c - K_PFXF + 1);
- X else
- X (void) sprintf(repbuf, "%d", c);
- X }
- X else
- X {
- X int alt = (c & 0x80);
- X
- X if (alt)
- X {
- X (void) strcpy(repbuf, "M(");
- X c &= 0x7F;
- X }
- X else
- X (void) strcpy(repbuf, "");
- X if (isprint(c))
- X {
- X if (c == '\'')
- X (void) strcat(repbuf, "'\\''");
- X else if (c == '\\')
- X (void) strcat(repbuf, "'\\\\'");
- X else
- X (void) sprintf(repbuf + strlen(repbuf), "'%c'", c);
- X }
- X else if (c == A_DEL)
- X (void) strcat(repbuf, "A_DEL");
- X else if (iscntrl(c))
- X {
- X (void) strcat(repbuf, "A_");
- X (void) strcat(repbuf, mascii[c]);
- X }
- X if (alt)
- X (void) strcat(repbuf + strlen(repbuf), ")");
- X }
- X
- X if (j < NUM_STATES - 1)
- X (void) strcat(repbuf + strlen(repbuf), ",");
- X (void) printf("%-7s", repbuf);
- X }
- X (void) printf("}, 0x%02x,0x%02x},\n", kp->spcl, kp->flgs);
- X }
- X (void) printf(" }\n};\n\n");
- X
- X (void) printf("static char *stringdefaults[] =\n{\n");
- X for (j = 0; j < NSTRKEYS; j++)
- X {
- X register char *cp;
- X
- X (void) printf(" \"");
- X for (cp = funkeys[j]; *cp; cp++)
- X if (isprint(*cp))
- X (void) putchar(*cp);
- X else
- X (void) printf("\\%03o", *cp);
- X (void) printf("\",\n");
- X }
- X (void) printf("};\n");
- X}
- X#endif /* REGEN */
- X
- X/*
- X * Here are the dump functions for human use. Each of these may be
- X * called by YACC productions, all are called by dump_all() below.
- X */
- X
- Xvoid list_shift(flag, leader)
- Xint flag;
- Xchar *leader;
- X{
- X struct key_t *kp;
- X
- X for (kp = kbd.keymap.key; kp < &(kbd.keymap.key[kbd.keymap.n_keys]); kp++)
- X if (kp[0].flgs & flag)
- X break;
- X
- X (void) printf("%s enabled\t", leader);
- X if (kp >= kbd.keymap.key + kbd.keymap.n_keys)
- X {
- X (void) printf("# nowhere\n");
- X return;
- X }
- X else
- X (void) printf("%s", keycaps[kp - kbd.keymap.key]);
- X
- X kbd.keymap.key[NUM_KEYS].flgs = ~kbd.keymap.key[NUM_KEYS - 1].flgs;
- X for (++kp ; kp <= kbd.keymap.key + kbd.keymap.n_keys; kp++)
- X if ((kp[0].flgs & flag) != (kp[-1].flgs & flag))
- X if (kp[0].flgs & flag)
- X {
- X if (kp < kbd.keymap.key + NUM_KEYS)
- X (void) printf(" %s", keycaps[kp - kbd.keymap.key]);
- X }
- X else
- X (void) printf(" - %s", keycaps[kp - kbd.keymap.key - 1]);
- X (void) putchar('\n');
- X}
- X
- Xvoid dump_keymap(lower, upper)
- Xint lower, upper;
- X{
- X int i;
- X
- X static char *ascii[] = /* use common names */
- X {
- X "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
- X "bs", "tab", "lf", "vt", "ff", "cr", "so", "si",
- X "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
- X "can", "em", "sub", "esc", "fs", "gs", "rs", "us",
- X };
- X struct key_t *kp;
- X
- X for (kp = &(kbd.keymap.key[lower]); kp <= kbd.keymap.key + upper; kp++)
- X {
- X char repbuf[10];
- X int j;
- X
- X (void) printf("%-12s ", keycaps[kp - &(kbd.keymap.key[0])]);
- X
- X for (j = 0; j < NUM_STATES; j++)
- X {
- X int c = kp->map[j];
- X
- X if (PSPECIAL(kp, j))
- X {
- X triple *sp;
- X
- X for (sp = specvals; sp->val != -1; sp++)
- X if (sp->val == c)
- X {
- X (void) strcpy(repbuf, sp->aname);
- X break;
- X }
- X if (sp->val == -1)
- X if (IS_FUNKEY(c))
- X (void) sprintf(repbuf, "fkey%d", c - K_FUNF + 1);
- X else if (IS_VTKEY(c))
- X (void) sprintf(repbuf, "vt%d", c - K_VTF + 1);
- X else if (IS_MGRKEY(c))
- X (void) sprintf(repbuf, "mgr%d", c - K_MGRF + 1);
- X else if (IS_PFXKEY(c))
- X (void) sprintf(repbuf, "pfx%d", c - K_PFXF + 1);
- X else
- X (void) sprintf(repbuf, "%d", c);
- X }
- X else
- X {
- X int alt = (c & META);
- X
- X if (alt)
- X c = (c & ~META);
- X if (isprint(c))
- X {
- X if (alt)
- X (void) strcpy(repbuf, "'!");
- X else
- X (void) strcpy(repbuf, "'");
- X if (c == '\'')
- X (void) strcat(repbuf, "\\''");
- X else if (c == '\\')
- X (void) strcat(repbuf, "\\\\'");
- X else
- X (void) sprintf(repbuf+strlen(repbuf), "%c'", c);
- X }
- X else if (iscntrl(c) || c == A_DEL)
- X {
- X if (alt)
- X (void) strcpy(repbuf, "!");
- X else
- X (void) strcpy(repbuf, "");
- X if (c == A_DEL)
- X (void) strcat(repbuf, "del");
- X else
- X (void) strcat(repbuf, ascii[c]);
- X }
- X }
- X
- X (void) printf("%-8s", repbuf);
- X }
- X (void) putchar('\n');
- X }
- X}
- X
- Xvoid dump_funkeys(lower, upper)
- Xint lower, upper;
- X{
- X int i;
- X
- X for (i = lower; i <= upper; i++)
- X if (strlen(funkeys[i - 1]))
- X {
- X (void) printf("fkey%d = \"", i);
- X dump_string(funkeys[i-1]);
- X (void) putchar('"');
- X (void) putchar('\n');
- X }
- X}
- X
- Xstatic void dump_all()
- X{
- X time_t now = time((time_t *)0);
- X int i;
- X
- X (void) printf("#\n# Key bindings:\n#\n");
- X (void) printf(
- X"# Ctrl Alt Alt Alt-Ctrl\n");
- X (void) printf(
- X"#Code Normal Shift Ctrl Shift Alt Shift Ctrl Shift\n");
- X (void) printf(
- X"#--------------------------------------------------------------------------\n");
- X
- X dump_keymap(0, kbd.keymap.n_keys - 1);
- X
- X (void) printf("#\n# Shift keys:\n#\n");
- X list_shift(KMF_CLOCK, "capslock");
- X list_shift(KMF_NLOCK, "numlock ");
- X
- X (void) printf("#\n# Function keys:\n#\n");
- X dump_funkeys(1, NSTRKEYS);
- X}
- X
- X/*
- X * Functions for meta-key enabling
- X */
- X
- Xint weak_binding(p, state)
- X/* test if key state has a `weak binding', not char or important special */
- Xstruct key_t *p;
- Xint state;
- X{
- X if (!PSPECIAL(p, state))
- X return(0);
- X else
- X {
- X register unchar val = p->map[state];
- X
- X return(val == K_NOP || val == K_ESN || val == K_ESO || val == K_ESL);
- X }
- X}
- X
- Xvoid enable_alt()
- X{
- X struct key_t *kp;
- X
- X /* for each non-special key that is ASCII printable in base state */
- X for (kp = &(kbd.keymap.key[0]); kp < &(kbd.keymap.key[kbd.keymap.n_keys]); kp++)
- X if (!PSPECIAL(kp, NORMAL) && isprint(kp->map[NORMAL]))
- X {
- X if (weak_binding(kp, ALTED))
- X {
- X kp->map[ALTED] = (kp->map[NORMAL] | META);
- X kp->spcl &=~ 0x08;
- X }
- X if (weak_binding(kp, ALTSHF))
- X {
- X kp->map[ALTSHF] = (kp->map[SHIFT] | META);
- X kp->spcl &=~ 0x04;
- X }
- X if (weak_binding(kp, ALTCTL))
- X {
- X kp->map[ALTCTL] = (kp->map[CTRL] | META);
- X kp->spcl &=~ 0x02;
- X }
- X if (weak_binding(kp, ALTSHFCTL))
- X {
- X kp->map[ALTSHFCTL] = (kp->map[SHFCTL] | META);
- X kp->spcl &=~ 0x01;
- X }
- X }
- X mapmods++;
- X}
- X
- X/*
- X * Other major functions. If it isn't static, it's because YACC may call it.
- X */
- X
- Xvoid restore_defaults()
- X{
- X int i;
- X
- X (void) memcpy(&kbd.keymap, &keydefaults, sizeof(keymap_t));
- X
- X for (i = 0; i < NSTRKEYS; i++)
- X (void) strcpy(funkeys[i], stringdefaults[i]);
- X mapmods++;
- X
- X}
- X
- Xint setkey(scancode, indx, kfunc)
- Xint scancode; /* scancode */
- Xint indx; /* map index */
- Xint kfunc; /* key function */
- X{
- X struct key_t *kp = kbd.keymap.key + scancode;
- X#ifdef DEBUG
- X (void) printf("keybind: code %d/state %d becomes %s%d\n",
- X scancode, indx,
- X (kfunc >= NUM_KEYS ? "special ": "character "),
- X kfunc - (kfunc >= NUM_KEYS) * NUM_KEYS);
- X#endif /* DEBUG */
- X
- X if (kfunc < NUM_KEYS)
- X kp->spcl &=~ (0x80>>indx);
- X else
- X {
- X kp->spcl |= (0x80>>indx);
- X kfunc -= NUM_KEYS;
- X }
- X kp->map[indx] = kfunc;
- X mapmods++;
- X}
- X
- Xint setstring(fnkey, str)
- Xint fnkey;
- Xchar *str;
- X{
- X extern char *malloc();
- X char *cp, *tp;
- X
- X#ifdef DEBUG
- X (void) printf("keybind: binding function key %d to \"", fnkey);
- X dump_string(str);
- X (void) putchar('"');
- X (void) putchar('\n');
- X#endif /* DEBUG */
- X
- X (void) strncpy(funkeys[fnkey], str, MAXFK);
- X stringmods++;
- X}
- X
- Xvoid clear_strings()
- X{
- X (void) memset(funkeys, '\0', (MAXFK + 1) * NSTRKEYS);
- X}
- X
- Xvoid do_changes()
- X/* execute all pending changes to key and string maps */
- X{
- X if (mapmods)
- X if (ioctl(ttyfd, PIO_KEYMAP, &kbd.keymap) == -1)
- X perror("keybind: PIO_KEYMAP ioctl failed");
- X
- X if (stringmods)
- X {
- X int i;
- X unchar *sp = kbd.strmap;
- X
- X for (i = 0; i < NSTRKEYS; i++)
- X {
- X if (sp + strlen(sp) + 1 - kbd.strmap > MAXSTRINGS)
- X {
- X (void) fprintf(stderr,
- X "keybind: out of string space at fkey %d\n", i);
- X return;
- X }
- X (void) strcpy(sp, funkeys[i]);
- X sp += strlen(sp) + 1;
- X }
- X
- X if (ioctl(ttyfd, PIO_STRMAP, kbd.strmap) == -1)
- X perror("keybind: PIO_STRMAP ioctl failed");
- X }
- X}
- X
- X/*
- X * The main sequence. All this does is the keymap read, a dispatch on options,
- X * and the keymap write.
- X */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int i, c, inputcount = 0;
- X unchar *cp;
- X char ofname[BUFSIZ];
- X
- X if ((ttyfd = open("/dev/tty", O_RDONLY)) < 0
- X && (ttyfd = open("/dev/console", O_RDONLY)) < 0)
- X {
- X perror("keybind: tty open failed!");
- X exit(1);
- X }
- X
- X if (ioctl(ttyfd, GIO_KEYMAP, &kbd.keymap) == -1)
- X {
- X perror("keybind: GIO_KEYMAP ioctl failed");
- X exit(1);
- X }
- X
- X if (ioctl(ttyfd, GIO_STRMAP, kbd.strmap) == -1)
- X {
- X perror("keybind: GIO_STRMAP ioctl failed");
- X exit(1);
- X }
- X for (i = 0, cp = kbd.strmap; *cp; cp += strlen(cp) + 1)
- X (void) strcpy(funkeys[i++], cp);
- X
- X for (++argv, --argc; argc; ++argv, --argc)
- X {
- X if (**argv == '-' && argv[0][1])
- X {
- X while (*++*argv != '\0')
- X switch(**argv)
- X {
- X case 'm': enable_alt(); break;
- X#ifdef REGEN
- X case 'c': cdump_keymap(); break;
- X#endif /* REGEN */
- X case 'd': dump_all(); break;
- X case 'r': restore_defaults(); inputcount++; break;
- X case 'o':
- X (void)strcpy(ofname, *++argv);
- X argc--;
- X goto nextarg; /* ick... */
- X default:
- X (void) fputs("usage: keymap [-mdrv] [-] [files...]\n",
- X stderr);
- X exit(1);
- X }
- X continue;
- X }
- X else
- X {
- X FILE *fp;
- X
- X if (**argv == '-')
- X {
- X inputcount++;
- X yyin = stdin;
- X yyparse();
- X }
- X else if ((fp = fopen(*argv, "r")) == (FILE *)NULL)
- X {
- X perror(*argv);
- X exit(1);
- X }
- X else /* O.K., it's a valid input source */
- X {
- X int c = fgetc(fp); /* peek at first character */
- X
- X inputcount++;
- X (void) ungetc(c, fp);
- X
- X /* if it looks like ascii, run source through interpreter */
- X if (isprint(c))
- X {
- X yyin = fp;
- X yyparse();
- X }
- X else if (fread(&kbd,sizeof(kbd_t),1,fp)!=1 || kbd.magic!=KBDHDMAGIC)
- X {
- X (void) fprintf(stderr, "keybind: garbled map dump file\n");
- X exit(1);
- X }
- X else /* we have a valid dump file */
- X {
- X mapmods++;
- X stringmods++;
- X
- X /* massage the loaded fundefs into something useful */
- X for (i = 0, cp = kbd.strmap; *cp; cp += strlen(cp) + 1)
- X (void) strcpy(funkeys[i++], cp);
- X }
- X }
- X }
- X nextarg:;
- X }
- X
- X /* if no file or - arguments, process stdin once */
- X if (inputcount == 0)
- X {
- X yyin = stdin;
- X yyparse();
- X }
- X
- X if (ofname[0] == '\0')
- X do_changes();
- X else
- X {
- X FILE *ofp;
- X
- X ofp = fopen(ofname, "w");
- X (void) fwrite(&kbd, sizeof(kbd_t), 1, ofp);
- X (void) fclose(ofp);
- X }
- X
- X (void) close(ttyfd);
- X exit(0);
- X}
- X
- X/* keybind.c ends here */
- END-of-keybind.c
- echo file: kgram.y
- sed 's/^X//' >kgram.y << 'END-of-kgram.y'
- X/*
- X * kgram.y -- YACC grammar for key-map interpreter
- X *
- X * @(#)kgram.y 1.2
- X *
- X * Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
- X * You may use, modify or redistribute this code freely, but do not delete
- X * this notice. Check with me before you make money with it.
- X */
- X%{
- X/*LINTLIBRARY*/
- X#ifndef lint
- Xstatic char *sccsid = "@(#)kgram.y 1.2";
- X#endif /* lint */
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <sys/types.h>
- X#include <sys/at_ansi.h>
- X#include <sys/kd.h>
- X#include "keybind.h"
- X
- Xextern kbd_t kbd;
- Xextern char yytext[];
- X
- Xextern void enable_alt(), list_shift(), restore_defaults();
- Xextern void dump_keymap(), dump_funkeys();
- Xextern void set_key(), set_string(), clear_strings();
- Xextern void do_changes();
- X
- Xstatic int prefval;
- Xstatic int codes1[NUM_KEYS];
- Xstatic int ccount;
- Xstatic int codes2[NUM_KEYS];
- X
- Xstatic void do_help();
- X%}
- X
- X%start map
- X
- X%token SCANCODE CHARKEY FUNKEY SPECIAL
- X%token PREFIX STRING
- X%token SHIFTER ENABLED DISABLED
- X%token META RESTORE DUMP SHIFTS FUNKEYS CLEARSTRINGS EXECUTE HELP
- X%token ASSIGN DASH
- X%token NEWLINE 10
- X%token LEXERR
- X
- X%% /* beginning of rules section */
- X
- X/* a map description consists of a sequence of commands */
- Xmap : /* EMPTY */
- X | map command NEWLINE
- X | map error NEWLINE
- X {yyerrok;}
- X | map NEWLINE
- X ;
- X
- Xcommand : SCANCODE funcs
- X {
- X int i;
- X
- X if (ccount > NUM_STATES)
- X yyerror("too many functions in scancode spec");
- X else
- X for (i = 0; i < ccount; i++)
- X if (codes1[i] >= 0)
- X setkey($1, i, codes1[i]);
- X }
- X
- X | SCANCODE ASSIGN func
- X {setkey($1, 0, $3);}
- X | PREFIX SCANCODE ASSIGN func
- X {setkey($2, $1, $4);}
- X | PREFIX PREFIX SCANCODE ASSIGN func
- X {setkey($3, ($1 | $2), $5);}
- X | PREFIX PREFIX PREFIX SCANCODE ASSIGN func
- X {setkey($4, ($1 | $2 | $3), $6);}
- X
- X | FUNKEY ASSIGN STRING
- X {setstring($1 - K_FUNF, yytext);}
- X | SHIFTER ENABLED ranges
- X {
- X int i, j;
- X
- X if (ccount == 0)
- X {
- X codes1[0] = 0;
- X codes2[0] = NUM_KEYS - 1;
- X ccount++;
- X }
- X for (i = 0; i < ccount; i++)
- X for (j = codes1[i]; j <= codes2[i]; j++)
- X kbd.keymap.key[j].flgs |= $1;
- X }
- X
- X | SHIFTER DISABLED ranges
- X {
- X int i, j;
- X
- X if (ccount == 0)
- X {
- X codes1[0] = 0;
- X codes2[0] = NUM_KEYS - 1;
- X ccount++;
- X }
- X for (i = 0; i < ccount; i++)
- X for (j = codes1[i]; j <= codes2[i]; j++)
- X kbd.keymap.key[j].flgs &=~ $1;
- X }
- X | DUMP ranges
- X {
- X int i, j;
- X
- X if (ccount == 0)
- X dump_keymap(0, kbd.keymap.n_keys - 1);
- X else
- X for (i = 0; i < ccount; i++)
- X dump_keymap(codes1[i], codes2[i]);
- X }
- X | FUNKEYS franges
- X {
- X int i, j;
- X
- X if (ccount == 0)
- X dump_funkeys(1, NSTRKEYS);
- X else
- X for (i = 0; i < ccount; i++)
- X dump_funkeys(codes1[i]-K_FUNF+1,codes2[i]-K_FUNF+1);
- X }
- X | SHIFTER
- X {
- X if ($1 == KMF_CLOCK)
- X list_shift(KMF_CLOCK, "capslock");
- X else
- X list_shift(KMF_NLOCK, "numlock ");
- X }
- X | META
- X {enable_alt();}
- X | RESTORE
- X {restore_defaults();}
- X | CLEARSTRINGS
- X {clear_strings();}
- X | EXECUTE
- X {do_changes();};
- X | HELP
- X {do_help();};
- X ;
- X
- Xranges : /* EMPTY */
- X {ccount = 0;}
- X | ranges SCANCODE DASH SCANCODE
- X {codes1[ccount] = $2; codes2[ccount] = $4; ccount++;}
- X | ranges SCANCODE
- X {codes1[ccount] = codes2[ccount] = $2; ccount++;}
- X ;
- X
- Xfranges : /* EMPTY */
- X {ccount = 0;}
- X | franges FUNKEY DASH FUNKEY
- X {codes1[ccount] = $2; codes2[ccount] = $4; ccount++;}
- X | franges FUNKEY
- X {codes1[ccount] = codes2[ccount] = $2; ccount++;}
- X ;
- X
- Xfunc : CHARKEY {$$ = ($1 & 0xff);}
- X | FUNKEY {$$ = ($1 & 0xff);}
- X | SPECIAL {$$ = $1 + NUM_KEYS;}
- X ;
- X
- Xfuncs : func
- X {ccount = 0; codes1[ccount++] = $1;}
- X | funcs func
- X {codes1[ccount++] = $2;}
- X | funcs DASH
- X {codes1[ccount++] = -1;}
- X | /* EMPTY */
- X {(void)yyerror("expected a list of function codes"); YYERROR;}
- X ;
- X%%
- X
- Xint yyerror(message)
- Xchar *message;
- X{
- X (void) fprintf(stderr, "keybind: %s\n", message);
- X}
- X
- Xvoid do_help()
- X{
- X#define P(s) (void) printf(s)
- XP("Keybind commands are:\n\n");
- X
- XP("@scancode [func...] -- assign functions to scancode\n");
- XP("[prefix] @scancode = [func] -- assign to key/state pair\n\n");
- X
- XP("fkey<nn> = \"string\" -- load string key\n\n");
- X
- XP("cl[earstrings] -- clear the string table\n");
- XP("capslock di[sabled] [range...] -- disable capslock on chars\n");
- XP("numlock di[sabled] [range...] -- disable numlock on chars\n");
- XP("du[mp] [range...] -- show functions of given keys\n");
- XP("[ca]pslock en[abled] [range...] -- enable capslock on chars\n");
- XP("[nu]mlock en[abled] [range...] -- enable numlock on chars\n");
- XP("ex[ecute] -- write changes to the driver\n");
- XP("fu[nkeys] [range...] -- show bindings of string keys\n");
- XP("he[lp] -- display this message\n");
- XP("me[ta] -- enable the Alt key as meta\n");
- XP("re[store] -- restore defaults\n");
- XP("ca[pslock] -- show keys capslock affects\n");
- XP("nu[mlock] -- show keys numlock affects\n\n");
- X
- XP("Ranges may be a character literal or two dash-separated char literals.\n");
- XP("Functions may be char literals or one of the named special functions\n");
- XP("documented in keyboard(7)\n");
- X}
- X
- X/* kgram.y ends here */
- END-of-kgram.y
- echo file: klex1.l
- sed 's/^X//' >klex1.l << 'END-of-klex1.l'
- X%{
- X/*
- X * klex.l -- lexical analyzer for the keybind mini-language interpreter
- X *
- X * @(#)klex1.l 1.2
- X *
- X * Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
- X * You may use, modify or redistribute this code freely, but do not delete
- X * this notice. Check with me before you make money with it.
- X */
- X/*LINTLIBRARY*/
- X#ifndef lint
- Xstatic char *sccsid = "@(#)klex1.l 1.2";
- X#endif /* lint */
- X
- X#include <sys/types.h>
- X#include <sys/at_ansi.h>
- X#include <sys/kd.h>
- X#include <sys/ascii.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include "keybind.h"
- X#include "y.tab.h"
- X
- Xextern yylval; /* used to pass token values to YACC */
- X
- Xstatic int yytokno = 0;
- Xstatic int smashcase = 1;
- Xstatic int interactive = 0;
- X
- X#undef input
- Xint input()
- X{
- X static int doprompt;
- X int c;
- X
- X if (doprompt-- == 1)
- X (void) fputs("*", stdout);
- X
- X if ((c = getc(yyin)) == '\n')
- X {
- X yylineno++;
- X if (interactive)
- X doprompt = 1;
- X }
- X
- X if (feof(yyin))
- X return(0);
- X else if (smashcase && isupper(c))
- X return(tolower(c));
- X else
- X return(c);
- X}
- X
- X#undef unput
- X#define unput(c) ungetc(c, yyin)
- X
- Xextern void dump_string();
- Xstatic void getstring();
- X%}
- X
- X%e 1700
- X%p 3700
- X%n 500
- X%k 50
- X%a 900
- X%o 800
- X
- X%%
- X
- Xclearstrings|cl {yytokno++; return(CLEARSTRINGS);}
- Xdisabled|di {yytokno++; return(DISABLED);}
- Xdump|du {yytokno++; return(DUMP);}
- Xenabled|en {yytokno++; return(ENABLED);}
- Xexecute|ex {yytokno++; return(EXECUTE);}
- Xfunkeys|fu {yytokno++; return(FUNKEYS);}
- Xhelp|he {yytokno++; interactive++; return(HELP);}
- Xmeta|me {yytokno++; return(META);}
- Xrestore|re {yytokno++; return(RESTORE);}
- X
- Xshift-? {yylval = SHIFTED; yytokno++; return(PREFIX);}
- Xctrl-? {yylval = CTRLED; yytokno++; return(PREFIX);}
- Xalt-? {yylval = ALTED; yytokno++; return(PREFIX);}
- X
- Xcapslock|ca {yylval = KMF_CLOCK; yytokno++; return(SHIFTER);}
- Xshiftlock|sh {yylval = KMF_CLOCK; yytokno++; return(SHIFTER);}
- Xnumlock|nu {yylval = KMF_NLOCK; yytokno++; return(SHIFTER);}
- X
- X\" {getstring(yytext, '"'); yytokno++; return(STRING);}
- X' {
- X getstring(yytext, '\'');
- X if (strlen(yytext) == 1)
- X {
- X yylval = yytext[0];
- X yytokno++;
- X return(CHARKEY);
- X }
- X else
- X {
- X (void) fprintf(stderr,
- X "keybind: bad character syntax, line %d token %d\n",
- X yylineno + 1, yytokno);
- X interactive--;
- X while (input() != '\n')
- X continue;
- X interactive++;
- X return(LEXERR);
- X }
- X }
- X
- X@[0-9][0-9][0-9] {yylval=atoi(yytext+1); yytokno++; return(SCANCODE);}
- END-of-klex1.l
- echo file: klex2.l
- sed 's/^X//' >klex2.l << 'END-of-klex2.l'
- X@. {
- X (void) fprintf(stderr,
- X "keybind: bad scan-code specifier, line %d, token %d\n",
- X yylineno, yytokno);
- X interactive--;
- X while (input() != '\n')
- X continue;
- X interactive++;
- X return(LEXERR);
- X }
- X
- Xnul {yylval = A_NUL; yytokno++; return(CHARKEY);}
- Xsoh {yylval = A_SOH; yytokno++; return(CHARKEY);}
- Xstx {yylval = A_STX; yytokno++; return(CHARKEY);}
- Xetx {yylval = A_ETX; yytokno++; return(CHARKEY);}
- Xeot {yylval = A_EOT; yytokno++; return(CHARKEY);}
- Xenq {yylval = A_ENQ; yytokno++; return(CHARKEY);}
- Xack {yylval = A_ACK; yytokno++; return(CHARKEY);}
- Xbel {yylval = A_BEL; yytokno++; return(CHARKEY);}
- Xbs {yylval = A_BS; yytokno++; return(CHARKEY);}
- Xht {yylval = A_HT; yytokno++; return(CHARKEY);}
- Xtab {yylval = A_HT; yytokno++; return(CHARKEY);}
- Xnl {yylval = A_NL; yytokno++; return(CHARKEY);}
- Xlf {yylval = A_NL; yytokno++; return(CHARKEY);}
- Xvt {yylval = A_VT; yytokno++; return(CHARKEY);}
- Xff {yylval = A_FF; yytokno++; return(CHARKEY);}
- Xcr {yylval = A_CR; yytokno++; return(CHARKEY);}
- Xso {yylval = A_SO; yytokno++; return(CHARKEY);}
- Xsi {yylval = A_SI; yytokno++; return(CHARKEY);}
- Xdle {yylval = A_DLE; yytokno++; return(CHARKEY);}
- Xdc1 {yylval = A_DC1; yytokno++; return(CHARKEY);}
- Xxon {yylval = A_DC1; yytokno++; return(CHARKEY);}
- Xdc2 {yylval = A_DC2; yytokno++; return(CHARKEY);}
- Xdc3 {yylval = A_DC3; yytokno++; return(CHARKEY);}
- Xxoff {yylval = A_DC3; yytokno++; return(CHARKEY);}
- Xdc4 {yylval = A_DC4; yytokno++; return(CHARKEY);}
- Xnak {yylval = A_NAK; yytokno++; return(CHARKEY);}
- Xsyn {yylval = A_SYN; yytokno++; return(CHARKEY);}
- Xetb {yylval = A_ETB; yytokno++; return(CHARKEY);}
- Xcan {yylval = A_CAN; yytokno++; return(CHARKEY);}
- Xem {yylval = A_EM; yytokno++; return(CHARKEY);}
- Xsub {yylval = A_SUB; yytokno++; return(CHARKEY);}
- Xesc {yylval = A_ESC; yytokno++; return(CHARKEY);}
- Xfs {yylval = A_FS; yytokno++; return(CHARKEY);}
- Xgs {yylval = A_GS; yytokno++; return(CHARKEY);}
- Xrs {yylval = A_RS; yytokno++; return(CHARKEY);}
- Xus {yylval = A_US; yytokno++; return(CHARKEY);}
- Xdel {yylval = A_DEL; yytokno++; return(CHARKEY);}
- Xcsi {yylval = A_CSI; yytokno++; return(CHARKEY);}
- X
- Xnop {yylval = K_NOP; yytokno++; return(SPECIAL);}
- Xlshift {yylval = K_LSH; yytokno++; return(SPECIAL);}
- Xrshift {yylval = K_RSH; yytokno++; return(SPECIAL);}
- Xclock {yylval = K_CLK; yytokno++; return(SPECIAL);}
- Xnlock {yylval = K_NLK; yytokno++; return(SPECIAL);}
- Xslock {yylval = K_SLK; yytokno++; return(SPECIAL);}
- Xalt {yylval = K_ALT; yytokno++; return(SPECIAL);}
- Xbtab {yylval = K_BTAB; yytokno++; return(SPECIAL);}
- Xctrl {yylval = K_CTL; yytokno++; return(SPECIAL);}
- Xlalt {yylval = K_LAL; yytokno++; return(SPECIAL);}
- Xralt {yylval = K_RAL; yytokno++; return(SPECIAL);}
- Xlctrl {yylval = K_LCT; yytokno++; return(SPECIAL);}
- Xrctrl {yylval = K_RCT; yytokno++; return(SPECIAL);}
- X
- Xfkey[0-9][0-9]? {yylval = K_FUNF+atoi(yytext+4)-1; yytokno++; return(FUNKEY);}
- X
- Xsysreq {yylval = K_SRQ; yytokno++; return(SPECIAL);}
- Xbrk {yylval = K_BRK; yytokno++; return(SPECIAL);}
- Xescn {yylval = K_ESN; yytokno++; return(SPECIAL);}
- Xesco {yylval = K_ESO; yytokno++; return(SPECIAL);}
- Xescl {yylval = K_ESL; yytokno++; return(SPECIAL);}
- Xrboot {yylval = K_RBT; yytokno++; return(SPECIAL);}
- Xdebug {yylval = K_DBG; yytokno++; return(SPECIAL);}
- Xnext {yylval = K_NEXT; yytokno++; return(SPECIAL);}
- Xprev {yylval = K_PREV; yytokno++; return(SPECIAL);}
- Xfnext {yylval = K_FRCNEXT; yytokno++; return(SPECIAL);}
- Xfprev {yylval = K_FRCPREV; yytokno++; return(SPECIAL);}
- X
- Xvt[0-9][0-9]? {yylval = K_VTF+atoi(yytext+2); yytokno++; return(SPECIAL);}
- Xvtf {yylval = K_VTF; yytokno++; return(SPECIAL);}
- Xvtl {yylval = K_VTL; yytokno++; return(SPECIAL);}
- Xmgr[0-9][0-9]? {yylval = K_MGRF+atoi(yytext+3); yytokno++; return(SPECIAL);}
- Xmgrf {yylval = K_MGRF; yytokno++; return(SPECIAL);}
- Xmgrl {yylval = K_MGRL; yytokno++; return(SPECIAL);}
- Xpfx[0-9][0-9]? {yylval = K_PFXF+atoi(yytext+3); yytokno++; return(SPECIAL);}
- Xpfxf {yylval = K_PFXF; yytokno++; return(SPECIAL);}
- Xpfxl {yylval = K_PFXL; yytokno++; return(SPECIAL);}
- X
- X"#" {while (input() != '\n') continue; unput('\n');}
- X
- X[\n;] {yytokno = 0; return(NEWLINE);}
- X= {yytokno++; return(ASSIGN);}
- X- {yytokno++; return(DASH);}
- X[\ \t,] ;
- X
- X"?" {yytokno++; interactive++; return(HELP);}
- X
- X. {
- X (void) fprintf(stderr,
- X "keybind: bad char, line %d, after token %d = \"",
- X yylineno, yytokno);
- X dump_string(yytext);
- X (void) fputs("\"\n", stdout);
- X interactive--;
- X while (input() != '\n')
- X continue;
- X interactive++;
- X return(LEXERR);
- X }
- X
- X%%
- X/*
- X * klex2.l -- lexical analyzer for keymap editor program, part 2
- X *
- X * @(#)klex2.l 1.2
- X *
- X * Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
- X * You may use, modify or redistribute this code freely, but do not delete
- X * this notice. Check with me before you make money with it.
- X */
- X
- Xstatic int yywrap()
- X{
- X if (interactive)
- X (void) putchar('\n');
- X interactive = 0;
- X return(EOF);
- X}
- X
- Xvoid getstring(buf, term)
- Xchar *buf, term;
- X{
- X char *tp;
- X int c, cval;
- X
- X smashcase = 0;
- X buf[0] = '\0';
- X for (tp = buf; (c = input()) != term && c != EOF; *tp++ = cval)
- X {
- X if (c == '\\')
- X {
- X c = input();
- X if (strchr("0123456789xX", c))
- X {
- X char *dp, *hex = "0123456789abcdef";
- X int dcount = 0;
- X
- X if (c == 'x' || c == 'X')
- X while ((dp = strchr(hex, (c = input()))) && (dcount++ < 2))
- X cval = (cval * 16) + (dp - hex);
- X else if (c == '0')
- X while (strchr("01234567", (c = input())) && (dcount++ < 3))
- X cval = (cval * 8) + (c - '0');
- X else
- X while (strchr("0123456789", (c = input())) && (dcount++ < 3))
- X cval = (cval * 10) + (c - '0');
- X unput(c);
- X }
- X else /* C-style character escapes */
- X {
- X switch (c)
- X {
- X case '\\': cval = '\\'; break;
- X case 'e': cval = '\033'; break;
- X case 'n': cval = '\n'; break;
- X case 't': cval = '\t'; break;
- X case 'b': cval = '\b'; break;
- X case 'r': cval = '\r'; break;
- X case 'v': cval = '\v'; break;
- X default: cval = c;
- X }
- X }
- X }
- X else if (c == '^') /* control-character syntax */
- X cval = (input() & 0x1f);
- X else if (c == '!') /* alt-character syntax */
- X cval = (input() | 0x80);
- X else
- X cval = c;
- X }
- X *tp = '\0';
- X smashcase = 1;
- X}
- X
- Xvoid dump_string(str)
- Xchar *str;
- X{
- X register char *cp;
- X
- X for (cp = str; *cp; cp++)
- X if (isprint(*cp))
- X (void) putchar(*cp);
- X else if (*cp == '"')
- X (void) fputs("\\\"", stdout);
- X else if (*cp == '\b')
- X (void) fputs("\\b", stdout);
- X else if (*cp == '\033')
- X (void) fputs("\\e", stdout);
- X else if (*cp == '\n')
- X (void) fputs("\\n", stdout);
- X else if (*cp == '\r')
- X (void) fputs("\\r", stdout);
- X else if (*cp == '\t')
- X (void) fputs("\\t", stdout);
- X else if (*cp == '\v')
- X (void) fputs("\\v", stdout);
- X else
- X (void) printf("\\x%02x", *cp);
- X}
- X
- X#ifdef MAIN
- Xint yylval;
- X
- Xmain()
- X{
- X int class;
- X
- X while ((class = yylex()) > 0)
- X {
- X if (class == NEWLINE)
- X (void) fputs("NEWLINE\n", stdout);
- X else
- X (void) printf("text \"%s\", class %d, value %d\n",
- X yytext, class, yylval);
- X yylval = 0;
- X }
- X}
- X
- X#endif /* MAIN */
- X
- X/* klex.l ends here */
- END-of-klex2.l
- echo file: kdefaults.h
- sed 's/^X//' >kdefaults.h << 'END-of-kdefaults.h'
- X/*
- X * @(#)kdefaults.h 1.1
- X *
- X * Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
- X * You may use, modify or redistribute this code freely, but do not delete
- X * this notice. Check with me before you make money with it.
- X */
- Xstatic keymap_t keydefaults =
- X{
- X 128,
- X {
- X/*000*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*001*/{{A_ESC, A_ESC, A_ESC, A_ESC, A_ESC, A_ESC, A_ESC, A_ESC }, 0x00,0x00},
- X/*002*/{{'1', '!', '1', '1', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*003*/{{'2', '@', '2', A_NUL, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*004*/{{'3', '#', '3', '3', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*005*/{{'4', '$', '4', '4', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*006*/{{'5', '%', '5', '5', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*007*/{{'6', '^', '6', A_RS, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*008*/{{'7', '&', '7', '7', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*009*/{{'8', '*', '8', '8', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*010*/{{'9', '(', '9', '9', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*011*/{{'0', ')', '0', '0', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*012*/{{'-', '_', '-', A_US, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*013*/{{'=', '+', '=', '=', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*014*/{{A_BS, A_BS, A_BS, A_BS, A_BS, A_BS, A_BS, A_BS }, 0x00,0x00},
- X/*015*/{{A_HT, A_GS, A_HT, A_GS, A_HT, A_GS, A_HT, A_GS }, 0x00,0x00},
- X/*016*/{{'q', 'Q', A_DC1, A_DC1, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*017*/{{'w', 'W', A_ETB, A_ETB, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*018*/{{'e', 'E', A_ENQ, A_ENQ, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*019*/{{'r', 'R', A_DC2, A_DC2, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*020*/{{'t', 'T', A_DC4, A_DC4, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*021*/{{'y', 'Y', A_EM, A_EM, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*022*/{{'u', 'U', A_NAK, A_NAK, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*023*/{{'i', 'I', A_HT, A_HT, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*024*/{{'o', 'O', A_SI, A_SI, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*025*/{{'p', 'P', A_DLE, A_DLE, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*026*/{{'[', '{', A_ESC, K_NOP, K_ESN, K_ESN, K_NOP, K_NOP }, 0x1f,0x00},
- X/*027*/{{']', '}', A_GS, K_NOP, K_ESN, K_ESN, K_NOP, K_NOP }, 0x1f,0x00},
- X/*028*/{{A_CR, A_CR, A_CR, A_CR, A_CR, A_CR, A_CR, A_CR }, 0x00,0x00},
- X/*029*/{{K_LCT, K_LCT, K_LCT, K_LCT, K_LCT, K_LCT, K_LCT, K_LCT }, 0xff,0x00},
- X/*030*/{{'a', 'A', A_SOH, A_SOH, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*031*/{{'s', 'S', A_DC3, A_DC3, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*032*/{{'d', 'D', A_EOT, A_EOT, K_ESN, K_ESN, K_DBG, K_NOP }, 0x0f,0x01},
- X/*033*/{{'f', 'F', A_ACK, A_ACK, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*034*/{{'g', 'G', A_BEL, A_BEL, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*035*/{{'h', 'H', A_BS, A_BS, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*036*/{{'j', 'J', A_NL, A_NL, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*037*/{{'k', 'K', A_VT, A_VT, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*038*/{{'l', 'L', A_FF, A_FF, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*039*/{{';', ':', ';', ':', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*040*/{{'\'', '"', '\'', '"', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*041*/{{'`', '~', '`', '~', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*042*/{{K_LSH, K_LSH, K_LSH, K_LSH, K_LSH, K_LSH, K_LSH, K_LSH }, 0xff,0x00},
- X/*043*/{{'\\', '|', A_FS, '|', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*044*/{{'z', 'Z', A_SUB, A_SUB, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*045*/{{'x', 'X', A_CAN, A_CAN, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*046*/{{'c', 'C', A_ETX, A_ETX, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*047*/{{'v', 'V', A_SYN, A_SYN, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*048*/{{'b', 'B', A_STX, A_STX, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*049*/{{'n', 'N', A_SO, A_SO, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*050*/{{'m', 'M', A_CR, A_CR, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x01},
- X/*051*/{{',', '<', ',', '<', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*052*/{{'.', '>', '.', '>', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*053*/{{'/', '?', '/', A_US, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*054*/{{K_RSH, K_RSH, K_RSH, K_RSH, K_RSH, K_RSH, K_RSH, K_RSH }, 0xff,0x00},
- X/*055*/{{'*', '*', '*', '*', K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*056*/{{K_LAL, K_LAL, K_LAL, K_LAL, K_LAL, K_LAL, K_LAL, K_LAL }, 0xff,0x00},
- X/*057*/{{' ', ' ', A_NUL, A_NUL, K_ESN, K_ESN, K_NOP, K_NOP }, 0x0f,0x00},
- X/*058*/{{K_CLK, K_CLK, K_CLK, K_CLK, K_CLK, K_CLK, K_CLK, K_CLK }, 0xff,0x00},
- X/*059*/{{F(1), F(13), F(25), F(37), F(1), F(13), F(25), F(37) }, 0xff,0x00},
- X/*060*/{{F(2), F(14), F(26), F(38), F(2), F(14), F(26), F(38) }, 0xff,0x00},
- X/*061*/{{F(3), F(15), F(27), F(39), F(3), F(15), F(27), F(39) }, 0xff,0x00},
- X/*062*/{{F(4), F(16), F(28), F(40), F(4), F(16), F(28), F(40) }, 0xff,0x00},
- X/*063*/{{F(5), F(17), F(29), F(41), F(5), F(17), F(29), F(41) }, 0xff,0x00},
- X/*064*/{{F(6), F(18), F(30), F(42), F(6), F(18), F(30), F(42) }, 0xff,0x00},
- X/*065*/{{F(7), F(19), F(31), F(43), F(7), F(19), F(31), F(43) }, 0xff,0x00},
- X/*066*/{{F(8), F(20), F(32), F(44), F(8), F(20), F(32), F(44) }, 0xff,0x00},
- X/*067*/{{F(9), F(21), F(33), F(45), F(9), F(21), F(33), F(45) }, 0xff,0x00},
- X/*068*/{{F(10), F(22), F(34), F(46), F(10), F(22), F(34), F(46) }, 0xff,0x00},
- X/*069*/{{K_NLK, K_NLK, K_NLK, K_NLK, K_NLK, K_NLK, K_NLK, K_NLK }, 0xff,0x00},
- X/*070*/{{K_SLK, K_SLK, K_BRK, K_BRK, K_SLK, K_SLK, K_BRK, K_BRK }, 0xff,0x00},
- X/*071*/{{F(49), '7', F(49), '7', F(49), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*072*/{{F(50), '8', F(50), '8', F(50), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*073*/{{F(51), '9', F(51), '9', F(51), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*074*/{{F(52), '-', F(52), '-', F(52), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*075*/{{F(53), '4', F(53), '4', F(53), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*076*/{{F(54), '5', F(54), '5', F(54), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*077*/{{F(55), '6', F(55), '6', F(55), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*078*/{{F(56), '+', F(56), '+', F(56), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*079*/{{F(57), '1', F(57), '1', F(57), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*080*/{{F(58), '2', F(58), '2', F(58), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*081*/{{F(59), '3', F(59), '3', F(59), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*082*/{{F(60), '0', F(60), '0', F(60), K_ESN, K_NOP, K_NOP }, 0xaf,0x02},
- X/*083*/{{A_DEL, '.', A_DEL, '.', A_DEL, K_ESN, K_RBT, K_NOP }, 0x07,0x02},
- X/*084*/{{F(60), F(26), F(60), K_NOP, K_SRQ, K_SRQ, K_SRQ, K_SRQ }, 0xff,0x00},
- X/*085*/{{F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58) }, 0xff,0x00},
- X/*086*/{{F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53) }, 0xff,0x00},
- X/*087*/{{F(11), F(23), F(35), F(47), F(11), F(23), F(35), F(47) }, 0xff,0x00},
- X/*088*/{{F(12), F(24), F(36), F(48), F(12), F(24), F(36), F(48) }, 0xff,0x00},
- X/*089*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*090*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*091*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*092*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*093*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*094*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*095*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*096*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*097*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*098*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*099*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*100*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*101*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*102*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*103*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*104*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*105*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*106*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*107*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*108*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*109*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*110*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*111*/{{F(51), F(51), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*112*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*113*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*114*/{{K_RAL, K_RAL, K_RAL, K_RAL, K_RAL, K_RAL, K_RAL, K_RAL }, 0xff,0x00},
- X/*115*/{{K_RCT, K_RCT, K_RCT, K_RCT, K_RCT, K_RCT, K_RCT, K_RCT }, 0xff,0x00},
- X/*116*/{{A_NL, A_NL, A_NL, A_NL, A_NL, A_NL, A_NL, A_NL }, 0x00,0x00},
- X/*117*/{{'/', '/', K_NOP, K_NOP, K_ESN, K_ESN, K_NOP, K_NOP }, 0x3f,0x00},
- X/*118*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*119*/{{K_BRK, K_BRK, K_BRK, K_BRK, K_BRK, K_BRK, K_BRK, K_BRK }, 0xff,0x00},
- X/*120*/{{F(50), F(50), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*121*/{{A_DEL, A_DEL, A_DEL, A_DEL, A_DEL, A_DEL, A_DEL, A_DEL }, 0x00,0x00},
- X/*122*/{{F(57), F(57), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*123*/{{F(60), F(60), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*124*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*125*/{{F(55), F(55), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*126*/{{F(59), F(59), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X/*127*/{{F(49), F(49), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP }, 0xff,0x00},
- X }
- X};
- X
- Xstatic char *stringdefaults[] =
- X{
- X "\033OP", "\033OQ", "\033OR", "\033OS", "\033OT", "\033OU", "\033OV",
- X "\033OW", "\033OX", "\033OY", "\033OZ", "\033OA", "\033Op", "\033Oq",
- X "\033Or", "\033Os", "\033Ot", "\033Ou", "\033Ov", "\033Ow", "\033Ox",
- X "\033Oy", "\033Oz", "\033Oa", "\033OP", "\033OQ", "\033OR", "\033OS",
- X "\033OT", "\033OU", "\033OV", "\033OW", "\033OX", "\033OY", "\033OZ",
- X "\033OA", "\033Op", "\033Oq", "\033Or", "\033Os", "\033Ot", "\033Ou",
- X "\033Ov", "\033Ow", "\033Ox", "\033Oy", "\033Oz", "\033Oa", "\033[H",
- X "\033[A", "\033[V", "-", "\033[D", "\033[G", "\033[C", "+",
- X "\033[Y", "\033[B", "\033[U", "\033[@", "\033[2",
- X "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
- X "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
- X};
- END-of-kdefaults.h
- echo file: keycaps
- sed 's/^X//' >keycaps << 'END-of-keycaps'
- X#
- X# Keycaps name list
- X# @(#)keycaps 1.1
- X000 0
- XEsc 1
- X1 2
- X2 3
- X3 4
- X4 5
- X5 6
- X6 7
- X7 8
- X8 9
- X9 10
- X0 11
- X- 12
- X= 13
- XBackspace 14
- XTab 15
- XQ 16
- XW 17
- XE 18
- XR 19
- XT 20
- XY 21
- XU 22
- XI 23
- XO 24
- XP 25
- X[ 26
- X] 27
- XEnter 28
- XLCtrl 29
- XA 30
- XS 31
- XD 32
- XF 33
- XG 34
- XH 35
- XJ 36
- XK 37
- XL 38
- X; 39
- X' 40
- X` 41
- XLShift 42
- X\\ 43
- XZ 44
- XX 45
- XC 46
- XV 47
- XB 48
- XN 49
- XM 50
- X, 51
- X. 52
- X/ 53
- XRShift 54
- X* 55
- XLAlt 56
- XSpc 57
- XRAlt 58
- XF1 59
- XF2 60
- XF3 61
- XF4 62
- XF5 63
- XF6 64
- XF7 65
- XF8 66
- XF9 67
- XF10 68
- XNumLock 69
- XScrollLock 70
- XHome 71
- XUp 72
- XPgUp 73
- XPadMinus 74
- XLeft 75
- XCenter 76
- XRight 77
- XPadPlus 78
- XEnd 79
- XDown 80
- XPgEnd 81
- XIns 82
- XDel 83
- X# All following keys are on the 101-key keyboard only
- XSysReq 84
- X085 85
- X086 86
- XF11 87
- XF12 88
- X089 89
- X090 90
- X091 91
- X092 92
- X093 93
- X094 94
- X095 95
- X096 96
- X097 97
- X098 98
- X099 99
- X100 100
- X101 101
- X102 102
- X103 103
- X104 104
- X105 105
- X106 106
- X107 107
- X108 108
- X109 109
- X110 110
- X111 111
- X112 112
- X113 113
- XRAlt 114
- XRCtrl 115
- XPadEnter 116
- XPadSlash 117
- X118 118
- XPause 119
- X120 120
- X121 121
- X122 122
- X123 123
- X124 124
- X125 125
- X126 126
- X127 127
- END-of-keycaps
- echo file: keybind.1
- sed 's/^X//' >keybind.1 << 'END-of-keybind.1'
- X.\" @(#)keybind.1 1.2
- X.\"
- X.\" Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
- X.\" You may use, modify or redistribute this code freely, but do not delete
- X.\" this notice. Check with me before you make money with it.
- X.\"
- X.TH KEYBIND 1 "Local"
- X.SH NAME
- Xkeybind \- key-map editor for XENIX and UNIX V.3.2 386 machines
- X.SH SYNOPSIS
- Xkeybind [-mdr] [-] [\fIfiles\fR...] [ -o \fIoutfile\fR ]
- X.SH DESCRIPTION
- XThis utility enables you to inspect and modify the console keyboard driver
- Xtables on for any UNIX version using the XENIX/386 keyboard driver (this
- Xincludes recent and future AT&T UNIX releases).
- X.SS Theory of Operation
- XAt startup, keybind reads in the current keyboard maps. After interpreting all
- Xswitches and digesting whatever input sources are specified, it attempts to
- Xwrite the resulting map and any changes in string assignments back to the
- Xmapping tables for your tty.
- X.PP
- XCalled with no arguments or with the argument - representing standard input,
- Xkeybind may be used interactively or fed from a keyboard map file; the
- Xmini-language used to describe key definitions is documented below.
- X.PP
- XThe -d flag dumps the current keyboard table in a format keybind will accept as
- Xinput; this is useful for inspecting key definitions. The -r and -m flags are
- Xintended to facilitate noninteractive use from scripts; the former restores
- Xthe default key mappings, and the latter enables Alt as a true Meta key.
- X.PP
- XThe flags (and -) may be used in any combination and will trigger their
- Xactions in the order they are given. Arguments mixed with the flags are
- Xtaken as the names of keyboard map files to be processed.
- X.PP
- XThe -o flag (which requires a filename argument) causes the contents of the
- Xkeymap and stringmap tables at the end of a keybind run to be dumped in binary
- Xform to the given filename. These dump files will be read in properly (and
- Xtheir contents loaded into the program's map-table space) when presented as
- Xfilename arguments to later keybind runs.
- X.PP
- XThis is much faster than an interpreting the equivalent text, because
- Xit concentrates the I/O into one belt and avoids the lexer/parser execution
- Xtime cost. Thus you can use -o to precompile a keyboard setup so that
- Xsubsequent keymap runs are very quick.
- X.SS Enabling Alt as a Meta key
- XThe -m option or the `meta' directive will remap the keyboard on so that the
- XAlt key acts as a meta key when combined with any printable character, or any
- Xshift-control modification of a printable; that is, it turns on the high (0x80)
- Xbit of the character.
- X.PP
- XThis is useful with GNU EMACS. To see why, run it, pull up an EMACS, set
- Xthe meta-flag global to non-nil, type ALT-x, and notice that it works!
- XTo arrange this behavior by default, you might put a `keybind -m' in an
- Xinitialization script under /etc/rc2.d to be executed whenever the system
- Xenters multiuser mode.
- X.PP
- XNote: the ISTRIP bit must be off in your termio structure for your meta key
- Xto work (otherwise the driver will happily strip the meta bit off your input
- Xkeystroke before making it available to the application). GNU EMACS does this
- Xitself; for other applications you may need to do an explicit stty -istrip or a
- XTCSETA{W} ioctl.
- X.PP
- XFunction keys and control-character keys and other special keys are not
- Xaffected by the alt-enable operation. Pains are also taken that this change not
- Xstep on window manager keys or other important special functions; specifically,
- Xit only modifies key/state pairs that are bound to the \fInop\fR, \fIescl\fR,
- X\fIescn\fR or \fIesco\fR functions.
- X.SS Keymap Definition Files
- XThe output of keybind -d is a keymap definition file describing the current
- Xstate of your keyboard. The syntax has been designed to resemble the
- Xconventions used in the \fIkeyboard\fR(7) entry as closely as possible.
- X.PP
- XEach map file is parsed as a sequence of newline- or semicolon-separated
- X\fIcommands\fR or comments.
- XCase of alphabetics and whitespace are ignored everywhere except within
- Xcharacter literals and strings.
- XComments may begin at any point with # and
- Xcontinue to end of line. Each command may be a \fIdirective\fR, a \fIkey
- Xdefinition\fR, a \fIstring assignment\fR, or a \fRshift modifier\fR.
- X.PP
- XThe following directives are defined:
- X.PP
- X\fIrestore\fR \-\- resets to the default bindings given in the
- X\fIkeyboard\fR(7) manual. Must be used with caution, see the BUGS note below.
- X.PP
- X\fImeta\fR \-\- enables the Alt key to function as a true meta, as with the
- X-m option (see above).
- X.PP
- X\fIdump\fR \-\- dumps portions of the keymap table. Without arguments it dumps
- Xthe entire table. It may take a list of scan-code ranges (see below) as
- Xarguments, in which case it dumps only the relevant characters.
- X.PP
- X\fIfunkeys\fR \-\- dumps portions of the function key table. Without arguments
- Xit dumps the entire table. It may take a list of function-key ranges (that is,
- Xfkey special values or dash-separated pairs of same) as arguments, in which
- Xcase it dumps only those function keys.
- X.PP
- X\fIclearstrings\fR \-\- normally, strings assigned to function keys are added
- Xto those already present in the keyboard driver's string table. If you don't
- Xneed the defaults, this wastes some of the limited space available for key
- Xmappings. The \fIclearstrings\fR directive clears the string assignment table
- X(no defaults are saved). Try using it if you get the `out of string space'
- Xabort message.
- X.PP
- X\fIcapslock\fR \-\- dumps information on which keys are affected by caps lock.
- X.PP
- X\fInumlock\fR \-\- dumps information on which keys are affected by num lock.
- X.PP
- X\fIexecute\fR \-\- sends pending keymap changes to the tty immediately using
- Xthe code normally called just before program exit. Intended for interactive
- Xuse.
- X.PP
- X\fIhelp\fR \-\- prints a command summary. Intended for interactive use; it
- Xalso turns on an asterisk prompt, which is turned off on EOF.
- X.PP
- XAs a convenience for interactive use, any directive may be abbreviated to its
- Xfirst two letters.
- X.PP
- XKey definitions may consist of \fIscan-code assignments\fR or \fIkey-state
- Xassignments\fR. The output of `keybind -d' is a list of scan-code assignments
- Xfor all defined scan-codes. Each one consists of a \fIscan-code specifier\fR
- Xfollowed by at most eight \fIkey values\fR, one for each shift state. If fewer
- Xthan eight values are given, states changed start from the left of the table.
- XA state may be skipped by putting a dash in its place in the list.
- X.PP
- XScan-code specifiers always begin with a @ (at-sign). There are two kinds;
- X\fInumeric\fR and \fImnemonic\fR. The former always consists of three zero
- Xfilled decimal digits after the @, giving the scan code's value. Mnemonic
- Xspecifiers, usually duplicate the graphic on the key cap to which the scan code
- Xcorresponds after the @. The output of `keybind -d' includes all valid
- Xmnemonic scan-code specifiers in the leftmost column. The two sets are not
- Xmutually exclusive; the unlisted numeric specifiers corresponding to mnemonics
- Xare also valid.
- X.PP
- XKey values may consist of \fIcharacter values\fR or \fIspecial values\fR.
- XSpecial values are those listed in \fIkeyboard\fR(7), plus the following
- Xadditions:
- X.PP
- Xvt[0-9]* \- the virtual terminal selectors.
- X.PP
- Xmgr[0-9]* \- the virtual terminal manager selectors.
- X.PP
- Xpfx[0-9]* \- undocumented, but in sys/kd.h; \fIyou\fR tell \fIme\fR.
- X.PP
- XA character value may consist of any of the standard mnemonics for control
- Xcharacters (refer to keybind -rd output for a nearly complete list; `nl' (0x0a),
- X`ht' (0x08) and `csi' (0x9b) are also accepted) or a \Iliteral\fR.
- X.PP
- XLiterals have the syntax of C character constants, with some additions.
- XThe backslash escape form \\xnn permits the use of two-digit hex constants.
- XThe backslash escape form \\dnnn permits the use of three-digit decimal
- Xconstants.
- XC-style octal escapes and special characters \\n, \\r, \\t, \\b, \\v are
- Xcorrecrtly interpreted.
- XAlso, the literal '\\e' is interpreted as ASCII escape (0x1b).
- XTwo-character literals of the form '^c' are interpreted as control characters.
- XTwo-character literals of the form '!c' are interpreted as meta characters;
- Xthat is, the value is that of the second character with the meta (0x80) bit
- Xturned on.
- XThe case of literals is preserved.
- X.PP
- XKey-state assignments set the value of a single key/state combination. They
- Xconsist of an optional \fIshift prefix\fR, a scan-code specifier, an equals
- Xsign and a key value. The shift prefix identifies the state of the key
- Xcorresponding to the scan code to which the key value should be assigned.
- XThe shift prefix may consist of the combination of the words \fBalt\fR,
- X\fIshift\fR, \fIctrl\fR, optionally trailed by hyphens. A key-state
- Xassignment with no prefix applies to the normal (unshifted) state of the
- Xkey.
- X.PP
- XString assignments consist of a function key name, followed by an equals sign,
- Xfollowed by a \fIstring literal\fR. String literals preserve case and have the
- Xsyntax of C strings, with the same additional escape conventions as described
- Xabove for character literals.
- X.PP
- XFinally, shift modifiers are used to control which characters are subject
- Xto shift-key modification. Each should begin with one of the keywords
- X\fIshiftlock\fR, \fIcapslock\fR, or \fInumlock\fR; \fIshiftlock\fR and
- X\fIcapslock\fR are equivalent. This should be followed by one of the words
- X`enabled' or `disabled' and a list of ranges of scan codes. If the list is
- Xempty, the shift modifier is applied to all scan codes.
- X.PP
- XA \fIrange\fR may be either a single scan code or a dash-separated pair of
- Xscan codes; the latter is interpreted as all scan codes numerically greater
- Xthan or equal to the first and less than or equal to the second.
- X.PP
- X.SH EXAMPLE
- XThe author finds the command file given as figure 1 below quite useful. To
- Xunderstand what it does, first note the following:
- X.PP
- XIf keybind is run from the console before vtlmgr, the key mappings will apply
- Xto all virtual terminals. However, string-key loadings will be changed on the
- Xconsole only. Thus, to give a key/state combination the same value (usable by
- Xan application that can do its own key bindings, such as EMACS) across all
- Xvirtual terminals, it is best to bind it to an esco/escn/escl value rather
- Xthan indirecting through a function key.
- X
- X.ce 1
- XFig 1: sample.kmf
- X
- X.in +10n
- X.nf
- X.so sample.kmf
- X.fi
- X.in
- X
- X.SH BUGS
- XDue to the absence of a reset ioctl(), the mappings that -r and the `restore'
- Xcommand reset to come from tables dumped out of 3.2u, tweaked to match the
- Xdefaults tables in \fIkeyboard\fR(7) and included into the code. If you have
- Xreason to suspect that the system defaults have changed, you can recompile
- Xwith -DREGEN and replace the system-default initializers with the output of
- Xa `keybind -c'.
- X.PP
- XRestoring defaults doesn't undo changes in the enabling of the shift-lock and
- Xnum-lock keys.
- X.PP
- XError handling in the keyboard map description parser is rudimentary.
- X.PP
- XBeware of confusing @[0-9] with @00[9]; the former are mnemonics for the
- Xdigit-key scan codes, the latter represent numeric scan codes.
- X.SH PORTABILITY NOTE
- XThis code should work on any AT/ISA/EISA box running XENIX/386 or an un-munged
- Xport of AT&T UNIX at release 3.2 or later. To check this, look for the
- XGIO_KEYMAP and SIO_KEYMAP ioctls in \fIkeyboard\fR(7); if these are present,
- Xyou have the XENIX keyboard driver and keybind should do the right thing.
- X.SH AUTHOR
- XEric S. Raymond (eric@snark.uu.net)
- X.SH SEE ALSO
- Xkeyboard(7)
- X
- X
- END-of-keybind.1
- echo file: sample.kmf
- sed 's/^X//' >sample.kmf << 'END-of-sample.kmf'
- X# Eric's keymap-refinition script for use with GNU EMACS
- X#
- X# @(#)sample.kmf 1.1
- X#
- Xkeybind <<EOF
- Xmeta # This helps with GNU EMACS
- Xalt-@F1 = vt0 # More convenient vt-select keys
- Xalt-@F2 = vt1
- Xalt-@F3 = vt2
- Xalt-@F4 = vt3
- Xalt-@F5 = vt4
- Xalt-@F6 = vt5
- Xalt-@F7 = vt6
- Xalt-@F8 = vt7
- X@PadMinus = escn # Use this for (kill-compilation)
- X@PadPlus = escn # Use this for (compile)
- X@ScrollLock = xoff # ^S
- Xcapslock disabled # Because I'm a poor typist
- XEOF
- END-of-sample.kmf
- exit
-
- --
- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
- Use a domain-based address or give alternate paths, or you may lose out.
-