From: steve@eowyn.gte.com (Steve Preston)
Newsgroups: comp.emacs
Subject: Re: emacs key bindings for the keypad
Date: 16 Dec 92 00:13:33 GMT
Organization: GTE Laboratories
In-reply-to: page@leadse5.UUCP's message of 11 Dec 92 01:44:29 GMT

>>>>> In article <19735@sunfse.ese.lmsc.lockheed.com>, page@leadse5.UUCP (Dan Page) writes:
> I have been trying furiously to map the keypad of my X terminal to
> emacs functions. Success has been spotty and not satisfactory. Mapping
> of the F1-F12 keys went off without a hitch using the sun-raw-map.
> However, my keypad is set to send a numeric value (or '.', or '-')
> when these keys are hit. So remapping the '5' key on the keypad also
> remaps the '5' key on the keyboard. Further, the PF1-PF4 keys seem to
> be dead when I am in emacs. I have successfully set the keypad to
> application mode when I am in an X window, but this somehow gets reset
> by emacs. I cannot find the equivalent of sun-raw-map that deals with
> the keypad. Calling all large brains to help me with this problem.

The problem is that, when running as an X client, emacs does not check
for "keypad" keysyms when a KeyPress event occurs.  It *does* check
for "function key" keysyms (at least on non-AIX machines).  There is
thus no way that emacs can know the difference between "keypad 5" and
regular "5".

I patched x11term to remedy this.  My emacs will act as if a keypad
key generates ESC O plus an alphabetic character.  This is what the
vt100 keypad keys transmit in keypad application mode.  Here is the
patch :
------------------------------cut here------------------------------
*** x11term.c.orig	Sat Oct 24 00:31:56 1992
--- x11term.c	Tue Dec 15 18:51:28 1992
***************
*** 1463,1468 ****
--- 1463,1528 ----
  #endif /* sun */
  	nbytes = strlen(mapping_buf);
        }
+       else if (IsKeypadKey(keysym)) {
+  	strcpy(mapping_buf,"\033O");  /* ESC - O (aka SS3) */
+  	switch (keysym) {
+  	case XK_KP_F1:
+  	  mapping_buf[2]='P';
+  	  break;
+  	case XK_KP_F2:
+  	  mapping_buf[2]='Q';
+  	  break;
+  	case XK_KP_F3:
+  	  mapping_buf[2]='R';
+  	  break;
+  	case XK_KP_F4:
+  	  mapping_buf[2]='S';
+  	  break;
+  	case XK_KP_Subtract:
+  	  mapping_buf[2]='m';
+  	  break;
+  	case XK_KP_Separator:
+  	  mapping_buf[2]='l';
+  	  break;
+  	case XK_KP_Enter:
+  	  mapping_buf[2]='e';
+  	  break;
+  	case XK_KP_Decimal:
+  	  mapping_buf[2]='n';
+  	  break;
+  	case XK_KP_0:
+  	  mapping_buf[2]='p';
+  	  break;
+  	case XK_KP_1:
+  	  mapping_buf[2]='q';
+  	  break;
+  	case XK_KP_2:
+  	  mapping_buf[2]='r';
+  	  break;
+  	case XK_KP_3:
+  	  mapping_buf[2]='s';
+  	  break;
+  	case XK_KP_4:
+  	  mapping_buf[2]='t';
+  	  break;
+  	case XK_KP_5:
+  	  mapping_buf[2]='u';
+  	  break;
+  	case XK_KP_6:
+  	  mapping_buf[2]='v';
+  	  break;
+  	case XK_KP_7:
+  	  mapping_buf[2]='w';
+  	  break;
+  	case XK_KP_8:
+  	  mapping_buf[2]='x';
+  	  break;
+  	case XK_KP_9:
+  	  mapping_buf[2]='y';
+  	  break;
+  	}
+  	nbytes = 3;
+       }
        else {
  #endif /* not AIX */
  	switch (keysym) {
------------------------------cut here------------------------------

And here are the relavent lines in my .emacs file

(setq load-path (cons  "/usr/local/emacs/emacs-lisp" load-path))
(setq term-setup-hook
 (function
  (lambda ()
    (if (eq window-system 'x)
	(progn (define-key mouse-map x-button-left 'x-mouse-ignore)
	       (define-key mouse-map x-button-middle 'x-mouse-set-point)
	       (define-key mouse-map x-button-right 'x-mouse-set-mark)
	       (load "term/x11.el")
	       )))))
(define-key function-keymap "8" 'scroll-one-line-down)
(define-key function-keymap "2" 'scroll-one-line-up)
(define-key function-keymap "5" 'goto-line)
(define-key function-keymap "3" 'forward-page-top)
(define-key function-keymap "9" 'backward-page-top)
(define-key function-keymap "7" 'top-of-window)
(define-key function-keymap "4" 'middle-of-window)
(define-key function-keymap "1" 'bottom-of-window)

The file x11.el to be loaded is just a cut-and-paste from vt100.el;
it should have the GPL header, like all the other FSF .el files.  I
put it into /usr/local/emacs/emacs-lisp/term/x11.el.

------------------------------x11.el------------------------------
;; Map VT100 function key escape sequences
;; into the standard slots in function-keymap.

(require 'keypad)

(defvar SS3-map nil
  "SS3-map maps the SS3 function keys on the VT100 keyboard.
The SS3 keys are the numeric keypad keys in keypad application mode
\(DECKPAM).  SS3 is DEC's name for the sequence <ESC>O which is
the common prefix of what these keys transmit.")

(if (not SS3-map)
    (progn

     (setq SS3-map (lookup-key global-map "\eO"))
     (if (not (keymapp SS3-map))
	 (setq SS3-map (make-keymap)))  ;; <ESC>O commands
     (setup-terminal-keymap SS3-map
	    '(("A" . ?u)	   ; up arrow
	      ("B" . ?d)	   ; down-arrow
	      ("C" . ?r)	   ; right-arrow
	      ("D" . ?l)	   ; left-arrow
	      ("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

     (define-key global-map "\eO" SS3-map)))

(global-set-key "\e[" nil)  ; so function keys can be remapped.
------------------------end of x11.el------------------------------
--
--
Steve Preston (spreston@gte.com)
Newsgroups: comp.emacs,gnu.emacs.help