[comp.emacs] term/wy75.el for Gnu Emacs

gudeman@arizona.edu (David Gudeman) (06/30/87)

;; Wyse 75 terminal setup file.
;; Written by David Gudeman, gudeman@arizona.edu
;; To use the keypad-map, the terminal should be in ANSI mode with
;;   curser key and keypad application modes ON.  If terminals are not
;;   expected to always be in ANSI mode, the ti field in the termcap
;;   should include '\E<'.  The keypad start field (ks) should always
;;   contain '\E[?1h\E=' to turn on the curser keys and keypad.  No
;;   padding is needed at 9600baud, I don't know about faster speeds.
;;   Here is a fairly well optimized termcap entry.

;; w4|wy75|wyse 75:\
;; 	:ae=^O:al=\E[L:AL=\E[%dL:as=^N:bs:bt=\E[Z:\
;; 	:cd=\E[J:ce=\E[K:ch=\E[%i%dG:cl=\E[H\E[J:cm=\E[%i%d;%dH:co#80:\
;; 	:cs=\E[%i%d;%dr:\cv=\E[%dH:\
;; 	:dc=\E[P:DC=\E[%dP:dl=\E[M:DL=\E[%dM:dN#1:do=\E[B:\
;; 	:ei=\E[4l:ho\E[H:ic=\E[@:IC=\E[%d@:im=\E[4h:ip=1:\
;; 	:kd=\EOB:ke=\E>:kh=\EOH:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:\
;; 	:li#24:nd=\E[C:pt:\
;; 	:se=\E[m:sf=^J:so=\E[7m:sr=\EM:\
;; 	:ti=\E[?7h:\
;; 	:ue=\E[p:ug#1:ul:up=\E[A:us=\E[8p:\
;; 	:vb=\E[?5h\200\200\200\200\200\200\E[?5l:

(require 'keypad)

(defvar keypad-map nil
  "keymap for arrow and keypad keys on the wyse 75 keyboard.  To set
keypad and arrow keys, execute: (define-key function-keymap KEY FUNCTION)
where FUNCTION is the function you want KEY bound to, and KEY is a string
representing the function key.  KEY is is defined by the following table
of (KEY - name) pairs:
  u - up arrow		C-a - PF1	- - minus
  d - down arror	C-b - PF2	, - comma
  r - right arrow	C-c - PF3	. - dot
  l - left arrow	C-d - PF4	0 - zero
  h - home		e - enter	1 - one etc.

The resetable function keys F6 to F16 and shifted F6 to F10 can also be
used if you redefine them with the function wy75-reset-keys.  For the
names of these function keys, see help for the variable Fkey-map.")

(or keypad-map
    (keymapp (lookup-key global-map "\eO"))
    (progn
      (setup-terminal-keymap
       keypad-map
       '(("A" . ?u)			; up arrow
	 ("B" . ?d)			; down arrow
	 ("C" . ?r)			; right arrow
	 ("D" . ?l)			; left arrow
	 ("H" . ?h)			; Home
	 ("M" . ?e)			; Enter
	 ("P" . ?\C-a)			; PF1
	 ("Q" . ?\C-b)			; PF2
	 ("R" . ?\C-c)			; PF3
	 ("S" . ?\C-d)			; PF4
	 ("l" . ?,)			; ,
	 ("m" . ?-)			; -
	 ("n" . ?.)			; .
	 ("p" . ?0)			; 0
	 ("q" . ?1)			; 1
	 ("r" . ?2)			; 2
	 ("s" . ?3)			; 3
	 ("t" . ?4)			; 4
	 ("u" . ?5)			; 5
	 ("v" . ?6)			; 6
	 ("w" . ?7)			; 7
	 ("x" . ?8)			; 8
	 ("y" . ?9)			; 9
	 ("\\" . ?\C-f)			; F6
	 ("]" . ?\C-g)			; F7
	 ("^" . ?\C-h)			; F8
	 ("_" . ?\C-i)			; F9
	 ("`" . ?\C-j)			; F10
	 ("a" . ?\C-k)			; F11
	 ("b" . ?\C-l)			; F12
	 ("c" . ?\C-m)			; F13
	 ("d" . ?\C-n)			; F14
	 ("e" . ??)			; F15 (Help)
	 ("f" . ?x)			; F16 (Do)
	 ("g" . ?\C-q)			; F6S
	 ("h" . ?\C-r)			; F7S
	 ("i" . ?\C-s)			; F8S
	 ("j" . ?\C-t)			; F9S
	 ("k" . ?\C-u))			; F10S
      (define-key global-map "\eO" keypad-map)
      (define-key global-map "\eG" keypad-map))); ESC-G is frequently recieved
						; instead of ESC-O.  Probably
						; a transmission error.

(defvar Fkey-map nil
    "Keymap for function keys on the wyse 75 keyboard.  To use, set
Fkey-map to t in your .emacs file.  If this is done, ESC-[ will no longer
be available as a command key sequence.  To set function keys, execute:
(define-key function-keymap KEY FUNCTION) where FUNCTION is the function you
want KEY bound to, and KEY is a string representing the function key.  KEY
is is defined by the following table of (KEY - name) pairs:

  a - F1	L - F5		C-i - F9	C-m - F13
  c - F2	C-f - F6	C-j - F10	C-n - F14
  C - F3	C-g - F7	C-k - F11	? - F15
  I - F4	C-h - F8	C-l - F12	x - F16
<shifted function keys>
  t - F1S	E - F5S		C-t - F9S	k - F13S
  E - F2S	C-q - F6S	C-u - F10S	s - F14S
  S - F3S	C-r - F7S	f - F11S	P - F15S
  A - F4S	C-s - F8S	T - F12S	N - F16S")

(if (eq t Fkey-map)
    (progn
      (setq Fkey-map (make-keymap))
      (setup-terminal-keymap
       Fkey-map
       ;; unshifted		shifted
       '(("?5i" . ?a)		("5i" . ?t)		; F1
	 ("?3i" . ?c)		("?1i" . ?E)		; F2
	 ("2i" . ?C)		("0i" . ?S)		; F3
	 ("@" . ?I)		("L" . ?A)		; F4
	 ("M" . ?L)		("K" . ?E)		; F5
	 ("17~" . ?\C-f)	("31~" . ?\C-q)		; F6
	 ("18~" . ?\C-g)	("32~" . ?\C-r)		; F7
	 ("19~" . ?\C-h)	("33~" . ?\C-s)		; F8
	 ("20~" . ?\C-i)	("34~" . ?\C-t)		; F9
	 ("21~" . ?\C-j)	("35~" . ?\C-u)		; F10
	 ("23~" . ?\C-k)	("1~" . ?f)		; F11
	 ("24~" . ?\C-l)	("2~" . ?T)		; F12
	 ("25~" . ?\C-m)	("3~" . ?k)		; F13
	 ("26~" . ?\C-n)	("4~" . ?s)		; F14
	 ("28~" . ??)		("5~" . ?P)		; F15
	 ("29~" . ?x)		("6~" . ?N)))		; F16
      (define-key esc-map "[" Fkey-map))))

(defun wy75-reset-keys (arg)
  "Set wyse 75 function keys F6 to F16 and shifted F6 to F10 to use ESC-O
prefix codes instead of ESC [ prefix.  THIS FUNCTION CHANGES THE TERMINAL
SETTINGS, it does not just affect mappings in software.  To make the new
settings permanent, go into Setup mode and exit, answering Y when it asks
if you want to save the changes for power on.  To set the keys to their
default values, call this function with a prefix argument.
Non-interactivaly, takes one arg: nil for ESC-O values and anything else
for default values."
  (interactive "P")
  (let ((i ?a) (j 17))
    (while (<= i ?p)
      (if arg
	  (send-string-to-terminal
	   (format "\e[>%c/\e[%d~/" i j))
	(send-string-to-terminal
	 (format "\e[>%c/\eO%c/" i (- i 5))))	; 5 = (- ?a ?\\)
      (setq i (1+ i)
	    j (+ j (if (memq j '(21 26 29)) 2 1))))))

(defun wy75-text-load (text field)
  "Load TEXT into a FIELD on a wyse 75 terminal.
TEXT is a string containing any characters exept C-@, C-a, and C-?.
Control characters have special graphic representations.  The character
following a C-n has its high bit set, the character following a C-o is
shifted to the control region.  That is, the sequence C-o-a produces C-a,
and the sequence C-n-a produces an 'a' with its high bit set.

Characters with the high bit set are interpreted differently.  For normal
printing characters, the high bit causes the character to be highlighted.
For control characters, the high bit sets up a field attribute causing
all following characters to be printed in a special way up to the next
field-setting character.  The field is defined by which bit is turned on
in the control character starting the field:

  bit  affect     character
   1   dim        C-a
   2   blink      C-b
   3   blank      C-d
   4   underline  C-h
   5   inverse    C-p

If the low bits are all off, a normal mode field is produced.  To get
combinition affects, take the bitwise-or of the characters using the
logior function.  If this produces one of the characters that can't be
sent, use C-o and C-n.

FIELD is an integer representing the field that the text is to be loaded
into: 1 for the top row (39 chars), 2 for the bottom row (78 chars),
3 for the bottom row when the shift key is being pressed (78 chars), and
4 for the bottom row independent of the shift key.  Also, the characters
'a' to 'p' are used in sequence for setting the function keys F6 to F16 and
shifted F6 to F10 (16 chars each).

Interactively, FIELD is the prefix arg and TEXT is prompted for."
  (interactive "sSend: \np")
  (if (string-match "[\C-@\C-a\C-?]" text)
      (error "illegal character in string"))
  (let ((c (cond ((= field 1) ?+)
		 ((= field 2) ?,)
		 ((or (= field 3) (= field 4)) ?-)
		 ((and (<= ?a field) (<= field ?p)) field)
		 (t (error "'%c': unrecognized field" field)))))
    (send-string-to-terminal
     (format "\e[>%c\C-a%s\C-a" c text))
    (if (= field 4)
	(send-string-to-terminal
	 (format "\e[>,\C-a%s\C-a" text)))))