[comp.unix.sysv386] emacs keymap for AT386?

ckp@grebyn.com (Checkpoint Technologies) (09/18/90)

Has anyone implemented an AT386 keymap for GNU emacs? I'd like to
be able to use the arrows, to use Page Up and Page Down, and I'd like
Alt to work for Meta.  I'm willing to sacrifice the Meta-[ current
functionality.  I'm using Interactive Unix 2.2.  Thanks.

-- 
First comes the logo: C H E C K P O I N T  T E C H N O L O G I E S      / /  
                                                                    \\ / /    
Then, the disclaimer:  All expressed opinions are, indeed, opinions. \  / o
Now for the witty part:    I'm pink, therefore, I'm spam!             \/

james@bigtex.cactus.org (James Van Artsdalen) (09/19/90)

In <22073@grebyn.com>, ckp@grebyn.UUCP (Checkpoint Technologies) wrote:

> Has anyone implemented an AT386 keymap for GNU emacs? I'd like to
> be able to use the arrows, to use Page Up and Page Down, and I'd like
> Alt to work for Meta.  I'm willing to sacrifice the Meta-[ current
> functionality.  I'm using Interactive Unix 2.2.  Thanks.

ksh is happier too.  This seems to work under SysVr4 also, though that
may be an accident.  Those of you with keyboards with too many keys
will need to add stuff to this.  -j is "James' mapping".

This is one of those barely-started, not-quite-finished programs.  I
hadn't even read the sources for over 2 years.  No, I don't remember
what's supposed to be in that 'puts("")' at the end, but it's just a
display routine, so no harm.  I suspect there are more general ways to
do this.  :-)

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

keymap_t map;

main(argc, argv)
int argc;
char **argv;
{
   int opt_print = 0;
   int opt_james = 0;
   int c;
   char *opt_file = NULL;
   char *opt_dump = NULL;
   extern char *optarg;
   extern int optind;

   while ((c = getopt(argc, argv, "pjf:d:")) != -1) {
      switch (c) {
       case 'p':
	 opt_print = 1;
	 break;
       case 'f':
	 if (opt_file) {
	    fputs("Only one -f file allowed.\n", stderr);
	    exit(EX_USAGE);
	 }
	 opt_file = optarg;
	 break;
       case 'd':
	 if (opt_dump) {
	    fputs("Only one -d file allowed.\n", stderr);
	    exit(EX_USAGE);
	 }
	 opt_dump = optarg;
	 break;
       case 'j':
	 opt_james = 1;
	 break;
       default:
	 fprintf(stderr, "Usage: %s [ options ]\n", argv[0]);
	 exit(EX_USAGE);
      }
   }

   if (argc == 1) {
      show_keys();
      exit(EX_OK);
   }

   if (opt_file)
     set_file(opt_file);

   if (opt_james)
      set_james();

   if (opt_dump)
     dump_file(opt_dump);

   if (opt_print) {
      show_keys();
      exit(EX_OK);
   }
}

dump_file(file)
char *file;
{
   FILE *f;

   if (ioctl(fileno(stdin), GIO_KEYMAP, &map) == -1)
     perror("ioctl(GIO_KEYMAP)");
   f = fopen(file, "w");
   if (!f)
     perror("fopen()");
   else if (fwrite(&map, sizeof(map), 1, f) != 1)
     perror("fwrite()");
   else if (fclose(f))
     perror("fclose()");
}

set_file(file)
char *file;
{
   FILE *f;
   int size;

   if (ioctl(fileno(stdin), GIO_KEYMAP, &map) == -1)
     perror("ioctl(GIO_KEYMAP)");

   size = map.n_keys;

   f = fopen(file, "r");
   if (!f)
     perror("fopen()");
   else if (fread(&map, sizeof(map), 1, f) != 1)
     perror("fread()");
   else if (fclose(f))
     perror("fclose()");
   else if (map.n_keys != size || map.key[0].map[0] || map.key[0].map[1] ||
	    map.key[0].map[2] || map.key[0].map[3] || map.key[0].map[4] ||
	    map.key[0].map[5] || map.key[0].map[6] || map.key[0].map[7])
     fputs("Corrupt keymap file\n", stderr);
   else if (ioctl(fileno(stdin), PIO_KEYMAP, &map) == -1)
     perror("ioctl(PIO_KEYMAP)");
}

