Function: x-dnd-handle-xds-drop

x-dnd-handle-xds-drop is a byte-compiled function defined in x-dnd.el.gz.

Signature

(x-dnd-handle-xds-drop EVENT WINDOW SOURCE VERSION)

Documentation

Handle an XDS (X Direct Save) protocol drop.

EVENT is the drag-n-drop event containing the drop. WINDOW is the window on top of which the drop is supposed to happen. SOURCE is the X window that sent the drop. VERSION is the version of the XDND protocol understood by SOURCE.

Source Code

;; Defined in /usr/src/emacs/lisp/x-dnd.el.gz
(defun x-dnd-handle-xds-drop (event window source version)
  "Handle an XDS (X Direct Save) protocol drop.
EVENT is the drag-n-drop event containing the drop.
WINDOW is the window on top of which the drop is supposed to happen.
SOURCE is the X window that sent the drop.
VERSION is the version of the XDND protocol understood by SOURCE."
  (if (not (windowp window))
      ;; We can't perform an XDS drop if there's no window from which
      ;; to determine the current directory.
      (let* ((start (event-start event))
             (frame (posn-window start)))
        (x-send-client-message frame source frame
                               "XdndFinished" 32
                               (list (string-to-number
                                      (frame-parameter frame
                                                       'outer-window-id)))))
    (let ((desired-name (x-window-property "XdndDirectSave0"
                                           (window-frame window)
                                           ;; We currently don't handle
                                           ;; any alternative character
                                           ;; encodings.
                                           "text/plain" source))
          (frame (window-frame window))
          (success nil) save-to save-to-remote hostname)
      (unwind-protect
          (when (stringp desired-name)
            (setq desired-name (decode-coding-string
                                desired-name
                                (or file-name-coding-system
                                    default-file-name-coding-system)))
            (let ((name (expand-file-name
                         (funcall x-dnd-direct-save-function
                                  t desired-name))))
              (setq save-to name save-to-remote name))
            (when save-to
              (if (file-remote-p save-to)
                  (setq hostname (file-remote-p save-to 'host)
                        save-to (file-local-name save-to))
                (setq hostname (system-name)))
              (with-selected-window window
                (let ((uri (format "file://%s%s" hostname save-to)))
                  (x-change-window-property "XdndDirectSave0"
                                            (encode-coding-string
                                             (url-encode-url uri) 'ascii)
                                            frame "text/plain" 8 nil source)
                  (let ((result (x-get-selection-internal 'XdndSelection
                                                          'XdndDirectSave0)))
                    (cond ((equal result "F")
                           (setq success
                                 (x-dnd-handle-octet-stream-for-drop save-to-remote))
                           (unless success
                             (x-change-window-property "XdndDirectSave0" ""
                                                       frame "text/plain" 8
                                                       nil source)))
                          ((equal result "S")
                           (setq success t))
                          ((equal result "E")
                           (setq success nil))
                          (t (error "Broken implementation of XDS: got %s in reply"
                                    result)))
                    (when success
                      (funcall x-dnd-direct-save-function nil save-to-remote)))))))
        ;; We assume XDS always comes from a client supporting version 2
        ;; or later, since custom actions aren't present before.
        (x-send-client-message frame source frame
                               "XdndFinished" 32
                               (list (string-to-number
                                      (frame-parameter frame
                                                       'outer-window-id))
                                     (if (>= version 5)
                                         (if success 1 0)
                                       0)
                                     (if (or (not success)
                                             (< version 5))
                                         0
                                       "XdndActionDirectSave")))))))