From: jct@se33.wg2.waii.com (Jim Thompson)
Newsgroups: comp.emacs
Subject: Re: Sun arrow keys with meta and control?
Date: 27 Aug 92 12:25:50 GMT
Distribution: comp
Organization: Western Geophysical Exploration Products
In-reply-to: griffith@harris.earley.sns.neuphilologie.uni-tuebingen's message of 25 Aug 92 18:15:34 GMT

In article <GRIFFITH.92Aug25201534@harris.earley.sns.neuphilologie.uni-tuebingen> griffith@harris.earley.sns.neuphilologie.uni-tuebingen (John Griffith) writes:
> I asked this question a couple weeks ago but got no response
> so I'll try it once again before giving up.  I know how to
> rebind the Sun function keys (including arrows) to whatever function
> I want.  What I would like to do but have been unable to figure out is
> how to bind meta-up-arrow to something different than plain up-arrow.
> Is this possible?  It seems that meta-up-arrow and up-arrow and control-
> up-arrow all put out the same key code as far as emacs is concerned.

If you run inside of an xterm, you can get modified function keys.
Following is a short monograph I wrote for our local Epoch users to
describe a scheme I use for function keys; it should get you started.
The xterm translations that you'll need are at the end of the article.

Note that some people prefer to use C-c instead of ESC as the prefix
for the function keys, so that function keys don't confuse interactive
searches.  I prefer to use ESC so that my bindings work with the Sun
console on those occasions when I use it.

Hope this helps.

--

When I first started using Xemacs here I learned how to bind the
function keys on my Sun-4 keyboard to bits of elisp code.  But I also
wanted to get modifier information on the keys so that Shift-F1 would
invoke a different lisp function than (unmodified) F1;  ditto for
Meta-F1 and Control-F1.  (Emacs stands for Esc Meta Alt Control Shift,
you know.)  To do this in Xemacs, I had to modify the X event
processing in the C source code.

In Epoch, fortunately, setting up for modified function keys is much
easier because Epoch gives you access to X primitives.  You can do it
all in elisp, no C-source hacking necessary.  Here, then, are some
bits of elisp code that will allow Epoch to discriminate between
modified and unmodified function keys.

				* * *

Back when I first hacked up the C code for Xemacs I settled on a
scheme for the values (character strings) that would be returned by
modified function keys, and I have continued to use that scheme for
the Epoch-elisp version.  That scheme was based on the processing
already in place in Xemacs for function keys, and that processing was
in turn based on the character sequences emitted by the Sun console
for function keys.

