From brant@manta.UUCP Sat Jun 4 13:05:04 1988 >From brant Sat Jun 4 13:02:53 1988 To: gnu@prep.ai.mit.edu Subject: Gnu Emacs update for AT&T UNIXpc Date: 4 Jun 88 13:02:53 EDT (Sat) From: brant@manta.UUCP (Brant Cheikes) I've sent this stuff several times, and it's never shown up in the distribution. So here goes again. All this stuff is for Gnu Emacs. It all works as of 18.51. Enclosed please find: 1. A replacement for src/m-7300.h. This version is CORRECT. Don't believe what anyone else tells you! It works fine and allows a shared demand-paged executable to be dumped out. 2. Diffs to src/emacs.c and src/dispnew.c that enable Gnu Emacs to support use of the UNIXpc mouse. 3. A new lisp file, att-mouse.el, that enables editing with the UNIXpc mouse. Please add this stuff to the distribution, you make stick any license info you want on it. Let me know if there are any problems. ----- begin m-7300.h /* m- file for AT&T UNIX PC model 7300 Copyright (C) 1986 Free Software Foundation, Inc. Modified for this machine by mtxinu!rtech!gonzo!daveb Minor fixes by manta!brant (Brant Cheikes) This file is part of GNU Emacs. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the GNU Emacs General Public License for full details. Everyone is granted permission to copy, modify and redistribute GNU Emacs, but only under the conditions described in the GNU Emacs General Public License. A copy of this license is supposed to have been given to you along with GNU Emacs so you can know your rights and responsibilities. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. */ /* In Release 3.5 and later, flexnames are supported, so #undef SHORTNAMES. For prior releases, #define SHORTNAMES. */ #undef SHORTNAMES /* The following three symbols give information on the size of various data types. */ #define SHORTBITS 16 /* Number of bits in a short */ #define INTBITS 32 /* Number of bits in an int */ #define LONGBITS 32 /* Number of bits in a long */ /* Define BIG_ENDIAN iff lowest-numbered byte in a word is the most significant byte. */ #define BIG_ENDIAN /* XINT must explicitly sign-extend */ #define EXPLICIT_SIGN_EXTEND /* Define how to take a char and sign-extend into an int. On machines where char is signed, this is a no-op. */ #define SIGN_EXTEND_CHAR(c) (c) /* Use type int rather than a union, to represent Lisp_Object */ #define NO_UNION_TYPE /* Now define a symbol for the cpu type, if your compiler does not define it automatically: vax, m68000, ns16000 are the ones defined so far. */ # ifndef mc68k # define mc68k # endif #ifndef m68k #define m68k #endif /* Cause crt0.c to define errno. */ #define NEED_ERRNO /* Data type of load average, as read out of kmem. */ /* These are commented out since it is not supported by this machine. */ /* #define LOAD_AVE_TYPE long */ /* Convert that into an integer that is 100 for a load average of 1.0 */ /* #define LOAD_AVE_CVT(x) (int) (((double) (x)) * 100.0) */ /* we need this next line in order for emacs to run at all */ #define LD_SWITCH_MACHINE -s /* fix this bug */ #define SWITCH_ENUM_BUG /* so we can enable some local hacks */ #define C_SWITCH_MACHINE -DUNIXPC_MOUSE /* If you've got the PD pty driver installed, uncomment the following line. */ /* #define HAVE_PTYS */ #define NLIST_STRUCT #define SEGMENT_MASK 65535 #define SECTION_ALIGNMENT 1023 #define NO_REMAP ----- end m-7300.h ----- begin patches to emacs.c *** emacs.c.old Fri Jun 24 09:58:23 1988 --- emacs.c Fri Jun 24 13:45:41 1988 *************** *** 1,6 /* Fully extensible Emacs, running on Unix, intended for GNU. Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is distributed in the hope that it will be useful, --- 1,13 ----- /* Fully extensible Emacs, running on Unix, intended for GNU. Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc. + Added a few hacks for the AT&T Unix PC mouse. + 12 September 1987 + Brant A. Cheikes + ARPA: brant@linc.cis.upenn.edu + Department of Computer and Information Science + University of Pennsylvania + This file is part of GNU Emacs. GNU Emacs is distributed in the hope that it will be useful, *************** *** 61,66 on subsequent starts. */ int initialized; /* Variable whose value is symbol giving operating system type */ Lisp_Object Vsystem_type; --- 68,84 ----- on subsequent starts. */ int initialized; + #ifdef UNIXPC_MOUSE + /* + * If the AT&T Unix PC mouse will be supported, then we need a global + * variable to tell various routines when it's active. + * + * Note: we want this to be a Lisp var visible to the world, but we + * only want select_mouse_reports to actually modify it. + */ + int mouse_active = 0; + #endif + /* Variable whose value is symbol giving operating system type */ Lisp_Object Vsystem_type; *************** *** 63,69 /* Variable whose value is symbol giving operating system type */ Lisp_Object Vsystem_type; ! /* If non-zero, emacs should not attempt to use an window-specific code, but instead should use the virtual terminal under which it was started */ int inhibit_window_system; --- 81,87 ----- /* Variable whose value is symbol giving operating system type */ Lisp_Object Vsystem_type; ! /* If non-zero, emacs should not attempt to use an window-specific code, but instead should use the virtual terminal under which it was started */ int inhibit_window_system; *************** *** 468,473 NULL (answer))) return Qnil; #endif /* subprocesses */ } #ifdef subprocesses --- 486,495 ----- NULL (answer))) return Qnil; #endif /* subprocesses */ + + #ifdef UNIXPC_MOUSE + if (mouse_active) Fselect_mouse_reports(0); + #endif } #ifdef subprocesses *************** *** 601,604 DEFVAR_BOOL ("noninteractive", &noninteractive1, "Non-nil means Emacs is running without interactive terminal."); } --- 623,631 ----- DEFVAR_BOOL ("noninteractive", &noninteractive1, "Non-nil means Emacs is running without interactive terminal."); + + #ifdef UNIXPC_MOUSE + DEFVAR_BOOL ("3b1-mouse-active", &mouse_active, + "Non-nil means the AT&T Unix PC mouse is enabled and sending reports."); + #endif } ----- end patches to emacs.c ----- begin patches to dispnew.c *** dispnew.c.old Fri Jun 24 09:58:22 1988 --- dispnew.c Fri Jun 24 13:45:40 1988 *************** *** 1,6 /* Newly written part of redisplay code. Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is distributed in the hope that it will be useful, --- 1,13 ----- /* Newly written part of redisplay code. Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc. + Added some hacks to support mouse on AT&T Unix PC. + Brant A. Cheikes + 12 September 1987 + ARPA: brant@linc.cis.upenn.edu + Department of Computer and Information Science + University of Pennsylvania + This file is part of GNU Emacs. GNU Emacs is distributed in the hope that it will be useful, *************** *** 1168,1173 fflush (stdout); } DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 1, 0, "Pause, without updating display, for ARG seconds.") (n) --- 1175,1233 ----- fflush (stdout); } + #ifdef UNIXPC_MOUSE + #include + + extern mouse_active; /* controlled by select-mouse-reports */ + /* defined in emacs.c */ + + /* Define a Lisp function to enable/disable Unix PC mouse reports. + * Currently only allows button up/down selection. + */ + DEFUN("select-mouse-reports", Fselect_mouse_reports, + Sselect_mouse_reports, + 1, 1, "p", + "Enable or disable Unix PC mouse reports. FLAGS is um_flags value.\n\ + See window(7) for argument values.") + (flags) + Lisp_Object flags; + { + struct umdata mouse_state; + + /* + * This function does not set x,y,w,h fields, and so MSOUT, MSIN + * mouse reports will likely be invalid. + */ + (void) ioctl(0, WIOCGETMOUSE, &mouse_state); + mouse_state.um_flags = XFASTINT(flags); + (void) ioctl(0, WIOCSETMOUSE, &mouse_state); + if ( XFASTINT(flags) ) + mouse_active = Qt; + else + mouse_active = Qnil; + return Qnil; + } + + DEFUN ("window-pixel-sizes", Fwindow_pixel_sizes, Swindow_pixel_sizes, 0, 0, 0, + "Return a list of the pixel sizes for this bitmap window.\n\ + \(uw_x uw_y uw_width uw_height uw_uflags uw_hs uw_vs uw_baseline)\n\ + See window(7) for details of the uwdata structure.") + () + { + struct uwdata wd; + + (void) ioctl(0, WIOCGETD, &wd); + return Fcons (wd.uw_x, + Fcons (wd.uw_y, + Fcons (wd.uw_width, + Fcons (wd.uw_height, + Fcons (wd.uw_uflags, + Fcons (wd.uw_hs, + Fcons (wd.uw_vs, + Qnil))))))); + } + #endif + DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 1, 0, "Pause, without updating display, for ARG seconds.") (n) *************** *** 1365,1370 defsubr (&Ssleep_for); defsubr (&Sbaud_rate); defsubr (&Ssend_string_to_terminal); DEFVAR_BOOL ("inverse-video", &inverse_video, "*Non-nil means use inverse-video."); --- 1425,1434 ----- defsubr (&Ssleep_for); defsubr (&Sbaud_rate); defsubr (&Ssend_string_to_terminal); + #ifdef UNIXPC_MOUSE + defsubr (&Sselect_mouse_reports); + defsubr (&Swindow_pixel_sizes); + #endif DEFVAR_BOOL ("inverse-video", &inverse_video, "*Non-nil means use inverse-video."); ----- end patches to dispnew.c ----- begin att-mouse.el ;;; att-mouse.el ;;; GNU Emacs Lisp code for AT&T UNIXpc (PC7300/3B1) mouse support ;;; ;;; Brant A. Cheikes ;;; Last Edit: 25 December 1987 ;;; ;;; Department of Computer and Information Science ;;; University of Pennsylvania ;;; ARPA: brant@linc.cis.upenn.edu ;;; UUCP: ...drexel!manta!brant ;;; ;;; Based on BBN Bitgraph mouse support code (bg-mouse.el) by ;;; John Robinson (jr@bbn-unix.arpa, bbncca!jr), Oct 1985 ;;; ;;; This code requires the following primitive UNIXpc mouse support ;;; routines defined in src/dispnew.c: ;;; ;;; (window-pixel-sizes) ==> returns list of values of uwdata structure. ;;; (select-mouse-reports ) ==> activate mouse reports ;;; Documentation for mouse functions is in window(7). ;;; ;;; These routines will be compiled if the symbol UNIXPC_MOUSE is defined ;;; to the C preprocessor. ;;; ;;; Notes: ;;; 1. This code recognizes multi-button mouse click sequences! ;;; 2. kill-emacs in src/emacs.c has been modified so that emacs ;;; will turn off mouse reporting if necessary before exiting. ;;; 3. This code sets hooks so that suspending emacs temporarily ;;; stops mouse reporting. ;;; ;;; Usage: ;;; 1. Cause this file to be loaded, e.g., (load "att-mouse") ;;; 2. Eval (activate-att-mouse t). Mouse handling is now active. ;;; Eval (activate-att-mouse nil) to turn off the mouse handler. ;;; ;;; MOUSE OPERATIONS PROVIDED ;;; ;;; Within the currently active window: ;;; ;;; L-- move point ;;; --R set mark ;;; -C- move point and yank ;;; -CR kill-region ;;; L-R copy-region-as-kill ;;; ;;; On a window's modeline: ;;; ;;; L-- scroll-up ;;; --R scroll-down ;;; -C- proportional goto-char ;;; ;;; In the minibuffer (the area below the bottom-most modeline): ;;; ;;; L-- execute-extended-command ;;; --R evaluate-expression ;;; -C- suspend-emacs ;;; ;;; In the "Scroll Bar" (the rightmost screen column) ;;; ;;; L-- this line to top ;;; --R this line to bottom ;;; -C- this line to middle ;;; ;;; If the global variable att-mouse-fast-select-window is nil, any mouse ;;; click sequence on a deselected window just selects that window. (defvar att-mouse-fast-select-window nil "If non-nil, mouse clicks on a deselected window just select that window.") (defvar att-mouse-buttons-down nil "Stores code representing which mouse buttons went down during the current sequence of mouse clicks.") (defvar att-mouse-click-start-position nil "A cons (X . Y) of pixel coordinates (relative to window) at which the first mouse click of the current click sequence took place.") (defun activate-att-mouse (flag) "If FLAG is non-nil, enable Unix PC mouse reporting and activate the mouse handler. If nil, deactivate mouse processing." (interactive) (if flag ;; enable mouse handling (progn (select-mouse-reports 3) ; both MSDOWN/MSUP are reported ;; set hooks so suspend-emacs temporarily stops mouse reporting (setq suspend-hook '(lambda nil (select-mouse-reports 0)) suspend-resume-hook '(lambda nil (select-mouse-reports 3))) ;; Put the mouse report handler into the global keymap (let ((esc-map (lookup-key global-map "\e["))) (if (not (keymapp esc-map)) (setq esc-map (make-sparse-keymap))) ; [ map (define-key esc-map "?" 'att-mouse-report) (global-set-key "\e[" esc-map))) ;; disable mouse handling (progn (select-mouse-reports 0) ; turn them off (setq suspend-hook nil ; remove suspend hooks suspend-resume-hook nil) (let ((esc-map (lookup-key global-map "\e["))) (if (keymapp esc-map) (define-key esc-map "?" nil)))))) (defun att-mouse-report () "Read and parse AT&T Unix PC mouse report. If the report is MSUP and all buttons are up, then perform the requested function. This is essentially a fast 'interrupt service routine.' Only do serious processing if we find all mouse buttons have gone up." (interactive) (let* ((x-pos-pixel (get-att-mouse-value ?\;)) (y-pos-pixel (get-att-mouse-value ?\;)) (buttons (get-att-mouse-value ?\;)) (reason (get-att-mouse-value ?M))) (cond ((= reason 1) ; MSDOWN ;; ;; A mouse button went down. ;; Store the code away representing which buttons are down. ;; We won't act on the request until all buttons are up. This ;; is so we can distinguish multi-button mouse clicks. ;; (if att-mouse-buttons-down (setq att-mouse-buttons-down (logior att-mouse-buttons-down buttons)) (progn ;; initialize the buttons-down value and save ;; the pixel coordinates of this (initial) mouse click. ;; the idea is that if the mouse moves between the time ;; that the initial button goes down and the last button ;; goes up, only the first mouse position is used. (setq att-mouse-buttons-down buttons) (setq att-mouse-click-start-position (cons x-pos-pixel y-pos-pixel))))) ((= reason 2) ; MSUP ;; ;; A mouse button went up. If all buttons are now up, act ;; on the button click stored in att-mouse-buttons-down. ;; (cond ((and att-mouse-buttons-down (numberp buttons) (zerop buttons)) ;; ok, all buttons are up, let's act ;; unwind-protect keeps lower level errors from ;; leaving the mouse status variables in a funny state (unwind-protect (do-att-mouse-function att-mouse-buttons-down att-mouse-click-start-position) (setq att-mouse-buttons-down nil att-mouse-click-start-position nil)))))))) (defun do-att-mouse-function (buttons x-y-pos) "Execute the mouse function indexed by BUTTONS depending upon the location of the mouse click. X-Y-POS should be a cons (X . Y) of the (x,y) coordinates (in pixels) of the mouse cursor." (let* ((pixel-sizes (window-pixel-sizes)) ; need to determine size of chars (char-pixel-width (nth 5 pixel-sizes)) (char-pixel-height (nth 6 pixel-sizes)) (x-pos-char (min (1- (screen-width)) (/ (car x-y-pos) char-pixel-width))) (y-pos-char (/ (cdr x-y-pos) char-pixel-height)) (window (mouse-pos-to-window x-pos-char y-pos-char)) (edges (window-edges window)) (old-window (selected-window)) (in-minibuf-p (= y-pos-char (1- (screen-height)))) (same-window-p (and (not in-minibuf-p) (eq window old-window))) (in-scrollbar-p (>= x-pos-char (1- (nth 2 edges)))) (in-modeline-p (= y-pos-char (1- (nth 3 edges))))) (setq x-pos-char (- x-pos-char (nth 0 edges))) (setq y-pos-char (- y-pos-char (nth 1 edges))) (cond (in-modeline-p ; mouse clicks on a window's modeline (select-window window) (cond ((= buttons 4) ; L-- scroll up (scroll-up)) ((= buttons 1) ; --R scroll down (scroll-down)) ((= buttons 2) ; -C- proportional goto char (goto-char (/ (* x-pos-char (- (point-max) (point-min))) (1- (window-width)))) (beginning-of-line) (what-cursor-position))) (select-window old-window)) (in-scrollbar-p ; mouse clicks in the "Scroll Bar" (select-window window) (scroll-up (cond ((= buttons 4) ; L-- this line to top y-pos-char) ((= buttons 1) ; --R this line to bottom (+ y-pos-char (- 2 (window-height)))) ((= buttons 2) ; -C- this line to middle (/ (+ 2 y-pos-char y-pos-char (- (window-height))) 2)) (t 0))) (select-window old-window)) (same-window-p ; mouse clicks in the current window (cond ((= buttons 4) ; L-- move point (mouse-move-point-to-x-y x-pos-char y-pos-char)) ((= buttons 1) ; --R set-mark (push-mark) (mouse-move-point-to-x-y x-pos-char y-pos-char) (exchange-point-and-mark)) ((= buttons 2) ; -C- move to point and yank (mouse-move-point-to-x-y x-pos-char y-pos-char) (setq this-command 'yank) (yank)) ((= buttons 3) ; -CR kill region ;; set mark at mouse position (push-mark) (mouse-move-point-to-x-y x-pos-char y-pos-char) (exchange-point-and-mark) ;; delete region between point and mark (setq this-command 'kill-region) (kill-region (point) (mark))) ((= buttons 5) ; L-R copy region into kill buffer ;; set mark at mouse position (push-mark) (mouse-move-point-to-x-y x-pos-char y-pos-char) (exchange-point-and-mark) ;; copy region between point and mark (setq this-command 'copy-region-as-kill) (copy-region-as-kill (point) (mark))))) (in-minibuf-p ; mouse clicks in the minibuffer (cond ((= buttons 1) ; --L eval expression (call-interactively 'eval-expression)) ((= buttons 4) ; R-- execute extended command (call-interactively 'execute-extended-command)) ((= buttons 2) ; -C- suspend emacs (suspend-emacs)))) (t ; mouse clicks in another window (select-window window) (cond ((not att-mouse-fast-select-window)) ((= buttons 4) ; L-- move point (mouse-move-point-to-x-y x-pos-char y-pos-char)) ((= buttons 1) ; --R set mark (push-mark) (mouse-move-point-to-x-y x-pos-char y-pos-char) (exchange-point-and-mark)) ((= buttons 2) ; -C- move point and yank (mouse-move-point-to-x-y x-pos-char y-pos-char) (setq this-command 'yank) (yank))))))) (defun get-att-mouse-value (term-char) "Read from terminal until TERM-CHAR is read, and return intervening number. Upon non-numeric not matching TERM-CHAR, signal an error." (let ((num 0) (char (- (read-char) 48))) (while (and (>= char 0) (<= char 9)) (setq num (+ (* num 10) char)) (setq char (- (read-char) 48))) (or (eq term-char (+ char 48)) (error "Invalid data in mouse report")) num)) (defun mouse-move-point-to-x-y (x y) "Position cursor in window coordinates. X and Y are 0-based character positions in the window." (move-to-window-line y) (move-to-column x)) (defun mouse-pos-to-window (x y) "Return window corresponding to given screen coordinates. X and Y are 0-based character positions on the screen." (let ((edges (window-edges)) (window nil)) (while (and (not (eq window (selected-window))) (or (< y (nth 1 edges)) (>= y (nth 3 edges)) (< x (nth 0 edges)) (>= x (nth 2 edges)))) (setq window (next-window window)) (setq edges (window-edges window))) (or window (selected-window)))) ----- end att-mouse.el --- Brant Cheikes University of Pennsylvania Department of Computer and Information Science Internet: brant@manta.pha.pa.us, UUCP: bpa!manta!brant