set_james()
{
   int i;

   if (ioctl(fileno(stdin), GIO_KEYMAP, &map) == -1)
     perror("ioctl(GIO_KEYMAP)");

   map.key[3].map[CTRL]  = 0;		/* "2" */
   map.key[7].map[CTRL]  = 0x1e;	/* "6" */
   map.key[12].map[CTRL] = 0x1f;	/* "-" */

   map.key[2].map[SHFCTL] = 0x21;	/* 1 */
   map.key[4].map[SHFCTL] = 0x23;	/* 3 */
   map.key[5].map[SHFCTL] = 0x24;	/* 4 */
   map.key[6].map[SHFCTL] = 0x25;	/* 5 */
   map.key[8].map[SHFCTL] = 0x26;	/* 7 */
   map.key[9].map[SHFCTL] = 0x2a;	/* 8 */
   map.key[10].map[SHFCTL] = 0x28;	/* 9 */
   map.key[11].map[SHFCTL] = 0x29;	/* 0 */
   map.key[13].map[SHFCTL] = 0x2b;	/* = */

   map.key[14].map[NORMAL] = 0x7f;	/* backspace */
   map.key[14].map[CTRL]   = 0x08;
   map.key[14].map[SHIFT]  = 0x08;
   map.key[14].map[SHFCTL] = 0x08;
   map.key[15].map[SHIFT] = 0x09;	/* tab */
   map.key[15].map[SHFCTL] = 0x09;

   for (i = 1; i <= 15; i++) {		/* ESC, 1-9, 0, -, =, backspace tab */
      map.key[i].spcl = 0;
      map.key[i].map[ALT]       = map.key[i].map[NORMAL] | 0x80;
      map.key[i].map[ALTSHF]    = map.key[i].map[SHIFT]  | 0x80;
      map.key[i].map[ALTCTL]    = map.key[i].map[CTRL]   | 0x80;
      map.key[i].map[ALTSHFCTL] = map.key[i].map[SHFCTL] | 0x80;
   }

   map.key[26].map[SHFCTL] = 0x1b;
   map.key[27].map[SHFCTL] = 0x1d;
   map.key[28].map[CTRL] = 0x0d;	/* enter */
   map.key[28].map[SHFCTL] = 0x0d;

   for (i = 16; i <= 28; i++) {			/* qwertyuiop[] enter */
      map.key[i].spcl = 0;
      map.key[i].map[ALT]       = map.key[i].map[NORMAL] | 0x80;
      map.key[i].map[ALTSHF]    = map.key[i].map[SHIFT]  | 0x80;
      map.key[i].map[ALTCTL]    = map.key[i].map[CTRL]   | 0x80;
      map.key[i].map[ALTSHFCTL] = map.key[i].map[SHFCTL] | 0x80;
   }

   map.key[41].map[SHFCTL] = 0x7e;	/* ` */

   for (i = 30; i <= 41; i++) {			/* asdfghjkl;'` */
      map.key[i].spcl = 0;
      map.key[i].map[ALT]       = map.key[i].map[NORMAL] | 0x80;
      map.key[i].map[ALTSHF]    = map.key[i].map[SHIFT]  | 0x80;
      map.key[i].map[ALTCTL]    = map.key[i].map[CTRL]   | 0x80;
      map.key[i].map[ALTSHFCTL] = map.key[i].map[SHFCTL] | 0x80;
   }

   for (i = 43; i <= 53; i++) {			/* \zxcvbnm,./ */
      map.key[i].spcl = 0;
      map.key[i].map[ALT]       = map.key[i].map[NORMAL]   | 0x80;
      map.key[i].map[ALTSHF]    = map.key[i].map[SHIFT]  | 0x80;
      map.key[i].map[ALTCTL]    = map.key[i].map[CTRL]   | 0x80;
      map.key[i].map[ALTSHFCTL] = map.key[i].map[SHFCTL] | 0x80;
   }

   map.key[71].spcl = 0;	/* Home */  
   map.key[72].spcl = 0;	/* Up */    
   map.key[73].spcl = 0;	/* PgUp */  
   map.key[75].spcl = 0;	/* Left */  
   map.key[77].spcl = 0;	/* Right */ 
   map.key[79].spcl = 0;	/* End */   
   map.key[80].spcl = 0;	/* Down */  
   map.key[81].spcl = 0;	/* PgDn */  
   map.key[83].spcl = 0;	/* Del */   

   map.key[71].map[NORMAL] = 0x01;	/* Home */
   map.key[72].map[NORMAL] = 0x10;	/* Up */
   map.key[73].map[NORMAL] = 0xf6;	/* PgUp */
   map.key[75].map[NORMAL] = 0x02;	/* Left */
   map.key[77].map[NORMAL] = 0x06;	/* Right */
   map.key[79].map[NORMAL] = 0x05;	/* End */
   map.key[80].map[NORMAL] = 0x0e;	/* Down */
   map.key[81].map[NORMAL] = 0x16;	/* PgDn */
   map.key[83].map[NORMAL] = 0x04;	/* Del */

   map.key[71].map[CTRL] = map.key[71].map[NORMAL];	/* Home */
   map.key[72].map[CTRL] = map.key[72].map[NORMAL];	/* Up */
   map.key[73].map[CTRL] = 0xbc;			/* PgUp */
   map.key[75].map[CTRL] = 0x82;			/* Left */
   map.key[77].map[CTRL] = 0x86;			/* Right */
   map.key[79].map[CTRL] = map.key[79].map[NORMAL];	/* End */
   map.key[80].map[CTRL] = map.key[80].map[NORMAL];	/* Down */
   map.key[81].map[CTRL] = 0xbe;			/* PgDn */
   map.key[83].map[CTRL] = 0x7f;			/* Del */

   map.key[71].map[ALT] = map.key[71].map[NORMAL] | 0x80;	/* Home */  
   map.key[72].map[ALT] = map.key[72].map[NORMAL] | 0x80;	/* Up */    
   map.key[73].map[ALT]  = 0xbc;				/* PgUp */
   map.key[75].map[ALT] = map.key[75].map[NORMAL] | 0x80;	/* Left */
   map.key[77].map[ALT] = map.key[77].map[NORMAL] | 0x80;	/* Right */  
   map.key[79].map[ALT] = map.key[79].map[NORMAL] | 0x80;	/* End */ 
   map.key[80].map[ALT] = map.key[80].map[NORMAL] | 0x80;	/* Down */   
   map.key[81].map[ALT]  = 0xbe;				/* PgDn */
   map.key[83].map[ALT] = map.key[83].map[NORMAL] | 0x80;	/* Del */  

   map.key[71].map[ALTSHF] = map.key[71].map[SHIFT] | 0x80;	/* Home */
   map.key[72].map[ALTSHF] = map.key[72].map[SHIFT] | 0x80;	/* Up */
   map.key[73].map[ALTSHF] = map.key[73].map[SHIFT] | 0x80;	/* PgUp */
   map.key[75].map[ALTSHF] = map.key[75].map[SHIFT] | 0x80;	/* Left */
   map.key[77].map[ALTSHF] = map.key[77].map[SHIFT] | 0x80;	/* Right */
   map.key[79].map[ALTSHF] = map.key[79].map[SHIFT] | 0x80;	/* End */
   map.key[80].map[ALTSHF] = map.key[80].map[SHIFT] | 0x80;	/* Down */
   map.key[81].map[ALTSHF] = map.key[81].map[SHIFT] | 0x80;	/* PgDn */
   map.key[83].map[ALTSHF] = map.key[83].map[SHIFT] | 0x80;	/* Del */

   map.key[71].map[ALTCTL] = map.key[71].map[CTRL] | 0x80;	/* Home */
   map.key[72].map[ALTCTL] = map.key[72].map[CTRL] | 0x80;	/* Up */
   map.key[73].map[ALTCTL] = map.key[73].map[CTRL];		/* PgUp */
   map.key[75].map[ALTCTL] = map.key[75].map[CTRL];		/* Left */
   map.key[77].map[ALTCTL] = map.key[77].map[CTRL];		/* Right */
   map.key[79].map[ALTCTL] = map.key[79].map[CTRL] | 0x80;	/* End */
   map.key[80].map[ALTCTL] = map.key[80].map[CTRL] | 0x80;	/* Down */
   map.key[81].map[ALTCTL] = map.key[81].map[CTRL];		/* PgDn */
   map.key[83].map[ALTCTL] = map.key[83].map[CTRL] | 0x80;	/* Del */

   map.key[71].map[ALTSHFCTL] = map.key[71].map[SHFCTL] | 0x80; /* Home */
   map.key[72].map[ALTSHFCTL] = map.key[72].map[SHFCTL] | 0x80; /* Up */
   map.key[73].map[ALTSHFCTL] = map.key[73].map[SHFCTL] | 0x80; /* PgUp */
   map.key[75].map[ALTSHFCTL] = map.key[75].map[SHFCTL] | 0x80; /* Left */
   map.key[77].map[ALTSHFCTL] = map.key[77].map[SHFCTL] | 0x80; /* Right */
   map.key[79].map[ALTSHFCTL] = map.key[79].map[SHFCTL] | 0x80; /* End */
   map.key[80].map[ALTSHFCTL] = map.key[80].map[SHFCTL] | 0x80; /* Down */
   map.key[81].map[ALTSHFCTL] = map.key[81].map[SHFCTL] | 0x80; /* PgDn */
   map.key[83].map[ALTSHFCTL] = map.key[83].map[SHFCTL] | 0x80; /* Del */

   if (ioctl(fileno(stdin), PIO_KEYMAP, &map) == -1) {
     perror("ioctl(PIO_KEYMAP)");
     exit(1);
   }
}

