+ (let ((button (mwheel-event-button event)))
+ (cond ((eq button mouse-wheel-down-event)
+ (condition-case nil (funcall mwheel-scroll-down-function amt)
+ ;; Make sure we do indeed scroll to the beginning of
+ ;; the buffer.
+ (beginning-of-buffer
+ (unwind-protect
+ (funcall mwheel-scroll-down-function)
+ ;; If the first scroll succeeded, then some scrolling
+ ;; is possible: keep scrolling til the beginning but
+ ;; do not signal an error. For some reason, we have
+ ;; to do it even if the first scroll signaled an
+ ;; error, because otherwise the window is recentered
+ ;; for a reason that escapes me. This problem seems
+ ;; to only affect scroll-down. --Stef
+ (set-window-start (selected-window) (point-min))))))
+ ((eq button mouse-wheel-up-event)
+ (condition-case nil (funcall mwheel-scroll-up-function amt)
+ ;; Make sure we do indeed scroll to the end of the buffer.
+ (end-of-buffer (while t (funcall mwheel-scroll-up-function)))))
+ (t (error "Bad binding in mwheel-scroll"))))
+ (if curwin (select-window curwin)))
+ ;; If there is a temporarily active region, deactivate it iff
+ ;; scrolling moves point.
+ (when opoint
+ (with-current-buffer buffer
+ (when (/= opoint (point))
+ (deactivate-mark)))))
+ (when (and mouse-wheel-click-event mouse-wheel-inhibit-click-time)
+ (if mwheel-inhibit-click-event-timer
+ (cancel-timer mwheel-inhibit-click-event-timer)
+ (add-hook 'pre-command-hook 'mwheel-filter-click-events))
+ (setq mwheel-inhibit-click-event-timer
+ (run-with-timer mouse-wheel-inhibit-click-time nil
+ 'mwheel-inhibit-click-timeout))))
+
+(defvar mwheel-installed-bindings nil)
+
+;; preloaded ;;;###autoload
+(define-minor-mode mouse-wheel-mode
+ "Toggle mouse wheel support.
+With prefix argument ARG, turn on if positive, otherwise off.
+Return non-nil if the new state is enabled."
+ :init-value t
+ ;; We'd like to use custom-initialize-set here so the setup is done
+ ;; before dumping, but at the point where the defcustom is evaluated,
+ ;; the corresponding function isn't defined yet, so
+ ;; custom-initialize-set signals an error.
+ :initialize 'custom-initialize-delay
+ :global t
+ :group 'mouse
+ ;; Remove previous bindings, if any.
+ (while mwheel-installed-bindings
+ (let ((key (pop mwheel-installed-bindings)))
+ (when (eq (lookup-key (current-global-map) key) 'mwheel-scroll)
+ (global-unset-key key))))
+ ;; Setup bindings as needed.
+ (when mouse-wheel-mode
+ (dolist (event (list mouse-wheel-down-event mouse-wheel-up-event))
+ (dolist (key (mapcar (lambda (amt) `[(,@(if (consp amt) (car amt)) ,event)])
+ mouse-wheel-scroll-amount))
+ (global-set-key key 'mwheel-scroll)
+ (push key mwheel-installed-bindings)))))
+
+;;; Compatibility entry point
+;; preloaded ;;;###autoload
+(defun mwheel-install (&optional uninstall)