home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / misc / x-sb-mouse / x-sb-mouse.el < prev    next >
Encoding:
Text File  |  1992-06-29  |  27.7 KB  |  613 lines

  1. ;;; x-sb-mouse.el : extended mouse support for emacs
  2. ;;; Copyright (C) 1992 Sullivan Beck
  3. ;;;
  4. ;;; This program is free software; you can redistribute it and/or modify
  5. ;;; it under the terms of the GNU General Public License as published by
  6. ;;; the Free Software Foundation; either version 1, or (at your option)
  7. ;;; any later version.
  8. ;;;
  9. ;;; This program is distributed in the hope that it will be useful,
  10. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ;;; GNU General Public License for more details.
  13. ;;;
  14. ;;; The GNU General Public License is available by anonymouse ftp from
  15. ;;; prep.ai.mit.edu in pub/gnu/COPYING.  Alternately, you can write to
  16. ;;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  17. ;;; USA.
  18. ;;--------------------------------------------------------------------
  19.  
  20. ;;; This is a new and hopefully better mouse package for emacs running
  21. ;;; under X.  Some of its features are:
  22. ;;;  1) It combines the features of x-mouse-drag and alt-mouse.
  23. ;;;  2) It allows you to use control, shift, and meta modifiers with the
  24. ;;;     mouse (in any combination).
  25. ;;;  3) It distinguishes between click and drag events.  A drag is where
  26. ;;;     the mouse button is moved with a button held down).
  27. ;;;  4) It recognizes 5 different parts of the window:
  28. ;;;       window : the window itself
  29. ;;;       mode   : the mode line of a window
  30. ;;;       border : the vertical border separating two windows split side
  31. ;;;                by side
  32. ;;;       inter  : the intersection of a mode line and the vertical border
  33. ;;;       mini   : the minibuffer
  34. ;;;     This allows a great deal of extra functionality not available in
  35. ;;;     the other two mouse packages such as both horizontal AND vertical
  36. ;;;     resizing of the windows.  You can even resize the minibuffer (as
  37. ;;;     long as you give it at least 1 line).
  38. ;;;  5) 120 click events and 24 drag events can be bound simply to emacs
  39. ;;;     functions by simply setting the appropriate variable (see
  40. ;;;     installation instructions below).
  41. ;;;  6) It is fully x-mouse compatible.  All packages that run on top
  42. ;;;     of x-mouse should also run on top of this one.
  43.  
  44. ;;; Although I have rewritten almost everything, segments of this package
  45. ;;; have been borrowed from both of the packages mentioned above.  Thanks
  46. ;;; to the authors (Eirik Fuller for alt-mouse and Peter Moore for
  47. ;;; x-mouse-drag) for their work.
  48.  
  49. ;;; The 120 valid click events are defined by where they occured (one of
  50. ;;; the 5 different recognized parts of the window) and what keyboard
  51. ;;; modifiers are used (none OR control, shift, meta, or any combination
  52. ;;; of the three modifiers).  Drag events are defined by where they
  53. ;;; start, where they end, and what keyboard modifiers are used.  Obviously
  54. ;;; there are a lot of them, but only a small number of them actually do
  55. ;;; anything.  Dragging mode lines around can resize windows vertically.
  56. ;;; Dragging borders around resize windows horizontally.  Dragging an
  57. ;;; intersection resizes horizontally and vertically simoultaneously.
  58. ;;; Keyboard modifiers are ignored for these drags.  The other type of
  59. ;;; drag that is recognized are those that begin and end in the same
  60. ;;; window.  All 24 of these (with keyboard modifiers) can be set by the
  61. ;;; user.
  62.  
  63. ;;; To examine the default bindings, either look at the 'setq' lines at
  64. ;;; the bottom of the file or run the command x-mouse-help (bound to
  65. ;;; shift-button-1 in the mode line.
  66.  
  67. ;;; HISTORY:
  68. ;;;
  69. ;;;   1.6        Fixed documentation.  Thanks to Bill Horne.
  70. ;;;
  71. ;;;              Fixed .texi file.  Thanks to George Ferguson, Robert
  72. ;;;              Chassell, Tonny Madsen, and many others for smaller
  73. ;;;              fixes.
  74. ;;;
  75. ;;;              Fixed x-help.  Thanks to Gnanasekaran Swaminathan.
  76. ;;;
  77. ;;;              Added Makefile written by George Ferguson.  Thanks!
  78. ;;;
  79. ;;;              Created 2 new files: xsbm-funs.el and xsbm-keys.el.
  80. ;;;
  81. ;;;              Added mode specific bindings.  Thanks to Dag Wanvik
  82. ;;;              and Shekhar Bapat.  Added x-mouse-global-set-key,
  83. ;;;              x-mouse-local-set-key, x-mouse-define-key,
  84. ;;;              x-mouse-global-unset-key, x-mouse-local-unset-key,
  85. ;;;              and x-mouse-undefine-key functions.  Added
  86. ;;;              x-mouse-bind-hook.
  87. ;;;
  88. ;;;              Added x-mouse-describe-event function and
  89. ;;;              x-mouse-describe-only variable.  Thanks to Lars Huttar.
  90. ;;;              x-mouse-describe-event is bound to C-h RET.
  91. ;;;
  92. ;;;              Modified x-mouse a lot to make it easier to extend.
  93. ;;;              Thanks to Lars Huttar.
  94. ;;;
  95. ;;;              Added the x-mouse-get-file command (written by Ik Su Yoo)
  96. ;;;              and the x-mouse-file-ignore-regexp variable.
  97. ;;;
  98. ;;;              Added x-mouse-copy-thing-to-point and
  99. ;;;              x-mouse-cut-thing-to-point.  Thanks to Nitin More.
  100.  
  101. ;;; The history of previous versions has been moved to the info file.
  102. ;;;
  103. ;;; I have tried to acknowledge all people who have contributed something,
  104. ;;; but occasionally I forget.  I apologize if I forgot you.  Mail me and
  105. ;;; I'll correct it.
  106.  
  107. ;;; COMMON QUESTIONS:
  108. ;;;
  109. ;;; Highlighting: I do not support highlighting (yet) in x-sb-mouse.
  110. ;;; The reason for this is that there is no standard way to do highlighting
  111. ;;; inside of emacs without first applying an unofficial patch to the
  112. ;;; source code and recompiling emacs.  Because it is unofficial, I do
  113. ;;; not support it.  Emacs 19 will have highlighting.  So does Epoch, but
  114. ;;; I don't use Epoch.  If anyone happens to fix this to highlight under
  115. ;;; Epoch, I'd appreciate it if you'd send me the diffs so that I can
  116. ;;; add it to the standard distribution.
  117. ;;;
  118. ;;; Popup menus:  Popup menus only work if emacs was compiled with
  119. ;;; HAVE_X_MENUS defined in the config.h file.  This does not work on
  120. ;;; all computers, but is part of the standard source code so I use it.
  121.  
  122. ;;; INSTALLING AND CUSTOMIZING
  123. ;;;
  124. ;;; Installing x-sb-mouse is very easy with the Makefile included.  It
  125. ;;; requires that you have the makeinfo program.  If you do not have it,
  126. ;;; you can get it by anonymous ftp from prep.ai.mit.edu:/pub/gnu/.
  127. ;;; It's in the file texinfo-2.15.tar.Z (or whatever the most recent
  128. ;;; version happens to be).  This is only necessary if you want to use
  129. ;;; the info file.  The actual mouse package can be compiled and installed
  130. ;;; without the makeinfo program.
  131. ;;;
  132. ;;; Edit the Makefile and decide where you want to install the program
  133. ;;; and set ELISPDIR to that directory.  If you are going to create an
  134. ;;; info file, set the INFODIR variable to the directory where it should
  135. ;;; be installed.
  136. ;;;
  137. ;;; Then just type one of the following:
  138. ;;;
  139. ;;;    make install       # to make and install everything
  140. ;;;    make install.src   # to make and install just the program
  141. ;;;    make install.info  # to make and install just the info file
  142. ;;;    make               # to make (but not install) everything
  143. ;;;    make src           # to make (but not install) just the program
  144. ;;;    make info          # to make (but not install) just the info file
  145. ;;;
  146. ;;; To try this out once (but NOT have it load every time you start up
  147. ;;; emacs), just load it with the 'M-x load-file' command to load the
  148. ;;; file x-sb-mouse.elc.
  149. ;;;
  150. ;;; To have it automatically start up each time you use emacs, just add
  151. ;;; the following to your .emacs file:
  152. ;;;
  153. ;;;   (setq term-setup-hook '(lambda () (load-library "x-sb-mouse")))
  154. ;;;
  155. ;;; This assumes that ELISPDIR is in the default load path (i.e. where
  156. ;;; all of the other .el and .elc files are kept).  If they are stored
  157. ;;; somewhere else, you will need to add two lines to your .emacs file:
  158. ;;;
  159. ;;;   (setq x-mouse-dir "DIR")
  160. ;;;   (setq term-setup-hook
  161. ;;;         '(lambda () (load "DIR/x-sb-mouse")))
  162. ;;;
  163. ;;; where you must replace DIR in the above lines with whatever you
  164. ;;; defined ELISPDIR to be in the Makefile.  For example, I keep a copy
  165. ;;; of the package in my "~/lisp/xsbm/" directory that I am working
  166. ;;; on and that's the one I want loaded, so in my .emacs file, I have:
  167. ;;;
  168. ;;;   (setq x-mouse-dir "~/lisp/xsbm")
  169. ;;;   (setq term-setup-hook
  170. ;;;         '(lambda () (load "~/lisp/xsbm/x-sb-mouse")))
  171. ;;;
  172. ;;; If you use any packages that require x-mouse (such as hyperbole or
  173. ;;; gdbsrc), they should be loaded AFTER x-sb-mouse.  They will probably
  174. ;;; redefine some of the default key bindings.  The function
  175. ;;; x-mouse-init-mouse-map will redefine these keys to whatever functions
  176. ;;; I have defined or that you have defined in your .emacs file.  The
  177. ;;; problem is that this will remove the bindings used by the other
  178. ;;; packages.  Hyperbole does NOT have this problem.  It allows you to
  179. ;;; toggle between it's bindings and your personal mouse bindings.  I
  180. ;;; am planning on adding a simple toggle function to x-sb-mouse which
  181. ;;; will hopefully solve this problem.
  182. ;;; 
  183. ;;; To change the bindings, simply add a line to your .emacs file putting
  184. ;;; in a new command.  For example, if you want clicking the first button
  185. ;;; inside a window with a meta modifier to insert the letter "a" when in
  186. ;;; text-mode and to run the command recenter when in lisp-mode rather
  187. ;;; than the default bindings and you want to change the default binding
  188. ;;; for clicking button 2 in the mode line to select that window, add the
  189. ;;; following to your .emacs file:
  190. ;;;
  191. ;;;   (setq x-mouse-bind-hook '(lambda ()
  192. ;;;     (x-mouse-define-key "x-mouse-m1-window-click" t
  193. ;;;      'text-mode '(lambda () (insert "a"))
  194. ;;;      'lisp-mode 'recenter))
  195. ;;;     (x-mouse-define-key "x-mouse-2-mode-click" t
  196. ;;;      'default   'x-mouse-select))
  197. ;;;
  198. ;;; As many mode specific bindings can be added as desired.  The first
  199. ;;; argument is a string of the form given in the example.  They all start
  200. ;;; with "x-mouse-" followed by any or all of the three keyboard modifiers
  201. ;;; "c" (control), "m" (meta), and "s" (shift) which must be in alphabetical
  202. ;;; order in the string.  This is followed by the button number (1, 2, or 3),
  203. ;;; where it occurs ("window", "mode", "border", "inter", or "mini"), and
  204. ;;; the type of event ("click" or "drag" - NOTE: only "window" drags are
  205. ;;; currently defined).
  206. ;;;
  207. ;;; More information on customization is included in the info file.  For
  208. ;;; interactively setting a binding, use x-mouse-global-set-key and
  209. ;;; x-mouse-local-set-key.
  210.  
  211. ;;; Please send any comments or suggestions to me at beck@qtp.ufl.edu.
  212.  
  213.  
  214. ;;;*************************************************************************
  215. ;;; User definable variables.  Set these in your .emacs file.
  216.  
  217. ;;(defvar x-mouse-dir "~/lisp")
  218. (defvar x-mouse-dir nil 
  219.   "*The directory where x-sb-mouse lives.
  220. If it is set to nil, then it looks in the load path.")
  221.  
  222. (defvar x-mouse-blink-cursor nil
  223.   "*If this is t, the cursor will blink temporarily to where a mouse event is.
  224. Pressing a mouse button will cause the cursor to appear there for a second.
  225. Releasing the mouse will cause the cursor to appear there for a second and
  226. then appear at the position of the press (if it was different) for a second.
  227. These 'blinks' do not interfere with executing commands during the delay.")
  228.  
  229. (defvar x-mouse-auto-set-mark t
  230.   "*If this is non-nil, the mark will be set every time the point is set.
  231. With this set, clicking in two spots defines a region (which you can
  232. kill, copy, etc.)")
  233.  
  234. (defvar x-mouse-duplicate-cut t
  235.   "*If non-nil, saving to the x-cut-buffer saves to the kill ring too.
  236. In other words, every time a region is saved/appended to the x-cut-buffer,
  237. it is also saved/appended to the kill ring.")
  238.  
  239. (defvar x-mouse-init-map t
  240.   "*If non-nil, initializes the mouse map to include all my default bindings.
  241. If it is t, all of the functionality still exists but the buttons are not
  242. defined and you'll have to do it yourself.")
  243.  
  244. (defvar x-mouse-help-to-menu t
  245.   "*If nil, sends help to a buffer rather than popup menus.
  246. Nice if you want to be able to refer back to the help while you type.
  247. Rather then set this manually, there is now an option in the menu to
  248. do this as a one time only command.")
  249.  
  250. (defvar x-mouse-describe-only nil
  251.   "*If non-nil, mouse events are not executed, just described.
  252. They are evaluated to see what function would be called; that function
  253. name is printed.  Used by describe-mouse-event.")
  254.  
  255. (defvar x-mouse-file-ignore-regexp ".o$\\|~$\\|#$\\|/$\\|@\\|*\\|.elc"
  256.   "*File endings to ignore in the x-mouse-get-file command.")
  257.  
  258.  
  259. ;;;*************************************************************************
  260. ;;; First we'll define the mouse map and some other necessary things.  This
  261. ;;; section should probably not be altered.
  262. (provide 'x-mouse)
  263. (provide 'x-sb-mouse)
  264.  
  265. (define-key help-map "\C-m" 'x-mouse-describe-event)
  266.  
  267. (defconst x-button-right (char-to-string 0))
  268. (defconst x-button-right-up (char-to-string 4))
  269. (defconst x-button-middle (char-to-string 1))
  270. (defconst x-button-middle-up (char-to-string 5))
  271. (defconst x-button-left (char-to-string 2))
  272. (defconst x-button-left-up (char-to-string 6))
  273.  
  274. (defconst x-button-s-right (char-to-string 16))
  275. (defconst x-button-s-right-up (char-to-string 20))
  276. (defconst x-button-s-middle (char-to-string 17))
  277. (defconst x-button-s-middle-up (char-to-string 21))
  278. (defconst x-button-s-left (char-to-string 18))
  279. (defconst x-button-s-left-up (char-to-string 22))
  280.  
  281. (defconst x-button-m-right (char-to-string 32))
  282. (defconst x-button-m-right-up (char-to-string 36))
  283. (defconst x-button-m-middle (char-to-string 33))
  284. (defconst x-button-m-middle-up (char-to-string 37))
  285. (defconst x-button-m-left (char-to-string 34))
  286. (defconst x-button-m-left-up (char-to-string 38))
  287.  
  288. (defconst x-button-c-right (char-to-string 64))
  289. (defconst x-button-c-right-up (char-to-string 68))
  290. (defconst x-button-c-middle (char-to-string 65))
  291. (defconst x-button-c-middle-up (char-to-string 69))
  292. (defconst x-button-c-left (char-to-string 66))
  293. (defconst x-button-c-left-up (char-to-string 70))
  294.  
  295. (defconst x-button-m-s-right (char-to-string 48))
  296. (defconst x-button-m-s-right-up (char-to-string 52))
  297. (defconst x-button-m-s-middle (char-to-string 49))
  298. (defconst x-button-m-s-middle-up (char-to-string 53))
  299. (defconst x-button-m-s-left (char-to-string 50))
  300. (defconst x-button-m-s-left-up (char-to-string 54))
  301.  
  302. (defconst x-button-c-s-right (char-to-string 80))
  303. (defconst x-button-c-s-right-up (char-to-string 84))
  304. (defconst x-button-c-s-middle (char-to-string 81))
  305. (defconst x-button-c-s-middle-up (char-to-string 85))
  306. (defconst x-button-c-s-left (char-to-string 82))
  307. (defconst x-button-c-s-left-up (char-to-string 86))
  308.  
  309. (defconst x-button-c-m-right (char-to-string 96))
  310. (defconst x-button-c-m-right-up (char-to-string 100))
  311. (defconst x-button-c-m-middle (char-to-string 97))
  312. (defconst x-button-c-m-middle-up (char-to-string 101))
  313. (defconst x-button-c-m-left (char-to-string 98))
  314. (defconst x-button-c-m-left-up (char-to-string 102))
  315.  
  316. (defconst x-button-c-m-s-right (char-to-string 112))
  317. (defconst x-button-c-m-s-right-up (char-to-string 116))
  318. (defconst x-button-c-m-s-middle (char-to-string 113))
  319. (defconst x-button-c-m-s-middle-up (char-to-string 117))
  320. (defconst x-button-c-m-s-left (char-to-string 114))
  321. (defconst x-button-c-m-s-left-up (char-to-string 118))
  322.  
  323. (defvar x-process-mouse-hook nil
  324.   "Hook to run after each mouse event is processed.  Should take two
  325. arguments; the first being a list (XPOS YPOS) corresponding to character
  326. offset from top left of screen and the second being a specifier for the
  327. buttons/keys.  This will normally be set on a per-buffer basis.")
  328. (defun x-flush-mouse-queue ()
  329.   "Process all queued mouse events."
  330.   ;; A mouse event causes a special character sequence to be given
  331.   ;; as keyboard input.  That runs this function, which process all
  332.   ;; queued mouse events and returns.
  333.   (interactive)
  334.   (while (> (x-mouse-events) 0)
  335.     (x-proc-mouse-event))
  336.   (and (boundp 'x-process-mouse-hook)
  337.        (symbol-value 'x-process-mouse-hook)
  338.        (funcall x-process-mouse-hook x-mouse-pos x-mouse-item)))
  339. (define-key global-map "\C-c\C-m" 'x-flush-mouse-queue)
  340. (define-key global-map "\C-x\C-@" 'x-flush-mouse-queue)
  341.  
  342.  
  343. ;;;*************************************************************************
  344. ;;; The following three functions (and the progn statement after) are what
  345. ;;; actually decide what to do when a press or release event occurs.  This
  346. ;;; section may be modified eventually as I add minibuffer functions and
  347. ;;; dragging from one window to another.
  348.  
  349. ;;; All a mouse press does is set some variables.
  350. (defun x-mouse-press (arg)
  351.   "Sets up all the parameters describing the environment of a button press.
  352. The following variables are set:
  353.   x-mouse-point-0     The current point
  354.   x-mouse-win-0       The current selected window
  355.   x-mouse-mode-0      The current major mode
  356.   x-mouse-pos-d       The position (relative to the screen) of the mouse
  357.   x-mouse-win-d       The window the mouse is in (nil if minibuffer)
  358.   x-mouse-mode-d      The major mode in the window where the mouse was pressed
  359.   x-mouse-coords-d    The position (relative to the window) of the mouse
  360.   x-mouse-point-d     The (point) of the mouse position in the window
  361.   x-mouse-type-d      The \"type\" of position where the press occured.
  362.       'window refers to a position actually in the window
  363.       'mode   refers to a position on the mode line of a window
  364.       'border refers to the column separating two horizontally split windows
  365.       'inter  refers to the intersection of a mode line and a border
  366.       'mini   refers to the minibuffer
  367.   x-mouse-press        This function was called for the press."
  368.   (save-window-excursion
  369.     (setq x-mouse-point-0 (point)
  370.           x-mouse-win-0 (selected-window)
  371.       x-mouse-mode-0 major-mode
  372.           x-mouse-press t
  373.           x-mouse-pos-d arg
  374.           x-mouse-win-d (x-mouse-window arg)
  375.       x-mouse-mode-d (save-window-excursion
  376.               (select-window x-mouse-win-d)
  377.               major-mode)
  378.           x-mouse-coords-d (x-mouse-coords x-mouse-pos-d x-mouse-win-d)
  379.           x-mouse-point-d (x-mouse-point arg x-mouse-win-d)
  380.           x-mouse-type-d (cond
  381.                           ((x-mouse-mini-p arg)
  382.                            'mini)
  383.                           ((x-mouse-inter-p arg x-mouse-win-d)
  384.                            'inter)
  385.                           ((x-mouse-mode-p arg x-mouse-win-d)
  386.                            'mode)
  387.                           ((x-mouse-border-p arg x-mouse-win-d)
  388.                            'border)
  389.                           (t 'window)))
  390.     (if x-mouse-blink-cursor
  391.     (progn
  392.       (select-window x-mouse-win-d)
  393.       (save-excursion
  394.         (goto-char x-mouse-point-d)
  395.         (sit-for 1))))))
  396.  
  397. (defvar x-mouse-press nil)
  398. ;;; This runction is called on a mouse release event and it sets up the
  399. ;;; remaining variables used to perform the desired action.
  400. (defun x-mouse-release (arg)
  401.   "Sets up all the parameters describing the environment of a button press.
  402. The following variables are set:
  403.   x-mouse-pos-u       The position (relative to the screen) of the mouse
  404.   x-mouse-win-u       The window the mouse is in (nil if minibuffer)
  405.   x-mouse-mode-u      The major mode in the window where the mouse was released
  406.   x-mouse-coords-u    The position (relative to the window) of the mouse
  407.   x-mouse-point-u     The (point) of the mouse position in the window
  408.   x-mouse-type-u      The \"type\" of position where the press occured.
  409.       'window refers to a position actually in the window
  410.       'mode   refers to a position on the mode line of a window
  411.       'border refers to the column separating two horizontally split windows
  412.       'inter  refers to the intersection of a mode line and a border
  413.       'mini   refers to the minibuffer
  414.   x-mouse-click       't if the down and up events occurred at the same place."
  415.   (save-window-excursion
  416.     (setq x-mouse-press ()
  417.           x-mouse-pos-u arg
  418.           x-mouse-click (equal x-mouse-pos-d x-mouse-pos-u)
  419.           x-mouse-win-u (x-mouse-window arg)
  420.       x-mouse-mode-u (save-window-excursion
  421.               (select-window x-mouse-win-u)
  422.               major-mode)
  423.           x-mouse-coords-u (x-mouse-coords x-mouse-pos-u x-mouse-win-u)
  424.           x-mouse-point-u (x-mouse-point arg x-mouse-win-u)
  425.           x-mouse-type-u (cond
  426.                           ((x-mouse-mini-p arg)
  427.                            'mini)
  428.                           ((x-mouse-inter-p arg x-mouse-win-u)
  429.                            'inter)
  430.                           ((x-mouse-mode-p arg x-mouse-win-u)
  431.                            'mode)
  432.                           ((x-mouse-border-p arg x-mouse-win-u)
  433.                            'border)
  434.                           (t 'window)))
  435.     (if x-mouse-blink-cursor
  436.     (progn
  437.       (select-window x-mouse-win-u)
  438.       (save-excursion
  439.         (goto-char x-mouse-point-u)
  440.         (sit-for 1))
  441.       (if (not x-mouse-click)
  442.           (progn
  443.         (select-window x-mouse-win-d)
  444.         (save-excursion
  445.           (goto-char x-mouse-point-d)
  446.           (sit-for 1))))))))
  447.  
  448. ;;; This function is called when a button is released.  The three arguments
  449. ;;; are the position of the mouse, the button number (1, 2, or 3), and
  450. ;;; a list of modifiers containing 'c, 's, and 'm in any combination.
  451. (defun x-mouse (arg button modifier)
  452.   (if x-mouse-press
  453.       (progn
  454.         (x-mouse-release arg)
  455.         ;; base is a string "x-mouse-"
  456.         ;; mods is one of the following: 
  457.         ;;    "", "c", "m", "s", "cm", "cs", "ms", "cms"
  458.         ;; but  is "1", "2", or "3"
  459.         ;; op   contains base mods, but, and "-"
  460.         ;; type contains "window", "mode", "border", "inter", or "mini"
  461.         ;; function contains the whole string
  462.         ;; x-mouse-windows contains info used in the resize commands
  463.         (let* ((base "x-mouse-")
  464.                (mods (if (memq 'c modifier) "c" ""))
  465.                (mods (if (memq 'm modifier) (concat mods "m") mods))
  466.                (mods (if (memq 's modifier) (concat mods "s") mods))
  467.                (but  (int-to-string button))
  468.                (op   (concat base mods but "-"))
  469.                (type (symbol-name x-mouse-type-d))
  470.                (function "x-mouse-ignore"))
  471.           ;; list ALL the combinations under which the function is evaluated
  472.           (cond
  473.            ;; any click event
  474.            (x-mouse-click
  475.         (setq function (concat op type "-click")))
  476.            ;; drag in a single window
  477.            ((and (eq x-mouse-type-d 'window) (eq x-mouse-type-u 'window)
  478.                  (eq x-mouse-win-d x-mouse-win-u))
  479.         (setq function (concat op "window-drag")))
  480.            ;; drag from mode to adjacent window
  481.            ((and (eq x-mouse-type-d 'mode) (eq x-mouse-type-u 'window))
  482.             (setq function "x-mouse-resize"))
  483.            ;; drag in a single mode line
  484.            ((and (eq x-mouse-type-d 'mode) (eq x-mouse-type-u 'mode)
  485.                  (eq x-mouse-win-d x-mouse-win-u))
  486.             (setq function (concat op "mode-click")))
  487.            ;; drag from mode to adjacent minibuffer
  488.            ((and (eq x-mouse-type-d 'mode) (eq x-mouse-type-u 'mini))
  489.             (setq function "x-mouse-resize"))
  490.            ;; drag from border to adjacent window
  491.            ((and (eq x-mouse-type-d 'border) (eq x-mouse-type-u 'window))
  492.             (setq function "x-mouse-resize"))
  493.            ;; drag in a single border
  494.            ((and (eq x-mouse-type-d 'border) (eq x-mouse-type-u 'border)
  495.                  (eq x-mouse-win-d x-mouse-win-u))
  496.             (setq function (concat op "border-click")))
  497.            ;; drag from inter to adjacent window
  498.            ((and (eq x-mouse-type-d 'inter) (eq x-mouse-type-u 'window))
  499.             (setq function "x-mouse-resize"))
  500.            ;; drag from inter to adjacent mini
  501.            ((and (eq x-mouse-type-d 'inter) (eq x-mouse-type-u 'mini))
  502.             (setq function "x-mouse-resize"))
  503.            ;; drag in mini
  504.            ((and (eq x-mouse-type-d 'mini) (eq x-mouse-type-u 'mini))
  505.             (setq function (concat op "mini-click")))
  506.            )
  507.           (setq x-mouse-press nil)
  508.       (if x-mouse-describe-only
  509.               (message "%s runs the function %s" function
  510.                (x-mouse-get-function-name function x-mouse-mode-u))
  511.         (funcall (x-mouse-get-function function x-mouse-mode-u)))))))
  512.  
  513. (defun x-mouse-init-mouse-map ()
  514.   "Sets up the mouse map (or resets it if it has gotten altered).
  515. This is useful for when some package alters the key bindings and
  516. you want to recover the default ones."
  517.   (interactive)
  518.   (define-key mouse-map x-button-left 'x-mouse-press)
  519.   (define-key mouse-map x-button-left-up
  520.     '(lambda (arg) (x-mouse arg 1 '())))
  521.   (define-key mouse-map x-button-middle 'x-mouse-press)
  522.   (define-key mouse-map x-button-middle-up
  523.     '(lambda (arg) (x-mouse arg 2 '())))
  524.   (define-key mouse-map x-button-right 'x-mouse-press)
  525.   (define-key mouse-map x-button-right-up
  526.     '(lambda (arg) (x-mouse arg 3 '())))
  527.  
  528.   (define-key mouse-map x-button-c-left 'x-mouse-press)
  529.   (define-key mouse-map x-button-c-left-up
  530.     '(lambda (arg) (x-mouse arg 1 '(c))))
  531.   (define-key mouse-map x-button-c-middle 'x-mouse-press)
  532.   (define-key mouse-map x-button-c-middle-up
  533.     '(lambda (arg) (x-mouse arg 2 '(c))))
  534.   (define-key mouse-map x-button-c-right 'x-mouse-press)
  535.   (define-key mouse-map x-button-c-right-up
  536.     '(lambda (arg) (x-mouse arg 3 '(c))))
  537.  
  538.   (define-key mouse-map x-button-m-left 'x-mouse-press)
  539.   (define-key mouse-map x-button-m-left-up
  540.     '(lambda (arg) (x-mouse arg 1 '(m))))
  541.   (define-key mouse-map x-button-m-middle 'x-mouse-press)
  542.   (define-key mouse-map x-button-m-middle-up
  543.     '(lambda (arg) (x-mouse arg 2 '(m))))
  544.   (define-key mouse-map x-button-m-right 'x-mouse-press)
  545.   (define-key mouse-map x-button-m-right-up
  546.     '(lambda (arg) (x-mouse arg 3 '(m))))
  547.  
  548.   (define-key mouse-map x-button-s-left 'x-mouse-press)
  549.   (define-key mouse-map x-button-s-left-up
  550.     '(lambda (arg) (x-mouse arg 1 '(s))))
  551.   (define-key mouse-map x-button-s-middle 'x-mouse-press)
  552.   (define-key mouse-map x-button-s-middle-up
  553.     '(lambda (arg) (x-mouse arg 2 '(s))))
  554.   (define-key mouse-map x-button-s-right 'x-mouse-press)
  555.   (define-key mouse-map x-button-s-right-up
  556.     '(lambda (arg) (x-mouse arg 3 '(s))))
  557.  
  558.   (define-key mouse-map x-button-c-m-left 'x-mouse-press)
  559.   (define-key mouse-map x-button-c-m-left-up
  560.     '(lambda (arg) (x-mouse arg 1 '(c m))))
  561.   (define-key mouse-map x-button-c-m-middle 'x-mouse-press)
  562.   (define-key mouse-map x-button-c-m-middle-up
  563.     '(lambda (arg) (x-mouse arg 2 '(c m))))
  564.   (define-key mouse-map x-button-c-m-right 'x-mouse-press)
  565.   (define-key mouse-map x-button-c-m-right-up
  566.     '(lambda (arg) (x-mouse arg 3 '(c m))))
  567.  
  568.   (define-key mouse-map x-button-c-s-left 'x-mouse-press)
  569.   (define-key mouse-map x-button-c-s-left-up
  570.     '(lambda (arg) (x-mouse arg 1 '(c s))))
  571.   (define-key mouse-map x-button-c-s-middle 'x-mouse-press)
  572.   (define-key mouse-map x-button-c-s-middle-up
  573.     '(lambda (arg) (x-mouse arg 2 '(c s))))
  574.   (define-key mouse-map x-button-c-s-right 'x-mouse-press)
  575.   (define-key mouse-map x-button-c-s-right-up
  576.     '(lambda (arg) (x-mouse arg 3 '(c s))))
  577.  
  578.   (define-key mouse-map x-button-m-s-left 'x-mouse-press)
  579.   (define-key mouse-map x-button-m-s-left-up
  580.     '(lambda (arg) (x-mouse arg 1 '(m s))))
  581.   (define-key mouse-map x-button-m-s-middle 'x-mouse-press)
  582.   (define-key mouse-map x-button-m-s-middle-up
  583.     '(lambda (arg) (x-mouse arg 2 '(m s))))
  584.   (define-key mouse-map x-button-m-s-right 'x-mouse-press)
  585.   (define-key mouse-map x-button-m-s-right-up
  586.     '(lambda (arg) (x-mouse arg 3 '(m s))))
  587.  
  588.   (define-key mouse-map x-button-c-m-s-left 'x-mouse-press)
  589.   (define-key mouse-map x-button-c-m-s-left-up
  590.     '(lambda (arg) (x-mouse arg 1 '(c m s))))
  591.   (define-key mouse-map x-button-c-m-s-middle 'x-mouse-press)
  592.   (define-key mouse-map x-button-c-m-s-middle-up
  593.     '(lambda (arg) (x-mouse arg 2 '(c m s))))
  594.   (define-key mouse-map x-button-c-m-s-right 'x-mouse-press)
  595.   (define-key mouse-map x-button-c-m-s-right-up
  596.     '(lambda (arg) (x-mouse arg 3 '(c m s)))))
  597.  
  598. ;;;*************************************************************************
  599.  
  600. (if x-mouse-dir
  601.     (progn
  602.       (load (concat (file-name-as-directory x-mouse-dir) "xsbm-funs"))
  603.       (load (concat (file-name-as-directory x-mouse-dir) "thing"))
  604.       (load (concat (file-name-as-directory x-mouse-dir) "xsbm-userfuns"))
  605.       (load (concat (file-name-as-directory x-mouse-dir) "xsbm-keys")))
  606.   (load "xsbm-funs")
  607.   (load "thing")
  608.   (load "xsbm-userfuns")
  609.   (load "xsbm-keys"))
  610.  
  611. (if x-mouse-init-map
  612.     (x-mouse-init-mouse-map))
  613.