Function: xterm-mouse-event

xterm-mouse-event is a byte-compiled function defined in xt-mouse.el.gz.

Signature

(xterm-mouse-event &optional EXTENSION)

Documentation

Convert XTerm mouse event to Emacs mouse event.

EXTENSION, if non-nil, means to use an extension to the usual terminal mouse protocol; we currently support the value 1006, which is the "1006" extension implemented in Xterm >= 277.

Source Code

;; Defined in /usr/src/emacs/lisp/xt-mouse.el.gz
(defun xterm-mouse-event (&optional extension)
  "Convert XTerm mouse event to Emacs mouse event.
EXTENSION, if non-nil, means to use an extension to the usual
terminal mouse protocol; we currently support the value 1006,
which is the \"1006\" extension implemented in Xterm >= 277."
  (let ((click (cond ((memq extension '(1006 nil))
		      (xterm-mouse--read-event-sequence extension))
		     (t
		      (error "Unsupported XTerm mouse protocol")))))
    (when (and click
               ;; In very obscure circumstances, the click may become
               ;; invalid (see bug#17378).
               (>= (nth 1 click) 0))
      (let* ((type (nth 0 click))
             (x    (nth 1 click))
             (y    (nth 2 click))
             ;; Emulate timestamp information.  This is accurate enough
             ;; for default value of mouse-1-click-follows-link (450msec).
	     (timestamp (if (not xt-mouse-epoch)
			    (progn (setq xt-mouse-epoch (float-time)) 0)
			  (car (time-convert (time-since xt-mouse-epoch)
					     1000))))
             (w (window-at x y))
             (ltrb (window-edges w))
             (left (nth 0 ltrb))
             (top (nth 1 ltrb))
             (posn (if w
		       (posn-at-x-y (- x left) (- y top) w t)
		     (append (list nil (if (and tab-bar-mode
                                                (or (not menu-bar-mode)
                                                    ;; The tab-bar is on the
                                                    ;; second row below menu-bar
                                                    (eq y 1)))
                                           'tab-bar
                                         'menu-bar))
                             (nthcdr 2 (posn-at-x-y x y (selected-frame))))))
             (event (list type posn)))
        (setcar (nthcdr 3 posn) timestamp)

        ;; Try to handle double/triple clicks.
        (let* ((last-click (terminal-parameter nil 'xterm-mouse-last-click))
               (last-type (nth 0 last-click))
               (last-name (symbol-name last-type))
               (last-time (nth 1 last-click))
               (click-count (nth 2 last-click))
               (last-x (nth 3 last-click))
               (last-y (nth 4 last-click))
               (this-time (float-time))
               (name (symbol-name type)))
          (cond
           ((not (string-match "down-" name))
            ;; For up events, make the up side match the down side.
            (setq this-time last-time)
            (when (and click-count (> click-count 1)
                       (string-match "down-" last-name)
                       (equal name (replace-match "" t t last-name)))
              (xterm-mouse--set-click-count event click-count)))
           ((and last-time
                 double-click-time
                 (or (eq double-click-time t)
                     (> double-click-time (* 1000 (- this-time last-time))))
                 (<= (abs (- x last-x))
                     (/ double-click-fuzz 8))
                 (<= (abs (- y last-y))
                     (/ double-click-fuzz 8))
                 (equal last-name (replace-match "" t t name)))
            (setq click-count (1+ click-count))
            (xterm-mouse--set-click-count event click-count))
           (t (setq click-count 1)))
          (set-terminal-parameter nil 'xterm-mouse-last-click
                                  (list type this-time click-count x y)))

        (set-terminal-parameter nil 'xterm-mouse-x x)
        (set-terminal-parameter nil 'xterm-mouse-y y)
        (setq last-input-event event)))))