;;;; Stuff to bind X function keys on Sun. -- Eero Simoncelli. ;;;; Adapted for DECstation ;;;; Keys in X generate a "keycode" which X translates into a ;;;; "keysym". They keysyms are turned into strings (we call them ;;;; "keymapstring"s here) when they are fed to Emacs. These strings ;;;; always begin with ESC-[. This file allows you to set the mapping ;;;; between keysyms and functions, assuming the standard mapping from ;;;; keysyms to keymapstrings. The keycode to keysym binding can be ;;;; set by calling the function xmodmap with an arg which is a ;;;; filename containing lines of the form "keycode = ". ;;;; To print out the current bindings, call "xmodmap -pk". To see ;;;; what keycodes are associated with what keys, run the command xev. ;;;; This file doesn't bind any keys, except for the Help key. Use ;;;; the define-x-fn-key function to bind keys. Use the "Help" ;;;; key to get a list of the current bindings! ;;;; *** This should be rewritten to allow modifiers (i.e., shift, control, ;;;; meta). ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Use this to bind dec function keys when using X windows. (defun define-x-fn-key (keysym def) (let ((keymapstring (keysym-to-keymapstring keysym))) (if (stringp keymapstring) (define-key x-fn-key-map keymapstring def) (error "Unknown key symbol %s does not appear in keysym-keymapstring-alist." keysym)))) ;;; This will be bound to the "Help" key. ;;; *** Should list mouse bindings, too. (defun describe-x-fn-bindings () (interactive) (let ((alist keysym-keymapstring-alist) binding keysym) (with-output-to-temp-buffer "*Help*" (princ "X keysym bindings:\n") (princ "-----------------\n") (while alist (setq keysym (car (car alist))) (setq binding (lookup-key x-fn-key-map (cdr (car alist)))) (cond ((numberp binding) (princ (format " %s:\t no keymap entry for this key symbol!\n" keysym))) ((eq binding 'x-fn-key-unbound) nil) (t (princ (format " %s:\t %s\n" keysym binding)))) (setq alist (cdr alist)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar x-fn-key-map (make-sparse-keymap) "*Keymap for ESC-[ encoded keyboard") (defun keysym-to-keymapstring (keysym) (cdr (assoc keysym keysym-keymapstring-alist))) (defun keymapstring-to-keysym (keymapstring) (car (rassoc keymapstring keysym-keymapstring-alist))) ;;; Like assoc, but cdr of pairs in alist are tested (defun rassoc (key alist) (while (and alist (not (equal (cdr (car alist)) key))) (setq alist (cdr alist))) (car alist)) (defun x-fn-key-unbound () (interactive) (beep) (message "X keysym %s not bound. Bind it w/define-x-fn-key." (keymapstring-to-keysym (substring (this-command-keys) 2)))) ;;; This captures the default correspondence between keysyms and the ;;; keymapstrings that Emacs receives. These correspond to the ;;; keyboard on a sparc, ASSUMING THE DEFAULT XMODMAP, which can be ;;; altered as described above. This alist is used to build the ;;; x-fn-key-map. ;;; Note 1 -- don't try this at home,,, and don't ever bind a key to "" -- ;;; this redefines ESC [ which screws everything up.. royally. ;;; Note 2 -- although x11term.c has chars for everything, show-chars ;;; doesn't report any chars for Prior, Next,, etc. not sure why. (setq keysym-keymapstring-alist '( ("Find" . "1~") ("Insert" . "2~") ;; ("Multi_key" . "") ;REMOVE on kbd . 3~ ("Select" . "4~") ;; ("Prior" . "5~") ;PREV on kbd, 5~ ;; ("Next" . "") ;6~ ("F1" . "11~") ("F2" . "12~") ("F3" . "13~") ("F4" . "14~") ("F5" . "15~") ("F6" . "17~") ("F7" . "18~") ("F8" . "19~") ("F9" . "20~") ("F10" . "21~") ;; ("F11" . "ESC") ;mapped to ESC somewhere ("F12" . "24~") ("F13" . "25~") ("F14" . "26~") ("Help" . "28~") ;shows mappings ("Menu" . "29~") ("F17" . "31~") ("F18" . "32~") ("F19" . "33~") ("F20" . "34~") )) ;;; these are not defined on the DECstation kbd ie show-chars doesn't ;;; return anything. so you can't use them. ; ("KP_F1" . "") ; ("KP_F2" . "") ; ("KP_F3" . "") ; ("KP_F4" . "") ;;; Go through keysym-keymapstring-alist, adding an unbound entry to ;;; x-fn-key-map for all keys that are not already there. This ;;; way, the user can preset some of them and they will not be blown ;;; away. It is important to have an entry for each X keymapstring, since ;;; otherwise you get echoed in your buffer! (let ((the-map x-fn-key-map) (alist keysym-keymapstring-alist)) (while alist (cond ((symbolp (lookup-key the-map (cdr (car alist)))) ;already has an entry nil) ((equal (car (car alist)) "Help") (define-key the-map (cdr (car alist)) 'describe-x-fn-bindings)) (t (define-key the-map (cdr (car alist)) 'x-fn-key-unbound))) (setq alist (cdr alist))) (define-key esc-map "[" the-map)) ;install it for prefix "\M-[" ;;; Print out chars typed - useful for finding out what sequences are generated ;;; by mouse, or fn keys. ;;; Randal L. Schwartz (defun show-chars () "Displays characters typed, terminated by a 3-second timeout." (interactive) (let ((chars "") (inhibit-quit t)) (message "Enter characters, terminated by 3-second timeout.") (while (not (sit-for 3)) (setq chars (concat chars (list (read-char))) quit-flag nil)) ; quit-flag maybe set by C-g (message "Characters entered: %s" (key-description chars)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; These X keysyms are automatically converted by Emacs into something useful: ;;; X keysym emacs keymapstring ;;; --------- --------------- ;;; BackSpace "C-h" ;;; LineFeed LFD ;;; Clear "C-k" ;;; Escape ESC ;;; Left "C-b" ;;; Up "C-p" ;;; Right "C-f" ;;; Down "C-n" ;;; KP_Space " " ;;; KP_Enter CR ;;; KP_Separator "," ;;; KP_Add "+" ;;; KP_Subtract "-" ;;; And these are (unfortunately) mapped to the same string as the Help keysym ;;; Select "-1z" ;;; Print "-1z" ;;; ... etc ;;; These are ignored: ;;; Pause ;;; Multi_key ;;; ........etc