+(defun mouse-sel-set-selection (selection value)
+ "Set the specified SELECTION to VALUE."
+ (if mouse-sel-set-selection-function
+ (funcall mouse-sel-set-selection-function selection value)
+ (put 'mouse-sel-internal-selection selection value)))
+
+(defun mouse-sel-get-selection (selection)
+ "Get the value of the specified SELECTION."
+ (if mouse-sel-get-selection-function
+ (funcall mouse-sel-get-selection-function selection)
+ (get 'mouse-sel-internal-selection selection)))
+
+(defun mouse-sel-selection-overlay (selection)
+ "Return overlay corresponding to SELECTION."
+ (let ((symbol (nth 1 (assoc selection mouse-sel-selection-alist))))
+ (or symbol (error "No overlay corresponding to %s selection" selection))
+ (symbol-value symbol)))
+
+(defun mouse-sel-selection-thing (selection)
+ "Return overlay corresponding to SELECTION."
+ (let ((symbol (nth 2 (assoc selection mouse-sel-selection-alist))))
+ (or symbol (error "No symbol corresponding to %s selection" selection))
+ symbol))
+
+(defun mouse-sel-region-to-primary (orig-window)
+ "Convert region to PRIMARY overlay and deactivate region.
+Argument ORIG-WINDOW specifies the window the cursor was in when the
+originating command was issued, and is used to determine whether the
+region was visible or not."
+ (if transient-mark-mode
+ (let ((overlay (mouse-sel-selection-overlay 'PRIMARY)))
+ (cond
+ ((and mark-active
+ (or highlight-nonselected-windows
+ (eq orig-window (selected-window))))
+ ;; Region was visible, so convert region to overlay
+ (move-overlay overlay (region-beginning) (region-end)
+ (current-buffer)))
+ ((eq orig-window (selected-window))
+ ;; Point was visible, so set overlay at point
+ (move-overlay overlay (point) (point) (current-buffer)))
+ (t
+ ;; Nothing was visible, so remove overlay
+ (delete-overlay overlay)))
+ (setq mark-active nil))))
+
+(defun mouse-sel-primary-to-region (&optional direction)
+ "Convert PRIMARY overlay to region.
+Optional argument DIRECTION specifies the mouse drag direction: a value of
+1 indicates that the mouse was dragged left-to-right, otherwise it was
+dragged right-to-left."
+ (let* ((overlay (mouse-sel-selection-overlay 'PRIMARY))
+ (start (overlay-start overlay))
+ (end (overlay-end overlay)))
+ (if (eq start end)
+ (progn
+ (if start (goto-char start))
+ (deactivate-mark))
+ (if (and mouse-sel-leave-point-near-mouse (eq direction 1))
+ (progn
+ (goto-char end)
+ (push-mark start 'nomsg 'active))
+ (goto-char start)
+ (push-mark end 'nomsg 'active)))
+ (if transient-mark-mode (delete-overlay overlay))))
+
+(defmacro mouse-sel-eval-at-event-end (event &rest forms)
+ "Evaluate forms at mouse position.
+Move to the end position of EVENT, execute FORMS, and restore original
+point and window."
+ (`
+ (let ((posn (event-end (, event))))
+ (if posn (mouse-minibuffer-check (, event)))
+ (if (and posn (not (windowp (posn-window posn))))
+ (error "Cursor not in text area of window"))
+ (let (orig-window orig-point-marker)
+ (setq orig-window (selected-window))
+ (if posn (select-window (posn-window posn)))
+ (setq orig-point-marker (point-marker))
+ (if (and posn (numberp (posn-point posn)))
+ (goto-char (posn-point posn)))
+ (unwind-protect
+ (progn
+ (,@ forms))
+ (goto-char (marker-position orig-point-marker))
+ (move-marker orig-point-marker nil)
+ (select-window orig-window)
+ )))))
+
+(put 'mouse-sel-eval-at-event-end 'lisp-indent-hook 1)
+
+;;=== Select ==============================================================
+
+(defun mouse-select (event)