/* unaccounted keys:
 *
 * control.
 * left shift.
 * alt.
 * right shift.
 * caps lock.
 * num lock.
 * scroll lock.
 * SysReq.
 *
 */

char *names[NUM_KEYS] = {   0,
		    "ESC",	/* 1 */
		    "1",
		    "2",
		    "3",
		    "4",
		    "5",
		    "6",
		    "7",
		    "8",
		    "9",	/* 10 */
		    "0",
		    "-",
		    "=",
		    "backspace",
		    "tab",
		    "q",
		    "w",
		    "e",
		    "r",
		    "t",	/* 20 */
		    "y",
		    "u",
		    "i",
		    "o",
		    "p",
		    "[",
		    "]",
		    "enter",
		    "control?",
		    "a",	/* 30 */
		    "s",
		    "d",
		    "f",
		    "g",
		    "h",
		    "j",
		    "k",
		    "l",
		    ";",
		    "'",	/* 40 */
		    "`",
		    "huh? 42",
		    "\\",
		    "z",
		    "x",
		    "c",
		    "v",
		    "b",
		    "n",
		    "m",	/* 50 */
		    ",",
		    ".",
		    "/",
		    "huh? 54",
		    "PrtSc",
		    "huh? 56",
		    "huh? 57",
		    "huh? 58",
		    "F1? 59",
		    "F2? 60",	/* 60 */
		    "F3? 61",
		    "F4? 62",
		    "F5? 63",
		    "F6? 64",
		    "F7? 65",
		    "F8? 66",
		    "F9? 67",
		    "F10? 68",
		    "huh? 69",
		    "huh? 70",	/* 70 */
		    "Home",
		    "Up",
		    "PgUp",
		    "Minus",
		    "Left",
		    "Center",
		    "Right",
		    "Plus",
		    "End",
		    "Down",	/* 80 */
		    "PgDn",
		    "Ins",
		    "Del"	/* 83 */
		   };

