diff options
| author | Nick Roberts | 2006-02-27 22:46:06 +0000 |
|---|---|---|
| committer | Nick Roberts | 2006-02-27 22:46:06 +0000 |
| commit | eff05ea122ad1b981118fa6b8262cd1fde74c2ba (patch) | |
| tree | 7fb6c445b39f63454845f3932d78070eb0661f96 | |
| parent | 0659521f758dffebc463e52277e8572dbcffa13d (diff) | |
| download | emacs-eff05ea122ad1b981118fa6b8262cd1fde74c2ba.tar.gz emacs-eff05ea122ad1b981118fa6b8262cd1fde74c2ba.zip | |
(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.
| -rw-r--r-- | lisp/t-mouse.el | 219 |
1 files changed, 91 insertions, 128 deletions
diff --git a/lisp/t-mouse.el b/lisp/t-mouse.el index 88f6ef1b12c..a1be0fbcf49 100644 --- a/lisp/t-mouse.el +++ b/lisp/t-mouse.el | |||
| @@ -1,19 +1,30 @@ | |||
| 1 | ;;; t-mouse.el --- mouse support within the text terminal | 1 | ;;; t-mouse.el --- mouse support within the text terminal |
| 2 | 2 | ||
| 3 | ;;; Copyright (C) 1994,1995 Alessandro Rubini <rubini@linux.it> | 3 | ;; Authors: Alessandro Rubini and Ian T Zimmerman |
| 4 | ;;; parts are by Ian T Zimmermann <itz@rahul.net>, 1995,1998 | 4 | ;; Maintainer: Nick Roberts <nickrob@gnu.org> |
| 5 | |||
| 6 | ;; Maintainer: gpm mailing list: gpm@prosa.it | ||
| 7 | ;; Keywords: mouse gpm linux | 5 | ;; Keywords: mouse gpm linux |
| 8 | 6 | ||
| 9 | ;;; This program is distributed in the hope that it will be useful, | 7 | ;; Copyright (C) 1994,1995 Alessandro Rubini <rubini@linux.it> |
| 10 | ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | 8 | ;; parts are by Ian T Zimmermann <itz@rahul.net>, 1995,1998 |
| 11 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 9 | ;; Copyright (C) 2006 |
| 12 | ;;; GNU General Public License for more details. | 10 | ;; Free Software Foundation, Inc. |
| 11 | |||
| 12 | ;; This file is part of GNU Emacs. | ||
| 13 | |||
| 14 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 15 | ;; it under the terms of the GNU General Public License as published by | ||
| 16 | ;; the Free Software Foundation; either version 2, or (at your option) | ||
| 17 | ;; any later version. | ||
| 18 | |||
| 19 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 20 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 21 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 22 | ;; GNU General Public License for more details. | ||
| 13 | 23 | ||
| 14 | ;;; You should have received a copy of the GNU General Public License | 24 | ;; You should have received a copy of the GNU General Public License |
| 15 | ;;; along with GNU Emacs; see the file COPYING. If not, write to | 25 | ;; along with GNU Emacs; see the file COPYING. If not, write to the |
| 16 | ;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 26 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 27 | ;; Boston, MA 02110-1301, USA. | ||
| 17 | 28 | ||
| 18 | ;;; Commentary: | 29 | ;;; Commentary: |
| 19 | 30 | ||
| @@ -23,11 +34,8 @@ | |||
| 23 | ;; The "gpm" server runs under Linux, so this package is rather | 34 | ;; The "gpm" server runs under Linux, so this package is rather |
| 24 | ;; Linux-dependent. | 35 | ;; Linux-dependent. |
| 25 | 36 | ||
| 26 | ;; Developed for GNU Emacs 19.34, likely won't work with many others | 37 | ;; Modified by Nick Roberts for Emacs 22. In particular, the mode-line is |
| 27 | ;; too much internals dependent cruft here. | 38 | ;; now position sensitive. |
| 28 | |||
| 29 | |||
| 30 | (require 'advice) | ||
| 31 | 39 | ||
| 32 | (defvar t-mouse-process nil | 40 | (defvar t-mouse-process nil |
| 33 | "Embeds the process which passes mouse events to emacs. | 41 | "Embeds the process which passes mouse events to emacs. |
| @@ -69,20 +77,19 @@ Useful for people who play strange games with their keyboard tables.") | |||
| 69 | (defun t-mouse-tty () | 77 | (defun t-mouse-tty () |
| 70 | "Returns number of virtual terminal Emacs is running on, as a string. | 78 | "Returns number of virtual terminal Emacs is running on, as a string. |
| 71 | For example, \"2\" for /dev/tty2." | 79 | For example, \"2\" for /dev/tty2." |
| 72 | (let ((buffer (generate-new-buffer "*t-mouse*"))) | 80 | (with-temp-buffer |
| 73 | (call-process "ps" nil buffer nil "h" (format "%s" (emacs-pid))) | 81 | (call-process "ps" nil t nil "h" (format "%s" (emacs-pid))) |
| 74 | (prog1 (save-excursion | 82 | (goto-char (point-min)) |
| 75 | (set-buffer buffer) | 83 | (if (or |
| 76 | (goto-char (point-min)) | 84 | ;; Many versions of "ps", all different.... |
| 77 | (if (or | 85 | (re-search-forward " +tty\\(.?[0-9a-f]\\)" nil t) |
| 78 | ;; Many versions of "ps", all different.... | 86 | (re-search-forward "p \\([0-9a-f]\\)" nil t) |
| 79 | (re-search-forward " +tty\\(.?[0-9a-f]\\)" nil t) | 87 | (re-search-forward "v0\\([0-9a-f]\\)" nil t) |
| 80 | (re-search-forward "p \\([0-9a-f]\\)" nil t) | 88 | (re-search-forward "[0-9]+ +\\([0-9]+\\)" nil t) |
| 81 | (re-search-forward "v0\\([0-9a-f]\\)" nil t) | 89 | (re-search-forward "[\\t ]*[0-9]+[\\t ]+\\([0-9]+\\)" nil t) |
| 82 | (re-search-forward "[0-9]+ +\\([0-9]+\\)" nil t) | 90 | (re-search-forward " +vc/\\(.?[0-9a-f]\\)" nil t) |
| 83 | (re-search-forward "[\\t ]*[0-9]+[\\t ]+\\([0-9]+\\)" nil t)) | 91 | (re-search-forward " +pts/\\(.?[0-9a-f]\\)" nil t)) |
| 84 | (buffer-substring (match-beginning 1) (match-end 1)))) | 92 | (buffer-substring (match-beginning 1) (match-end 1))))) |
| 85 | (kill-buffer buffer)))) | ||
| 86 | 93 | ||
| 87 | 94 | ||
| 88 | ;; due to a horrible kludge in Emacs' keymap handler | 95 | ;; due to a horrible kludge in Emacs' keymap handler |
| @@ -128,62 +135,34 @@ For example, \"2\" for /dev/tty2." | |||
| 128 | (put event-sym 'event-kind 'mouse-click))) | 135 | (put event-sym 'event-kind 'mouse-click))) |
| 129 | (setq all-sets (cdr all-sets)))) | 136 | (setq all-sets (cdr all-sets)))) |
| 130 | 137 | ||
| 131 | |||
| 132 | ;;; This fun is partly Copyright (C) 1994 Per Abrahamsen <abraham@iesd.auc.dk> | ||
| 133 | ;; This is basically a feeble attempt to mimic what the c function | ||
| 134 | ;; buffer_posn_from_coords in dispnew.c does. I wish that function | ||
| 135 | ;; were exported to Lisp. | ||
| 136 | |||
| 137 | (defun t-mouse-lispy-buffer-posn-from-coords (w col line) | ||
| 138 | "Return buffer position of character at COL and LINE within window W. | ||
| 139 | COL and LINE are glyph coordinates, relative to W topleft corner." | ||
| 140 | (save-window-excursion | ||
| 141 | (select-window w) | ||
| 142 | (save-excursion | ||
| 143 | (move-to-window-line line) | ||
| 144 | (move-to-column (+ col (current-column) | ||
| 145 | (if (not (window-minibuffer-p w)) 0 | ||
| 146 | (- (minibuffer-prompt-width))) | ||
| 147 | (max 0 (1- (window-hscroll))))) | ||
| 148 | (point)))) | ||
| 149 | |||
| 150 | ;; compute one element of the form (WINDOW BUFFERPOS (COL . ROW) TIMESTAMP) | ||
| 151 | |||
| 152 | (defun t-mouse-make-event-element (x-dot-y-avec-time) | 138 | (defun t-mouse-make-event-element (x-dot-y-avec-time) |
| 153 | (let* ((x-dot-y (nth 0 x-dot-y-avec-time)) | 139 | (let* ((x-dot-y (nth 0 x-dot-y-avec-time)) |
| 154 | (x (car x-dot-y)) | 140 | (x (car x-dot-y)) |
| 155 | (y (cdr x-dot-y)) | 141 | (y (cdr x-dot-y)) |
| 156 | (timestamp (nth 1 x-dot-y-avec-time)) | ||
| 157 | (w (window-at x y)) | 142 | (w (window-at x y)) |
| 158 | (left-top-right-bottom (window-edges w)) | 143 | (ltrb (window-edges w)) |
| 159 | (left (nth 0 left-top-right-bottom)) | 144 | (left (nth 0 ltrb)) |
| 160 | (top (nth 1 left-top-right-bottom)) | 145 | (top (nth 1 ltrb))) |
| 161 | (right (nth 2 left-top-right-bottom)) | 146 | (if w (posn-at-x-y (- x left) (- y top) w t) |
| 162 | (bottom (nth 3 left-top-right-bottom)) | 147 | (append (list nil 'menu-bar) (nthcdr 2 (posn-at-x-y x y w t)))))) |
| 163 | (coords-or-part (coordinates-in-window-p x-dot-y w))) | ||
| 164 | (cond | ||
| 165 | ((consp coords-or-part) | ||
| 166 | (let ((wx (car coords-or-part)) (wy (cdr coords-or-part))) | ||
| 167 | (if (< wx (- right left 1)) | ||
| 168 | (list w | ||
| 169 | (t-mouse-lispy-buffer-posn-from-coords w wx wy) | ||
| 170 | coords-or-part timestamp) | ||
| 171 | (list w 'vertical-scroll-bar | ||
| 172 | (cons (1+ wy) (- bottom top)) timestamp)))) | ||
| 173 | ((eq coords-or-part 'mode-line) | ||
| 174 | (list w 'mode-line (cons (- x left) 0) timestamp)) | ||
| 175 | ((eq coords-or-part 'vertical-line) | ||
| 176 | (list w 'vertical-line (cons 0 (- y top)) timestamp))))) | ||
| 177 | 148 | ||
| 178 | ;;; This fun is partly Copyright (C) 1994 Per Abrahamsen <abraham@iesd.auc.dk> | 149 | ;;; This fun is partly Copyright (C) 1994 Per Abrahamsen <abraham@iesd.auc.dk> |
| 179 | |||
| 180 | (defun t-mouse-make-event () | 150 | (defun t-mouse-make-event () |
| 181 | "Makes a Lisp style event from the contents of mouse input accumulator. | 151 | "Makes a Lisp style event from the contents of mouse input accumulator. |
| 182 | Also trims the accumulator by all the data used to build the event." | 152 | Also trims the accumulator by all the data used to build the event." |
| 183 | (let (ob (ob-pos (condition-case nil | 153 | (let (ob (ob-pos (condition-case nil |
| 184 | (read-from-string t-mouse-filter-accumulator) | 154 | (progn |
| 155 | ;; this test is just needed for Fedora Core 3 | ||
| 156 | (if (string-match "STILL RUNNING_1\n" | ||
| 157 | t-mouse-filter-accumulator) | ||
| 158 | (setq t-mouse-filter-accumulator | ||
| 159 | (substring | ||
| 160 | t-mouse-filter-accumulator (match-end 0)))) | ||
| 161 | (read-from-string t-mouse-filter-accumulator)) | ||
| 185 | (error nil)))) | 162 | (error nil)))) |
| 186 | (if (not ob-pos) nil | 163 | ;; this test is just needed for Fedora Core 3 |
| 164 | (if (or (eq (car ob-pos) 'STILL) (eq (car ob-pos) '***) (not ob-pos)) | ||
| 165 | nil | ||
| 187 | (setq ob (car ob-pos)) | 166 | (setq ob (car ob-pos)) |
| 188 | (setq t-mouse-filter-accumulator | 167 | (setq t-mouse-filter-accumulator |
| 189 | (substring t-mouse-filter-accumulator (cdr ob-pos))) | 168 | (substring t-mouse-filter-accumulator (cdr ob-pos))) |
| @@ -193,7 +172,6 @@ Also trims the accumulator by all the data used to build the event." | |||
| 193 | (let ((event-type (nth 0 ob)) | 172 | (let ((event-type (nth 0 ob)) |
| 194 | (current-xy-avec-time (nth 1 ob)) | 173 | (current-xy-avec-time (nth 1 ob)) |
| 195 | (type-switch (length ob))) | 174 | (type-switch (length ob))) |
| 196 | |||
| 197 | (if t-mouse-fix-21 | 175 | (if t-mouse-fix-21 |
| 198 | (let | 176 | (let |
| 199 | ;;Acquire the event's symbol's name. | 177 | ;;Acquire the event's symbol's name. |
| @@ -223,8 +201,6 @@ Also trims the accumulator by all the data used to build the event." | |||
| 223 | ;;events have many types but fortunately they differ in length | 201 | ;;events have many types but fortunately they differ in length |
| 224 | 202 | ||
| 225 | (cond | 203 | (cond |
| 226 | ;;sink all events on the stupid text mode menubar. | ||
| 227 | ((and menu-bar-mode (eq 0 (cdr t-mouse-current-xy))) nil) | ||
| 228 | ((= type-switch 4) ;must be drag | 204 | ((= type-switch 4) ;must be drag |
| 229 | (let ((count (nth 2 ob)) | 205 | (let ((count (nth 2 ob)) |
| 230 | (start-element | 206 | (start-element |
| @@ -250,7 +226,6 @@ Also trims the accumulator by all the data used to build the event." | |||
| 250 | 'mouse-movement) | 226 | 'mouse-movement) |
| 251 | (t-mouse-make-event-element current-xy-avec-time)))))))) | 227 | (t-mouse-make-event-element current-xy-avec-time)))))))) |
| 252 | 228 | ||
| 253 | |||
| 254 | (defun t-mouse-process-filter (proc string) | 229 | (defun t-mouse-process-filter (proc string) |
| 255 | (setq t-mouse-filter-accumulator | 230 | (setq t-mouse-filter-accumulator |
| 256 | (concat t-mouse-filter-accumulator string)) | 231 | (concat t-mouse-filter-accumulator string)) |
| @@ -264,29 +239,11 @@ Also trims the accumulator by all the data used to build the event." | |||
| 264 | (print unread-command-events t-mouse-debug-buffer)) | 239 | (print unread-command-events t-mouse-debug-buffer)) |
| 265 | (setq event (t-mouse-make-event))))) | 240 | (setq event (t-mouse-make-event))))) |
| 266 | 241 | ||
| 267 | 242 | (defun t-mouse-mouse-position-function (pos) | |
| 268 | ;; this overrides a C function which stupidly assumes (no X => no mouse) | ||
| 269 | (defadvice mouse-position (around t-mouse-mouse-position activate) | ||
| 270 | "Return the t-mouse-position unless running with a window system. | 243 | "Return the t-mouse-position unless running with a window system. |
| 271 | The (secret) scrollbar interface is not implemented yet." | 244 | The (secret) scrollbar interface is not implemented yet." |
| 272 | (if (not window-system) | 245 | (setcdr pos t-mouse-current-xy) |
| 273 | (setq ad-return-value | 246 | pos) |
| 274 | (cons (selected-frame) t-mouse-current-xy)) | ||
| 275 | ad-do-it)) | ||
| 276 | |||
| 277 | (setq mouse-sel-set-selection-function | ||
| 278 | (function (lambda (type value) | ||
| 279 | (if (not window-system) | ||
| 280 | (if (eq 'PRIMARY type) (kill-new value)) | ||
| 281 | (funcall t-mouse-prev-set-selection-function | ||
| 282 | type value))))) | ||
| 283 | |||
| 284 | (setq mouse-sel-get-selection-function | ||
| 285 | (function (lambda (type) | ||
| 286 | (if (not window-system) | ||
| 287 | (if (eq 'PRIMARY type) | ||
| 288 | (current-kill 0) "") | ||
| 289 | (funcall t-mouse-prev-get-selection-function type))))) | ||
| 290 | 247 | ||
| 291 | ;; It should be possible to just send SIGTSTP to the inferior with | 248 | ;; It should be possible to just send SIGTSTP to the inferior with |
| 292 | ;; stop-process. That doesn't work; mev receives the signal fine but | 249 | ;; stop-process. That doesn't work; mev receives the signal fine but |
| @@ -307,35 +264,41 @@ The (secret) scrollbar interface is not implemented yet." | |||
| 307 | ;(continue-process t-mouse-process) | 264 | ;(continue-process t-mouse-process) |
| 308 | (process-send-string t-mouse-process "pop\n"))))) | 265 | (process-send-string t-mouse-process "pop\n"))))) |
| 309 | 266 | ||
| 310 | 267 | ;;;###autoload | |
| 311 | ;;; User commands | 268 | (define-minor-mode t-mouse-mode |
| 312 | 269 | "Toggle t-mouse mode. | |
| 313 | (defun t-mouse-stop () | 270 | With prefix arg, turn t-mouse mode on iff arg is positive. |
| 314 | "Stop getting mouse events from an asynchronous process." | 271 | |
| 315 | (interactive) | 272 | Turn it on to use emacs mouse commands, and off to use t-mouse commands." |
| 316 | (delete-process t-mouse-process) | 273 | nil " Mouse" nil :global t |
| 317 | (setq t-mouse-process nil)) | 274 | (if t-mouse-mode |
| 318 | 275 | ;; Turn it on | |
| 319 | (defun t-mouse-run () | 276 | (unless window-system |
| 320 | "Starts getting a stream of mouse events from an asynchronous process. | 277 | ;; Starts getting a stream of mouse events from an asynchronous process. |
| 321 | Only works if Emacs is running on a virtual terminal without a window system. | 278 | ;; Only works if Emacs is running on a virtual terminal without a window system. |
| 322 | Returns the newly created asynchronous process." | 279 | (progn |
| 323 | (interactive) | 280 | (setq mouse-position-function #'t-mouse-mouse-position-function) |
| 324 | (let ((tty (t-mouse-tty)) | 281 | (let ((tty (t-mouse-tty)) |
| 325 | (process-connection-type t)) | 282 | (process-connection-type t)) |
| 326 | (if (or window-system (not (stringp tty))) | 283 | (if (not (stringp tty)) |
| 327 | (error "Run t-mouse on a virtual terminal without a window system")) | 284 | (error "Cannot find a virtual terminal.")) |
| 328 | (setq t-mouse-process | 285 | (setq t-mouse-process |
| 329 | (start-process "t-mouse" nil | 286 | (start-process "t-mouse" nil |
| 330 | "mev" "-i" "-E" "-C" tty | 287 | "mev" "-i" "-E" "-C" tty |
| 331 | (if t-mouse-swap-alt-keys | 288 | (if t-mouse-swap-alt-keys |
| 332 | "-M-leftAlt" "-M-rightAlt") | 289 | "-M-leftAlt" "-M-rightAlt") |
| 333 | "-e-move" "-dall" "-d-hard" | 290 | "-e-move" |
| 334 | "-f"))) | 291 | "-dall" "-d-hard" |
| 335 | (setq t-mouse-filter-accumulator "") | 292 | "-f"))) |
| 336 | (set-process-filter t-mouse-process 't-mouse-process-filter) | 293 | (setq t-mouse-filter-accumulator "") |
| 337 | (process-kill-without-query t-mouse-process) | 294 | (set-process-filter t-mouse-process 't-mouse-process-filter) |
| 338 | t-mouse-process) | 295 | ; use commented line instead for emacs 21.4 onwards |
| 296 | (process-kill-without-query t-mouse-process))) | ||
| 297 | ; (set-process-query-on-exit-flag t-mouse-process nil))) | ||
| 298 | ;; Turn it off | ||
| 299 | (setq mouse-position-function nil) | ||
| 300 | (delete-process t-mouse-process) | ||
| 301 | (setq t-mouse-process nil))) | ||
| 339 | 302 | ||
| 340 | (provide 't-mouse) | 303 | (provide 't-mouse) |
| 341 | 304 | ||