[comp.sources.misc] v04i031: GNU Emacs Mouse Editing on tty-5620 - Part 3 of 3

heiser@ethz.UUCP (Gernot Heiser) (08/13/88)

Posting-number: Volume 4, Issue 31
Submitted-by: "Gernot Heiser" <heiser@ethz.UUCP>
Archive-name: gnumacs-blit/Part3

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 3)."
# Contents:  emacs/mega-lilith.el emacs/mega-lilith.tex
# Wrapped by heiser@eiger on Sun Aug  7 14:16:02 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'emacs/mega-lilith.el' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'emacs/mega-lilith.el'\"
else
echo shar: Extracting \"'emacs/mega-lilith.el'\" \(22798 characters\)
sed "s/^X//" >'emacs/mega-lilith.el' <<'END_OF_FILE'
X;; GNU Emacs code for Teletype 5620 mouse.
X;; Copyright (C) Free Software Foundation Sept 1987.
X
X
X;; This file is part of GNU Emacs.
X
X;; Gnu Emacs is distributed in the hope that it will be useful,
X;; but WITHOUT ANY WARRANTY.  No author or distributor
X;; accepts responsibility to anyone for the consequences of using it
X;; or for whether it(se serves any particular purpose or works at all,
X;; unless he says so in writing. Refer to the GNU Emacs General Public
X;; License for full details.
X
X;; Everyone is granted permission to copy, modify and redistribute
X;; GNU Emacs, but only under the conditions described in the
X;; GNU Emacs General Public License.   A copy of this license is
X;; supposed to have been given to you along with GNU Emacs so you
X;; can know your rights and responsibilities.  It should be in a
X;; file named COPYING.  Among other things, the copyright notice
X;; and this notice must be preserved on all copies.
X
X
X;;; Author: paolo conti, September 1987 (conti@iis.uucp)
X;;; ideas stolen from the version for the BBN Bitgraph mouse by John Robinson
X
X(provide 'mega-lilith)
X
X(defconst selection ?S
X  "letter terminating selection events")
X
X(defconst click ?R
X  "letter terminating normal mouse events")
X
X(defconst compressed-click ?Q
X  "letter terminating compressed mouse events")
X
X(defconst layer-resized ?C
X  "letter terminating layer size events")
X
X(defconst resizing-event ?c
X  "letter terminating resizing events communicated autonomously by
X   the terminal")
X
X(defconst select 1
X  "reported by terminal for a selection event")
X
X(defconst copy 2
X  "reported by terminal for a copy event")
X
X(defconst delete 3
X  "reported by terminal for a delete event")
X
X(defconst move 4
X  "reported by terminal for a move event")
X
X(defun 5620-mouse-report ()
X  "called every time a mouse event has happened; it decodes the event and executes the required actions"
X  (interactive)
X  (let* ((event (5620-get-mouse-event))
X	 (type (car event))
X	 (parameters (cdr event)))
X    (cond
X      ((eq type selection)
X       (5620-handle-selection parameters))
X      ((eq type click)
X       (5620-handle-click parameters))
X      ((eq type compressed-click)
X       (5620-handle-compressed-click parameters))
X      ((eq type layer-resized)
X       (5620-resize-layer parameters))
X      ((eq type resizing-event)
X       (read-char)    ;; to flush the lf following the "c" in resizing events
X       (5620-redraw-display)))))
X
X(defun 5620-handle-selection (number-list)
X  "checks wether the selected region is legal (i.e. in one window or
Xin two abutting windows on the same buffer); if so, executes the requested
Xaction on the region (i.e. select, move, copy or delete)"
X  (let* ((y0 (car number-list))
X	 (x0 (nth 1 number-list))
X	 (y1 (nth 2 number-list))	 
X	 (x1 (nth 3 number-list))	 
X	 (action (nth 4 number-list))
X	 (window0 (5620-pos-to-window x0 y0))
X	 (window1 (5620-pos-to-window x1 y1))
X	 (edges0 (window-edges window0))
X	 (edges1 (window-edges window1))
X	 (top1-of-0 (eq (nth 3 edges0)
X			(nth 1 edges1)))
X	 (top0-of-1 (eq (nth 3 edges1)
X		        (nth 1 edges0))))
X    ;;; check for all possible invalid selections
X    (cond ((not (or (eq window0 window1) top0-of-1 top1-of-0))
X	   (error "invalid selection; windows don't abut"))
X	  ((not (eq (window-buffer window0) (window-buffer window1)))
X	   (error "invalid selection; windows not on same buffer"))
X          ((or (eq y0 (screen-height)) (eq y1 (screen-height)))
X           (error "invalid selection; selection ends in mini-buffer"))
X	  ((or (eq y0 (nth 3 edges0))
X	       (eq y1 (nth 3 edges1)))
X	   (error "invalid selection; selection ends in mode line"))
X	  ((or (= x0 0)
X	       (= x1 0))
X	   (error "invalid selection; selection ends in scroll bar"))
X    ;;; treat a valid selection
X	  (t
X	   (let ((old-window (selected-window))
X		 (old-point (point-marker))
X		 (window-x0 (1- (- x0 (nth 0 edges0))))
X		 (window-y0 (1- (- y0 (nth 1 edges0))))
X		 (window-x1 (1- (- x1 (nth 0 edges1))))
X		 (window-y1 (1- (- y1 (nth 1 edges1))))
X		 end-of-selection
X		 point-in-new-window)
X	     ;find and save end of selection
X	     (select-window window1)
X	     (5620-move-point-to-x-y window-x1 window-y1)
X	     (setq end-of-selection (point))
X	     ;go to start of selection
X	     (select-window window0)
X	     (setq point-in-new-window (point))
X	     (5620-move-point-to-x-y window-x0 window-y0)
X	     ;treat according to action
X	     (cond
X	      ((/= end-of-selection (point))
X	       (cond
X		((or (eq action select) (eq action copy))
X		 ; avoid appending in previous kill entry
X		 (setq last-command nil)
X		 (copy-region-as-kill (point) end-of-selection))
X		; case action move or delete
X		(t
X		 (setq last-command nil)
X		 (kill-region (point) end-of-selection)))
X	       (cond
X		((or (eq action copy) (eq action move))
X		 (select-window old-window)
X		 (goto-char (marker-position old-point))
X		 (setq this-command 'yank)
X		 (yank)
X		 (pop-mark)
X		 (princ ""))
X		((eq action select)
X		 (goto-char point-in-new-window)
X		 (select-window old-window)
X		 (goto-char (marker-position old-point)))))
X	      ;;; selection is empty;
X	      (t
X	       (push-mark end-of-selection)
X	       (goto-char point-in-new-window)
X	       (select-window old-window)
X	       (goto-char (marker-position old-point)))))))))
X
X
X;;; the following information may be accessed by the functions
X;;; bound to mouse events; these functions all don't take parameters
X;;; but access global variables
X
X(defvar buttons0 0
X  "buttons pressed for the current click event")
X
X(defvar x0
X  "screen column where a mouse button was last pressed")
X
X(defvar y0
X  "screen line where a mouse button was last pressed")
X
X(defvar window0
X  "window in which a mouse button was last pressed")
X
X(defvar site0
X  "site in which a mouse button was last pressed; sites include the scroll-bar,
Xthe mode-line etc")
X
X(defvar x1
X  "screen column where the mouse button(s) was (were) released")
X
X(defvar y1
X  "screen line where the mouse button(s) was (were) released")
X
X
X(defun 5620-handle-click (parameters)
X  "handles the mouse events which are not selection events; calls the function
Xbound to the given region of the screen and to the givenn buttons"
X  (let ((new-buttons (nth 2 parameters)))
X    (cond
X     ((= buttons0 0)
X      (setq buttons0 new-buttons)
X      (setq y0 (car parameters))
X      (setq x0 (nth 1 parameters))
X      (let ((site-info (5620-get-site-info x0 y0)))
X	(setq site0 (car site-info))
X	(setq window0 (nth 1 site-info))))
X     ((> new-buttons buttons0)
X      (setq buttons0 new-buttons))
X     ((= new-buttons 0)
X      (setq y1 (car parameters))
X      (setq x1 (nth 1 parameters))
X      (let ((action (aref (aref 5620-button-actions site0)
X			  (1- buttons0))))
X	(setq buttons0 0)
X	(cond
X	 ((not (null action))
X	  (funcall action))
X	 (t
X	  (error "Gaat's no? No action defined for those buttons")))))
X     ;;; some, but not all buttons released
X     (t nil))))
X
X
X(defun 5620-handle-compressed-click (parameters)
X  "handles the mouse events which are not selection events; calls the function
Xbound to the given region of the screen and to the given buttons"
X    (setq y0 (car parameters))
X    (setq x0 (nth 1 parameters))
X    (setq y1 (nth 2 parameters))
X    (setq x1 (nth 3 parameters))
X    (setq buttons0 (nth 4 parameters))
X    (let ((site-info (5620-get-site-info x0 y0)))
X      (setq site0 (car site-info))
X      (setq window0 (nth 1 site-info)))
X    (let ((action (aref (aref 5620-button-actions site0)
X			  (1- buttons0))))
X      (setq buttons0 0)
X      (cond
X	((not (null action))
X	 (funcall action))
X	(t
X	  (error "Gaat's no? No action defined for those buttons")))))
X
X(defun 5620-get-site-info (x y)
X  "returns a list with the site (scroll-bar, buffer-area etc) and with the
Xwindow the coordinates lie in"
X  (let* ((window (5620-pos-to-window x y))
X	 (edges (window-edges window))
X	 (site
X	  (cond
X	   ((= y (screen-height))
X	    (cond
X	     ((= x 0)
X	      echo-close-box)
X	     (t
X              echo-area)))
X	   ((= x 0)
X	    (cond
X	     ((= y (nth 3 edges))
X	      close-box)
X	     (t scroll-bar)))
X	   ((= y (nth 3 edges))
X	    mode-line)
X	   (t buffer-area))))
X    (list site window)))
X
X;;;
X;;; functions which may be bound to clicks in different sites
X;;;
X
X(defun 5620-scroll-up ()
X  "scrolls the line the mouse was clicked in to the top of its window" 
X  (let ((site-info (5620-get-site-info x1 y1))
X	(current-window (selected-window)))
X    (cond
X     ((and (eq (car site-info) scroll-bar)
X	   (eq (nth 1 site-info) window0))
X      (select-window window0)
X      (scroll-up (- y1 1 (nth 1 (window-edges window0))))
X      (select-window current-window)))))
X
X(defconst 5620-symmetric-scrolling nil
X  "*if nil, the action 5620-scroll-down is the perfect inverse of
X5620-scroll-up; otherwise the pointed line is scrolled to the bottom")
X
X(defun 5620-scroll-down ()
X  "scrolls down in the window the mouse was clicked in; the semantic depends
X on the value of the variable 5620-scroll-line-to-bottom"
X  (let ((site-info (5620-get-site-info x1 y1))
X	(current-window (selected-window)))
X    (cond
X     ((and (eq (car site-info) scroll-bar)
X	   (eq (nth 1 site-info) window0))
X      (select-window window0)
X      (cond
X       ((null 5620-symmetric-scrolling)
X	(scroll-up (- (1+ y1)  (nth 3 (window-edges window0)))))
X       (t (scroll-up (- (nth 1 (window-edges window0)) (1- y1)))))
X      (select-window current-window)))))
X
X(defun 5620-set-point ()
X  "selects the window where the mouse was clicked and sets it's point at
Xthe proper location"
X  (let ((site-info (5620-get-site-info x1 y1)))
X    (cond ((and (eq (car site-info) buffer-area)
X	        (eq (nth 1 site-info) window0))
X	   (select-window window0)
X	   (let ((edges0 (window-edges window0)))
X	     (5620-move-point-to-x-y
X	      (1- (- x1 (nth 0 edges0)))
X	      (1- (- y1 (nth 1 edges0)))))))))
X
X(defun 5620-yank ()
X  "inserts the top of the kill ring at point (and not at the location of
Xthe mouse click!); if the mouse was not clicked in the selected-window,
Xthe function does nothing"
X  (let ((site-info (5620-get-site-info x1 y1)))
X    (cond
X     ((and (eq (car site-info) buffer-area)
X	   (eq (nth 1 site-info) window0)
X	   (eq window0 (selected-window)))
X      (setq this-command 'yank)
X      (yank)))))
X
X(defun 5620-split-window ()
X  "splits the window in which the mouse was clicked at the line the click
Xoccured"
X  (let ((site-info (5620-get-site-info x1 y1))
X	(current-window (selected-window)))
X    (cond
X     ((and (eq (car site-info) scroll-bar)
X	   (eq (nth 1 site-info) window0))
X      (select-window window0)
X      (let ((edges0 (window-edges window0)))
X	(split-window-vertically (- y1 (nth 1 edges0)))
X	(select-window current-window))))))
X
X(defun 5620-move-border ()
X  "moves the border on which the mouse was pressed to the line the mouse
Xwas released. Allows to enlarge a window at the cost of its neighbour.
XThe neighbour window can't be killed with 5620-move-border. The echo area
Xcan't be enlarged with 5620-move-border."
X    (cond
X     ((and (eq site0 mode-line)
X	   (/= y0 (1- (screen-height))))
X      (let* ((current-window (selected-window))
X	     (edges0 (window-edges window0))
X	     (offset (- y1 (nth 3 edges0)))
X	     (enable
X	      (cond
X	       ((< offset 0)
X		(>= offset (- window-min-height (window-height window0))))
X	       ((> offset 0)
X		(<= offset
X		    (- (window-height (5620-pos-to-window x0 (1+ y0)))
X		       window-min-height))))))
X	(cond
X	 (enable
X	  (select-window window0)
X	  (enlarge-window offset)
X	  (cond
X	   ((window-point current-window)
X	    (select-window current-window)))))))))
X
X(defun 5620-flip-from-column ()
X  "displays in the window the part of the buffer corresponding to the ratio
Xbetween the column where the mouse was clicked and the number of columns of
Xthe screen. Flipping in the first column displays the top of the buffer, flipping
Xin the central column the central part of the buffer etc"
X  (let ((site-info (5620-get-site-info x1 y1))
X	(current-window (selected-window)))
X    (cond
X     ((and (eq (car site-info) site0)
X	   (eq (nth 1 site-info) window0))
X      (select-window window0)
X
X      ;; we'd like to have
X      ;; (goto-char (+ (point-min)
X      ;; 	     (/ (* (1- x1)
X      ;; 	       (- (point-max) (point-min)))
X      ;;	    (1- (window-width)))))
X      ;; but we must avoid the first multiplication in order to avoid
X      ;; an overflow for very long files;
X       (let* ((a (1- x1))
X	      (b (- (point-max) (point-min)))
X	      (c (1- (window-width)))
X	      (a_div_c (/ a c))
X	      (a_mod_c (% a c))
X	      (b_div_c (/ b c))
X	      (b_mod_c (% b c)))
X	 (goto-char ( + (point-min)
X			(+ (* c a_div_c b_div_c)
X			   (* a_div_c b_mod_c)
X			   (* a_mod_c b_div_c)
X			   (/ (* a_mod_c b_mod_c) c)))))
X      (select-window current-window)))))
X
X(defun 5620-flip-from-line ()
X  "displays in the window the part of the buffer corresponding to the ratio
Xbetween the window line where the mouse was clicked and the number of lines of
Xthe screen. Flipping in the top line displays the top of the buffer, flipping
Xin the middle of the window the central part of the buffer etc
XNote: 5620-flip-from-column will usually permit a more precise flipping, since most windows have much more columns than lines"
X  (let ((site-info (5620-get-site-info x1 y1))
X	(current-window (selected-window)))
X    (cond
X     ((and (eq (car site-info) site0)
X	   (eq (nth 1 site-info) window0))
X      (select-window window0)
X
X      ;; we'd like to have
X      ;; (goto-char ( + (point-min)
X      ;;	     (/ (* (1- (- y1 (nth 1 (window-edges))))
X      ;;	          (- (point-max) (point-min)))
X      ;;	       (-  (window-height) 2))))
X      ;; but we must avoid the first multiplication in order to avoid
X      ;; an overflow for very long files;
X       (let* ((a (1- (- y1 (nth 1 (window-edges)))))
X	      (b (- (point-max) (point-min)))
X	      (c (-  (window-height) 2))
X	      (a_div_c (/ a c))
X	      (a_mod_c (% a c))
X	      (b_div_c (/ b c))
X	      (b_mod_c (% b c)))
X	 (goto-char ( + (point-min)
X			(+ (* c a_div_c b_div_c)
X			   (* a_div_c b_mod_c)
X			   (* a_mod_c b_div_c)
X			   (/ (* a_mod_c b_mod_c) c)))))
X       (select-window current-window)))))
X
X(defun 5620-select-window ()
X  "makes the window the mouse was clicked in the active window"
X  (let ((site-info (5620-get-site-info x1 y1))
X	(current-window (selected-window)))
X    (cond
X     ((and (eq (car site-info) site0)
X	   (eq (nth 1 site-info) window0))
X      (select-window window0)))))
X
X(defun 5620-delete-window ()
X  "kills the window the mouse was clicked in"
X  (let ((site-info (5620-get-site-info x1 y1))
X	(current-window (selected-window)))
X    (cond
X     ((and (eq (car site-info) site0)
X	   (eq (nth 1 site-info) window0))
X      (delete-window window0)
X      (cond
X       ((window-point current-window)
X	(select-window current-window)))))))
X
X(defun 5620-select-minibuffer ()
X  "Selects the minibuffer if it is active"
X  (let ((edges (window-edges))
X	(window nil))
X    (while (and (not (eq window (selected-window)))
X		(>  (screen-height) (nth 3 edges)))
X      (setq window (next-window window))
X      (setq edges (window-edges window)))
X    (select-window window)))
X
X(defun 5620-find-forward ()
X  "Searches forward for the string in the kill ring"
X  (let ((search-string (car kill-ring)))
X    (cond
X     ((looking-at search-string)
X      (search-forward search-string)))
X    (search-forward search-string)))
X
X(defun 5620-find-backward ()
X  "Searches backward for the string in the kill ring."
X  (let ((search-string (car kill-ring))
X	(old-point (point)))
X    (search-backward search-string)
X    (cond
X     ((eq (length search-string)
X	  (- old-point (point)))
X      (search-backward search-string)))))
X
X(defun 5620-set-sam-scrolling ()
X  "Binds the buttons in the scroll-bar the same way the editor sam does"
X  (interactive)
X  (5620-bind-click 'right 'scroll-bar '5620-scroll-up)
X  (5620-bind-click 'left 'scroll-bar '5620-scroll-down)
X  (5620-bind-click 'middle 'scroll-bar '5620-flip-from-line)
X  (5620-bind-click 'left-middle 'scroll-bar '5620-split-window))
X
X(defun 5620-set-lilith-scrolling ()
X  "Binds the buttons in the scroll-bar the default way"
X  (interactive)
X  (5620-bind-click 'left 'scroll-bar '5620-scroll-up)
X  (5620-bind-click 'right 'scroll-bar '5620-scroll-down)
X  (5620-bind-click 'middle 'scroll-bar '5620-split-window))
X
X
X(defconst buffer-area 0
X  "*the whole Emacs window except its mode line")
X
X(defconst scroll-bar 1
X  "*the leftmost column of the screen")
X
X(defconst mode-line 2
X  "*the lowest line of an Emacs window (inverted)")
X
X(defconst close-box 3
X  "*the part of the scroll bar at the left of the mode line")
X
X(defconst echo-area 4
X  "*the bottom line of the screen or layer")
X
X(defconst echo-close-box 5
X  "*the part of the scroll bar at the left of the echo area") 
X
X(defun make-vector-7 ()
X  (vector nil nil nil nil nil nil nil))
X
X(defvar 5620-button-actions
X  (vector (make-vector-7) (make-vector-7) (make-vector-7)
X	  (make-vector-7) (make-vector-7) (make-vector-7)))
X
X
X(defconst right             1 "*")
X(defconst middle            2 "*")
X(defconst middle-right      3 "*")
X(defconst left              4 "*")
X(defconst left-right        5 "*")
X(defconst left-middle       6 "*")
X(defconst left-middle-right 7 "*")
X
X(defun 5620-bind-click (buttons-symbol site-symbol action)
X  "Binds BUTTONS clicked in SITE to the function ACTION"
X  (interactive "vButtons: \nvSite: \naAction: ")
X  (let((site (eval site-symbol))
X       (buttons (eval buttons-symbol)))
X    (if (and (integerp buttons) (> buttons 0) (< buttons 8))
X	(cond
X	 ((< site (length 5620-button-actions))
X	  (aset (aref 5620-button-actions site) (1- buttons) action))
X	 (t
X	  (error (concat site-symbol " is not a predefined site"))))
X      (error "buttons should be between 1 and 7"))))
X
X(5620-bind-click 'left 'scroll-bar '5620-scroll-up)
X(5620-bind-click 'right 'scroll-bar '5620-scroll-down)
X(5620-bind-click 'middle 'scroll-bar '5620-split-window)
X(5620-bind-click 'left 'buffer-area '5620-set-point)
X(5620-bind-click 'middle 'buffer-area '5620-yank)
X(5620-bind-click 'left 'close-box '5620-select-window)
X(5620-bind-click 'left-right 'close-box '5620-delete-window)
X(5620-bind-click 'middle 'mode-line '5620-move-border)
X(5620-bind-click 'left 'mode-line '5620-flip-from-column)
X(5620-bind-click 'left 'echo-area '5620-find-forward)
X(5620-bind-click 'middle 'echo-area '5620-find-backward)
X(5620-bind-click 'left 'echo-close-box '5620-select-minibuffer)
X
X(defun 5620-bind-selection-buttons (select-button copy-button)
X  "sets the SELECT-BUTTON and COPY-BUTTON; these must be different and
Xboth must be in {left, middle, right}; the delete button is set automatically
Xto the third button"
X  (interactive "vSelection Button: \nvCopy Button: ")
X  (setq select-button (eval select-button))
X  (setq copy-button (eval copy-button))
X  (cond
X   ((/= select-button copy-button)
X    (send-string-to-terminal
X     (concat "\e[?" 0 ";" select-button ";" copy-button "b")))
X   (t
X    (error "selection and copy button must be different"))))
X
X
X(defun 5620-get-tty-num ()
X  "Read an integer from terminal, and return a list with the char following
X   the int and the int"
X  (let
X      ((num 0)
X       (char (- (read-char) 48)))
X    (while (and (>= char 0)
X		(<= char 9))
X      (setq num (+ (* num 10) char))
X      (setq char (- (read-char) 48)))
X    (list (+ char 48) num)))
X
X(defun 5620-get-mouse-event ()
X  "Read a list of numbers from the terminal until one of them is not
X   terminated by a semi-colon and reports a list containing the numbers read"
X  (interactive)
X  (let ((result nil)
X	(next-item (5620-get-tty-num)))
X    (while
X	(= (car next-item) ?;)
X      (setq result (append result (cdr next-item)))
X      (setq next-item (5620-get-tty-num)))
X    (setq result (append result (cdr next-item)))
X    (cons (car next-item) result)))
X
X(defun 5620-move-point-to-x-y (x y)
X  "Position cursor in window coordinates.
XX and Y are 0-based character positions in the window."
X  (move-to-window-line y)
X  (move-to-column (+ (current-column)
X		     (min (- (window-width) 1) x))))
X
X(defun 5620-pos-to-window (x y)
X  "Find window corresponding to screen coordinates.
XX and Y are 1-based character positions on the screen."
X  (let ((edges (window-edges))
X	(window nil))
X    (setq x (max x 1))
X    (while (and (not (eq window (selected-window)))
X		(or (<= y (nth 1 edges))
X		    (>  y (nth 3 edges))
X		    (<= x (nth 0 edges))
X		    (>  x (nth 2 edges))))
X      (setq window (next-window window))
X      (setq edges (window-edges window)))
X    (or window (selected-window))))
X
X(defvar redraw-called-interacively nil
X  "tells wether 5620-redraw-display was called from the user, in which case
Xthe screen is redrawn at least once, or wether it was called after the
Xscreen size has been required, in which case the screen is redrawn only if
Xit's size has changed; the solution with the global variable is very ugly")
X
X(defun 5620-redraw-display ()
X  "refreshes the screen after having asked how big the layer currently is"
X  (interactive)
X  (setq redraw-called-interacively t)
X  (send-string-to-terminal "\e[?C"))
X
X(defun 5620-resize-layer (parameters)
X  (let ((new-height (nth 0 parameters))
X	(new-width (1- (nth 1 parameters)))
X	layer-resized)
X    (cond
X     ((/= new-height (screen-height))
X      (set-screen-height new-height)
X      (setq layer-resized t)))
X    (cond
X     ((/= new-width (screen-width))
X      (set-screen-width new-width)
X      (setq layer-resized t)))
X    (cond
X     ((and
X       redraw-called-interacively
X       (null layer-resized))
X      (redraw-display)))
X    (setq redraw-called-interacively nil)))
X
X(setq suspend-hook
X      (cond
X       ((and (boundp 'suspend-hook) suspend-hook)
X	(append suspend-hook '((send-string-to-terminal "\e[?0s"))))
X       (t
X        '(lambda ()
X	  (send-string-to-terminal "\e[?0s")))))
X
X(setq suspend-resume-hook
X      (cond
X       ((and (boundp 'suspend-resume-hook) suspend-resume-hook)
X	(append suspend-resume-hook '((send-string-to-terminal "\e[?1s")
X				      (send-string-to-terminal "\e[?C"))))
X       (t
X        '(lambda ()
X	   (send-string-to-terminal "\e[?1s")
X	   (send-string-to-terminal "\e[?C")))))
X
X;;;
X;;; send initialization strings to the terminal
X;;;
X
X;;; enable mouse
X(send-string-to-terminal "\e[?1m")
X
X;;; enable scroll-bar
X(send-string-to-terminal "\e[?1s")
X
X;;; take scroll bar in account
X(set-screen-width (1- (screen-width)))
X
X;;;define default selection and copy buttons
X(5620-bind-selection-buttons 'right 'middle)
X
X;;; unbind "\e[" if it is bound to a function, since otherwise
X;;; "\e[" can't be bound
X
X(let ((binding (global-key-binding "\e[")))
X  (cond
X   ((and (not (null binding))
X	 (not (keymapp binding)))
X    (global-unset-key "\e["))))
X;;
X;;
X;;
X(global-set-key "\e[?" '5620-mouse-report)
X;;
X;;; ask for current layer size
X;;
X(send-string-to-terminal "\e[?C")
X;;
X;;
X;;
X(run-hooks 'mega-lilith-hook)END_OF_FILE
if test 22798 -ne `wc -c <'emacs/mega-lilith.el'`; then
    echo shar: \"'emacs/mega-lilith.el'\" unpacked with wrong size!
fi
# end of 'emacs/mega-lilith.el'
fi
if test -f 'emacs/mega-lilith.tex' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'emacs/mega-lilith.tex'\"
else
echo shar: Extracting \"'emacs/mega-lilith.tex'\" \(26703 characters\)
sed "s/^X//" >'emacs/mega-lilith.tex' <<'END_OF_FILE'
X\hyphenation{}
X
X\documentstyle[A4,E,ETHtechreport,11pt,IIS]{article}
X\reportnumber{87/6}
X
X\begin{document}
X
X\title{Mega-Lilith: An Efficient Mouse Support for GNU Emacs
Xon the Teletype DMD 5620}
X
X\author{Paolo Conti\\Gernot Heiser}
X
X\maketitle
X
X\begin{abstract}
X
XA software package which provides advanced mouse support for the GNU
XEmacs editor on the Teletype DMD 5620 terminal is presented. It allows
Xthe user to perform the basic editing operations delete, copy, move,
Xsnarf and paste quickly and conveniently using the mouse.  All these
Xcommands can be executed in one step, even across windows and buffers.
XMoreover, searching and window managing operations can be performed
Xwith the mouse. The binding of different operations to particular
Xmouse events can be redefined by the user, thus shortening the
Xlearning period. The package consists of two parts: A terminal
Xemulator for the layers program sends to the host information about
Xmouse events and handles the appropriate inverting of selected
Xregions. A package of Emacs Lisp functions performs the appropriate
Xoperations.
X
X\end{abstract}
X
X\section{Introduction}
X
XThe present report describes a powerful interface between the GNU
XEmacs editor and the mouse of a Teletype DMD 5620 terminal. The
Xinterface consists of two parts: A terminal emulator running under
Xlayers provides the user with appropriate feedback about the attempted
Xediting operations and reports the user's intent to the host. A
Xpackage of Lisp functions performs the actual operations in Emacs.
X
XFrom previous programming experience we learned that when developing
Xor debugging a program, lot of time is spent in moving and copying
Xaround portions of source code. Hence, the most important feature of
Xthe mouse support for an editor is fast and convenient access to the
Xbasic operations delete, copy and move.  In particular, it should be
Xpossible to move or copy portions of text (single identifiers or whole
Xprocedures) from any place in the file and insert them at the current
Xinsertion point with as little repositioning of the mouse as possible.
XFor our implementation of these textual commands we have borrowed most
Xideas from the editors running on the Lilith computer [Gut], since
Xthey permit to rearrange portions of text in what we have found to be
Xan efficient way.
X
XFurther operations supported by the Mega-Lilith mouse interface
Xinclude creation, resizing, activation, deletion,
Xscrolling and flipping of Emacs windows, and searching for strings.
XAll that can be performed using nothing but the mouse.
X
XIn section 2, we explain the main properties of our mouse support for
XEmacs. Section 3 describes the implemented functionality in detail. It can
Xbe used as a user manual. Section 4 describes the terminal emulator
Xneeded to support mouse editing on the 5620 terminal. Appendix A
Xcontains a quick reference for the default settings of mouse commands,
Xappendix B a list of available functions that can be bound to mouse
Xevents and appendix C the Unix manual page of our terminal emulator.
X
X\section{Design concepts of the Mega-Lilith interface}
X
XThe Mega-Lilith interface meets the following requirements
Xfor textual operations: Deleting, copying and moving of text
Xcan be performed with a single mouse command, i.e. without
Xrepositioning of point in between. The destination of a copy or move
Xoperation needs not be in the same buffer or window as the source.
XFurthermore, the size of the text portion to be
Xselected must not necessarily fit on the screen or in one window.
XText can be selected across two windows, provided the windows where the
Xselection starts and ends display the same buffer. Hence,
Xcopying a procedure or a full paragraph from one buffer
Xto another is as fast and as easy as copying a single statement.
X
XThe implementation of these requirements forced a slight deviation
Xfrom the original Emacs philosophy: copying or moving portions of text
Xwithout repositioning point is not a standard Emacs feature. Since we
Xwant to insert a selected portion of text at the current location of
Xpoint, there is a difference between our notion of selected text and
Xthe usual Emacs notion of region. The Emacs region is delimited by
Xpoint and mark, which makes it impossible to select text without
Xmodifying the location of the insertion point. Conversely, our
Xselected text is delimited only by the mouse locations where the
Xselecting operation started and ended. Moreover, the selection may
Xextend over parts of two windows, something normally unknown in Emacs.
X
XA portion of text is selected by sweeping a part of the screen while
Xkeeping the selection button depressed. The selected text portion is
Xdisplayed in inverse video. The selected text can be deleted with the
Xdelete button, copied to the location of point with the copy button or
Xmoved (i.e. copied to the destination and deleted from the source) by
Xpressing both the delete and copy button. After each insertion, point
Xis left at the end of the inserted text. Hence portions of text can be
Xcollected from different places and inserted at the current insertion
Xposition without ever repositioning point. The selection, copy and
Xdelete buttons are predefined, but the user can change the bindings
Xaccording to taste.
X
XMega-Lilith allows to search forward and backward for the last
Xselected string. For example, when wondering about the meaning of the
Xparameters in a certain procedure call, the procedure's declaration
Xcan be found with just a few mouse clicks.
X
XSeveral other commands are bound to mouse events: the portion of text
Xdisplayed in a window can be changed with different scrolling and
Xflipping commands, and windows can be created, resized and deleted by
Xclicking the mouse in the appropriate screen areas.
X
XUser taylorability enhances the acceptance of a highly interactive
Xtool considerably. A programmer will be less reluctant to use a new
Xeditor if he or she can execute basic operations like positioning the
Xinsertion mark or scrolling up a window with the same mouse buttons
Xhe/she is used to. Hence, in Mega-Lilith, the binding of mouse buttons
Xto commands can be changed (even interactively) by the user. Moreover,
Xthe semantics of some operations depend on the settings of certain
Xflags, allowing the user to set up an environment similar to what
Xhe/she is used to.
X
XIn the design of our mouse interface we tried to minimize the amount
Xof information exchanged between the terminal and the host. This
Ximproves response times when working with low speed lines.  Once the
Xselection button has been pressed, the terminal autonomously does the
Xhighlighting of the selected region (in different patterns, according
Xto the type of the selection). Only after all buttons have been
Xreleased, the terminal emulator communicates to the host the screen
Xcoordinates of the start and end and the type of the selection.
X
X
X\section{Functionality of Mega-Lilith}
X
X\subsection{Setting point and moving text around}
X
XWith Mega-Lilith the insertion point can be set anywhere with the mouse. Text
Xdisplayed in Emacs windows can be deleted, copied or moved to another
Xlocation and/or saved in the kill ring with mouse operations. The mark
Xcan be set anywhere and the content of the kill ring can be inserted
Xat the location of point.
X
XTo {\em set point}, click the left button in the buffer area of an
XEmacs window. The {\em buffer area} consists of the full window except the
Xleftmost column or scroll bar and the lowest line or mode line. The
Xmode line is always displayed in inverse video, while the scroll bar
Xis separated from the remaining part of the window by a vertical line.
X
XSetting point in a window automatically selects it, i.e. makes it the current
Xwindow.
X
XIn order to {\em select} a portion of text for deletion, copy or move,
Xpress the right mouse button (or {\em selection button}) at the
Xbeginning of the text and release the button on the end of the text.
XThe selected text is displayed in inverse video. The operation
Xperformed on the selected text portion depends on which other buttons
Xwere pressed during the selection. In any case the selected region is
Xcopied to the kill ring.
X
XIf no other button is pressed during the selection, the result is a
Xplain selection.  Pressing the middle button (the {\em copy button})
Xduring the selection marks it a {\em copy selection}, pressing the
Xleft button (the {\em delete button}) produces a {\em delete
Xselection} and pressing both the copy and delete buttons a {\em move
Xselection} (move = copy + delete!).
X
XWhen the selection is completed, i.e. when all buttons have been released, the
Xoperation corresponding to the selection kind is performed. For a delete
Xselection this means the selected text is killed and point is set to the place
Xof the deletion. A copy selection inserts the selected text at the location of
Xpoint, moving point after the newly inserted text. Move works like copy except
Xthat the selected text is removed from its original place.
X
XIf a plain selection is {\em empty} (i.e. starts and ends at the same
Xposition) the {\em mark} is set to that position. This allows setting
Xthe mark to a character position by simply pointing to the character
Xwith the right mouse button (similiar to setting point). Empty copy,
Xdelete or move selections are no-ops, i.e. perform no operation.
X
XA non-empty plain selection does not modify the positions of point and mark.
XLike other kinds of selections it has the side effect of copying the selected
Xtext to the kill ring, as mentioned earlier.
X
XText needs not to be selected in the currently active
Xwindow. This allows to move or copy a portion of text from one window
Xto another, even from one buffer to another. Moreover, the
Xselection may span two windows, provided the windows abut and display
Xthe same buffer. This allows to select large portions of text
Xwhich don't fit into a window.
X
XThe selected region is highlighted according to the operation to be
Xperformed on it. While the contents of a plain selection are uniformly
Xdisplayed in inverse video, a copy selection has a {\em ragged top}, a
Xdelete selection a {\em ragged bottom}, and a move selection has both.
X
XSelection kinds can be changed arbirtarily as long as the selection
Xprocess is not finished. For example, releasing the copy button in a
Xcopy selection changes nothing, pressing it again transforms the
Xselection kind back to plain.  Similiar transformations are possible
Xby pressing and releasing other buttons.  To get used to the
Xmechanism, play a bit with the mouse while keeping the selection
Xbutton pressed and observe the highlighting.
X
XPreviously selected text can be {\em yanked} at the location of point
Xpressing the middle button. Nothing happens if the mouse click did not
Xoccur in the active window.
X
XNote that the current version does not support selections in the
Xminibuffer. That is somewhat unelegant and inconsistent but should not
Xrepresent a practical problem.
X
X\subsection{Scrolling and flipping}
X
XThe text displayed in an Emacs window can be scrolled up, scrolled
Xdown and flipped with mouse commands.
X
XTo {\em scroll} in a window, position the mouse in the {\em scroll
Xbar}, i.e. in the leftmost column of the screen, separated by a
Xvertical line. If the left button is clicked, the line which the mouse
Xpoints to is moved to the top of the window. Analogously, clicking the
Xright mouse button in the scroll bar moves the line where the mouse
Xwas clicked to the bottom of the screen. A previous part of the buffer
Xis shown in the window.
X
XTo display an arbitrary part of the buffer in a window, click the left
Xbutton in its {\em mode line}, i.e. its lowest, inverted line. Clicking in the
Xmiddle of the mode line displays the central part of the buffer,
Xclicking its rightmost column displays the end of the buffer etc. See
Xappendix B if you prefer the {\em flipping} operation to be bound to
Xsome button(s) in the scroll bar.
X
XSome editors, like {\em Sam}, let the operation scroll down be the perfect
Xinverse of scroll up. The number of lines scrolled down equals the
Xnumber of lines between the mouse position and the top (rather than
Xbottom) of the window. If your previously favorite editor scrolls in
Xthis way, set the Emacs variable {\tt 5620-symmetric-scrolling} to {\tt t}
X(see appendix B). If you really can't live without {\em Sam}'s scrolling
Xmechanism call the function {\tt 5620-set-sam-scrolling}. This will bind the
Xbuttons in the scroll bar the way {\em Sam} does: right for scrolling up,
Xleft for scrolling down (symmetrically) and middle for flipping.
X
X\subsection{Creating, deleting activating and resizing windows}
X
XEmacs windows can be splitted, resized, activated and deleted with the
Xmouse.
X
XTo {\em split} a window click the middle button in the window's scroll
Xbar. The window will be divided into two, with the upper one's mode
Xline lying where the mouse was clicked. The splitting will be
Xsuccessful only if the hight of both the resulting windows is greater
Xor equal to the variable {\tt window-min-heigth} (which defaults to 4).
X
XWindows can be {\em resized} by moving their mode line. Position the
Xmouse on the mode line, push the middle mouse button, move the mouse
Xup or down and release the button. The mode line will be moved to the
Xline where the mouse button was released, provided no window becomes
Xto small. The bottommost mode line cannot be moved: the echo area
Xcannot be resized this way.
X
XA window can be {\em selected} by clicking the left button in its {\em close box}
X(i.e. the part of the scroll bar to the left of the mode line). While
Xclicking in the buffer part of a window selects it and sets point
Xwhere the mouse was clicked, a click in its close box
Xactivates a window without modifying point.
X
XIf the minibuffer is active it can be selected by clicking the left
Xbutton in the {\em echo close box} (the part of the scroll bar to the left of
Xthe echo area). 
X
XA window can be {\em deleted} by clicking both the left and right mouse
Xbuttons (in either order) in its close box. The freed space is divided among the
Xremaining windows. Note that the same buttons are used for deleting text.
X
X\subsection{Searching}
X
XMega-Lilith allows to {\em search forward or backward} for strings without
Xtyping them in explicitly: clicking the left mouse button in the echo area of a
Xwindow makes the editor search for the string at the top of the kill ring.
XSince selected text is always copied to the kill
Xring, another occurrence of a particular string can be found by first selecting
Xit and then clicking the left button in the echo area. Clicking the middle
Xbutton works the same, except that the search goes backwards. Clicking again
Xsearches for the next occurence of the same string. This even works across
Xwindows: the search can be performed in a window different from the one where
Xthe string had been selected.
X
X\subsection{User taylorability and extendability}
X
XMega-Lilith allows for easy rebinding of mouse buttons (or combinations of
Xbuttons) to commands. Programmers familiar with Emacs Lisp can define new
Xcommands and bind these to mouse buttons in addition to (or in place of) the
Xexisting commands.
X
XCommands can be bound to buttons with the function {\tt
X5620-bind-click}, which takes as parameters the name of the button(s),
Xe.g. {\tt left} or {\tt left-middle-right} (in that order!), the site,
Xe.g.  {\tt scroll-bar}, {\tt mode-line}, {\tt buffer-area}, and the
Xname of the operation to be performed, e.g. {\tt 5620-scroll-up}, {\tt
X5620-scroll-down}. In order to disable an operation previously
Xenabled, bind the corresponding button(s) to nil.  See appendix B for
Xthe names of the sites, buttons and operations and appendix A for the
Xdefault bindings. {\tt 5620-bind-click} can be called either from your
X{\tt .emacs} file or interactively.
X
XThe function {\tt 5620-bind-selection-buttons} allows to define the
Xbuttons for the selection operations. It takes as arguments the
Xselection button and the copy button.  Both must be a single button;
X{\tt middle-left} for example is not a valid selection button.
XMoreover, for obvious reasons the selection button and the copy button
Xmust be different. The delete button is always set to the button which
Xis neither selection nor copy.
X
XThe selection button all by itself must not be bound to a
Xcommand with {\tt 5620-bind-\-click}, since every time the selection button is
Xthe first button pressed, a selection, not a mouse click, occurs.
XHowever, you may bind the selection button together with other buttons
Xto an operation. For example, the call {\tt (5620-bind-click 'middle-right
X'buffer-area 'set-point)} is legal even if the select button is set to
X{\tt right}. If the selection button is pressed first, the selection is
Xtreated; if the middle button is pressed first, the set-point command
Xis executed. Note that in the scroll bar no selections occur; hence the
Xscroll button can freely be bound there.
X
X\section{The terminal emulator {\em 5620\_mouse}}
X
XIn order to use Mega-Lilith, a terminal must be available which provides the
Xeditor with the required mouse information. To this end we wrote the
X5620\_mouse terminal emulator for the Teletype DMD 5620 terminal. This emulator
Xis written in {\em C} and cross-compiled on the Unix system into native code
Xfor the DMD's processor. It is downloaded to the terminal when the user
Xexecutes the shell script {\em 5620\_mouse}.  This section describes the
Xemulator from the user's point of view; for more detailed information, cf. the
XUnix manual page in appendix C.
X
X\subsection{General features}
X
XA layer into which 5620\_mouse has been downloaded behaves in most respects
Xlike a `plain' layer, i.e. one with no program downloaded into. Almost every
Xprogram that runs as a process connected to a plain layer should be able to run
Xin exactly the same way in connection with a 5620\_mouse layer.
X
XOutside any editor, the main difference between a plain layer and a 5620\_mouse
Xlayer is an additional menu appearing when pressing the middle mouse button. It
Xallows for two selections, one to toggle the layer display between {\em normal}
Xand {\em inverse video}, another to {\em clone} a new layer. Cloning is like
Xcreating a new layer; the only difference is that the cloned layer is itself a
X5620\_mouse layer and hence behaves as if 5620\_mouse had been downloaded into
Xit.
X
XCloning is also done automatically, immediately after 5620\_mouse has been
Xdownloaded into a layer. To this end, an {\em init file} can be specified as
Xfor the {\em layers} program. Contrary to layers, 5620\_mouse allows to specify
Xwindow sizes in character units. This is convenient when defining a window of,
Xsay, 80 columns width. Note, however, that the scrollbar reduces the usable
Xwindow size by one; in order to have 80 columns available for editing, the layer
Xwidth must be specified to be 81.
X
X\subsection{Display capabilities}
X
X5620\_mouse supports more advanced display capabilities than a plain layer (or
Xa 5620 without layers). In particular the function {\em Define Scrolling
XRegion} allows for faster scrolling in Emacs when several editor windows are
Xopen. This is because Emacs can now scroll windows individually; this not only
Xreduces the amount of screen updating to be performed by the terminal but also
Xthe amount of data the editor has to send, which is particularly important
Xwhen working over slow transmission lines.
X
X\subsection{Selections and mouse events}
X
XThe crucial difference between 5620\_mouse and a plain layer is the handling of
Xmouse button clicks when editing. To this end the editor instructs the terminal
Xto enter {\em open mode} and provide a scroll bar. The editor also informs the
Xterminal about the user's choice of the select and copy buttons.
X
XWhenever the user presses the selection button (other than in the
Xscroll bar) the terminal highlights the area of the screen which is textually in
Xbetween the point where the selection button was pressed and the current mouse
Xposition. If the user presses the copy or delete button during the selection,
Xthe terminal changes the selection feedback to reflect the selection kind as
Xdescribed in section 3. When the user finishes the selection by releasing all
Xmouse buttons, the terminal reverts the displayed text back to normal video. It
Xthen reports the start and end coordinates and the selection kind to the
Xeditor. An illegal selection, like releasing the mouse button(s) outside the
Xlayer, is reported as `invalid'.
X
XOther mouse clicks are reported immediately. The terminal communicates
Xto the editor the place of the mouse event and the state of the mouse
Xbuttons. The only feedback provided by the terminal in this case is a
Xshaded cursor indicating the character the user points to.
X
X\subsection{Setting up the terminal environment}
X
XThe program {\em mtermcap} is a companion of {\em 5620\_mouse}, used to set up
Xthe terminal environment for proper operation of all programs that make use of
Xterminal capabilities. It is automatically executed when {\em 5620\_mouse} is
Xloaded. The user is advised to run it whenever he/she performs a remote login
Xor after resizing a layer. For details on how to run {\em mtermcap}  cf. the
XUnix manual page in appendix C.
X
X\begin{thebibliography}{Gut}
X
X\bibitem[Gut]{Gut}J\"urg Gutknecht.
X{\em Concepts of the text editor Lara.}
XComm. ACM, Vol.28, September 1985, pp.942--960
X
X\end{thebibliography}
X
X\onecolumn
X
X\appendix
X\section{Mega-Lilith quick reference}
X
X
X\begin{center}
X{
X\large
X\vspace{5ex}
X
X{\Large \underline{Clicks}\\[5ex]} 
X\newlength{\maxcolwidth}
X\settowidth{\maxcolwidth}{search backward}
X\begin{tabular}{c|*{4}{p{\maxcolwidth}}}\\[0.5ex]
X   & left & middle & right & left-right \\[0.5ex] \hline
X  buffer area & set point & yank at point & \em{select} &  \\[0.5ex]
X  mode line & flip & move border &  &  \\[0.5ex]
X  scroll bar & scroll up & split window & scroll down &  \\[0.5ex]
X  close box & select window &  &  & delete window \\[0.5ex]
X  echo area & search forward & search backward &  &  \\[0.5ex]
X  echo close box & select minibuf & & & \\
X\end{tabular}
X
X\vspace{10ex}
X
X{\Large \underline{Selections}\\[5ex]} 
X
X\begin{tabular}{c|cccc} 
X  button(s) & right & middle-right & left-right & left-middle-right \\[0.5ex]
X  \hline
X  operation & select & copy & delete & move 
X\end{tabular}
X
X\vspace{10ex}
X} 
X\end{center}
X
X
X\section{Predefined constants, variables and functions}
X
X\subsection{Variables to be set by the user}
X
X\newcommand{\fn}[1]{{\tt`#1'}\\}
X
X\newcommand{\fnempty}[1]{{\tt`#1'}}
X
X\newenvironment{flist}{\begin{list}{}
X{\setlength{\leftmargin}{2.5cm} \setlength{\itemindent}{-2.5cm}}}%
X{\end{list}}
X
X
X\begin{flist}
X
X\item \fn{5620-symmetric-scrolling}
X*if nil, the command 5620-scroll-down is the perfect inverse of
X5620-scroll-up; otherwise the line pointed to is scrolled to the bottom
X\end{flist}
X
X\subsection{Functions to change default bindings}
X
X\begin{flist}
X
X\item \fn{5620-bind-click}
XBinds BUTTONS clicked in SITE to the function COMMAND
X
X\item \fn{5620-bind-selection-buttons}
Xsets the SELECT-BUTTON and COPY-BUTTON; these must be different and
Xand either left, middle or right; the delete button is set implicitely
Xto the remaining button
X
X\item \fn{5620-set-sam-scrolling}
Xbinds the buttons in the scroll-bar the same way the editor sam does:
Xthe right mouse button scrolls up, the left button scrolls down and the middle
Xbutton splits the window. The variable
X5620-symmetric-scrolling is set to nil. Hence scroll-down scrolls the pointed
Xline to the bottom of the window.
X
X\item \fn{5620-set-lilith-scrolling}
XBinds the buttons in the scroll-bar as they are bound per default:
Xthe left mouse button scrolls up, the right button scrolls down and the middle
Xbutton flips to the appropriate part of text. The variable
X5620-symmetric-scrolling is set to t. Moreover, the split operation
Xis bound to the buttons left-middle, which is not a sam feature.
X
X\end{flist}
X
X\subsection{Predefined button names}
X
X\begin{flist}
X
X\item \fnempty{left}
X
X\item \fnempty{middle}
X
X\item \fnempty{right}
X
X\item \fnempty{left-middle}
X
X\item \fnempty{left-right}
X
X\item \fnempty{middle-right}
X
X\item \fnempty{left-middle-right}
X
X\end{flist}
X
X\subsection{Predefined site names}
X
X\begin{flist}
X
X\item \fn{buffer-area}
X*the whole Emacs window except its mode line and scroll bar
X
X\item \fn{close-box}
X*the part of the scroll bar to the left of the mode line
X
X\item \fn{echo-area}
X*the bottom line of the screen or layer
X
X\item \fn{echo-close-box}
X*the part of the scroll bar to the left of the echo area
X
X\item \fn{mode-line}
X*the lowest line of an Emacs window (inverted)
X
X\item \fn{scroll-bar}
X*the leftmost column of the screen (empty and separated by a vertical line)
X
X\end{flist}
X
X\subsection{Predefined functions to be bound to mouse events}
X
X\begin{flist}
X
X\item \fn{5620-delete-window}
Xkills the window clicked with the mouse
X
X\item \fn{5620-find-backward}
XSearches backward for the string in the kill ring
X
X\item \fn{5620-flip-from-column}
Xdisplays in the window the part of the buffer corresponding to the ratio
Xbetween the column where the mouse was clicked and the number of columns in
Xthe window. Flipping in the first column displays the top of the buffer, flipping
Xin the central column the central part of the buffer etc
X
X\item \fn{5620-flip-from-line}
Xdisplays in the window the part of the buffer corresponding to the ratio
Xbetween the window line where the mouse was clicked and the number of lines of
Xthe screen. Flipping in the top line displays the top of the buffer, fliping
Xin the middle of the window the middle part of the buffer etc.
XNote: 5620-flip-from-column will usually permit a more precise flipping, since
Xmost windows have much more columns than lines
X
X\item \fn{5620-move-border}
Xmoves the border on which the mouse was pressed to the line the mouse
Xwas released. Allows to enlarge a window at its neighbour's expense.
XThe neighbour window can't be killed with 5620-move-border. The echo area
Xcan't be resized with 5620-move-border.
X
X\item \fn{5620-scroll-up}
Xscrolls the line in which the mouse was clicked to the top of its window
X
X\item \fn{5620-scroll-down}
Xscrolls down in the window clicked with the mouse; the semantics depends
X on the value of the variable 5620-scroll-line-to-bottom
X
X\item \fn{5620-select-minibuffer}
XSelects the minibuffer if it is active
X
X\item \fn{5620-select-window}
Xselects the window in which the mouse was clicked
X
X\item \fn{5620-set-point}
Xselects the window in which the mouse was clicked and sets point
X
X\item \fn{5620-split-window}
Xsplits the window in which the mouse was clicked at the line of the click
X
X\item \fn{5620-redraw-display}
Xrefreshes the screen after having asked how big the layer currently is
X
X\item \fn{5620-yank}
Xinserts the top of the kill ring at point
X
X\end{flist}
X
X\end{document}
END_OF_FILE
if test 26703 -ne `wc -c <'emacs/mega-lilith.tex'`; then
    echo shar: \"'emacs/mega-lilith.tex'\" unpacked with wrong size!
fi
chmod +x 'emacs/mega-lilith.tex'
# end of 'emacs/mega-lilith.tex'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Gernot Heiser <heiser@iis.UUCP> Phone:       +41 1/256 23 48
Integrated Systems Laboratory   CSNET/ARPA:  heiser%ifi.ethz.ch@relay.cs.net
ETH Zuerich                     EARN/BITNET: GRIDFILE@CZHETH5A
CH-8092 Zuerich, Switzerland    EUNET/UUCP:  {uunet,mcvax,...}!iis!heiser