home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / keybind < prev    next >
Encoding:
Internet Message Format  |  1989-10-26  |  60.0 KB

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