;;; xt-mouse.el --- Support the mouse when emacs run in an xterm.;; Copyright (C) 1994 Free Software Foundation;; Author: Per Abrahamsen <abraham@dina.kvl.dk>;; Keywords: mouse, terminals;; This file is part of GNU Emacs.;; 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., 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, USA.;;; Comments:;; Enable mouse support when running inside an xterm or Linux console.;; This is actually useful when you are running X11 locally, but is;; working on remote machine over a modem line or through a gateway.;; It works by translating xterm escape codes into generic emacs mouse;; events so it should work with any package that uses the mouse.;; The xterm mouse escape codes are supposedly also supported by the;; Linux console, but I have not been able to verify this.;; You don't have to turn off xterm mode to use the normal xterm mouse;; functionality, it is still available by holding down the SHIFT key;; when you press the mouse button.;;; Todo:;; Support multi-click -- somehow.;; Clicking on the mode-line does not work, although it should.;;; Code: (define-keyfunction-key-map"\e[M"'xterm-mouse-translate)(defvarxterm-mouse-last)(defunxterm-mouse-translate(event);; Read a click and release event from XTerm.(save-excursion(save-window-excursion(deactivate-mark)(let*((xterm-mouse-last)(down(xterm-mouse-event))(down-command(nth0down))(down-data(nth1down))(down-where(nth1down-data))(down-binding(key-binding(if(symbolpdown-where)(vectordown-wheredown-command)(vectordown-command)))))(or(and(eq(read-char)?\e)(eq(read-char)?\[)(eq(read-char)?M))(error"Unexpected escape sequence from XTerm"))(let*((click(xterm-mouse-event))(click-command(nth0click))(click-data(nth1click))(click-where(nth1click-data)))(if(memqdown-binding'(nilignore))(if(and(symbolpclick-where)(not(eq'menu-barclick-where)))(vector(listclick-whereclick-data)click)(vectorclick))(setqunread-command-events(if(eqdown-whereclick-where)(listclick)(list;; Cheat `mouse-drag-region' with move event.(list'mouse-movementclick-data);; Generate a drag event.(if(symbolpdown-where)0(list(intern(concat"drag-mouse-"(+1xterm-mouse-last)))down-dataclick-data)))))(if(and(symbolpdown-where)(not(eq'menu-bardown-where)))(vector(listdown-wheredown-data)down)(vectordown))))))))(defvarxterm-mouse-x0"Position of last xterm mouse event relative to the frame.")(defvarxterm-mouse-y0"Position of last xterm mouse event relative to the frame.")(defadvicemouse-position(aroundxterm-mouseactivate)"Use last key from xterm-mouse-mode if available."(let((answerad-do-it))(setqad-return-value(ifxterm-mouse-mode(cons(caranswer)(consxterm-mouse-xxterm-mouse-y))answer))))(defunxterm-mouse-event();; Convert XTerm mouse event to Emacs mouse event.(let*((type(-(read-char)?))(x(-(read-char)?1))(y(-(read-char)?1))(point(consxy))(window(window-atxy))(where(ifwindow(coordinates-in-window-ppointwindow)'menu-bar))(pos(if(conspwhere)(progn(select-windowwindow)(goto-char(window-startwindow))(move-to-window-line(cdrwhere))(move-to-column(+(carwhere)(current-column)(if(string-match"\\` \\*Minibuf"(buffer-name))(-(minibuffer-prompt-width))0)(max0(1-(window-hscroll)))))(point))where))(mouse(intern(if(eqtype3)(concat"mouse-"(+1xterm-mouse-last))(setqxterm-mouse-lasttype)(concat"down-mouse-"(+1type))))))(setqxterm-mouse-xxxterm-mouse-yy)(listmouse(listwindowpospoint(/(nth2(current-time))1000)))));; Indicator for the xterm-mouse mode.(defvarxterm-mouse-modenil)(or(assq'xterm-mouse-modeminor-mode-alist)(setqminor-mode-alist(cons'(xterm-mouse-mode(" Mouse"))minor-mode-alist)));;;###autoload(defunxterm-mouse-mode(arg)"Toggle XTerm mouse mode.With prefix arg, turn XTerm mouse mode on iff arg is positive.Turn it on to use emacs mouse commands, and off to use xterm mouse commands."(interactive"P")(if(or(and(nullarg)xterm-mouse-mode)(<=(prefix-numeric-valuearg)0));; Turn it off(ifxterm-mouse-mode(progn(turn-off-xterm-mouse-tracking)(setqxterm-mouse-modenil)(set-buffer-modified-p(buffer-modified-p))));;Turn it on(ifxterm-mouse-mode()(setqxterm-mouse-modet)(turn-on-xterm-mouse-tracking)(set-buffer-modified-p(buffer-modified-p)))))(defunturn-on-xterm-mouse-tracking();; Enable emacs mouse tracking in xterm.(ifxterm-mouse-mode(send-string-to-terminal"\e[?1000h")))(defunturn-off-xterm-mouse-tracking();; Disable disable emacs mouse tracking in xterm.(ifxterm-mouse-mode(send-string-to-terminal"\e[?1000l")));; Restore normal mouse behaviour outside Emacs.(add-hook'suspend-hook'turn-off-xterm-mouse-tracking)(add-hook'suspend-resume-hook'turn-on-xterm-mouse-tracking)(add-hook'kill-emacs-hook'turn-off-xterm-mouse-tracking)(provide'xt-mouse);;; xt-mouse.el ends here