home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / unix / volume20 / keybind < prev    next >
Encoding:
Internet Message Format  |  1989-10-27  |  60.3 KB

  1. Path: wuarchive!uwm.edu!cs.utexas.edu!uunet!bbn.com!rsalz
  2. From: rsalz@uunet.uu.net (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v20i081:  Rebind the console keyboard in Xenix or System Vr3.2.1+
  5. Message-ID: <2098@papaya.bbn.com>
  6. Date: 27 Oct 89 17:27:21 GMT
  7. Lines: 1912
  8. Approved: rsalz@uunet.UU.NET
  9.  
  10. Submitted-by: Eric S. Raymond <eric@snark.uu.net>
  11. Posting-number: Volume 20, Issue 81
  12. Archive-name: keybind
  13.  
  14. [  I have not even tried to compile this this.  /r$  ]
  15.  
  16. This program is an editor/minilanguage that lets you tweak the tables in
  17. the XENIX or System Vr3.2.1+ console keyboard driver for fun and profit.
  18.  
  19. It is particularly useful if you use GNU EMACS or anything else that likes
  20. to have a real Meta key; see the -m option and `meta' directive. You can
  21. also map your virtual terminal selector functions to more convenient
  22. places than the bizarre Alt-cokebottle-foobar sequences they default to.
  23.  
  24. Some may also find klex[12].l and kgram.y interesting as a simple but
  25. nontrivial example of lex/yacc usage, illustrating how to build a
  26. minilanguage with per-line error recovery.
  27.  
  28. This release adds the capability to `precompile' keyboard mappings using
  29. the -o option; the binary dump files produced can be loaded by subsequent
  30. keybind runs, avoiding the interpreter's lexer and parser overhead.
  31.  
  32. #!/bin/sh
  33. : "This is a shell archive, meaning:                              "
  34. : "1. Remove everything above the #! /bin/sh line.                "
  35. : "2. Save the resulting test in a file.                          "
  36. : "3. Execute the file with /bin/sh (not csh) to create the files:"
  37. : "    READ.ME"
  38. : "    Makefile"
  39. : "    keybind.c"
  40. : "    kgram.y"
  41. : "    klex1.l"
  42. : "    klex2.l"
  43. : "    kdefaults.h"
  44. : "    keycaps"
  45. : "    keybind.1"
  46. : "    sample.kmf"
  47. echo file: READ.ME
  48. sed 's/^X//' >READ.ME << 'END-of-READ.ME'
  49. X        Release 1.1 notes -- August 1, 1989
  50. X
  51. XThis program is an editor/minilanguage that lets you tweak the tables in the
  52. XXENIX or System Vr3.2.1+ console keyboard driver for fun and profit.
  53. X
  54. XIt is particularly useful if you use GNU EMACS or anything else that likes
  55. Xto have a real Meta key; see the -m option and `meta' directive. You can also
  56. Xmap your virtual terminal selector functions to more convenient places than
  57. Xthe bizarre Alt-cokebottle-foobar sequences they default to.
  58. X
  59. XSome may also find klex[12].l and kgram.y interesting as a simple but
  60. Xnontrivial example of lex/yacc usage, illustrating how to build a minilanguage
  61. Xwith per-line error recovery.
  62. X
  63. XThis replaces and extends the `alter' program I posted a couple of weeks ago;
  64. Xyou can throw that out now.
  65. X
  66. X        Release 1.2 notes -- August 14 1989
  67. X
  68. XThis release adds the capability to `precompile' keyboard mappings using
  69. Xthe -o option; the binary dump files produced can be loaded by subsequent
  70. Xkeybind runs, avoiding the interpreter's lexer and parser overhead.
  71. X
  72. X                    Eric S. Raymond (eric@snark.uu.net)
  73. END-of-READ.ME
  74. echo file: Makefile
  75. sed 's/^X//' >Makefile << 'END-of-Makefile'
  76. X# Makefile for the key mapper utility
  77. X#
  78. X#    @(#)Makefile    1.2
  79. X#
  80. X# Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
  81. X# You may use, modify or redistribute this code freely, but do not delete
  82. X# this notice. Check with me before you make money with it.
  83. X#
  84. X# Note: if you are running 3.2.1 rather than 3.2u, you have only 256 bytes of
  85. X# string definition space per tty, and you need to add -DMAXSTRINGS=256 to your
  86. X# compile flags. Otherwise it will be assumed that you have 512 bytes of
  87. X# string space per tty.
  88. X#
  89. XCFLAGS = -O    # -g -DYYDEBUG    # -DMAXSTRINGS=256
  90. XLDFLAGS = -s
  91. XYFLAGS = -v
  92. X
  93. Xkeybind: keybind.o kgram.o klex.o
  94. X    $(CC) $(LDFLAGS) keybind.o kgram.o klex.o -ll -o keybind
  95. X
  96. Xkeybind.o: keybind.c kdefaults.h keycaps.h keybind.h
  97. Xkgram.o: kgram.c keybind.h
  98. Xklex.o: klex.c y.tab.h
  99. X
  100. Xklex.l: klex1.l keycaps.l klex2.l
  101. X    cat klex1.l keycaps.l klex2.l >klex.l
  102. X
  103. Xkdefaults.h:
  104. X    keybind -c >kdefaults.h
  105. X
  106. X# keycaps.h is the keycaps include file for C programs
  107. XCFILTER = '/^\([^    ]*\).*/s//"@\1",/p'
  108. Xkeycaps.h:
  109. X    sed -n -e '/^#/d' -e $(CFILTER) <keycaps >keycaps.h
  110. X
  111. X# keycaps.l is the keycaps include file for lex programs
  112. XLFILTER = '/\(.*\)    \(.*\)/s//"@\1"    {yylval=\2;yytokno++;return(SCANCODE);}/'
  113. Xkeycaps.l:
  114. X    tr <keycaps "[A-Z]" "[a-z]" | sort -r | sed -e '/^#/d' -e $(LFILTER) >keycaps.l
  115. X
  116. Xkgram.c y.tab.h: kgram.y
  117. X    @echo expect conflicts: 3 shift/reduce
  118. X    yacc -d $(YFLAGS) kgram.y
  119. X    mv y.tab.c kgram.c
  120. X
  121. X# This is a lexical analyzer tester
  122. Xklex: klex.c y.tab.h
  123. X    $(CC) $(CFLAGS) -DMAIN klex.c -ll -o klex
  124. X
  125. Xlint: keybind.c kgram.c klex.c
  126. X    lint keybind.c kgram.c klex.c
  127. X
  128. Xkeybind.lpr:
  129. X    nroff -T$(LPT) -man keybind.1 $(REGS) >$keybind.lpr
  130. X
  131. Xhelp:
  132. X    @nroff -e -man keybind.1 | more
  133. X
  134. XSOURCES = keybind.c kgram.y klex[12].l kdefaults.h keycaps
  135. Xshar:
  136. X    shar READ.ME Makefile $(SOURCES) keybind.1 sample.kmf >keybind.shar
  137. X
  138. Xclean:
  139. X    rm -f kgram.c klex.c y.tab.h y.output klex keybind *.o *~
  140. X    rm -f keycaps.h keycaps.l klex.[lc] keybind.shar
  141. END-of-Makefile
  142. echo file: keybind.c
  143. sed 's/^X//' >keybind.c << 'END-of-keybind.c'
  144. X/*
  145. X * keybind -- console/virtual tty keyboard remapper for 6386WGS systems
  146. X *
  147. X *    @(#)keybind.c    1.2
  148. X *
  149. X * Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
  150. X * You may use, modify or redistribute this code freely, but do not delete
  151. X * this notice. Check with me before you make money with it.
  152. X */
  153. X#ifndef lint
  154. Xstatic char *sccsid = "@(#)keybind.c    1.2";
  155. X#endif /* lint */
  156. X
  157. X#include <stdio.h>
  158. X#include <fcntl.h>
  159. X#include <sys/types.h>
  160. X#include <sys/at_ansi.h>
  161. X#include <sys/kd.h>
  162. X#include <ctype.h>
  163. X#include <sys/ascii.h>
  164. X#include "keybind.h"
  165. X
  166. X#ifndef MAXSTRINGS
  167. X#define MAXSTRINGS    STRTABLN
  168. X#endif /* MAXSTRINGS */
  169. X
  170. Xextern FILE *yyin;
  171. X#ifdef YYDEBUG
  172. Xextern int yydebug;
  173. X#endif /* YYDEBUG */
  174. X
  175. Xextern void exit();
  176. Xextern void perror();
  177. X
  178. X#define M(c)        (0x80 | (c))
  179. X#define F(n)        ((n) + K_FUNF - 1)
  180. X#define VTK(n)        ((n) + K_VTF)
  181. X#define IS_VTKEY(c)    (((c) >= K_VTF) && ((c) <= K_VTL))
  182. X#define MGR(n)        ((n) + K_MGRF)
  183. X#define IS_MGRKEY(c)    (((c) >= K_MGRF) && ((c) <= K_MGRL))
  184. X#define PFX(n)        ((n) + K_PFXF)
  185. X#define IS_PFXKEY(c)    (((c) >= K_PFXF) && ((c) <= K_PFXL))
  186. X
  187. X#define META        0x80
  188. X#define PSPECIAL(p,i)    (p->spcl & (0x80>>(i)))
  189. X
  190. Xtypedef struct
  191. X{
  192. X    int val;
  193. X    char *name;
  194. X}
  195. Xsymbol;
  196. X
  197. Xtypedef struct
  198. X{
  199. X    int val;
  200. X    char *aname;
  201. X    char *mname;
  202. X}
  203. Xtriple;
  204. X
  205. Xkbd_t kbd = {KBDHDMAGIC};            /* our workspace */
  206. X
  207. Xstatic char    funkeys[NSTRKEYS][MAXFK+1];    /* function key strings */
  208. Xstatic int    mapmods = 0;            /* count map table changes */
  209. Xstatic int    stringmods = 0;            /* count string key changes */
  210. Xstatic int    ttyfd;                /* fd of console */
  211. X
  212. X/*
  213. X * The name table for printout of keycaps is generated from the master
  214. X * keycaps table.
  215. X */
  216. Xstatic char *keycaps[] =
  217. X{
  218. X#include "keycaps.h"
  219. X};
  220. X
  221. X/*
  222. X * Defaults tables -- regen defaults.h with keybind -c output if the system
  223. X * defaults ever change. Be sure to do this *before* you let vtlmgr run!
  224. X */
  225. X#include "kdefaults.h"
  226. X
  227. Xstatic triple specvals[] =
  228. X/* note: the second-column token have to match up with the lexical analyzer */
  229. X{
  230. X    K_NOP,    "nop",    "NOP",    /* Keys with no function */
  231. X    K_LSH,    "lshft",    "LSH",    /* Left shift */
  232. X    K_RSH,    "rshft",    "RSH",    /* Right shift */
  233. X    K_CLK,    "clock",    "CLK",    /* Caps lock */
  234. X    K_NLK,    "nlock",    "NLK",    /* Num lock */
  235. X    K_SLK,    "slock",    "SLK",    /* Scroll lock */
  236. X    K_ALT,    "alt",    "ALT",    /* Alt */
  237. X    K_BTAB,   "btab",    "BTAB",    /* Back tab */
  238. X    K_CTL,    "ctl",    "CTL",    /* Control */
  239. X    K_LAL,    "lalt",    "LAL",    /* Left alt */
  240. X    K_RAL,    "ralt",    "RAL",    /* Right alt */
  241. X    K_LCT,    "lctrl",    "LCT",    /* Left control */
  242. X    K_RCT,    "rctrl",    "RCT",    /* Right control */
  243. X    K_SRQ,    "sysreq",    "SRQ",    /* System request */
  244. X    K_BRK,    "break",    "BRK",    /* Break */
  245. X    K_ESN,    "escn",    "ESN",    /* <ESC> N <unalt'd value> sequence */
  246. X    K_ESO,    "esco",    "ESO",    /* <ESC> O <unalt'd value> sequence */
  247. X    K_ESL,    "escl",    "ESL",    /* <ESC> L <unalt'd value> sequence */
  248. X    K_RBT,    "reboot",    "RBT",    /* Reboot system */
  249. X    K_DBG,    "debug",    "DBG",    /* Invoke debugger */
  250. X    K_NEXT,    "next",    "NEXT",    /* Next virtual terminal */
  251. X    K_PREV,    "prev",    "PREV",    /* Previous virtual terminal */
  252. X    K_FRCNEXT,    "frcnext",    "FRCNEXT",
  253. X    K_FRCPREV,    "frcprev",    "FRCPREV",
  254. X    -1
  255. X};
  256. X
  257. X#ifdef REGEN
  258. X/*
  259. X * This enables us to regenerate the defaults
  260. X */
  261. Xstatic void cdump_keymap()
  262. X{
  263. X    int    j;
  264. X
  265. X    static char *mascii[] =        /* use Microsoft's IBM-style NL/HT */
  266. X    {
  267. X    "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
  268. X    "BS",  "HT",  "NL",  "VT",  "FF",  "CR",  "SO",  "SI", 
  269. X    "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
  270. X    "CAN", "EM",  "SUB", "ESC", "FS",  "GS",  "RS",  "US",
  271. X    };
  272. X
  273. X    struct key_t *kp;
  274. X
  275. X    (void) printf("static keymap_t keydefaults[] = \n{\n    %d,\n    {\n",
  276. X          kbd.keymap.n_keys);
  277. X
  278. X    for (kp = &(kbd.keymap.key[0]); kp < &(kbd.keymap.key[kbd.keymap.n_keys]); kp++)
  279. X    {
  280. X    char    repbuf[10];
  281. X
  282. X    (void) printf("/*%03d*/{{", kp - &(kbd.keymap.key[0]));
  283. X    for (j = 0; j < NUM_STATES; j++)
  284. X    {
  285. X        int    c = kp->map[j];
  286. X
  287. X        if (PSPECIAL(kp, j))
  288. X        {
  289. X        triple *sp;
  290. X    
  291. X        for (sp = specvals; sp->val != -1; sp++)
  292. X            if (sp->val == c)
  293. X            {
  294. X            (void) strcpy(repbuf, "K_");
  295. X            (void) strcat(repbuf, sp->mname);
  296. X            break;
  297. X            }
  298. X        if (sp->val == -1)
  299. X            if (IS_FUNKEY(c))
  300. X            (void) sprintf(repbuf, "F(%d)", c - K_FUNF + 1);
  301. X            else if (IS_VTKEY(c))
  302. X            (void) sprintf(repbuf, "VTK(%d)", c - K_VTF + 1);
  303. X            else if (IS_MGRKEY(c))
  304. X            (void) sprintf(repbuf, "MGR(%d)", c - K_MGRF + 1);
  305. X            else if (IS_PFXKEY(c))
  306. X            (void) sprintf(repbuf, "PFX(%d)", c - K_PFXF + 1);
  307. X            else
  308. X            (void) sprintf(repbuf, "%d", c);
  309. X        }
  310. X        else
  311. X        {
  312. X        int alt = (c & 0x80);
  313. X
  314. X        if (alt)
  315. X        {
  316. X            (void) strcpy(repbuf, "M(");
  317. X            c &= 0x7F;
  318. X        }
  319. X        else
  320. X            (void) strcpy(repbuf, "");
  321. X        if (isprint(c))
  322. X        {
  323. X            if (c == '\'')
  324. X            (void) strcat(repbuf, "'\\''");
  325. X            else if (c == '\\')
  326. X            (void) strcat(repbuf, "'\\\\'");
  327. X            else
  328. X            (void) sprintf(repbuf + strlen(repbuf), "'%c'", c);
  329. X        }
  330. X        else if (c == A_DEL)
  331. X            (void) strcat(repbuf, "A_DEL");
  332. X        else if (iscntrl(c))
  333. X        {
  334. X            (void) strcat(repbuf, "A_");
  335. X            (void) strcat(repbuf, mascii[c]);
  336. X        }
  337. X        if (alt)
  338. X            (void) strcat(repbuf + strlen(repbuf), ")");
  339. X        }
  340. X
  341. X        if (j < NUM_STATES - 1)
  342. X        (void) strcat(repbuf + strlen(repbuf), ",");
  343. X        (void) printf("%-7s", repbuf);
  344. X    }
  345. X    (void) printf("}, 0x%02x,0x%02x},\n", kp->spcl, kp->flgs);
  346. X    }
  347. X    (void) printf("    }\n};\n\n");
  348. X
  349. X    (void) printf("static char *stringdefaults[] =\n{\n");
  350. X    for (j = 0; j < NSTRKEYS; j++)
  351. X    {
  352. X    register char *cp;
  353. X
  354. X    (void) printf("    \"");
  355. X    for (cp = funkeys[j]; *cp; cp++)
  356. X        if (isprint(*cp))
  357. X        (void) putchar(*cp);
  358. X        else
  359. X        (void) printf("\\%03o", *cp);
  360. X    (void) printf("\",\n");
  361. X    }
  362. X    (void) printf("};\n");
  363. X}
  364. X#endif /* REGEN */
  365. X
  366. X/*
  367. X * Here are the dump functions for human use. Each of these may be
  368. X * called by YACC productions, all are called by dump_all() below.
  369. X */
  370. X
  371. Xvoid list_shift(flag, leader)
  372. Xint flag;
  373. Xchar *leader;
  374. X{
  375. X    struct key_t *kp;
  376. X
  377. X    for (kp = kbd.keymap.key; kp < &(kbd.keymap.key[kbd.keymap.n_keys]); kp++)
  378. X    if (kp[0].flgs & flag)
  379. X        break;
  380. X
  381. X    (void) printf("%s enabled\t", leader);
  382. X    if (kp >= kbd.keymap.key + kbd.keymap.n_keys)
  383. X    {
  384. X    (void) printf("# nowhere\n");
  385. X    return;
  386. X    }
  387. X    else
  388. X    (void) printf("%s", keycaps[kp - kbd.keymap.key]);
  389. X
  390. X    kbd.keymap.key[NUM_KEYS].flgs = ~kbd.keymap.key[NUM_KEYS - 1].flgs;
  391. X    for (++kp ; kp <= kbd.keymap.key + kbd.keymap.n_keys; kp++)
  392. X    if ((kp[0].flgs & flag) != (kp[-1].flgs & flag))
  393. X        if (kp[0].flgs & flag)
  394. X        {
  395. X        if (kp < kbd.keymap.key + NUM_KEYS)
  396. X            (void) printf(" %s", keycaps[kp - kbd.keymap.key]); 
  397. X        }
  398. X            else
  399. X        (void) printf(" - %s", keycaps[kp - kbd.keymap.key - 1]); 
  400. X    (void) putchar('\n');
  401. X}
  402. X
  403. Xvoid dump_keymap(lower, upper)
  404. Xint lower, upper;
  405. X{
  406. X    int i;
  407. X
  408. X    static char *ascii[] =        /* use common names */
  409. X    {
  410. X    "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
  411. X    "bs",  "tab",  "lf",  "vt",  "ff",  "cr",  "so",  "si", 
  412. X    "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
  413. X    "can", "em",  "sub", "esc", "fs",  "gs",  "rs",  "us",
  414. X    };
  415. X    struct key_t *kp;
  416. X
  417. X    for (kp = &(kbd.keymap.key[lower]); kp <= kbd.keymap.key + upper; kp++)
  418. X    {
  419. X    char    repbuf[10];
  420. X    int    j;
  421. X
  422. X    (void) printf("%-12s  ", keycaps[kp - &(kbd.keymap.key[0])]);
  423. X
  424. X    for (j = 0; j < NUM_STATES; j++)
  425. X    {
  426. X        int    c = kp->map[j];
  427. X
  428. X        if (PSPECIAL(kp, j))
  429. X        {
  430. X        triple *sp;
  431. X    
  432. X        for (sp = specvals; sp->val != -1; sp++)
  433. X            if (sp->val == c)
  434. X            {
  435. X            (void) strcpy(repbuf, sp->aname);
  436. X            break;
  437. X            }
  438. X        if (sp->val == -1)
  439. X            if (IS_FUNKEY(c))
  440. X            (void) sprintf(repbuf, "fkey%d", c - K_FUNF + 1);
  441. X            else if (IS_VTKEY(c))
  442. X            (void) sprintf(repbuf, "vt%d", c - K_VTF + 1);
  443. X            else if (IS_MGRKEY(c))
  444. X            (void) sprintf(repbuf, "mgr%d", c - K_MGRF + 1);
  445. X            else if (IS_PFXKEY(c))
  446. X            (void) sprintf(repbuf, "pfx%d", c - K_PFXF + 1);
  447. X            else
  448. X            (void) sprintf(repbuf, "%d", c);
  449. X        }
  450. X        else
  451. X        {
  452. X        int alt = (c & META);
  453. X
  454. X        if (alt)
  455. X            c = (c & ~META);
  456. X        if (isprint(c))
  457. X        {
  458. X            if (alt)
  459. X            (void) strcpy(repbuf, "'!");
  460. X            else
  461. X            (void) strcpy(repbuf, "'");
  462. X            if (c == '\'')
  463. X            (void) strcat(repbuf, "\\''");
  464. X            else if (c == '\\')
  465. X            (void) strcat(repbuf, "\\\\'");
  466. X            else
  467. X            (void) sprintf(repbuf+strlen(repbuf), "%c'", c);
  468. X        }
  469. X        else if (iscntrl(c) || c == A_DEL)
  470. X        {
  471. X            if (alt)
  472. X            (void) strcpy(repbuf, "!");
  473. X            else
  474. X            (void) strcpy(repbuf, "");
  475. X            if (c == A_DEL)
  476. X            (void) strcat(repbuf, "del");
  477. X            else
  478. X            (void) strcat(repbuf, ascii[c]);
  479. X        }
  480. X        }
  481. X
  482. X        (void) printf("%-8s", repbuf);
  483. X    }
  484. X    (void) putchar('\n');
  485. X    }
  486. X}
  487. X
  488. Xvoid dump_funkeys(lower, upper)
  489. Xint lower, upper;  
  490. X{
  491. X    int i;
  492. X
  493. X    for (i = lower; i <= upper; i++)
  494. X    if (strlen(funkeys[i - 1]))
  495. X    {
  496. X        (void) printf("fkey%d = \"", i);
  497. X        dump_string(funkeys[i-1]);
  498. X        (void) putchar('"');
  499. X        (void) putchar('\n');
  500. X    }
  501. X}
  502. X
  503. Xstatic void dump_all()
  504. X{
  505. X    time_t    now = time((time_t *)0);
  506. X    int i;
  507. X
  508. X    (void) printf("#\n# Key bindings:\n#\n");
  509. X    (void) printf(
  510. X"#                                     Ctrl             Alt    Alt    Alt-Ctrl\n");
  511. X    (void) printf(
  512. X"#Code         Normal  Shift   Ctrl    Shift   Alt     Shift   Ctrl    Shift\n");
  513. X    (void) printf(
  514. X"#--------------------------------------------------------------------------\n");
  515. X
  516. X    dump_keymap(0, kbd.keymap.n_keys - 1);
  517. X
  518. X    (void) printf("#\n# Shift keys:\n#\n");
  519. X    list_shift(KMF_CLOCK, "capslock");
  520. X    list_shift(KMF_NLOCK, "numlock ");
  521. X
  522. X    (void) printf("#\n# Function keys:\n#\n");
  523. X    dump_funkeys(1, NSTRKEYS);
  524. X}
  525. X
  526. X/*
  527. X * Functions for meta-key enabling
  528. X */
  529. X
  530. Xint weak_binding(p, state)
  531. X/* test if key state has a `weak binding', not char or important special */
  532. Xstruct key_t *p;
  533. Xint state;
  534. X{
  535. X    if (!PSPECIAL(p, state))
  536. X    return(0);
  537. X    else
  538. X    {
  539. X    register unchar val = p->map[state];
  540. X
  541. X    return(val == K_NOP || val == K_ESN || val == K_ESO || val == K_ESL);
  542. X    }
  543. X}
  544. X
  545. Xvoid enable_alt()
  546. X{
  547. X    struct key_t *kp;
  548. X
  549. X    /* for each non-special key that is ASCII printable in base state */
  550. X    for (kp = &(kbd.keymap.key[0]); kp < &(kbd.keymap.key[kbd.keymap.n_keys]); kp++)
  551. X    if (!PSPECIAL(kp, NORMAL) && isprint(kp->map[NORMAL]))
  552. X    {
  553. X        if (weak_binding(kp, ALTED))
  554. X        {
  555. X        kp->map[ALTED]     = (kp->map[NORMAL] | META);
  556. X        kp->spcl &=~ 0x08;
  557. X        }
  558. X        if (weak_binding(kp, ALTSHF))
  559. X        {
  560. X        kp->map[ALTSHF]    = (kp->map[SHIFT] | META);
  561. X        kp->spcl &=~ 0x04;
  562. X        }
  563. X        if (weak_binding(kp, ALTCTL))
  564. X        {
  565. X        kp->map[ALTCTL]    = (kp->map[CTRL] | META);
  566. X        kp->spcl &=~ 0x02;
  567. X        }
  568. X        if (weak_binding(kp, ALTSHFCTL))
  569. X        {
  570. X        kp->map[ALTSHFCTL] = (kp->map[SHFCTL] | META);
  571. X        kp->spcl &=~ 0x01;
  572. X        }
  573. X    }
  574. X    mapmods++;
  575. X}
  576. X
  577. X/*
  578. X * Other major functions. If it isn't static, it's because YACC may call it.
  579. X */
  580. X
  581. Xvoid restore_defaults()
  582. X{
  583. X    int    i;
  584. X
  585. X    (void) memcpy(&kbd.keymap, &keydefaults, sizeof(keymap_t));
  586. X
  587. X    for (i = 0; i < NSTRKEYS; i++)
  588. X    (void) strcpy(funkeys[i], stringdefaults[i]);
  589. X    mapmods++;
  590. X    
  591. X}
  592. X
  593. Xint setkey(scancode, indx, kfunc)
  594. Xint scancode;    /* scancode */
  595. Xint indx;    /* map index */
  596. Xint kfunc;    /* key function */
  597. X{
  598. X    struct key_t    *kp = kbd.keymap.key + scancode;
  599. X#ifdef DEBUG
  600. X    (void) printf("keybind: code %d/state %d becomes %s%d\n",
  601. X          scancode, indx,
  602. X          (kfunc >= NUM_KEYS ? "special ": "character "),
  603. X          kfunc - (kfunc >= NUM_KEYS) * NUM_KEYS);
  604. X#endif /* DEBUG */
  605. X
  606. X    if (kfunc < NUM_KEYS)
  607. X    kp->spcl &=~ (0x80>>indx);
  608. X    else
  609. X    {
  610. X    kp->spcl |= (0x80>>indx);
  611. X    kfunc -= NUM_KEYS;
  612. X    }
  613. X    kp->map[indx] = kfunc;
  614. X    mapmods++;
  615. X}
  616. X
  617. Xint setstring(fnkey, str)
  618. Xint fnkey;
  619. Xchar *str;
  620. X{
  621. X    extern char *malloc();
  622. X    char *cp, *tp;
  623. X
  624. X#ifdef DEBUG
  625. X    (void) printf("keybind: binding function key %d to \"", fnkey);
  626. X    dump_string(str);
  627. X    (void) putchar('"');
  628. X    (void) putchar('\n');
  629. X#endif /* DEBUG */
  630. X
  631. X    (void) strncpy(funkeys[fnkey], str, MAXFK);
  632. X    stringmods++;
  633. X}
  634. X
  635. Xvoid clear_strings()
  636. X{
  637. X    (void) memset(funkeys, '\0', (MAXFK + 1) * NSTRKEYS);
  638. X}
  639. X
  640. Xvoid do_changes()
  641. X/* execute all pending changes to key and string maps */
  642. X{
  643. X    if (mapmods)
  644. X    if (ioctl(ttyfd, PIO_KEYMAP, &kbd.keymap) == -1)
  645. X        perror("keybind: PIO_KEYMAP ioctl failed");
  646. X
  647. X    if (stringmods)
  648. X    {
  649. X    int        i;
  650. X    unchar        *sp = kbd.strmap;
  651. X    
  652. X    for (i = 0; i < NSTRKEYS; i++)
  653. X    {
  654. X        if (sp + strlen(sp) + 1 - kbd.strmap > MAXSTRINGS)
  655. X        {
  656. X        (void) fprintf(stderr,
  657. X                   "keybind: out of string space at fkey %d\n", i);
  658. X        return;
  659. X        }
  660. X        (void) strcpy(sp, funkeys[i]);
  661. X        sp += strlen(sp) + 1;
  662. X    }
  663. X        
  664. X    if (ioctl(ttyfd, PIO_STRMAP, kbd.strmap) == -1)
  665. X        perror("keybind: PIO_STRMAP ioctl failed");
  666. X    }
  667. X}
  668. X
  669. X/*
  670. X * The main sequence. All this does is the keymap read, a dispatch on options,
  671. X * and the keymap write.
  672. X */
  673. X
  674. Xmain(argc, argv)
  675. Xint argc;
  676. Xchar **argv;
  677. X{
  678. X    int i, c, inputcount = 0;
  679. X    unchar *cp;
  680. X    char ofname[BUFSIZ];
  681. X
  682. X    if ((ttyfd = open("/dev/tty", O_RDONLY)) < 0
  683. X            && (ttyfd = open("/dev/console", O_RDONLY)) < 0)
  684. X    {
  685. X    perror("keybind: tty open failed!");
  686. X    exit(1);
  687. X    }
  688. X
  689. X    if (ioctl(ttyfd, GIO_KEYMAP, &kbd.keymap) == -1)
  690. X    {
  691. X    perror("keybind: GIO_KEYMAP ioctl failed");
  692. X    exit(1);
  693. X    }
  694. X
  695. X    if (ioctl(ttyfd, GIO_STRMAP, kbd.strmap) == -1)
  696. X    {
  697. X    perror("keybind: GIO_STRMAP ioctl failed");
  698. X    exit(1);
  699. X    }
  700. X    for (i = 0, cp = kbd.strmap; *cp; cp += strlen(cp) + 1)
  701. X    (void) strcpy(funkeys[i++], cp);
  702. X
  703. X    for (++argv, --argc; argc; ++argv, --argc)
  704. X    {
  705. X    if (**argv == '-' && argv[0][1])
  706. X    {
  707. X        while (*++*argv != '\0')
  708. X        switch(**argv)
  709. X        {
  710. X        case 'm': enable_alt(); break;
  711. X#ifdef REGEN
  712. X        case 'c': cdump_keymap(); break;
  713. X#endif /* REGEN */
  714. X        case 'd': dump_all(); break;
  715. X        case 'r': restore_defaults(); inputcount++; break;
  716. X        case 'o':
  717. X            (void)strcpy(ofname, *++argv);
  718. X            argc--;
  719. X            goto nextarg;    /* ick... */
  720. X        default:
  721. X            (void) fputs("usage: keymap [-mdrv] [-] [files...]\n",
  722. X                 stderr);
  723. X            exit(1);
  724. X        }
  725. X        continue;
  726. X    }
  727. X    else
  728. X    {
  729. X        FILE    *fp;
  730. X
  731. X        if (**argv == '-')
  732. X        {
  733. X        inputcount++;
  734. X        yyin = stdin;
  735. X        yyparse();
  736. X        }
  737. X        else if ((fp = fopen(*argv, "r")) == (FILE *)NULL)
  738. X        {
  739. X        perror(*argv);
  740. X        exit(1);
  741. X        }
  742. X        else    /* O.K., it's a valid input source */
  743. X        {
  744. X        int    c = fgetc(fp);    /* peek at first character */
  745. X
  746. X        inputcount++;
  747. X        (void) ungetc(c, fp);
  748. X
  749. X        /* if it looks like ascii, run source through interpreter */
  750. X        if (isprint(c))
  751. X        {
  752. X            yyin = fp;
  753. X            yyparse();
  754. X        }
  755. X        else if (fread(&kbd,sizeof(kbd_t),1,fp)!=1 || kbd.magic!=KBDHDMAGIC)
  756. X        {
  757. X            (void) fprintf(stderr, "keybind: garbled map dump file\n");
  758. X            exit(1);
  759. X        }
  760. X        else        /* we have a valid dump file */
  761. X        {
  762. X            mapmods++;
  763. X            stringmods++;
  764. X
  765. X            /* massage the loaded fundefs into something useful */
  766. X            for (i = 0, cp = kbd.strmap; *cp; cp += strlen(cp) + 1)
  767. X            (void) strcpy(funkeys[i++], cp);
  768. X        }
  769. X        }
  770. X    }
  771. X    nextarg:;
  772. X    }
  773. X
  774. X    /* if no file or - arguments, process stdin once */
  775. X    if (inputcount == 0)
  776. X    {
  777. X    yyin = stdin;
  778. X    yyparse();
  779. X    }
  780. X    
  781. X    if (ofname[0] == '\0')
  782. X    do_changes();
  783. X    else
  784. X    {
  785. X    FILE    *ofp;
  786. X
  787. X    ofp = fopen(ofname, "w");
  788. X    (void) fwrite(&kbd, sizeof(kbd_t), 1, ofp);
  789. X    (void) fclose(ofp);
  790. X    }
  791. X
  792. X    (void) close(ttyfd);
  793. X    exit(0);    
  794. X}
  795. X
  796. X/* keybind.c ends here */
  797. END-of-keybind.c
  798. echo file: kgram.y
  799. sed 's/^X//' >kgram.y << 'END-of-kgram.y'
  800. X/*
  801. X * kgram.y -- YACC grammar for key-map interpreter
  802. X *
  803. X *    @(#)kgram.y    1.2
  804. X *
  805. X * Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
  806. X * You may use, modify or redistribute this code freely, but do not delete
  807. X * this notice. Check with me before you make money with it.
  808. X */
  809. X%{
  810. X/*LINTLIBRARY*/
  811. X#ifndef lint
  812. Xstatic char *sccsid = "@(#)kgram.y    1.2";
  813. X#endif /* lint */
  814. X
  815. X#include <stdio.h>
  816. X#include <string.h>
  817. X#include <sys/types.h>
  818. X#include <sys/at_ansi.h>
  819. X#include <sys/kd.h>
  820. X#include "keybind.h"
  821. X
  822. Xextern kbd_t    kbd;
  823. Xextern char yytext[];
  824. X
  825. Xextern void enable_alt(), list_shift(), restore_defaults();
  826. Xextern void dump_keymap(), dump_funkeys();
  827. Xextern void set_key(), set_string(), clear_strings();
  828. Xextern void do_changes();
  829. X
  830. Xstatic int    prefval;
  831. Xstatic int    codes1[NUM_KEYS];
  832. Xstatic int    ccount;
  833. Xstatic int    codes2[NUM_KEYS];
  834. X
  835. Xstatic void do_help();
  836. X%}   
  837. X
  838. X%start map
  839. X
  840. X%token SCANCODE CHARKEY FUNKEY SPECIAL
  841. X%token PREFIX STRING
  842. X%token SHIFTER ENABLED DISABLED
  843. X%token META RESTORE DUMP SHIFTS FUNKEYS CLEARSTRINGS EXECUTE HELP
  844. X%token ASSIGN DASH
  845. X%token NEWLINE    10
  846. X%token LEXERR
  847. X
  848. X%%    /* beginning of rules section */
  849. X
  850. X/* a map description consists of a sequence of commands */
  851. Xmap    :    /* EMPTY */
  852. X    |    map command NEWLINE
  853. X    |    map error NEWLINE
  854. X        {yyerrok;}
  855. X    |    map NEWLINE
  856. X    ;
  857. X
  858. Xcommand    :    SCANCODE funcs
  859. X        {
  860. X            int i;
  861. X
  862. X            if (ccount > NUM_STATES)
  863. X            yyerror("too many functions in scancode spec");
  864. X            else
  865. X            for (i = 0; i < ccount; i++)
  866. X                if (codes1[i] >= 0)
  867. X                setkey($1, i, codes1[i]);
  868. X        }
  869. X
  870. X    |    SCANCODE ASSIGN func
  871. X        {setkey($1, 0, $3);}
  872. X    |    PREFIX SCANCODE ASSIGN func
  873. X        {setkey($2, $1, $4);}
  874. X    |    PREFIX PREFIX SCANCODE ASSIGN func
  875. X        {setkey($3, ($1 | $2), $5);}
  876. X    |    PREFIX PREFIX PREFIX SCANCODE ASSIGN func
  877. X        {setkey($4, ($1 | $2 | $3), $6);}
  878. X
  879. X    |    FUNKEY ASSIGN STRING
  880. X            {setstring($1 - K_FUNF, yytext);}
  881. X    |    SHIFTER ENABLED ranges
  882. X        {
  883. X            int i, j;
  884. X
  885. X            if (ccount == 0)
  886. X            {
  887. X            codes1[0] = 0;
  888. X            codes2[0] = NUM_KEYS - 1;
  889. X            ccount++;
  890. X            }
  891. X            for (i = 0; i < ccount; i++)
  892. X            for (j = codes1[i]; j <= codes2[i]; j++)
  893. X                kbd.keymap.key[j].flgs |= $1;
  894. X        }
  895. X
  896. X    |    SHIFTER DISABLED ranges
  897. X        {
  898. X            int i, j;
  899. X
  900. X            if (ccount == 0)
  901. X            {
  902. X            codes1[0] = 0;
  903. X            codes2[0] = NUM_KEYS - 1;
  904. X            ccount++;
  905. X            }
  906. X            for (i = 0; i < ccount; i++)
  907. X            for (j = codes1[i]; j <= codes2[i]; j++)
  908. X                kbd.keymap.key[j].flgs &=~ $1;
  909. X        }
  910. X    |    DUMP ranges
  911. X        {
  912. X            int i, j;
  913. X
  914. X            if (ccount == 0)
  915. X            dump_keymap(0, kbd.keymap.n_keys - 1);
  916. X            else
  917. X            for (i = 0; i < ccount; i++)
  918. X                dump_keymap(codes1[i], codes2[i]);
  919. X        }
  920. X    |    FUNKEYS franges
  921. X        {
  922. X            int i, j;
  923. X
  924. X            if (ccount == 0)
  925. X            dump_funkeys(1, NSTRKEYS);
  926. X            else
  927. X            for (i = 0; i < ccount; i++)
  928. X                dump_funkeys(codes1[i]-K_FUNF+1,codes2[i]-K_FUNF+1);
  929. X        }
  930. X    |    SHIFTER
  931. X        {
  932. X            if ($1 == KMF_CLOCK)
  933. X            list_shift(KMF_CLOCK, "capslock");
  934. X            else
  935. X            list_shift(KMF_NLOCK, "numlock ");
  936. X        }
  937. X    |    META
  938. X        {enable_alt();}
  939. X    |    RESTORE
  940. X        {restore_defaults();}
  941. X    |    CLEARSTRINGS
  942. X        {clear_strings();}
  943. X    |    EXECUTE
  944. X        {do_changes();};
  945. X    |    HELP
  946. X        {do_help();};
  947. X    ;
  948. X
  949. Xranges    :    /* EMPTY */
  950. X        {ccount = 0;}
  951. X    |    ranges SCANCODE DASH SCANCODE
  952. X        {codes1[ccount] = $2; codes2[ccount] = $4; ccount++;}
  953. X    |    ranges SCANCODE
  954. X        {codes1[ccount] = codes2[ccount] = $2; ccount++;}
  955. X    ;
  956. X
  957. Xfranges    :    /* EMPTY */
  958. X        {ccount = 0;}
  959. X    |    franges FUNKEY DASH FUNKEY
  960. X        {codes1[ccount] = $2; codes2[ccount] = $4; ccount++;}
  961. X    |    franges FUNKEY
  962. X        {codes1[ccount] = codes2[ccount] = $2; ccount++;}
  963. X    ;
  964. X
  965. Xfunc    :    CHARKEY        {$$ = ($1 & 0xff);}
  966. X    |    FUNKEY        {$$ = ($1 & 0xff);}
  967. X    |    SPECIAL        {$$ = $1 + NUM_KEYS;}
  968. X    ;
  969. X
  970. Xfuncs    :    func
  971. X        {ccount = 0; codes1[ccount++] = $1;}
  972. X    |    funcs func
  973. X        {codes1[ccount++] = $2;}
  974. X    |    funcs DASH
  975. X        {codes1[ccount++] = -1;}
  976. X    |    /* EMPTY */
  977. X        {(void)yyerror("expected a list of function codes"); YYERROR;}
  978. X    ;
  979. X%%
  980. X
  981. Xint yyerror(message)
  982. Xchar    *message;
  983. X{
  984. X    (void) fprintf(stderr, "keybind: %s\n", message);
  985. X}
  986. X
  987. Xvoid do_help()
  988. X{
  989. X#define P(s)    (void) printf(s)
  990. XP("Keybind commands are:\n\n");
  991. X
  992. XP("@scancode [func...]              -- assign functions to scancode\n");
  993. XP("[prefix] @scancode = [func]      -- assign to key/state pair\n\n");
  994. X
  995. XP("fkey<nn> = \"string\"              -- load string key\n\n");
  996. X
  997. XP("cl[earstrings]                   -- clear the string table\n");
  998. XP("capslock di[sabled] [range...]   -- disable capslock on chars\n");
  999. XP("numlock di[sabled] [range...]    -- disable numlock on chars\n");
  1000. XP("du[mp] [range...]                -- show functions of given keys\n");
  1001. XP("[ca]pslock en[abled] [range...]  -- enable capslock on chars\n");
  1002. XP("[nu]mlock en[abled] [range...]   -- enable numlock on chars\n");
  1003. XP("ex[ecute]                        -- write changes to the driver\n");
  1004. XP("fu[nkeys] [range...]             -- show bindings of string keys\n");
  1005. XP("he[lp]                           -- display this message\n");
  1006. XP("me[ta]                           -- enable the Alt key as meta\n");
  1007. XP("re[store]                        -- restore defaults\n");
  1008. XP("ca[pslock]                       -- show keys capslock affects\n");
  1009. XP("nu[mlock]                        -- show keys numlock affects\n\n");
  1010. X
  1011. XP("Ranges may be a character literal or two dash-separated char literals.\n");
  1012. XP("Functions may be char literals or one of the named special functions\n");
  1013. XP("documented in keyboard(7)\n");
  1014. X}
  1015. X
  1016. X/* kgram.y ends here */
  1017. END-of-kgram.y
  1018. echo file: klex1.l
  1019. sed 's/^X//' >klex1.l << 'END-of-klex1.l'
  1020. X%{
  1021. X/*
  1022. X * klex.l -- lexical analyzer for the keybind mini-language interpreter
  1023. X *
  1024. X *    @(#)klex1.l    1.2
  1025. X *
  1026. X * Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
  1027. X * You may use, modify or redistribute this code freely, but do not delete
  1028. X * this notice. Check with me before you make money with it.
  1029. X */
  1030. X/*LINTLIBRARY*/
  1031. X#ifndef lint
  1032. Xstatic char *sccsid = "@(#)klex1.l    1.2";
  1033. X#endif /* lint */
  1034. X
  1035. X#include <sys/types.h>
  1036. X#include <sys/at_ansi.h>
  1037. X#include <sys/kd.h>
  1038. X#include <sys/ascii.h>
  1039. X#include <string.h>
  1040. X#include <ctype.h>
  1041. X#include "keybind.h"
  1042. X#include "y.tab.h"
  1043. X
  1044. Xextern yylval;    /* used to pass token values to YACC */
  1045. X
  1046. Xstatic int yytokno = 0;
  1047. Xstatic int smashcase = 1;
  1048. Xstatic int interactive = 0;
  1049. X
  1050. X#undef input
  1051. Xint input()
  1052. X{
  1053. X    static int doprompt;
  1054. X    int c;
  1055. X
  1056. X    if (doprompt-- == 1)
  1057. X    (void) fputs("*", stdout);
  1058. X
  1059. X    if ((c = getc(yyin)) == '\n')
  1060. X    {
  1061. X    yylineno++;
  1062. X    if (interactive)
  1063. X        doprompt = 1;
  1064. X    }
  1065. X
  1066. X    if (feof(yyin))
  1067. X    return(0);
  1068. X    else if (smashcase && isupper(c))    
  1069. X    return(tolower(c));
  1070. X    else
  1071. X    return(c);
  1072. X}
  1073. X
  1074. X#undef unput
  1075. X#define unput(c)    ungetc(c, yyin)
  1076. X
  1077. Xextern void dump_string();
  1078. Xstatic void getstring();
  1079. X%}
  1080. X
  1081. X%e    1700
  1082. X%p    3700
  1083. X%n    500
  1084. X%k    50
  1085. X%a    900
  1086. X%o    800
  1087. X
  1088. X%%
  1089. X
  1090. Xclearstrings|cl    {yytokno++; return(CLEARSTRINGS);}
  1091. Xdisabled|di    {yytokno++; return(DISABLED);}
  1092. Xdump|du        {yytokno++; return(DUMP);}
  1093. Xenabled|en    {yytokno++; return(ENABLED);}
  1094. Xexecute|ex    {yytokno++; return(EXECUTE);}
  1095. Xfunkeys|fu    {yytokno++; return(FUNKEYS);}
  1096. Xhelp|he        {yytokno++; interactive++; return(HELP);}
  1097. Xmeta|me        {yytokno++; return(META);}
  1098. Xrestore|re    {yytokno++; return(RESTORE);}
  1099. X
  1100. Xshift-?        {yylval = SHIFTED; yytokno++; return(PREFIX);}
  1101. Xctrl-?        {yylval = CTRLED; yytokno++; return(PREFIX);}
  1102. Xalt-?        {yylval = ALTED; yytokno++; return(PREFIX);}
  1103. X
  1104. Xcapslock|ca    {yylval = KMF_CLOCK; yytokno++; return(SHIFTER);}
  1105. Xshiftlock|sh    {yylval = KMF_CLOCK; yytokno++; return(SHIFTER);}
  1106. Xnumlock|nu    {yylval = KMF_NLOCK; yytokno++; return(SHIFTER);}
  1107. X
  1108. X\"        {getstring(yytext, '"'); yytokno++; return(STRING);}
  1109. X'        {
  1110. X            getstring(yytext, '\'');
  1111. X            if (strlen(yytext) == 1)
  1112. X            {
  1113. X            yylval = yytext[0];
  1114. X            yytokno++;
  1115. X            return(CHARKEY);
  1116. X            }
  1117. X                else
  1118. X            {
  1119. X            (void) fprintf(stderr,
  1120. X                "keybind: bad character syntax, line %d token %d\n",
  1121. X                 yylineno + 1, yytokno);
  1122. X            interactive--;
  1123. X            while (input() != '\n')
  1124. X                continue;
  1125. X            interactive++;
  1126. X            return(LEXERR);
  1127. X            }
  1128. X        }
  1129. X
  1130. X@[0-9][0-9][0-9]    {yylval=atoi(yytext+1); yytokno++; return(SCANCODE);}
  1131. END-of-klex1.l
  1132. echo file: klex2.l
  1133. sed 's/^X//' >klex2.l << 'END-of-klex2.l'
  1134. X@.        {
  1135. X            (void) fprintf(stderr,
  1136. X            "keybind: bad scan-code specifier, line %d, token %d\n",
  1137. X            yylineno, yytokno);
  1138. X            interactive--;
  1139. X            while (input() != '\n')
  1140. X                continue;
  1141. X            interactive++;
  1142. X            return(LEXERR);
  1143. X        }
  1144. X
  1145. Xnul        {yylval = A_NUL; yytokno++; return(CHARKEY);}
  1146. Xsoh        {yylval = A_SOH; yytokno++; return(CHARKEY);}
  1147. Xstx        {yylval = A_STX; yytokno++; return(CHARKEY);}
  1148. Xetx        {yylval = A_ETX; yytokno++; return(CHARKEY);}
  1149. Xeot        {yylval = A_EOT; yytokno++; return(CHARKEY);}
  1150. Xenq        {yylval = A_ENQ; yytokno++; return(CHARKEY);}
  1151. Xack        {yylval = A_ACK; yytokno++; return(CHARKEY);}
  1152. Xbel        {yylval = A_BEL; yytokno++; return(CHARKEY);}
  1153. Xbs        {yylval = A_BS; yytokno++; return(CHARKEY);}
  1154. Xht        {yylval = A_HT; yytokno++; return(CHARKEY);}
  1155. Xtab        {yylval = A_HT; yytokno++; return(CHARKEY);}
  1156. Xnl        {yylval = A_NL; yytokno++; return(CHARKEY);}
  1157. Xlf        {yylval = A_NL; yytokno++; return(CHARKEY);}
  1158. Xvt        {yylval = A_VT; yytokno++; return(CHARKEY);}
  1159. Xff        {yylval = A_FF; yytokno++; return(CHARKEY);}
  1160. Xcr        {yylval = A_CR; yytokno++; return(CHARKEY);}
  1161. Xso        {yylval = A_SO; yytokno++; return(CHARKEY);}
  1162. Xsi        {yylval = A_SI; yytokno++; return(CHARKEY);}
  1163. Xdle        {yylval = A_DLE; yytokno++; return(CHARKEY);}
  1164. Xdc1        {yylval = A_DC1; yytokno++; return(CHARKEY);}
  1165. Xxon        {yylval = A_DC1; yytokno++; return(CHARKEY);}
  1166. Xdc2        {yylval = A_DC2; yytokno++; return(CHARKEY);}
  1167. Xdc3        {yylval = A_DC3; yytokno++; return(CHARKEY);}
  1168. Xxoff        {yylval = A_DC3; yytokno++; return(CHARKEY);}
  1169. Xdc4        {yylval = A_DC4; yytokno++; return(CHARKEY);}
  1170. Xnak        {yylval = A_NAK; yytokno++; return(CHARKEY);}
  1171. Xsyn        {yylval = A_SYN; yytokno++; return(CHARKEY);}
  1172. Xetb        {yylval = A_ETB; yytokno++; return(CHARKEY);}
  1173. Xcan        {yylval = A_CAN; yytokno++; return(CHARKEY);}
  1174. Xem        {yylval = A_EM; yytokno++; return(CHARKEY);}
  1175. Xsub        {yylval = A_SUB; yytokno++; return(CHARKEY);}
  1176. Xesc        {yylval = A_ESC; yytokno++; return(CHARKEY);}
  1177. Xfs        {yylval = A_FS; yytokno++; return(CHARKEY);}
  1178. Xgs        {yylval = A_GS; yytokno++; return(CHARKEY);}
  1179. Xrs        {yylval = A_RS; yytokno++; return(CHARKEY);}
  1180. Xus        {yylval = A_US; yytokno++; return(CHARKEY);}
  1181. Xdel        {yylval = A_DEL; yytokno++; return(CHARKEY);}
  1182. Xcsi        {yylval = A_CSI; yytokno++; return(CHARKEY);}
  1183. X
  1184. Xnop        {yylval = K_NOP; yytokno++; return(SPECIAL);}
  1185. Xlshift        {yylval = K_LSH; yytokno++; return(SPECIAL);}
  1186. Xrshift        {yylval = K_RSH; yytokno++; return(SPECIAL);}
  1187. Xclock        {yylval = K_CLK; yytokno++; return(SPECIAL);}
  1188. Xnlock        {yylval = K_NLK; yytokno++; return(SPECIAL);}
  1189. Xslock        {yylval = K_SLK; yytokno++; return(SPECIAL);}
  1190. Xalt        {yylval = K_ALT; yytokno++; return(SPECIAL);}
  1191. Xbtab        {yylval = K_BTAB; yytokno++; return(SPECIAL);}
  1192. Xctrl        {yylval = K_CTL; yytokno++; return(SPECIAL);}
  1193. Xlalt        {yylval = K_LAL; yytokno++; return(SPECIAL);}
  1194. Xralt        {yylval = K_RAL; yytokno++; return(SPECIAL);}
  1195. Xlctrl        {yylval = K_LCT; yytokno++; return(SPECIAL);}
  1196. Xrctrl        {yylval = K_RCT; yytokno++; return(SPECIAL);}
  1197. X
  1198. Xfkey[0-9][0-9]?    {yylval = K_FUNF+atoi(yytext+4)-1; yytokno++; return(FUNKEY);}
  1199. X
  1200. Xsysreq        {yylval = K_SRQ; yytokno++; return(SPECIAL);}
  1201. Xbrk        {yylval = K_BRK; yytokno++; return(SPECIAL);}
  1202. Xescn        {yylval = K_ESN; yytokno++; return(SPECIAL);}
  1203. Xesco        {yylval = K_ESO; yytokno++; return(SPECIAL);}
  1204. Xescl        {yylval = K_ESL; yytokno++; return(SPECIAL);}
  1205. Xrboot        {yylval = K_RBT; yytokno++; return(SPECIAL);}
  1206. Xdebug        {yylval = K_DBG; yytokno++; return(SPECIAL);}
  1207. Xnext        {yylval = K_NEXT; yytokno++; return(SPECIAL);}
  1208. Xprev        {yylval = K_PREV; yytokno++; return(SPECIAL);}
  1209. Xfnext        {yylval = K_FRCNEXT; yytokno++; return(SPECIAL);}
  1210. Xfprev        {yylval = K_FRCPREV; yytokno++; return(SPECIAL);}
  1211. X
  1212. Xvt[0-9][0-9]?    {yylval = K_VTF+atoi(yytext+2); yytokno++; return(SPECIAL);}
  1213. Xvtf        {yylval = K_VTF; yytokno++; return(SPECIAL);}
  1214. Xvtl        {yylval = K_VTL; yytokno++; return(SPECIAL);}
  1215. Xmgr[0-9][0-9]?    {yylval = K_MGRF+atoi(yytext+3); yytokno++; return(SPECIAL);}
  1216. Xmgrf        {yylval = K_MGRF; yytokno++; return(SPECIAL);}
  1217. Xmgrl        {yylval = K_MGRL; yytokno++; return(SPECIAL);}
  1218. Xpfx[0-9][0-9]?    {yylval = K_PFXF+atoi(yytext+3); yytokno++; return(SPECIAL);}
  1219. Xpfxf        {yylval = K_PFXF; yytokno++; return(SPECIAL);}
  1220. Xpfxl        {yylval = K_PFXL; yytokno++; return(SPECIAL);}
  1221. X
  1222. X"#"        {while (input() != '\n') continue; unput('\n');}
  1223. X
  1224. X[\n;]        {yytokno = 0; return(NEWLINE);}
  1225. X=        {yytokno++; return(ASSIGN);}
  1226. X-        {yytokno++; return(DASH);}
  1227. X[\ \t,]        ;
  1228. X
  1229. X"?"        {yytokno++; interactive++; return(HELP);}
  1230. X
  1231. X.        {
  1232. X            (void) fprintf(stderr,
  1233. X                "keybind: bad char, line %d, after token %d = \"",
  1234. X                 yylineno, yytokno);
  1235. X            dump_string(yytext);
  1236. X            (void) fputs("\"\n", stdout);
  1237. X            interactive--;
  1238. X            while (input() != '\n')
  1239. X            continue;
  1240. X            interactive++;
  1241. X            return(LEXERR);
  1242. X        }
  1243. X
  1244. X%%
  1245. X/*
  1246. X * klex2.l -- lexical analyzer for keymap editor program, part 2
  1247. X *
  1248. X *    @(#)klex2.l    1.2
  1249. X *
  1250. X * Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
  1251. X * You may use, modify or redistribute this code freely, but do not delete
  1252. X * this notice. Check with me before you make money with it.
  1253. X */
  1254. X
  1255. Xstatic int yywrap()
  1256. X{
  1257. X    if (interactive)
  1258. X    (void) putchar('\n');
  1259. X    interactive = 0;
  1260. X    return(EOF);
  1261. X}
  1262. X
  1263. Xvoid getstring(buf, term)
  1264. Xchar    *buf, term;
  1265. X{
  1266. X    char *tp;
  1267. X    int c, cval;
  1268. X
  1269. X    smashcase = 0;
  1270. X    buf[0] = '\0';
  1271. X    for (tp = buf; (c = input()) != term && c != EOF; *tp++ = cval)
  1272. X    {
  1273. X    if (c == '\\')
  1274. X    {
  1275. X        c = input();
  1276. X        if (strchr("0123456789xX", c))
  1277. X        {
  1278. X        char *dp, *hex = "0123456789abcdef";
  1279. X        int dcount = 0;
  1280. X
  1281. X        if (c == 'x' || c == 'X')
  1282. X            while ((dp = strchr(hex, (c = input()))) && (dcount++ < 2))
  1283. X            cval = (cval * 16) + (dp - hex);
  1284. X        else if (c == '0')
  1285. X            while (strchr("01234567", (c = input())) && (dcount++ < 3))
  1286. X            cval = (cval * 8) + (c - '0');
  1287. X        else
  1288. X            while (strchr("0123456789", (c = input())) && (dcount++ < 3))
  1289. X            cval = (cval * 10) + (c - '0');
  1290. X        unput(c);
  1291. X        }
  1292. X        else        /* C-style character escapes */
  1293. X        {
  1294. X        switch (c)
  1295. X        {
  1296. X        case '\\': cval = '\\'; break;
  1297. X        case 'e': cval = '\033'; break;
  1298. X        case 'n': cval = '\n'; break;
  1299. X        case 't': cval = '\t'; break;
  1300. X        case 'b': cval = '\b'; break;
  1301. X        case 'r': cval = '\r'; break;
  1302. X        case 'v': cval = '\v'; break;
  1303. X        default: cval = c;
  1304. X        }
  1305. X        }
  1306. X    }
  1307. X    else if (c == '^')    /* control-character syntax */
  1308. X        cval = (input() & 0x1f);
  1309. X    else if (c == '!')    /* alt-character syntax */
  1310. X        cval = (input() | 0x80);
  1311. X    else
  1312. X        cval = c;
  1313. X    }
  1314. X    *tp = '\0';
  1315. X    smashcase = 1;
  1316. X}
  1317. X
  1318. Xvoid dump_string(str)
  1319. Xchar *str;
  1320. X{
  1321. X    register char *cp;
  1322. X
  1323. X    for (cp = str; *cp; cp++)
  1324. X    if (isprint(*cp))
  1325. X        (void) putchar(*cp);
  1326. X    else if (*cp == '"')
  1327. X        (void) fputs("\\\"", stdout);
  1328. X    else if (*cp == '\b')
  1329. X        (void) fputs("\\b", stdout);
  1330. X    else if (*cp == '\033')
  1331. X        (void) fputs("\\e", stdout);
  1332. X    else if (*cp == '\n')
  1333. X        (void) fputs("\\n", stdout);
  1334. X    else if (*cp == '\r')
  1335. X        (void) fputs("\\r", stdout);
  1336. X    else if (*cp == '\t')
  1337. X        (void) fputs("\\t", stdout);
  1338. X    else if (*cp == '\v')
  1339. X        (void) fputs("\\v", stdout);
  1340. X    else
  1341. X        (void) printf("\\x%02x", *cp);
  1342. X}
  1343. X
  1344. X#ifdef MAIN
  1345. Xint yylval;
  1346. X
  1347. Xmain()
  1348. X{
  1349. X    int class;
  1350. X
  1351. X    while ((class = yylex()) > 0)
  1352. X    {
  1353. X    if (class == NEWLINE)
  1354. X        (void) fputs("NEWLINE\n", stdout);
  1355. X    else
  1356. X        (void) printf("text \"%s\", class %d, value %d\n",
  1357. X                        yytext, class, yylval);
  1358. X    yylval = 0;
  1359. X    }
  1360. X}
  1361. X
  1362. X#endif /* MAIN */
  1363. X
  1364. X/* klex.l ends here */
  1365. END-of-klex2.l
  1366. echo file: kdefaults.h
  1367. sed 's/^X//' >kdefaults.h << 'END-of-kdefaults.h'
  1368. X/*
  1369. X *    @(#)kdefaults.h    1.1
  1370. X *
  1371. X * Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
  1372. X * You may use, modify or redistribute this code freely, but do not delete
  1373. X * this notice. Check with me before you make money with it.
  1374. X */
  1375. Xstatic keymap_t keydefaults =
  1376. X{
  1377. X    128,
  1378. X    {
  1379. X/*000*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1380. X/*001*/{{A_ESC, A_ESC, A_ESC, A_ESC, A_ESC, A_ESC, A_ESC, A_ESC  }, 0x00,0x00},
  1381. X/*002*/{{'1',   '!',   '1',   '1',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1382. X/*003*/{{'2',   '@',   '2',   A_NUL, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1383. X/*004*/{{'3',   '#',   '3',   '3',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1384. X/*005*/{{'4',   '$',   '4',   '4',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1385. X/*006*/{{'5',   '%',   '5',   '5',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1386. X/*007*/{{'6',   '^',   '6',   A_RS,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1387. X/*008*/{{'7',   '&',   '7',   '7',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1388. X/*009*/{{'8',   '*',   '8',   '8',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1389. X/*010*/{{'9',   '(',   '9',   '9',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1390. X/*011*/{{'0',   ')',   '0',   '0',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1391. X/*012*/{{'-',   '_',   '-',   A_US,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1392. X/*013*/{{'=',   '+',   '=',   '=',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1393. X/*014*/{{A_BS,  A_BS,  A_BS,  A_BS,  A_BS,  A_BS,  A_BS,  A_BS   }, 0x00,0x00},
  1394. X/*015*/{{A_HT,  A_GS,  A_HT,  A_GS,  A_HT,  A_GS,  A_HT,  A_GS   }, 0x00,0x00},
  1395. X/*016*/{{'q',   'Q',   A_DC1, A_DC1, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1396. X/*017*/{{'w',   'W',   A_ETB, A_ETB, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1397. X/*018*/{{'e',   'E',   A_ENQ, A_ENQ, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1398. X/*019*/{{'r',   'R',   A_DC2, A_DC2, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1399. X/*020*/{{'t',   'T',   A_DC4, A_DC4, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1400. X/*021*/{{'y',   'Y',   A_EM,  A_EM,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1401. X/*022*/{{'u',   'U',   A_NAK, A_NAK, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1402. X/*023*/{{'i',   'I',   A_HT,  A_HT,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1403. X/*024*/{{'o',   'O',   A_SI,  A_SI,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1404. X/*025*/{{'p',   'P',   A_DLE, A_DLE, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1405. X/*026*/{{'[',   '{',   A_ESC, K_NOP, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x1f,0x00},
  1406. X/*027*/{{']',   '}',   A_GS,  K_NOP, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x1f,0x00},
  1407. X/*028*/{{A_CR,  A_CR,  A_CR,  A_CR,  A_CR,  A_CR,  A_CR,  A_CR   }, 0x00,0x00},
  1408. X/*029*/{{K_LCT, K_LCT, K_LCT, K_LCT, K_LCT, K_LCT, K_LCT, K_LCT  }, 0xff,0x00},
  1409. X/*030*/{{'a',   'A',   A_SOH, A_SOH, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1410. X/*031*/{{'s',   'S',   A_DC3, A_DC3, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1411. X/*032*/{{'d',   'D',   A_EOT, A_EOT, K_ESN, K_ESN, K_DBG, K_NOP  }, 0x0f,0x01},
  1412. X/*033*/{{'f',   'F',   A_ACK, A_ACK, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1413. X/*034*/{{'g',   'G',   A_BEL, A_BEL, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1414. X/*035*/{{'h',   'H',   A_BS,  A_BS,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1415. X/*036*/{{'j',   'J',   A_NL,  A_NL,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1416. X/*037*/{{'k',   'K',   A_VT,  A_VT,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1417. X/*038*/{{'l',   'L',   A_FF,  A_FF,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1418. X/*039*/{{';',   ':',   ';',   ':',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1419. X/*040*/{{'\'',  '"',   '\'',  '"',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1420. X/*041*/{{'`',   '~',   '`',   '~',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1421. X/*042*/{{K_LSH, K_LSH, K_LSH, K_LSH, K_LSH, K_LSH, K_LSH, K_LSH  }, 0xff,0x00},
  1422. X/*043*/{{'\\',  '|',   A_FS,  '|',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1423. X/*044*/{{'z',   'Z',   A_SUB, A_SUB, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1424. X/*045*/{{'x',   'X',   A_CAN, A_CAN, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1425. X/*046*/{{'c',   'C',   A_ETX, A_ETX, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1426. X/*047*/{{'v',   'V',   A_SYN, A_SYN, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1427. X/*048*/{{'b',   'B',   A_STX, A_STX, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1428. X/*049*/{{'n',   'N',   A_SO,  A_SO,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1429. X/*050*/{{'m',   'M',   A_CR,  A_CR,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x01},
  1430. X/*051*/{{',',   '<',   ',',   '<',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1431. X/*052*/{{'.',   '>',   '.',   '>',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1432. X/*053*/{{'/',   '?',   '/',   A_US,  K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1433. X/*054*/{{K_RSH, K_RSH, K_RSH, K_RSH, K_RSH, K_RSH, K_RSH, K_RSH  }, 0xff,0x00},
  1434. X/*055*/{{'*',   '*',   '*',   '*',   K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1435. X/*056*/{{K_LAL, K_LAL, K_LAL, K_LAL, K_LAL, K_LAL, K_LAL, K_LAL  }, 0xff,0x00},
  1436. X/*057*/{{' ',   ' ',   A_NUL, A_NUL, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x0f,0x00},
  1437. X/*058*/{{K_CLK, K_CLK, K_CLK, K_CLK, K_CLK, K_CLK, K_CLK, K_CLK  }, 0xff,0x00},
  1438. X/*059*/{{F(1),  F(13), F(25), F(37), F(1),  F(13), F(25), F(37)  }, 0xff,0x00},
  1439. X/*060*/{{F(2),  F(14), F(26), F(38), F(2),  F(14), F(26), F(38)  }, 0xff,0x00},
  1440. X/*061*/{{F(3),  F(15), F(27), F(39), F(3),  F(15), F(27), F(39)  }, 0xff,0x00},
  1441. X/*062*/{{F(4),  F(16), F(28), F(40), F(4),  F(16), F(28), F(40)  }, 0xff,0x00},
  1442. X/*063*/{{F(5),  F(17), F(29), F(41), F(5),  F(17), F(29), F(41)  }, 0xff,0x00},
  1443. X/*064*/{{F(6),  F(18), F(30), F(42), F(6),  F(18), F(30), F(42)  }, 0xff,0x00},
  1444. X/*065*/{{F(7),  F(19), F(31), F(43), F(7),  F(19), F(31), F(43)  }, 0xff,0x00},
  1445. X/*066*/{{F(8),  F(20), F(32), F(44), F(8),  F(20), F(32), F(44)  }, 0xff,0x00},
  1446. X/*067*/{{F(9),  F(21), F(33), F(45), F(9),  F(21), F(33), F(45)  }, 0xff,0x00},
  1447. X/*068*/{{F(10), F(22), F(34), F(46), F(10), F(22), F(34), F(46)  }, 0xff,0x00},
  1448. X/*069*/{{K_NLK, K_NLK, K_NLK, K_NLK, K_NLK, K_NLK, K_NLK, K_NLK  }, 0xff,0x00},
  1449. X/*070*/{{K_SLK, K_SLK, K_BRK, K_BRK, K_SLK, K_SLK, K_BRK, K_BRK  }, 0xff,0x00},
  1450. X/*071*/{{F(49), '7',   F(49), '7',   F(49), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1451. X/*072*/{{F(50), '8',   F(50), '8',   F(50), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1452. X/*073*/{{F(51), '9',   F(51), '9',   F(51), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1453. X/*074*/{{F(52), '-',   F(52), '-',   F(52), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1454. X/*075*/{{F(53), '4',   F(53), '4',   F(53), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1455. X/*076*/{{F(54), '5',   F(54), '5',   F(54), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1456. X/*077*/{{F(55), '6',   F(55), '6',   F(55), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1457. X/*078*/{{F(56), '+',   F(56), '+',   F(56), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1458. X/*079*/{{F(57), '1',   F(57), '1',   F(57), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1459. X/*080*/{{F(58), '2',   F(58), '2',   F(58), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1460. X/*081*/{{F(59), '3',   F(59), '3',   F(59), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1461. X/*082*/{{F(60), '0',   F(60), '0',   F(60), K_ESN, K_NOP, K_NOP  }, 0xaf,0x02},
  1462. X/*083*/{{A_DEL, '.',   A_DEL, '.',   A_DEL, K_ESN, K_RBT, K_NOP  }, 0x07,0x02},
  1463. X/*084*/{{F(60), F(26), F(60), K_NOP, K_SRQ, K_SRQ, K_SRQ, K_SRQ  }, 0xff,0x00},
  1464. X/*085*/{{F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58)  }, 0xff,0x00},
  1465. X/*086*/{{F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53)  }, 0xff,0x00},
  1466. X/*087*/{{F(11), F(23), F(35), F(47), F(11), F(23), F(35), F(47)  }, 0xff,0x00},
  1467. X/*088*/{{F(12), F(24), F(36), F(48), F(12), F(24), F(36), F(48)  }, 0xff,0x00},
  1468. X/*089*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1469. X/*090*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1470. X/*091*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1471. X/*092*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1472. X/*093*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1473. X/*094*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1474. X/*095*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1475. X/*096*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1476. X/*097*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1477. X/*098*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1478. X/*099*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1479. X/*100*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1480. X/*101*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1481. X/*102*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1482. X/*103*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1483. X/*104*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1484. X/*105*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1485. X/*106*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1486. X/*107*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1487. X/*108*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1488. X/*109*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1489. X/*110*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1490. X/*111*/{{F(51), F(51), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1491. X/*112*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1492. X/*113*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1493. X/*114*/{{K_RAL, K_RAL, K_RAL, K_RAL, K_RAL, K_RAL, K_RAL, K_RAL  }, 0xff,0x00},
  1494. X/*115*/{{K_RCT, K_RCT, K_RCT, K_RCT, K_RCT, K_RCT, K_RCT, K_RCT  }, 0xff,0x00},
  1495. X/*116*/{{A_NL,  A_NL,  A_NL,  A_NL,  A_NL,  A_NL,  A_NL,  A_NL   }, 0x00,0x00},
  1496. X/*117*/{{'/',   '/',   K_NOP, K_NOP, K_ESN, K_ESN, K_NOP, K_NOP  }, 0x3f,0x00},
  1497. X/*118*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1498. X/*119*/{{K_BRK, K_BRK, K_BRK, K_BRK, K_BRK, K_BRK, K_BRK, K_BRK  }, 0xff,0x00},
  1499. X/*120*/{{F(50), F(50), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1500. X/*121*/{{A_DEL, A_DEL, A_DEL, A_DEL, A_DEL, A_DEL, A_DEL, A_DEL  }, 0x00,0x00},
  1501. X/*122*/{{F(57), F(57), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1502. X/*123*/{{F(60), F(60), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1503. X/*124*/{{K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1504. X/*125*/{{F(55), F(55), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1505. X/*126*/{{F(59), F(59), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1506. X/*127*/{{F(49), F(49), K_NOP, K_NOP, K_NOP, K_NOP, K_NOP, K_NOP  }, 0xff,0x00},
  1507. X    }
  1508. X};
  1509. X
  1510. Xstatic char *stringdefaults[] =
  1511. X{
  1512. X    "\033OP", "\033OQ", "\033OR", "\033OS", "\033OT", "\033OU", "\033OV",
  1513. X    "\033OW", "\033OX", "\033OY", "\033OZ", "\033OA", "\033Op", "\033Oq",
  1514. X    "\033Or", "\033Os", "\033Ot", "\033Ou", "\033Ov", "\033Ow", "\033Ox",
  1515. X    "\033Oy", "\033Oz", "\033Oa", "\033OP", "\033OQ", "\033OR", "\033OS",
  1516. X    "\033OT", "\033OU", "\033OV", "\033OW", "\033OX", "\033OY", "\033OZ",
  1517. X    "\033OA", "\033Op", "\033Oq", "\033Or", "\033Os", "\033Ot", "\033Ou",
  1518. X    "\033Ov", "\033Ow", "\033Ox", "\033Oy", "\033Oz", "\033Oa", "\033[H",
  1519. X    "\033[A", "\033[V", "-",    "\033[D",   "\033[G", "\033[C", "+",
  1520. X    "\033[Y", "\033[B", "\033[U", "\033[@", "\033[2",
  1521. X    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 
  1522. X    "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
  1523. X};
  1524. END-of-kdefaults.h
  1525. echo file: keycaps
  1526. sed 's/^X//' >keycaps << 'END-of-keycaps'
  1527. X#
  1528. X# Keycaps name list
  1529. X#    @(#)keycaps    1.1
  1530. X000    0
  1531. XEsc    1
  1532. X1    2
  1533. X2    3
  1534. X3    4
  1535. X4    5
  1536. X5    6
  1537. X6    7
  1538. X7    8
  1539. X8    9
  1540. X9    10
  1541. X0    11
  1542. X-    12
  1543. X=    13
  1544. XBackspace    14
  1545. XTab    15
  1546. XQ    16
  1547. XW    17
  1548. XE    18
  1549. XR    19
  1550. XT    20
  1551. XY    21
  1552. XU    22
  1553. XI    23
  1554. XO    24
  1555. XP    25
  1556. X[    26
  1557. X]    27
  1558. XEnter    28
  1559. XLCtrl    29
  1560. XA    30
  1561. XS    31
  1562. XD    32
  1563. XF    33
  1564. XG    34
  1565. XH    35
  1566. XJ    36
  1567. XK    37
  1568. XL    38
  1569. X;    39
  1570. X'    40
  1571. X`    41
  1572. XLShift    42
  1573. X\\    43
  1574. XZ    44
  1575. XX    45
  1576. XC    46
  1577. XV    47
  1578. XB    48
  1579. XN    49
  1580. XM    50
  1581. X,    51
  1582. X.    52
  1583. X/    53
  1584. XRShift    54
  1585. X*    55
  1586. XLAlt    56
  1587. XSpc    57
  1588. XRAlt    58
  1589. XF1    59
  1590. XF2    60
  1591. XF3    61
  1592. XF4    62
  1593. XF5    63
  1594. XF6    64
  1595. XF7    65
  1596. XF8    66
  1597. XF9    67
  1598. XF10    68
  1599. XNumLock    69
  1600. XScrollLock    70
  1601. XHome    71
  1602. XUp    72
  1603. XPgUp    73
  1604. XPadMinus    74
  1605. XLeft    75
  1606. XCenter    76
  1607. XRight    77
  1608. XPadPlus    78
  1609. XEnd    79
  1610. XDown    80
  1611. XPgEnd    81
  1612. XIns    82
  1613. XDel    83
  1614. X# All following keys are on the 101-key keyboard only
  1615. XSysReq    84
  1616. X085    85
  1617. X086    86
  1618. XF11    87
  1619. XF12    88
  1620. X089    89
  1621. X090    90
  1622. X091    91
  1623. X092    92
  1624. X093    93
  1625. X094    94
  1626. X095    95
  1627. X096    96
  1628. X097    97
  1629. X098    98
  1630. X099    99
  1631. X100    100
  1632. X101    101
  1633. X102    102
  1634. X103    103
  1635. X104    104
  1636. X105    105
  1637. X106    106
  1638. X107    107
  1639. X108    108
  1640. X109    109
  1641. X110    110
  1642. X111    111
  1643. X112    112
  1644. X113    113
  1645. XRAlt    114
  1646. XRCtrl    115
  1647. XPadEnter    116
  1648. XPadSlash    117
  1649. X118    118
  1650. XPause    119
  1651. X120    120
  1652. X121    121
  1653. X122    122
  1654. X123    123
  1655. X124    124
  1656. X125    125
  1657. X126    126
  1658. X127    127
  1659. END-of-keycaps
  1660. echo file: keybind.1
  1661. sed 's/^X//' >keybind.1 << 'END-of-keybind.1'
  1662. X.\"    @(#)keybind.1    1.2
  1663. X.\"
  1664. X.\" Copyright 1989 by Eric S. Raymond (eric@snark.uu.net), all rights reserved
  1665. X.\" You may use, modify or redistribute this code freely, but do not delete
  1666. X.\" this notice. Check with me before you make money with it.
  1667. X.\" 
  1668. X.TH KEYBIND 1 "Local"
  1669. X.SH NAME
  1670. Xkeybind \- key-map editor for XENIX and UNIX V.3.2 386 machines
  1671. X.SH SYNOPSIS
  1672. Xkeybind [-mdr] [-] [\fIfiles\fR...] [ -o \fIoutfile\fR ]
  1673. X.SH DESCRIPTION
  1674. XThis utility enables you to inspect and modify the console keyboard driver
  1675. Xtables on for any UNIX version using the XENIX/386 keyboard driver (this
  1676. Xincludes recent and future AT&T UNIX releases).
  1677. X.SS Theory of Operation
  1678. XAt startup, keybind reads in the current keyboard maps. After interpreting all
  1679. Xswitches and digesting whatever input sources are specified, it attempts to
  1680. Xwrite the resulting map and any changes in string assignments back to the
  1681. Xmapping tables for your tty.
  1682. X.PP
  1683. XCalled with no arguments or with the argument - representing standard input,
  1684. Xkeybind may be used interactively or fed from a keyboard map file; the
  1685. Xmini-language used to describe key definitions is documented below.
  1686. X.PP
  1687. XThe -d flag dumps the current keyboard table in a format keybind will accept as
  1688. Xinput; this is useful for inspecting key definitions. The -r and -m flags are
  1689. Xintended to facilitate noninteractive use from scripts; the former restores
  1690. Xthe default key mappings, and the latter enables Alt as a true Meta key.
  1691. X.PP
  1692. XThe flags (and -) may be used in any combination and will trigger their
  1693. Xactions in the order they are given. Arguments mixed with the flags are
  1694. Xtaken as the names of keyboard map files to be processed.
  1695. X.PP
  1696. XThe -o flag (which requires a filename argument) causes the contents of the
  1697. Xkeymap and stringmap tables at the end of a keybind run to be dumped in binary
  1698. Xform to the given filename. These dump files will be read in properly (and
  1699. Xtheir contents loaded into the program's map-table space) when presented as
  1700. Xfilename arguments to later keybind runs.
  1701. X.PP
  1702. XThis is much faster than an interpreting the equivalent text, because
  1703. Xit concentrates the I/O into one belt and avoids the lexer/parser execution
  1704. Xtime cost. Thus you can use -o to precompile a keyboard setup so that
  1705. Xsubsequent keymap runs are very quick.
  1706. X.SS Enabling Alt as a Meta key
  1707. XThe -m option or the `meta' directive will remap the keyboard on so that the
  1708. XAlt key acts as a meta key when combined with any printable character, or any
  1709. Xshift-control modification of a printable; that is, it turns on the high (0x80)
  1710. Xbit of the character.
  1711. X.PP
  1712. XThis is useful with GNU EMACS. To see why, run it, pull up an EMACS, set
  1713. Xthe meta-flag global to non-nil, type ALT-x, and notice that it works!
  1714. XTo arrange this behavior by default, you might put a `keybind -m' in an
  1715. Xinitialization script under /etc/rc2.d to be executed whenever the system
  1716. Xenters multiuser mode.
  1717. X.PP
  1718. XNote: the ISTRIP bit must be off in your termio structure for your meta key
  1719. Xto work (otherwise the driver will happily strip the meta bit off your input
  1720. Xkeystroke before making it available to the application). GNU EMACS does this
  1721. Xitself; for other applications you may need to do an explicit stty -istrip or a
  1722. XTCSETA{W} ioctl.
  1723. X.PP
  1724. XFunction keys and control-character keys and other special keys are not
  1725. Xaffected by the alt-enable operation. Pains are also taken that this change not
  1726. Xstep on window manager keys or other important special functions; specifically,
  1727. Xit only modifies key/state pairs that are bound to the \fInop\fR, \fIescl\fR,
  1728. X\fIescn\fR or \fIesco\fR functions.
  1729. X.SS Keymap Definition Files
  1730. XThe output of keybind -d is a keymap definition file describing the current
  1731. Xstate of your keyboard. The syntax has been designed to resemble the
  1732. Xconventions used in the \fIkeyboard\fR(7) entry as closely as possible.
  1733. X.PP
  1734. XEach map file is parsed as a sequence of newline- or semicolon-separated
  1735. X\fIcommands\fR or comments.
  1736. XCase of alphabetics and whitespace are ignored everywhere except within
  1737. Xcharacter literals and strings.
  1738. XComments may begin at any point with # and
  1739. Xcontinue to end of line. Each command may be a \fIdirective\fR, a \fIkey
  1740. Xdefinition\fR, a \fIstring assignment\fR, or a \fRshift modifier\fR.
  1741. X.PP
  1742. XThe following directives are defined:
  1743. X.PP
  1744. X\fIrestore\fR \-\- resets to the default bindings given in the
  1745. X\fIkeyboard\fR(7) manual. Must be used with caution, see the BUGS note below.
  1746. X.PP
  1747. X\fImeta\fR \-\- enables the Alt key to function as a true meta, as with the
  1748. X-m option (see above).
  1749. X.PP
  1750. X\fIdump\fR \-\- dumps portions of the keymap table. Without arguments it dumps
  1751. Xthe entire table. It may take a list of scan-code ranges (see below) as
  1752. Xarguments, in which case it dumps only the relevant characters.
  1753. X.PP
  1754. X\fIfunkeys\fR \-\- dumps portions of the function key table. Without arguments
  1755. Xit dumps the entire table. It may take a list of function-key ranges (that is,
  1756. Xfkey special values or dash-separated pairs of same) as arguments, in which
  1757. Xcase it dumps only those function keys.
  1758. X.PP
  1759. X\fIclearstrings\fR \-\- normally, strings assigned to function keys are added
  1760. Xto those already present in the keyboard driver's string table. If you don't
  1761. Xneed the defaults, this wastes some of the limited space available for key
  1762. Xmappings. The \fIclearstrings\fR directive clears the string assignment table
  1763. X(no defaults are saved). Try using it if you get the `out of string space'
  1764. Xabort message.
  1765. X.PP
  1766. X\fIcapslock\fR \-\- dumps information on which keys are affected by caps lock.
  1767. X.PP
  1768. X\fInumlock\fR \-\- dumps information on which keys are affected by num lock.
  1769. X.PP
  1770. X\fIexecute\fR \-\- sends pending keymap changes to the tty immediately using
  1771. Xthe code normally called just before program exit. Intended for interactive
  1772. Xuse.
  1773. X.PP
  1774. X\fIhelp\fR \-\- prints a command summary. Intended for interactive use; it
  1775. Xalso turns on an asterisk prompt, which is turned off on EOF.
  1776. X.PP
  1777. XAs a convenience for interactive use, any directive may be abbreviated to its
  1778. Xfirst two letters.
  1779. X.PP
  1780. XKey definitions may consist of \fIscan-code assignments\fR or \fIkey-state
  1781. Xassignments\fR. The output of `keybind -d' is a list of scan-code assignments
  1782. Xfor all defined scan-codes. Each one consists of a \fIscan-code specifier\fR
  1783. Xfollowed by at most eight \fIkey values\fR, one for each shift state. If fewer
  1784. Xthan eight values are given, states changed start from the left of the table.
  1785. XA state may be skipped by putting a dash in its place in the list.
  1786. X.PP
  1787. XScan-code specifiers always begin with a @ (at-sign). There are two kinds;
  1788. X\fInumeric\fR and \fImnemonic\fR. The former always consists of three zero
  1789. Xfilled decimal digits after the @, giving the scan code's value. Mnemonic
  1790. Xspecifiers, usually duplicate the graphic on the key cap to which the scan code
  1791. Xcorresponds after the @. The output of `keybind -d' includes all valid 
  1792. Xmnemonic scan-code specifiers in the leftmost column. The two sets are not
  1793. Xmutually exclusive; the unlisted numeric specifiers corresponding to mnemonics
  1794. Xare also valid.
  1795. X.PP
  1796. XKey values may consist of \fIcharacter values\fR or \fIspecial values\fR.
  1797. XSpecial values are those listed in \fIkeyboard\fR(7), plus the following
  1798. Xadditions:
  1799. X.PP
  1800. Xvt[0-9]* \- the virtual terminal selectors.
  1801. X.PP
  1802. Xmgr[0-9]* \- the virtual terminal manager selectors.
  1803. X.PP
  1804. Xpfx[0-9]* \- undocumented, but in sys/kd.h; \fIyou\fR tell \fIme\fR.
  1805. X.PP
  1806. XA character value may consist of any of the standard mnemonics for control
  1807. Xcharacters (refer to keybind -rd output for a nearly complete list; `nl' (0x0a),
  1808. X`ht' (0x08) and `csi' (0x9b) are also accepted) or a \Iliteral\fR.
  1809. X.PP
  1810. XLiterals have the syntax of C character constants, with some additions.
  1811. XThe backslash escape form \\xnn permits the use of two-digit hex constants.
  1812. XThe backslash escape form \\dnnn permits the use of three-digit decimal
  1813. Xconstants.
  1814. XC-style octal escapes and special characters \\n, \\r, \\t, \\b, \\v are
  1815. Xcorrecrtly interpreted.
  1816. XAlso, the literal '\\e' is interpreted as ASCII escape (0x1b).
  1817. XTwo-character literals of the form '^c' are interpreted as control characters.
  1818. XTwo-character literals of the form '!c' are interpreted as meta characters;
  1819. Xthat is, the value is that of the second character with the meta (0x80) bit
  1820. Xturned on.
  1821. XThe case of literals is preserved.
  1822. X.PP
  1823. XKey-state assignments set the value of a single key/state combination. They
  1824. Xconsist of an optional \fIshift prefix\fR, a scan-code specifier, an equals
  1825. Xsign and a key value. The shift prefix identifies the state of the key
  1826. Xcorresponding to the scan code to which the key value should be assigned.
  1827. XThe shift prefix may consist of the combination of the words \fBalt\fR,
  1828. X\fIshift\fR, \fIctrl\fR, optionally trailed by hyphens. A key-state
  1829. Xassignment with no prefix applies to the normal (unshifted) state of the
  1830. Xkey.
  1831. X.PP
  1832. XString assignments consist of a function key name, followed by an equals sign,
  1833. Xfollowed by a \fIstring literal\fR. String literals preserve case and have the
  1834. Xsyntax of C strings, with the same additional escape conventions as described
  1835. Xabove for character literals.
  1836. X.PP
  1837. XFinally, shift modifiers are used to control which characters are subject
  1838. Xto shift-key modification. Each should begin with one of the keywords
  1839. X\fIshiftlock\fR, \fIcapslock\fR, or \fInumlock\fR; \fIshiftlock\fR and
  1840. X\fIcapslock\fR are equivalent. This should be followed by one of the words
  1841. X`enabled' or `disabled' and a list of ranges of scan codes. If the list is
  1842. Xempty, the shift modifier is applied to all scan codes.
  1843. X.PP
  1844. XA \fIrange\fR may be either a single scan code or a dash-separated pair of
  1845. Xscan codes; the latter is interpreted as all scan codes numerically greater
  1846. Xthan or equal to the first and less than or equal to the second.
  1847. X.PP
  1848. X.SH EXAMPLE
  1849. XThe author finds the command file given as figure 1 below quite useful. To
  1850. Xunderstand what it does, first note the following:
  1851. X.PP
  1852. XIf keybind is run from the console before vtlmgr, the key mappings will apply
  1853. Xto all virtual terminals. However, string-key loadings will be changed on the
  1854. Xconsole only. Thus, to give a key/state combination the same value (usable by
  1855. Xan application that can do its own key bindings, such as EMACS) across all
  1856. Xvirtual terminals, it is best to bind it to an esco/escn/escl value rather
  1857. Xthan indirecting through a function key.
  1858. X
  1859. X.ce 1
  1860. XFig 1: sample.kmf
  1861. X
  1862. X.in +10n
  1863. X.nf
  1864. X.so sample.kmf
  1865. X.fi
  1866. X.in
  1867. X
  1868. X.SH BUGS
  1869. XDue to the absence of a reset ioctl(), the mappings that -r and the `restore'
  1870. Xcommand reset to come from tables dumped out of 3.2u, tweaked to match the
  1871. Xdefaults tables in \fIkeyboard\fR(7) and included into the code. If you have
  1872. Xreason to suspect that the system defaults have changed, you can recompile
  1873. Xwith -DREGEN and replace the system-default initializers with the output of
  1874. Xa `keybind -c'.
  1875. X.PP
  1876. XRestoring defaults doesn't undo changes in the enabling of the shift-lock and
  1877. Xnum-lock keys.
  1878. X.PP
  1879. XError handling in the keyboard map description parser is rudimentary.
  1880. X.PP
  1881. XBeware of confusing @[0-9] with @00[9]; the former are mnemonics for the
  1882. Xdigit-key scan codes, the latter represent numeric scan codes. 
  1883. X.SH PORTABILITY NOTE
  1884. XThis code should work on any AT/ISA/EISA box running XENIX/386 or an un-munged
  1885. Xport of AT&T UNIX at release 3.2 or later. To check this, look for the
  1886. XGIO_KEYMAP and SIO_KEYMAP ioctls in \fIkeyboard\fR(7); if these are present,
  1887. Xyou have the XENIX keyboard driver and keybind should do the right thing.
  1888. X.SH AUTHOR
  1889. XEric S. Raymond (eric@snark.uu.net)
  1890. X.SH SEE ALSO
  1891. Xkeyboard(7)
  1892. X
  1893. X
  1894. END-of-keybind.1
  1895. echo file: sample.kmf
  1896. sed 's/^X//' >sample.kmf << 'END-of-sample.kmf'
  1897. X# Eric's keymap-refinition script for use with GNU EMACS
  1898. X#
  1899. X#    @(#)sample.kmf    1.1
  1900. X#
  1901. Xkeybind <<EOF
  1902. Xmeta                    # This helps with GNU EMACS
  1903. Xalt-@F1 = vt0           # More convenient vt-select keys
  1904. Xalt-@F2 = vt1
  1905. Xalt-@F3 = vt2
  1906. Xalt-@F4 = vt3
  1907. Xalt-@F5 = vt4
  1908. Xalt-@F6 = vt5
  1909. Xalt-@F7 = vt6
  1910. Xalt-@F8 = vt7
  1911. X@PadMinus = escn        # Use this for (kill-compilation)
  1912. X@PadPlus = escn         # Use this for (compile)
  1913. X@ScrollLock = xoff      # ^S
  1914. Xcapslock disabled       # Because I'm a poor typist
  1915. XEOF
  1916. END-of-sample.kmf
  1917. exit
  1918.  
  1919. -- 
  1920. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  1921. Use a domain-based address or give alternate paths, or you may lose out.
  1922.