Mercurial > emacs
diff lisp/t-mouse.el @ 69189:ec62f416bd30
(t-mouse-tty): Use with-temp-buffer. Add more
terminal types.
(t-mouse-lispy-buffer-posn-from-coords): Remove. Use C
primitive...
(t-mouse-make-event-element): ...posn-at-x-y instead.
(t-mouse-make-event): Deal with Fedora Core 3.
(t-mouse-make-event): Don't sink the `stupid text mode menubar'.
(t-mouse-mouse-position-function): New function. Use it instead
of advising mouse-position.
(t-mouse-mode): New minor mode.
(t-mouse-stop, t-mouse-run): Remove. Use t-mouse-mode instead.
author | Nick Roberts <nickrob@snap.net.nz> |
---|---|
date | Mon, 27 Feb 2006 22:46:06 +0000 |
parents | ee54b3a792ff |
children | 4c0f4c81c362 |
line wrap: on
line diff
--- a/lisp/t-mouse.el Mon Feb 27 22:30:58 2006 +0000 +++ b/lisp/t-mouse.el Mon Feb 27 22:46:06 2006 +0000 @@ -1,19 +1,30 @@ ;;; t-mouse.el --- mouse support within the text terminal -;;; Copyright (C) 1994,1995 Alessandro Rubini <rubini@linux.it> -;;; parts are by Ian T Zimmermann <itz@rahul.net>, 1995,1998 - -;; Maintainer: gpm mailing list: gpm@prosa.it +;; Authors: Alessandro Rubini and Ian T Zimmerman +;; Maintainer: Nick Roberts <nickrob@gnu.org> ;; Keywords: mouse gpm linux -;;; This program is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;; GNU General Public License for more details. +;; Copyright (C) 1994,1995 Alessandro Rubini <rubini@linux.it> +;; parts are by Ian T Zimmermann <itz@rahul.net>, 1995,1998 +;; Copyright (C) 2006 +;; Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. -;;; You should have received a copy of the GNU General Public License -;;; along with GNU Emacs; see the file COPYING. If not, write to -;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. ;;; Commentary: @@ -23,11 +34,8 @@ ;; The "gpm" server runs under Linux, so this package is rather ;; Linux-dependent. -;; Developed for GNU Emacs 19.34, likely won't work with many others -;; too much internals dependent cruft here. - - -(require 'advice) +;; Modified by Nick Roberts for Emacs 22. In particular, the mode-line is +;; now position sensitive. (defvar t-mouse-process nil "Embeds the process which passes mouse events to emacs. @@ -69,20 +77,19 @@ (defun t-mouse-tty () "Returns number of virtual terminal Emacs is running on, as a string. For example, \"2\" for /dev/tty2." - (let ((buffer (generate-new-buffer "*t-mouse*"))) - (call-process "ps" nil buffer nil "h" (format "%s" (emacs-pid))) - (prog1 (save-excursion - (set-buffer buffer) - (goto-char (point-min)) - (if (or - ;; Many versions of "ps", all different.... - (re-search-forward " +tty\\(.?[0-9a-f]\\)" nil t) - (re-search-forward "p \\([0-9a-f]\\)" nil t) - (re-search-forward "v0\\([0-9a-f]\\)" nil t) - (re-search-forward "[0-9]+ +\\([0-9]+\\)" nil t) - (re-search-forward "[\\t ]*[0-9]+[\\t ]+\\([0-9]+\\)" nil t)) - (buffer-substring (match-beginning 1) (match-end 1)))) - (kill-buffer buffer)))) + (with-temp-buffer + (call-process "ps" nil t nil "h" (format "%s" (emacs-pid))) + (goto-char (point-min)) + (if (or + ;; Many versions of "ps", all different.... + (re-search-forward " +tty\\(.?[0-9a-f]\\)" nil t) + (re-search-forward "p \\([0-9a-f]\\)" nil t) + (re-search-forward "v0\\([0-9a-f]\\)" nil t) + (re-search-forward "[0-9]+ +\\([0-9]+\\)" nil t) + (re-search-forward "[\\t ]*[0-9]+[\\t ]+\\([0-9]+\\)" nil t) + (re-search-forward " +vc/\\(.?[0-9a-f]\\)" nil t) + (re-search-forward " +pts/\\(.?[0-9a-f]\\)" nil t)) + (buffer-substring (match-beginning 1) (match-end 1))))) ;; due to a horrible kludge in Emacs' keymap handler @@ -128,62 +135,34 @@ (put event-sym 'event-kind 'mouse-click))) (setq all-sets (cdr all-sets)))) - -;;; This fun is partly Copyright (C) 1994 Per Abrahamsen <abraham@iesd.auc.dk> -;; This is basically a feeble attempt to mimic what the c function -;; buffer_posn_from_coords in dispnew.c does. I wish that function -;; were exported to Lisp. - -(defun t-mouse-lispy-buffer-posn-from-coords (w col line) - "Return buffer position of character at COL and LINE within window W. -COL and LINE are glyph coordinates, relative to W topleft corner." - (save-window-excursion - (select-window w) - (save-excursion - (move-to-window-line line) - (move-to-column (+ col (current-column) - (if (not (window-minibuffer-p w)) 0 - (- (minibuffer-prompt-width))) - (max 0 (1- (window-hscroll))))) - (point)))) - -;; compute one element of the form (WINDOW BUFFERPOS (COL . ROW) TIMESTAMP) - (defun t-mouse-make-event-element (x-dot-y-avec-time) (let* ((x-dot-y (nth 0 x-dot-y-avec-time)) (x (car x-dot-y)) (y (cdr x-dot-y)) - (timestamp (nth 1 x-dot-y-avec-time)) (w (window-at x y)) - (left-top-right-bottom (window-edges w)) - (left (nth 0 left-top-right-bottom)) - (top (nth 1 left-top-right-bottom)) - (right (nth 2 left-top-right-bottom)) - (bottom (nth 3 left-top-right-bottom)) - (coords-or-part (coordinates-in-window-p x-dot-y w))) - (cond - ((consp coords-or-part) - (let ((wx (car coords-or-part)) (wy (cdr coords-or-part))) - (if (< wx (- right left 1)) - (list w - (t-mouse-lispy-buffer-posn-from-coords w wx wy) - coords-or-part timestamp) - (list w 'vertical-scroll-bar - (cons (1+ wy) (- bottom top)) timestamp)))) - ((eq coords-or-part 'mode-line) - (list w 'mode-line (cons (- x left) 0) timestamp)) - ((eq coords-or-part 'vertical-line) - (list w 'vertical-line (cons 0 (- y top)) timestamp))))) + (ltrb (window-edges w)) + (left (nth 0 ltrb)) + (top (nth 1 ltrb))) + (if w (posn-at-x-y (- x left) (- y top) w t) + (append (list nil 'menu-bar) (nthcdr 2 (posn-at-x-y x y w t)))))) ;;; This fun is partly Copyright (C) 1994 Per Abrahamsen <abraham@iesd.auc.dk> - (defun t-mouse-make-event () "Makes a Lisp style event from the contents of mouse input accumulator. Also trims the accumulator by all the data used to build the event." (let (ob (ob-pos (condition-case nil - (read-from-string t-mouse-filter-accumulator) + (progn + ;; this test is just needed for Fedora Core 3 + (if (string-match "STILL RUNNING_1\n" + t-mouse-filter-accumulator) + (setq t-mouse-filter-accumulator + (substring + t-mouse-filter-accumulator (match-end 0)))) + (read-from-string t-mouse-filter-accumulator)) (error nil)))) - (if (not ob-pos) nil + ;; this test is just needed for Fedora Core 3 + (if (or (eq (car ob-pos) 'STILL) (eq (car ob-pos) '***) (not ob-pos)) + nil (setq ob (car ob-pos)) (setq t-mouse-filter-accumulator (substring t-mouse-filter-accumulator (cdr ob-pos))) @@ -193,7 +172,6 @@ (let ((event-type (nth 0 ob)) (current-xy-avec-time (nth 1 ob)) (type-switch (length ob))) - (if t-mouse-fix-21 (let ;;Acquire the event's symbol's name. @@ -223,8 +201,6 @@ ;;events have many types but fortunately they differ in length (cond - ;;sink all events on the stupid text mode menubar. - ((and menu-bar-mode (eq 0 (cdr t-mouse-current-xy))) nil) ((= type-switch 4) ;must be drag (let ((count (nth 2 ob)) (start-element @@ -250,7 +226,6 @@ 'mouse-movement) (t-mouse-make-event-element current-xy-avec-time)))))))) - (defun t-mouse-process-filter (proc string) (setq t-mouse-filter-accumulator (concat t-mouse-filter-accumulator string)) @@ -264,29 +239,11 @@ (print unread-command-events t-mouse-debug-buffer)) (setq event (t-mouse-make-event))))) - -;; this overrides a C function which stupidly assumes (no X => no mouse) -(defadvice mouse-position (around t-mouse-mouse-position activate) +(defun t-mouse-mouse-position-function (pos) "Return the t-mouse-position unless running with a window system. The (secret) scrollbar interface is not implemented yet." - (if (not window-system) - (setq ad-return-value - (cons (selected-frame) t-mouse-current-xy)) - ad-do-it)) - -(setq mouse-sel-set-selection-function - (function (lambda (type value) - (if (not window-system) - (if (eq 'PRIMARY type) (kill-new value)) - (funcall t-mouse-prev-set-selection-function - type value))))) - -(setq mouse-sel-get-selection-function - (function (lambda (type) - (if (not window-system) - (if (eq 'PRIMARY type) - (current-kill 0) "") - (funcall t-mouse-prev-get-selection-function type))))) + (setcdr pos t-mouse-current-xy) + pos) ;; It should be possible to just send SIGTSTP to the inferior with ;; stop-process. That doesn't work; mev receives the signal fine but @@ -307,35 +264,41 @@ ;(continue-process t-mouse-process) (process-send-string t-mouse-process "pop\n"))))) - -;;; User commands - -(defun t-mouse-stop () - "Stop getting mouse events from an asynchronous process." - (interactive) - (delete-process t-mouse-process) - (setq t-mouse-process nil)) +;;;###autoload +(define-minor-mode t-mouse-mode + "Toggle t-mouse mode. +With prefix arg, turn t-mouse mode on iff arg is positive. -(defun t-mouse-run () - "Starts getting a stream of mouse events from an asynchronous process. -Only works if Emacs is running on a virtual terminal without a window system. -Returns the newly created asynchronous process." - (interactive) - (let ((tty (t-mouse-tty)) - (process-connection-type t)) - (if (or window-system (not (stringp tty))) - (error "Run t-mouse on a virtual terminal without a window system")) - (setq t-mouse-process - (start-process "t-mouse" nil - "mev" "-i" "-E" "-C" tty - (if t-mouse-swap-alt-keys - "-M-leftAlt" "-M-rightAlt") - "-e-move" "-dall" "-d-hard" - "-f"))) - (setq t-mouse-filter-accumulator "") - (set-process-filter t-mouse-process 't-mouse-process-filter) - (process-kill-without-query t-mouse-process) - t-mouse-process) +Turn it on to use emacs mouse commands, and off to use t-mouse commands." + nil " Mouse" nil :global t + (if t-mouse-mode + ;; Turn it on + (unless window-system + ;; Starts getting a stream of mouse events from an asynchronous process. + ;; Only works if Emacs is running on a virtual terminal without a window system. + (progn + (setq mouse-position-function #'t-mouse-mouse-position-function) + (let ((tty (t-mouse-tty)) + (process-connection-type t)) + (if (not (stringp tty)) + (error "Cannot find a virtual terminal.")) + (setq t-mouse-process + (start-process "t-mouse" nil + "mev" "-i" "-E" "-C" tty + (if t-mouse-swap-alt-keys + "-M-leftAlt" "-M-rightAlt") + "-e-move" + "-dall" "-d-hard" + "-f"))) + (setq t-mouse-filter-accumulator "") + (set-process-filter t-mouse-process 't-mouse-process-filter) +; use commented line instead for emacs 21.4 onwards + (process-kill-without-query t-mouse-process))) +; (set-process-query-on-exit-flag t-mouse-process nil))) + ;; Turn it off + (setq mouse-position-function nil) + (delete-process t-mouse-process) + (setq t-mouse-process nil))) (provide 't-mouse)