show_keys()
{
   int i;

   if (ioctl(fileno(stdin), GIO_KEYMAP, &map) == -1) {
     perror("ioctl(GIO_KEYMAP)");
     exit(1);
   }

   printf("size: %d\n", map.n_keys);

   for (i = 0; i < map.n_keys; i++) {
      printf("\nkey: %3d\tspecial: %2x\tflags: %2x", i,
	     (int) map.key[i].spcl, (int) map.key[i].flgs);
      if (names[i])
	printf("\t\tcap: \"%s\"", names[i]);
      puts("");
      printf("\tnorm:\t%2x\tshift:\t%2x\tctrl:\t%2x\tshft-ctrl:\t%2x\n",
	     map.key[i].map[0], map.key[i].map[1], map.key[i].map[2],
	     map.key[i].map[3]);
      printf("    alt norm:\t%2x\tshift:\t%2x\tctrl:\t%2x\tshft-ctrl:\t%2x\n",
	     map.key[i].map[4], map.key[i].map[5], map.key[i].map[6],
	     map.key[i].map[7]);
   }
}
-- 
James R. Van Artsdalen          james@bigtex.cactus.org   "Live Free or Die"
Dell Computer Co    9505 Arboretum Blvd Austin TX 78759         512-338-8789

john@jwt.UUCP (John Temples) (09/19/90)

