From 63408057e7b8f8f9e04fa689117c75b498406daf Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sat, 14 Jul 2012 23:40:12 +0800 Subject: [PATCH] * xt-mouse.el: Implement extended mouse coordinates. (xterm-mouse-translate): Move code into xterm-mouse-translate-1. (xterm-mouse-translate-extended, xterm-mouse-translate-1) (xterm-mouse--read-event-sequence-1000) (xterm-mouse--read-event-sequence-1006): New functions. For old mouse protocol, handle M-mouse-X events correctly. (xterm-mouse-event): New arg specifying mouse protocol. (turn-on-xterm-mouse-tracking-on-terminal) (turn-off-xterm-mouse-tracking-on-terminal): Send DEC 1006 sequence to toggle extended coordinates on newer XTerms. This appears to be harmless on terminals which do not support this. Fixes: debbugs:10642 --- lisp/ChangeLog | 14 +++++ lisp/xt-mouse.el | 179 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 139 insertions(+), 54 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 8fee2598235..7bb09181b96 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,17 @@ +2012-07-14 Chong Yidong + + * xt-mouse.el: Implement extended mouse coordinates (Bug#10642). + (xterm-mouse-translate): Move code into xterm-mouse-translate-1. + (xterm-mouse-translate-extended, xterm-mouse-translate-1) + (xterm-mouse--read-event-sequence-1000) + (xterm-mouse--read-event-sequence-1006): New functions. For old + mouse protocol, handle M-mouse-X events correctly. + (xterm-mouse-event): New arg specifying mouse protocol. + (turn-on-xterm-mouse-tracking-on-terminal) + (turn-off-xterm-mouse-tracking-on-terminal): Send DEC 1006 + sequence to toggle extended coordinates on newer XTerms. This + appears to be harmless on terminals which do not support this. + 2012-07-14 Leo Liu Add fringe bitmap indicators for flymake. (Bug#11253) diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el index 06d82870f8c..3c2a3c57c78 100644 --- a/lisp/xt-mouse.el +++ b/lisp/xt-mouse.el @@ -47,33 +47,49 @@ ;; Mouse events symbols must have an 'event-kind property with ;; the value 'mouse-click. (dolist (event-type '(mouse-1 mouse-2 mouse-3 - M-down-mouse-1 M-down-mouse-2 M-down-mouse-3)) + M-down-mouse-1 M-down-mouse-2 M-down-mouse-3)) (put event-type 'event-kind 'mouse-click)) (defun xterm-mouse-translate (_event) "Read a click and release event from XTerm." + (xterm-mouse-translate-1)) + +(defun xterm-mouse-translate-extended (_event) + "Read a click and release event from XTerm. +Similar to `xterm-mouse-translate', but using the \"1006\" +extension, which supports coordinates >= 231 (see +http://invisible-island.net/xterm/ctlseqs/ctlseqs.html)." + (xterm-mouse-translate-1 1006)) + +(defun xterm-mouse-translate-1 (&optional extension) (save-excursion (save-window-excursion (deactivate-mark) - (let* ((xterm-mouse-last) - (down (xterm-mouse-event)) + (let* ((xterm-mouse-last nil) + (down (xterm-mouse-event extension)) (down-command (nth 0 down)) - (down-data (nth 1 down)) - (down-where (nth 1 down-data)) + (down-data (nth 1 down)) + (down-where (nth 1 down-data)) (down-binding (key-binding (if (symbolp down-where) (vector down-where down-command) (vector down-command)))) (is-click (string-match "^mouse" (symbol-name (car down))))) + ;; Retrieve the expected preface for the up-event. (unless is-click - (unless (and (eq (read-char) ?\e) - (eq (read-char) ?\[) - (eq (read-char) ?M)) + (unless (cond ((null extension) + (and (eq (read-char) ?\e) + (eq (read-char) ?\[) + (eq (read-char) ?M))) + ((eq extension 1006) + (and (eq (read-char) ?\e) + (eq (read-char) ?\[) + (eq (read-char) ?<)))) (error "Unexpected escape sequence from XTerm"))) - (let* ((click (if is-click down (xterm-mouse-event))) - ;; (click-command (nth 0 click)) - (click-data (nth 1 click)) + ;; Process the up-event. + (let* ((click (if is-click down (xterm-mouse-event extension))) + (click-data (nth 1 click)) (click-where (nth 1 click-data))) (if (memq down-binding '(nil ignore)) (if (and (symbolp click-where) @@ -81,17 +97,18 @@ (vector (list click-where click-data) click) (vector click)) (setq unread-command-events - (if (eq down-where click-where) - (list click) - (list - ;; Cheat `mouse-drag-region' with move event. - (list 'mouse-movement click-data) - ;; Generate a drag event. - (if (symbolp down-where) - 0 - (list (intern (format "drag-mouse-%d" - (+ 1 xterm-mouse-last))) - down-data click-data))))) + (append (if (eq down-where click-where) + (list click) + (list + ;; Cheat `mouse-drag-region' with move event. + (list 'mouse-movement click-data) + ;; Generate a drag event. + (if (symbolp down-where) + 0 + (list (intern (format "drag-mouse-%d" + (1+ xterm-mouse-last))) + down-data click-data)))) + unread-command-events)) (if xterm-mouse-debug-buffer (print unread-command-events xterm-mouse-debug-buffer)) (if (and (symbolp down-where) @@ -118,7 +135,7 @@ (terminal-parameter nil 'xterm-mouse-y)))) pos) -;; read xterm sequences above ascii 127 (#x7f) +;; Read XTerm sequences above ASCII 127 (#x7f) (defun xterm-mouse-event-read () ;; We get the characters decoded by the keyboard coding system. Try ;; to recover the raw character. @@ -147,11 +164,82 @@ (fdiff (- f (* 1.0 maxwrap dbig)))) (+ (truncate fdiff) (* maxwrap dbig)))))) -(defun xterm-mouse-event () - "Convert XTerm mouse event to Emacs mouse event." - (let* ((type (- (xterm-mouse-event-read) #o40)) - (x (- (xterm-mouse-event-read) #o40 1)) - (y (- (xterm-mouse-event-read) #o40 1)) +;; Normal terminal mouse click reporting: expect three bytes, of the +;; form . Return a list (EVENT-TYPE X Y). +(defun xterm-mouse--read-event-sequence-1000 () + (list (let ((code (- (xterm-mouse-event-read) 32))) + (intern + ;; For buttons > 3, the release-event looks differently + ;; (see xc/programs/xterm/button.c, function EditorButton), + ;; and come in a release-event only, no down-event. + (cond ((>= code 64) + (format "mouse-%d" (- code 60))) + ((memq code '(8 9 10)) + (setq xterm-mouse-last code) + (format "M-down-mouse-%d" (- code 7))) + ((= code 11) + (format "M-mouse-%d" (- xterm-mouse-last 7))) + ((= code 3) + ;; For buttons > 5 xterm only reports a + ;; button-release event. Avoid error by mapping + ;; them all to mouse-1. + (format "mouse-%d" (+ 1 (or xterm-mouse-last 0)))) + (t + (setq xterm-mouse-last code) + (format "down-mouse-%d" (+ 1 code)))))) + ;; x and y coordinates + (- (xterm-mouse-event-read) 33) + (- (xterm-mouse-event-read) 33))) + +;; XTerm's 1006-mode terminal mouse click reporting has the form +;;