The standard Sun sequences for function keys is as follows:

	ESC  [  0  0  0  z

where the digits 000 vary from key to key.  For example, F1 transmits 

	ESC  [  2  2  4  z.

There are some variations from this.  The num-lock key doesn't
transmit anything, nor does the Stop key, and the arrow keys transmit
sequences such as 

	ESC [ A

for up, with A being replaced by B, C, and D for down, right and left,
respectively.

In my scheme for numbering, however, I wanted to have access to every
key, and I wanted the values as consistent as possible.  So I overrode
the Sun-terminal standard and gave ESC-[-digit-digit-digit-z codes to
the arrow keys and the other "missing' keys.  Fortunately, the
numbering convention chosen by Sun was consistent, and deducing the
values to use for the missing keys was easy.

To encode modifier information, I chose to vary the terminating
letter, working my way backward through the alphabet.  Thus, Shift-
modified keys would transmit 'y' instead of 'z' as their terminal
letter, Control-modified keys, 'x', and Meta-modified keys, 'w'.  (I
did not make provisions for multiply-modified keys, but the same
scheme could be extended, with 'v' representing Shift-Control, etc.)

So the scheme, then is: ESC [ identies a function or special key,
three ASCII digits identify which key, and a terminal letter
identifies the modifier.

				* * *

Two sections of elisp code are needed to use the function keys.  The
first assigns character sequences to the keys, and the second assigns
character sequences to lisp functions.

[The first applies only to Epoch users, so I have deleted it for
 posting to comp.emacs.  To get modified function keys with vanilla
 emacs, you'll need to run inside of an xterm, and use the
 translations at the end of the article.]

				* * *

The second section of will vary greatly from person to person as
preferences for key functions vary.  The following code fragment comes
from my .emacs; I have deleted most of the actual define-key
statements for the sake of brevity.

;; This code shamelessly stolen from Jeff Peck's sun.el:
;;  Jeff Peck, Sun Microsystems Inc  <peck@sun.com>
;;

;; This function can be bound to unused keys
(defun unbound-key () (interactive))

;; Define a new keymap for the Sun function keys
(defvar sun-raw-map (make-sparse-keymap) "*Keymap for ESC-[ encoded keyboard")

;; Place bindings to useful functions into the new map
; Left group of function keys
(define-key sun-raw-map "233z" 'start-kbd-macro)	; F10
(define-key sun-raw-map "192z" 'end-kbd-macro)		; F11 & L1
(define-key sun-raw-map "193z" 'call-last-kbd-macro)	; L2
(define-key sun-raw-map "193y" 'repeat-complex-command) ; S-L2

; ... many other assignments deleted

;; Tell Emacs that "ESC-[" sequences should divert to the new map for
;; further interpretation
(define-key esc-map "[" sun-raw-map)

;; Keep the default bindings for the arrow keys, so this code can be
;; used with Epoch or with plain Emacs running in a Sun terminal
(define-key esc-map "[A" 'previous-line )		; R8
(define-key esc-map "[B" 'next-line)		; R14
(define-key esc-map "[C" 'forward-char)		; R12
(define-key esc-map "[D" 'backward-char)		; R10
(define-key esc-map "[[" 'backward-paragraph)	; the original esc-[

				* * *

My suggestions for using all this are as follows.  First, put the
entire first section into a file called "epokeys.el" and place this
file somewhere in your load-path.  Byte-compile epokeys.el; it won't
make a great deal of difference in the speed of loading, but it will
make you feel better.  In your .emacs, load epokeys if you're running
Epoch: 

(defvar in-epoch (boundp 'epoch::version))

(if in-epoch
    (progn
      (setq load-path (cons (expand-file-name "~/Epoch") load-path))
      (load "epokeys")

      ;; other epoch-specific processing

     ))

How to load the second bit of code depends upon personal preference;
I have the entire section in my .emacs, since I'm always running
either in Epoch or from a sun terminal.

Which reminds me, there's a set of translations that you can place in
your .Xdefaults to make your xterm function keys look like sunterm
function keys; by using it you still have access to modified function
keys even in xterm.  (Except for Meta-modified keys; for some reason,
I didn't include that set of definitions.  It wouldn't be hard to add,
though.)

				* * *

Place the following resource definition in your .Xdefaults:

xterm*vt100*Translations: #override \n\
		Shift	<Key>L1:	string("0x1b") string("[192y") \n\
		Shift	<Key>L2:	string("0x1b") string("[193y") \n\
		Shift	<Key>L3:	string("0x1b") string("[194y") \n\
		Shift	<Key>L4:	string("0x1b") string("[195y") \n\
		Shift	<Key>L5:	string("0x1b") string("[196y") \n\
		Shift	<Key>L6:	string("0x1b") string("[197y") \n\
		Shift	<Key>L7:	string("0x1b") string("[198y") \n\
		Shift	<Key>L8:	string("0x1b") string("[199y") \n\
		Shift	<Key>L9:	string("0x1b") string("[200y") \n\
		Shift	<Key>L10:	string("0x1b") string("[201y") \n\
		Shift	<Key>Help:	string("0x1b") string("[207y") \n\
		Shift	<Key>R1:	string("0x1b") string("[208y") \n\
		Shift	<Key>R2:	string("0x1b") string("[209y") \n\
		Shift	<Key>R3:	string("0x1b") string("[210y") \n\
		Shift	<Key>R4:	string("0x1b") string("[211y") \n\
		Shift	<Key>R5:	string("0x1b") string("[212y") \n\
		Shift	<Key>R6:	string("0x1b") string("[213y") \n\
		Shift	<Key>R7:	string("0x1b") string("[214y") \n\
		Shift	<Key>Up:	string("0x1b") string("[215y") \n\
		Shift	<Key>R9:	string("0x1b") string("[216y") \n\
		Shift	<Key>Left:	string("0x1b") string("[217y") \n\
		Shift	<Key>R11:	string("0x1b") string("[218y") \n\
		Shift	<Key>Right:	string("0x1b") string("[219y") \n\
		Shift	<Key>R13:	string("0x1b") string("[220y") \n\
		Shift	<Key>Down:	string("0x1b") string("[221y") \n\
		Shift	<Key>R15:	string("0x1b") string("[222y") \n\
		Shift	<Key>F1:	string("0x1b") string("[224y") \n\
		Shift	<Key>F2:	string("0x1b") string("[225y") \n\
		Shift	<Key>F3:	string("0x1b") string("[226y") \n\
		Shift	<Key>F4:	string("0x1b") string("[227y") \n\
		Shift	<Key>F5:	string("0x1b") string("[228y") \n\
		Shift	<Key>F6:	string("0x1b") string("[229y") \n\
		Shift	<Key>F7:	string("0x1b") string("[230y") \n\
		Shift	<Key>F8:	string("0x1b") string("[231y") \n\
		Shift	<Key>F9:	string("0x1b") string("[232y") \n\
		Shift	<Key>F10:	string("0x1b") string("[233y") \n\
		Shift	<Key>Insert:	  string("0x1b") string("[247y") \n\
		Shift	<Key>KP_Decimal:  string("0x1b") string("[249y") \n\
		Shift	<Key>KP_Enter:	  string("0x1b") string("[250y") \n\
		Shift	<Key>KP_Add:	  string("0x1b") string("[253y") \n\
		Shift	<Key>KP_Subtract: string("0x1b") string("[254y") \n\
		Shift	<Key>Num_Lock:	  string("0x1b") string("[255y") \n\
		Ctrl	<Key>L1:	string("0x1b") string("[192x") \n\
		Ctrl	<Key>L2:	string("0x1b") string("[193x") \n\
		Ctrl	<Key>L3:	string("0x1b") string("[194x") \n\
		Ctrl	<Key>L4:	string("0x1b") string("[195x") \n\
		Ctrl	<Key>L5:	string("0x1b") string("[196x") \n\
		Ctrl	<Key>L6:	string("0x1b") string("[197x") \n\
		Ctrl	<Key>L7:	string("0x1b") string("[198x") \n\
		Ctrl	<Key>L8:	string("0x1b") string("[199x") \n\
		Ctrl	<Key>L9:	string("0x1b") string("[200x") \n\
		Ctrl	<Key>L10:	string("0x1b") string("[201x") \n\
		Ctrl	<Key>Help:	string("0x1b") string("[207x") \n\
		Ctrl	<Key>R1:	string("0x1b") string("[208x") \n\
		Ctrl	<Key>R2:	string("0x1b") string("[209x") \n\
		Ctrl	<Key>R3:	string("0x1b") string("[210x") \n\
		Ctrl	<Key>R4:	string("0x1b") string("[211x") \n\
		Ctrl	<Key>R5:	string("0x1b") string("[212x") \n\
		Ctrl	<Key>R6:	string("0x1b") string("[213x") \n\
		Ctrl	<Key>R7:	string("0x1b") string("[214x") \n\
		Ctrl	<Key>Up:	string("0x1b") string("[215x") \n\
		Ctrl	<Key>R9:	string("0x1b") string("[216x") \n\
		Ctrl	<Key>Left:	string("0x1b") string("[217x") \n\
		Ctrl	<Key>R11:	string("0x1b") string("[218x") \n\
		Ctrl	<Key>Right:	string("0x1b") string("[219x") \n\
		Ctrl	<Key>R13:	string("0x1b") string("[220x") \n\
		Ctrl	<Key>Down:	string("0x1b") string("[221x") \n\
		Ctrl	<Key>R15:	string("0x1b") string("[222x") \n\
		Ctrl	<Key>F1:	string("0x1b") string("[224x") \n\
		Ctrl	<Key>F2:	string("0x1b") string("[225x") \n\
		Ctrl	<Key>F3:	string("0x1b") string("[226x") \n\
		Ctrl	<Key>F4:	string("0x1b") string("[227x") \n\
		Ctrl	<Key>F5:	string("0x1b") string("[228x") \n\
		Ctrl	<Key>F6:	string("0x1b") string("[229x") \n\
		Ctrl	<Key>F7:	string("0x1b") string("[230x") \n\
		Ctrl	<Key>F8:	string("0x1b") string("[231x") \n\
		Ctrl	<Key>F9:	string("0x1b") string("[232x") \n\
		Ctrl	<Key>F10:	string("0x1b") string("[233x") \n\
		Ctrl	<Key>Insert:	  string("0x1b") string("[247x") \n\
		Ctrl	<Key>KP_Decimal:  string("0x1b") string("[249x") \n\
		Ctrl	<Key>KP_Enter:	  string("0x1b") string("[250x") \n\
		Ctrl	<Key>KP_Add:	  string("0x1b") string("[253x") \n\
		Ctrl	<Key>KP_Subtract: string("0x1b") string("[254x") \n\
		Ctrl	<Key>Num_Lock:	  string("0x1b") string("[255x") \n\
			<Key>L1:	string("0x1b") string("[192z") \n\
			<Key>L2:	string("0x1b") string("[193z") \n\
			<Key>L3:	string("0x1b") string("[194z") \n\
			<Key>L4:	string("0x1b") string("[195z") \n\
			<Key>L5:	string("0x1b") string("[196z") \n\
			<Key>L6:	string("0x1b") string("[197z") \n\
			<Key>L7:	string("0x1b") string("[198z") \n\
			<Key>L8:	string("0x1b") string("[199z") \n\
			<Key>L9:	string("0x1b") string("[200z") \n\
			<Key>L10:	string("0x1b") string("[201z") \n\
			<Key>Help:	string("0x1b") string("[207z") \n\
			<Key>R1:	string("0x1b") string("[208z") \n\
			<Key>R2:	string("0x1b") string("[209z") \n\
			<Key>R3:	string("0x1b") string("[210z") \n\
			<Key>R4:	string("0x1b") string("[211z") \n\
			<Key>R5:	string("0x1b") string("[212z") \n\
			<Key>R6:	string("0x1b") string("[213z") \n\
			<Key>R7:	string("0x1b") string("[214z") \n\
			<Key>Up:	string("0x1b") string("[215z") \n\
			<Key>R9:	string("0x1b") string("[216z") \n\
			<Key>Left:	string("0x1b") string("[217z") \n\
			<Key>R11:	string("0x1b") string("[218z") \n\
			<Key>Right:	string("0x1b") string("[219z") \n\
			<Key>R13:	string("0x1b") string("[220z") \n\
			<Key>Down:	string("0x1b") string("[221z") \n\
			<Key>R15:	string("0x1b") string("[222z") \n\
			<Key>F1:	string("0x1b") string("[224z") \n\
			<Key>F2:	string("0x1b") string("[225z") \n\
			<Key>F3:	string("0x1b") string("[226z") \n\
			<Key>F4:	string("0x1b") string("[227z") \n\
			<Key>F5:	string("0x1b") string("[228z") \n\
			<Key>F6:	string("0x1b") string("[229z") \n\
			<Key>F7:	string("0x1b") string("[230z") \n\
			<Key>F8:	string("0x1b") string("[231z") \n\
			<Key>F9:	string("0x1b") string("[232z") \n\
			<Key>F10:	string("0x1b") string("[233z") \n\
			<Key>Insert:	  string("0x1b") string("[247z") \n\
			<Key>KP_Decimal:  string("0x1b") string("[249z") \n\
			<Key>KP_Enter:	  string("0x1b") string("[250z") \n\
			<Key>KP_Add:	  string("0x1b") string("[253z") \n\
			<Key>KP_Subtract: string("0x1b") string("[254z") \n\
			<Key>Num_Lock:	  string("0x1b") string("[255z") \n

--
   _    Jim Thompson           |  Wanted:
 _| ~-  thompson@wg2.waii.com  |	Nick Park's "Grand Day Out"
 \,  _} Western Geophysical    |	on VHS-format videotape
   \(   Houston, Texas         |  Email me if you know where I can buy it.