In article <47366@bigtex.cactus.org> james@bigtex.cactus.org (James Van Artsdalen) writes:

[ keyboard mapping program ]

>   if (ioctl(fileno(stdin), GIO_KEYMAP, &map) == -1)

These ioctls don't seem to work under ESIX D.  I get an "Invalid
argument" back when I try to run them.  Looking in kd.h,
they're commented as "Xenix keyboard and display ioctl's."  Any other
ESIX people get this to work?

Just wanting to make ^2 generate a NUL for emacs...
-- 
John W. Temples -- john@jwt.UUCP (uunet!jwt!john)

marc@dumbcat.sf.ca.us (Marco S Hyman) (09/20/90)

In article <22073@grebyn.com> ckp@grebyn.UUCP (Checkpoint Technologies) writes:
    Has anyone implemented an AT386 keymap for GNU emacs? I'd like to
    be able to use the arrows, to use Page Up and Page Down, and I'd like
    Alt to work for Meta.  I'm willing to sacrifice the Meta-[ current
    functionality.  I'm using Interactive Unix 2.2.  Thanks.
    

I keep this as at386 and AT386 in .../emacs/lisp/term.

(enjoy)

// marc

;; @(#) at386.el 22jul90 marc@dumbcat.sf.ca.us
;; Map AT386 cursor movement, function, and alt key sequences
;;
;; There were two ways to go in creating this file.  The first was to copy
;; the vt100 example using the keypad functions, the other was to copy the
;; sun example and map things direct.  I went with the sun example because I
;; use a sun at work and prefer the set-ups to be similar.

(defun unbound-key ()
  "Placeholder for undefined keys."
  (interactive)
  (error "unbound-key"))

(defun scroll-up-n (n)
  "Scroll up n (defualt 1) line."
  (interactive "p")
  (scroll-up n))

(defun scroll-down-n (n)
  "Scroll down n (defualt 1) line."
  (interactive "p")
  (scroll-down n))

;; define the pc cursor key keymap and bind it to the existing ESC-[ map or
;; a new keymap if no existing ESC-[ map.  Assign default values.

(defvar pc-cursor-map nil
  "keymap for the cursor movement keys on pc style keyboards.")

(if (not pc-cursor-map)
    (progn
     (setq pc-cursor-map (lookup-key global-map "\e["))
     (if (not (keymapp pc-cursor-map))
	 (setq pc-cursor-map (make-sparse-keymap)))))

(define-key pc-cursor-map "@" 'yank)			; insert
(define-key pc-cursor-map "A" 'previous-line)		; up-arrow
(define-key pc-cursor-map "B" 'next-line)		; down-arrow
(define-key pc-cursor-map "C" 'forward-char)		; right-arrow
(define-key pc-cursor-map "D" 'backward-char)		; left-arrow
(define-key pc-cursor-map "G" 'recenter)		; keypad 5
(define-key pc-cursor-map "H" 'beginning-of-buffer)	; home
(define-key pc-cursor-map "S" 'unbound-key)		; keypad minus
(define-key pc-cursor-map "T" 'unbound-key)		; keypad plus
(define-key pc-cursor-map "U" 'scroll-up)		; page down
(define-key pc-cursor-map "V" 'scroll-down)		; page up
(define-key pc-cursor-map "Y" 'end-of-buffer)		; end

;; define the pc function key keymap and bind it to the existing ESC-O map or
;; a new keymap if no existing ESC-O map.  Assign default values.

(defvar pc-function-map nil
  "keymap for the function keys on a pc style keyboard.")

(if (not pc-function-map)
    (progn
     (setq pc-function-map (lookup-key global-map "\eO"))
     (if (not (keymapp pc-function-map))
	 (setq pc-function-map (make-sparse-keymap)))))

(define-key pc-function-map "P" 'unbound-key)		; F1
(define-key pc-function-map "Q" 'unbound-key)		; F2
(define-key pc-function-map "R" 'scroll-down-n)		; F3
(define-key pc-function-map "S" 'scroll-up-n)		; F4
(define-key pc-function-map "T" 'shell)			; F5
(define-key pc-function-map "U" 'shrink-window)		; F6
(define-key pc-function-map "V" 'enlarge-window)	; F7
(define-key pc-function-map "W" 'unbound-key)		; F8
(define-key pc-function-map "X" 'unbound-key)		; F9
(define-key pc-function-map "Y" 'unbound-key)		; F10
(define-key pc-function-map "Z" 'unbound-key)		; F11
(define-key pc-function-map "A" 'unbound-key)		; F12
(define-key pc-function-map "p" 'unbound-key)		; shift-F1
(define-key pc-function-map "q" 'unbound-key)		; shift-F2
(define-key pc-function-map "r" 'unbound-key)		; shift-F3
(define-key pc-function-map "s" 'unbound-key)		; shift-F4
(define-key pc-function-map "t" 'unbound-key)		; shift-F5
(define-key pc-function-map "u" 'unbound-key)		; shift-F6
(define-key pc-function-map "v" 'unbound-key)		; shift-F7
(define-key pc-function-map "w" 'unbound-key)		; shift-F8
(define-key pc-function-map "x" 'unbound-key)		; shift-F9
(define-key pc-function-map "y" 'unbound-key)		; shift-F10
(define-key pc-function-map "z" 'unbound-key)		; shift-F11
(define-key pc-function-map "a" 'unbound-key)		; shift-F12

;; Enable the just defined pc cursor and function keys.  Note that the
;; existing ESC-[ is mapped to ESC-[[.  There is no existing ESC-O to get
;; remapped.

(define-key esc-map "[" pc-cursor-map)
(define-key esc-map "[[" 'backward-paragraph)
(define-key esc-map "O" pc-function-map)

;; since .emacs gets loaded BEFORE this file a hook is provided to add local
;; bindings to the cursor and function maps.  An example entry in your
;; .emacs might look like.
;; (setq at386-term-hook 
;;   '((define-key pc-function-map "P" 'goto-line)
;;     (define-key pc-function-map "Q" 'what-line)))

(defvar at386-term-hook nil
  "At386 startup hook to modify default key bindings.")

(run-hooks 'at386-term-hook)

;; should map \eN as an additional META key -- would allow alt-x to work where
;; esc-x works now.
-- 
// marc@dumbcat.sf.ca.us
// {ames,decwrl,sun}!pacbell!dumbcat!marc