diff options
| author | Jan Djärv | 2004-02-10 17:27:26 +0000 |
|---|---|---|
| committer | Jan Djärv | 2004-02-10 17:27:26 +0000 |
| commit | b9aafad504b1d74b069788a088f7ee4b152f5628 (patch) | |
| tree | fd4197ad46eaeb470e14ce2938539ef759d4782b | |
| parent | 706c1e4f43811f71e482aa4e53f28acde4d4c776 (diff) | |
| download | emacs-b9aafad504b1d74b069788a088f7ee4b152f5628.tar.gz emacs-b9aafad504b1d74b069788a088f7ee4b152f5628.zip | |
x-dnd.el: Add COMPOUND_TEXT, handle FILE_NAME correctly, add Motif (CDE)
protocol.
| -rw-r--r-- | lisp/ChangeLog | 17 | ||||
| -rw-r--r-- | lisp/x-dnd.el | 320 |
2 files changed, 311 insertions, 26 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index cd9bee3d932..177bb887d35 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,20 @@ | |||
| 1 | 2004-02-10 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * x-dnd.el (x-dnd-types-alist): Add COMPOUND_TEXT, FILE_NAME | ||
| 4 | handeled by x-dnd-handle-file-name. | ||
| 5 | (x-dnd-known-types): Add COMPOUND_TEXT. | ||
| 6 | (x-dnd-init-frame): Call x-dnd-init-motif-for-frame. | ||
| 7 | (x-dnd-get-state-cons-for-frame): Must do copy-sequence on | ||
| 8 | x-dnd-empty-state. | ||
| 9 | (x-dnd-forget-drop): Ditto. | ||
| 10 | (x-dnd-save-state): Add optional parameter extra-data (for Motif). | ||
| 11 | (x-dnd-handle-one-url): Return private when inserting text. | ||
| 12 | (x-dnd-insert-ctext): New function. | ||
| 13 | (x-dnd-handle-file-name): New function for FILE_NAME. | ||
| 14 | (x-dnd-handle-drag-n-drop-event): Add Motif, remove call to error. | ||
| 15 | (x-dnd-init-motif-for-frame, x-dnd-get-motif-value) | ||
| 16 | (x-dnd-motif-value-to-list, x-dnd-handle-motif): New functions. | ||
| 17 | |||
| 1 | 2004-02-10 Kenichi Handa <handa@m17n.org> | 18 | 2004-02-10 Kenichi Handa <handa@m17n.org> |
| 2 | 19 | ||
| 3 | * term/x-win.el (x-select-utf8-or-ctext): Use compare-strings | 20 | * term/x-win.el (x-select-utf8-or-ctext): Use compare-strings |
diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el index ad55e3cbd34..14681ae7497 100644 --- a/lisp/x-dnd.el +++ b/lisp/x-dnd.el | |||
| @@ -77,13 +77,14 @@ if some action was made, or nil if the URL is ignored." | |||
| 77 | '( | 77 | '( |
| 78 | ("text/uri-list" . x-dnd-handle-uri-list) | 78 | ("text/uri-list" . x-dnd-handle-uri-list) |
| 79 | ("text/x-moz-url" . x-dnd-handle-moz-url) | 79 | ("text/x-moz-url" . x-dnd-handle-moz-url) |
| 80 | ("FILE_NAME" . x-dnd-handle-uri-list) | ||
| 81 | ("_NETSCAPE_URL" . x-dnd-handle-uri-list) | 80 | ("_NETSCAPE_URL" . x-dnd-handle-uri-list) |
| 81 | ("FILE_NAME" . x-dnd-handle-file-name) | ||
| 82 | ("UTF8_STRING" . x-dnd-insert-utf8-text) | 82 | ("UTF8_STRING" . x-dnd-insert-utf8-text) |
| 83 | ("text/plain;charset=UTF-8" . x-dnd-insert-utf8-text) | 83 | ("text/plain;charset=UTF-8" . x-dnd-insert-utf8-text) |
| 84 | ("text/plain;charset=utf-8" . x-dnd-insert-utf8-text) | 84 | ("text/plain;charset=utf-8" . x-dnd-insert-utf8-text) |
| 85 | ("text/unicode" . x-dnd-insert-utf16-text) | 85 | ("text/unicode" . x-dnd-insert-utf16-text) |
| 86 | ("text/plain" . x-dnd-insert-text) | 86 | ("text/plain" . x-dnd-insert-text) |
| 87 | ("COMPOUND_TEXT" . x-dnd-insert-ctext) | ||
| 87 | ("STRING" . x-dnd-insert-text) | 88 | ("STRING" . x-dnd-insert-text) |
| 88 | ("TEXT" . x-dnd-insert-text) | 89 | ("TEXT" . x-dnd-insert-text) |
| 89 | ) | 90 | ) |
| @@ -108,13 +109,14 @@ is successful, nil if not." | |||
| 108 | (defvar x-dnd-known-types | 109 | (defvar x-dnd-known-types |
| 109 | '("text/uri-list" | 110 | '("text/uri-list" |
| 110 | "text/x-moz-url" | 111 | "text/x-moz-url" |
| 111 | "FILE_NAME" | ||
| 112 | "_NETSCAPE_URL" | 112 | "_NETSCAPE_URL" |
| 113 | "FILE_NAME" | ||
| 113 | "UTF8_STRING" | 114 | "UTF8_STRING" |
| 114 | "text/plain;charset=UTF-8" | 115 | "text/plain;charset=UTF-8" |
| 115 | "text/plain;charset=utf-8" | 116 | "text/plain;charset=utf-8" |
| 116 | "text/unicode" | 117 | "text/unicode" |
| 117 | "text/plain" | 118 | "text/plain" |
| 119 | "COMPOUND_TEXT" | ||
| 118 | "STRING" | 120 | "STRING" |
| 119 | "TEXT" | 121 | "TEXT" |
| 120 | ) | 122 | ) |
| @@ -131,15 +133,17 @@ last window drag was in, | |||
| 131 | types available for drop, | 133 | types available for drop, |
| 132 | the action suggested by the source, | 134 | the action suggested by the source, |
| 133 | the type we want for the drop, | 135 | the type we want for the drop, |
| 134 | the action we want for the drop.") | 136 | the action we want for the drop, |
| 137 | any protocol specific data.") | ||
| 135 | 138 | ||
| 136 | (defvar x-dnd-empty-state [nil nil nil nil nil nil]) | 139 | (defvar x-dnd-empty-state [nil nil nil nil nil nil nil]) |
| 137 | 140 | ||
| 138 | 141 | ||
| 139 | 142 | ||
| 140 | (defun x-dnd-init-frame (&optional frame) | 143 | (defun x-dnd-init-frame (&optional frame) |
| 141 | "Setup drag and drop for FRAME (i.e. create appropriate properties)." | 144 | "Setup drag and drop for FRAME (i.e. create appropriate properties)." |
| 142 | (x-dnd-init-xdnd-for-frame frame)) | 145 | (x-dnd-init-xdnd-for-frame frame) |
| 146 | (x-dnd-init-motif-for-frame frame)) | ||
| 143 | 147 | ||
| 144 | (defun x-dnd-get-state-cons-for-frame (frame-or-window) | 148 | (defun x-dnd-get-state-cons-for-frame (frame-or-window) |
| 145 | "Return the entry in x-dnd-current-state for a frame or window." | 149 | "Return the entry in x-dnd-current-state for a frame or window." |
| @@ -147,7 +151,8 @@ the action we want for the drop.") | |||
| 147 | (window-frame frame-or-window))) | 151 | (window-frame frame-or-window))) |
| 148 | (display (frame-parameter frame 'display))) | 152 | (display (frame-parameter frame 'display))) |
| 149 | (if (not (assoc display x-dnd-current-state)) | 153 | (if (not (assoc display x-dnd-current-state)) |
| 150 | (push (cons display x-dnd-empty-state) x-dnd-current-state)) | 154 | (push (cons display (copy-sequence x-dnd-empty-state)) |
| 155 | x-dnd-current-state)) | ||
| 151 | (assoc display x-dnd-current-state))) | 156 | (assoc display x-dnd-current-state))) |
| 152 | 157 | ||
| 153 | (defun x-dnd-get-state-for-frame (frame-or-window) | 158 | (defun x-dnd-get-state-for-frame (frame-or-window) |
| @@ -173,7 +178,8 @@ FRAME-OR-WINDOW is the frame or window that the mouse is over." | |||
| 173 | (defun x-dnd-forget-drop (frame-or-window) | 178 | (defun x-dnd-forget-drop (frame-or-window) |
| 174 | "Remove all state for the last drop. | 179 | "Remove all state for the last drop. |
| 175 | FRAME-OR-WINDOW is the frame or window that the mouse is over." | 180 | FRAME-OR-WINDOW is the frame or window that the mouse is over." |
| 176 | (setcdr (x-dnd-get-state-cons-for-frame frame-or-window) x-dnd-empty-state)) | 181 | (setcdr (x-dnd-get-state-cons-for-frame frame-or-window) |
| 182 | (copy-sequence x-dnd-empty-state))) | ||
| 177 | 183 | ||
| 178 | (defun x-dnd-maybe-call-test-function (window action) | 184 | (defun x-dnd-maybe-call-test-function (window action) |
| 179 | "Call `x-dnd-test-function' if something has changed. | 185 | "Call `x-dnd-test-function' if something has changed. |
| @@ -202,16 +208,18 @@ action and type we got from `x-dnd-test-function'." | |||
| 202 | (cons (aref current-state 5) | 208 | (cons (aref current-state 5) |
| 203 | (aref current-state 4)))) | 209 | (aref current-state 4)))) |
| 204 | 210 | ||
| 205 | (defun x-dnd-save-state (window action action-type &optional types) | 211 | (defun x-dnd-save-state (window action action-type &optional types extra-data) |
| 206 | "Save the state of the current drag and drop. | 212 | "Save the state of the current drag and drop. |
| 207 | WINDOW is the window the mouse is over. ACTION is the action suggested | 213 | WINDOW is the window the mouse is over. ACTION is the action suggested |
| 208 | by the source. ACTION-TYPE is the result of calling `x-dnd-test-function'. | 214 | by the source. ACTION-TYPE is the result of calling `x-dnd-test-function'. |
| 209 | If given, TYPES are the types for the drop data that the source supports." | 215 | If given, TYPES are the types for the drop data that the source supports. |
| 216 | EXTRA-DATA is data needed for a specific protocol." | ||
| 210 | (let ((current-state (x-dnd-get-state-for-frame window))) | 217 | (let ((current-state (x-dnd-get-state-for-frame window))) |
| 211 | (aset current-state 5 (car action-type)) | 218 | (aset current-state 5 (car action-type)) |
| 212 | (aset current-state 4 (cdr action-type)) | 219 | (aset current-state 4 (cdr action-type)) |
| 213 | (aset current-state 3 action) | 220 | (aset current-state 3 action) |
| 214 | (if types (aset current-state 2 types)) | 221 | (when types (aset current-state 2 types)) |
| 222 | (when extra-data (aset current-state 6 extra-data)) | ||
| 215 | (aset current-state 1 window) | 223 | (aset current-state 1 window) |
| 216 | (aset current-state 0 (if (and (windowp window) | 224 | (aset current-state 0 (if (and (windowp window) |
| 217 | (window-live-p window)) | 225 | (window-live-p window)) |
| @@ -219,15 +227,6 @@ If given, TYPES are the types for the drop data that the source supports." | |||
| 219 | (setcdr (x-dnd-get-state-cons-for-frame window) current-state))) | 227 | (setcdr (x-dnd-get-state-cons-for-frame window) current-state))) |
| 220 | 228 | ||
| 221 | 229 | ||
| 222 | (defun x-dnd-test-and-save-state (window action types) | ||
| 223 | "Test if drop shall be accepted, and save the state for future reference. | ||
| 224 | ACTION is the suggested action by the source. | ||
| 225 | TYPES is a list of types the source supports." | ||
| 226 | (x-dnd-save-state window | ||
| 227 | action | ||
| 228 | (x-dnd-maybe-call-test-function window action) | ||
| 229 | types)) | ||
| 230 | |||
| 231 | (defun x-dnd-handle-one-url (window action arg) | 230 | (defun x-dnd-handle-one-url (window action arg) |
| 232 | "Handle one dropped url by calling the appropriate handler. | 231 | "Handle one dropped url by calling the appropriate handler. |
| 233 | The handler is first localted by looking at `x-dnd-protocol-alist'. | 232 | The handler is first localted by looking at `x-dnd-protocol-alist'. |
| @@ -259,7 +258,9 @@ Returns ACTION." | |||
| 259 | (funcall (cdr bf) uri action) | 258 | (funcall (cdr bf) uri action) |
| 260 | (throw 'done t))) | 259 | (throw 'done t))) |
| 261 | nil)) | 260 | nil)) |
| 262 | (x-dnd-insert-text window action uri)) | 261 | (progn |
| 262 | (x-dnd-insert-text window action uri) | ||
| 263 | (setq ret 'private))) | ||
| 263 | ret)) | 264 | ret)) |
| 264 | 265 | ||
| 265 | 266 | ||
| @@ -352,6 +353,13 @@ TEXT is the text as a string, WINDOW is the window where the drop happened." | |||
| 352 | TEXT is the text as a string, WINDOW is the window where the drop happened." | 353 | TEXT is the text as a string, WINDOW is the window where the drop happened." |
| 353 | (x-dnd-insert-text window action (decode-coding-string text 'utf-16le))) | 354 | (x-dnd-insert-text window action (decode-coding-string text 'utf-16le))) |
| 354 | 355 | ||
| 356 | (defun x-dnd-insert-ctext (window action text) | ||
| 357 | "Decode the compound text and insert it at point. | ||
| 358 | TEXT is the text as a string, WINDOW is the window where the drop happened." | ||
| 359 | (x-dnd-insert-text window action | ||
| 360 | (decode-coding-string text | ||
| 361 | 'compound-text-with-extensions))) | ||
| 362 | |||
| 355 | (defun x-dnd-insert-text (window action text) | 363 | (defun x-dnd-insert-text (window action text) |
| 356 | "Insert text at point or push to the kill ring if buffer is read only. | 364 | "Insert text at point or push to the kill ring if buffer is read only. |
| 357 | TEXT is the text as a string, WINDOW is the window where the drop happened." | 365 | TEXT is the text as a string, WINDOW is the window where the drop happened." |
| @@ -377,6 +385,19 @@ STRING is the uri-list as a string. The URIs are separated by \r\n." | |||
| 377 | (when did-action (setq retval did-action)))) | 385 | (when did-action (setq retval did-action)))) |
| 378 | retval)) | 386 | retval)) |
| 379 | 387 | ||
| 388 | (defun x-dnd-handle-file-name (window action string) | ||
| 389 | "Prepend file:// to file names and call `x-dnd-handle-one-url'. | ||
| 390 | WINDOW is the window where the drop happened. | ||
| 391 | STRING is the file names as a string, separated by nulls." | ||
| 392 | (let ((uri-list (split-string string "[\0\r\n]" t)) | ||
| 393 | retval) | ||
| 394 | (dolist (bf uri-list) | ||
| 395 | ;; If one URL is handeled, treat as if the whole drop succeeded. | ||
| 396 | (let* ((file-uri (concat "file://" bf)) | ||
| 397 | (did-action (x-dnd-handle-one-url window action file-uri))) | ||
| 398 | (when did-action (setq retval did-action)))) | ||
| 399 | retval)) | ||
| 400 | |||
| 380 | 401 | ||
| 381 | (defun x-dnd-choose-type (types &optional known-types) | 402 | (defun x-dnd-choose-type (types &optional known-types) |
| 382 | "Choose which type we want to receive for the drop. | 403 | "Choose which type we want to receive for the drop. |
| @@ -438,14 +459,16 @@ TODO: Add Motif and OpenWindows." | |||
| 438 | (format (aref client-message 2)) | 459 | (format (aref client-message 2)) |
| 439 | (data (aref client-message 3))) | 460 | (data (aref client-message 3))) |
| 440 | 461 | ||
| 441 | (cond ((equal "DndProtocol" message-atom) ;; Old KDE 1.x. | 462 | (cond ((equal "DndProtocol" message-atom) ; Old KDE 1.x. |
| 442 | (x-dnd-handle-old-kde event frame window message-atom format data)) | 463 | (x-dnd-handle-old-kde event frame window message-atom format data)) |
| 443 | 464 | ||
| 444 | ((and (> (length message-atom) 4) ;; XDND protocol. | 465 | ((equal "_MOTIF_DRAG_AND_DROP_MESSAGE" message-atom) ; Motif |
| 466 | (x-dnd-handle-motif event frame window message-atom format data)) | ||
| 467 | |||
| 468 | ((and (> (length message-atom) 4) ; XDND protocol. | ||
| 445 | (equal "Xdnd" (substring message-atom 0 4))) | 469 | (equal "Xdnd" (substring message-atom 0 4))) |
| 446 | (x-dnd-handle-xdnd event frame window message-atom format data)) | 470 | (x-dnd-handle-xdnd event frame window message-atom format data))))) |
| 447 | 471 | ||
| 448 | (t (error "Unknown DND atom: %s" message-atom))))) | ||
| 449 | 472 | ||
| 450 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 473 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 451 | ;;; Old KDE protocol. Only dropping of files. | 474 | ;;; Old KDE protocol. Only dropping of files. |
| @@ -471,7 +494,7 @@ TODO: Add Motif and OpenWindows." | |||
| 471 | "Mapping from XDND action types to lisp symbols.") | 494 | "Mapping from XDND action types to lisp symbols.") |
| 472 | 495 | ||
| 473 | (defun x-dnd-init-xdnd-for-frame (frame) | 496 | (defun x-dnd-init-xdnd-for-frame (frame) |
| 474 | "Set the XdndAware for FRAME to indicate that we do XDND." | 497 | "Set the XdndAware property for FRAME to indicate that we do XDND." |
| 475 | (x-change-window-property "XdndAware" | 498 | (x-change-window-property "XdndAware" |
| 476 | '(5) ;; The version of XDND we support. | 499 | '(5) ;; The version of XDND we support. |
| 477 | frame "ATOM" 32 t)) | 500 | frame "ATOM" 32 t)) |
| @@ -566,7 +589,6 @@ FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent." | |||
| 566 | (if (windowp window) (select-window window)) | 589 | (if (windowp window) (select-window window)) |
| 567 | (let* ((dnd-source (aref data 0)) | 590 | (let* ((dnd-source (aref data 0)) |
| 568 | (value (and (x-dnd-current-type window) | 591 | (value (and (x-dnd-current-type window) |
| 569 | ;; Get selection with target DELETE if move. | ||
| 570 | (x-get-selection-internal | 592 | (x-get-selection-internal |
| 571 | 'XdndSelection | 593 | 'XdndSelection |
| 572 | (intern (x-dnd-current-type window))))) | 594 | (intern (x-dnd-current-type window))))) |
| @@ -597,6 +619,252 @@ FORMAT is 32 (not used). MESSAGE is the data part of an XClientMessageEvent." | |||
| 597 | 619 | ||
| 598 | (t (error "Unknown XDND message %s %s" message data)))) | 620 | (t (error "Unknown XDND message %s %s" message data)))) |
| 599 | 621 | ||
| 622 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 623 | ;;; Motif protocol. | ||
| 624 | |||
| 625 | (defun x-dnd-init-motif-for-frame (frame) | ||
| 626 | "Set _MOTIF_DRAG_RECEIVER_INFO for FRAME to indicate that we do Motif DND." | ||
| 627 | (x-change-window-property "_MOTIF_DRAG_RECEIVER_INFO" | ||
| 628 | (list | ||
| 629 | (byteorder) | ||
| 630 | 0 ; The Motif DND version. | ||
| 631 | 5 ; We want drag dynamic. | ||
| 632 | 0 0 0 0 0 0 0 | ||
| 633 | 0 0 0 0 0 0) ; Property must be 16 bytes. | ||
| 634 | frame "_MOTIF_DRAG_RECEIVER_INFO" 8 t)) | ||
| 635 | |||
| 636 | (defun x-dnd-get-motif-value (data offset size byteorder) | ||
| 637 | (cond ((eq size 2) | ||
| 638 | (if (eq byteorder ?l) | ||
| 639 | (+ (ash (aref data (1+ offset)) 8) | ||
| 640 | (aref data offset)) | ||
| 641 | (+ (ash (aref data offset) 8) | ||
| 642 | (aref data (1+ offset))))) | ||
| 643 | |||
| 644 | ((eq size 4) | ||
| 645 | (if (eq byteorder ?l) | ||
| 646 | (cons (+ (ash (aref data (+ 3 offset)) 8) | ||
| 647 | (aref data (+ 2 offset))) | ||
| 648 | (+ (ash (aref data (1+ offset)) 8) | ||
| 649 | (aref data offset))) | ||
| 650 | (cons (+ (ash (aref data offset) 8) | ||
| 651 | (aref data (1+ offset))) | ||
| 652 | (+ (ash (aref data (+ 2 offset)) 8) | ||
| 653 | (aref data (+ 3 offset)))))))) | ||
| 654 | |||
| 655 | (defun x-dnd-motif-value-to-list (value size byteorder) | ||
| 656 | (let ((bytes (cond ((eq size 2) | ||
| 657 | (list (logand (lsh value -8) ?\xff) | ||
| 658 | (logand value ?\xff))) | ||
| 659 | |||
| 660 | ((eq size 4) | ||
| 661 | (if (consp value) | ||
| 662 | (list (logand (lsh (car value) -8) ?\xff) | ||
| 663 | (logand (car value) ?\xff) | ||
| 664 | (logand (lsh (cdr value) -8) ?\xff) | ||
| 665 | (logand (cdr value) ?\xff)) | ||
| 666 | (list (logand (lsh value -24) ?\xff) | ||
| 667 | (logand (lsh value -16) ?\xff) | ||
| 668 | (logand (lsh value -8) ?\xff) | ||
| 669 | (logand value ?\xff))))))) | ||
| 670 | (if (eq byteorder ?l) | ||
| 671 | (reverse bytes) | ||
| 672 | bytes))) | ||
| 673 | |||
| 674 | |||
| 675 | (defvar x-dnd-motif-message-types | ||
| 676 | '((0 . XmTOP_LEVEL_ENTER) | ||
| 677 | (1 . XmTOP_LEVEL_LEAVE) | ||
| 678 | (2 . XmDRAG_MOTION) | ||
| 679 | (3 . XmDROP_SITE_ENTER) | ||
| 680 | (4 . XmDROP_SITE_LEAVE) | ||
| 681 | (5 . XmDROP_START) | ||
| 682 | (6 . XmDROP_FINISH) | ||
| 683 | (7 . XmDRAG_DROP_FINISH) | ||
| 684 | (8 . XmOPERATION_CHANGED)) | ||
| 685 | "Mapping from numbers to Motif DND message types.") | ||
| 686 | |||
| 687 | (defvar x-dnd-motif-to-action | ||
| 688 | '((1 . move) | ||
| 689 | (2 . copy) | ||
| 690 | (3 . link) ; Both 3 and 4 has been seen as link. | ||
| 691 | (4 . link) | ||
| 692 | (2 . private)) ; Motif does not have private, so use copy for private. | ||
| 693 | "Mapping from number to operation for Motif DND.") | ||
| 694 | |||
| 695 | (defun x-dnd-handle-motif (event frame window message-atom format data) | ||
| 696 | (let* ((message-type (cdr (assoc (aref data 0) x-dnd-motif-message-types))) | ||
| 697 | (source-byteorder (aref data 1)) | ||
| 698 | (my-byteorder (byteorder)) | ||
| 699 | (source-flags (x-dnd-get-motif-value data 2 2 source-byteorder)) | ||
| 700 | (source-action (cdr (assoc (logand ?\xF source-flags) | ||
| 701 | x-dnd-motif-to-action)))) | ||
| 702 | |||
| 703 | (cond ((eq message-type 'XmTOP_LEVEL_ENTER) | ||
| 704 | (let* ((dnd-source (x-dnd-get-motif-value | ||
| 705 | data 8 4 source-byteorder)) | ||
| 706 | (selection-atom (x-dnd-get-motif-value | ||
| 707 | data 12 4 source-byteorder)) | ||
| 708 | (atom-name (x-get-atom-name selection-atom)) | ||
| 709 | (types (when atom-name | ||
| 710 | (x-get-selection-internal (intern atom-name) | ||
| 711 | 'TARGETS)))) | ||
| 712 | (x-dnd-forget-drop frame) | ||
| 713 | (when types (x-dnd-save-state window nil nil | ||
| 714 | types | ||
| 715 | dnd-source)))) | ||
| 716 | |||
| 717 | ;; Can not forget drop here, LEAVE comes before DROP_START and | ||
| 718 | ;; we need the state in DROP_START. | ||
| 719 | ((eq message-type 'XmTOP_LEVEL_LEAVE) | ||
| 720 | nil) | ||
| 721 | |||
| 722 | ((eq message-type 'XmDRAG_MOTION) | ||
| 723 | (let* ((state (x-dnd-get-state-for-frame frame)) | ||
| 724 | (timestamp (x-dnd-motif-value-to-list | ||
| 725 | (x-dnd-get-motif-value data 4 4 | ||
| 726 | source-byteorder) | ||
| 727 | 4 my-byteorder)) | ||
| 728 | (x (x-dnd-motif-value-to-list | ||
| 729 | (x-dnd-get-motif-value data 8 2 source-byteorder) | ||
| 730 | 2 my-byteorder)) | ||
| 731 | (y (x-dnd-motif-value-to-list | ||
| 732 | (x-dnd-get-motif-value data 10 2 source-byteorder) | ||
| 733 | 2 my-byteorder)) | ||
| 734 | (dnd-source (aref state 6)) | ||
| 735 | (first-move (not (aref state 3))) | ||
| 736 | (action-type (x-dnd-maybe-call-test-function | ||
| 737 | window | ||
| 738 | source-action)) | ||
| 739 | (reply-action (car (rassoc (car action-type) | ||
| 740 | x-dnd-motif-to-action))) | ||
| 741 | (reply-flags | ||
| 742 | (x-dnd-motif-value-to-list | ||
| 743 | (if reply-action | ||
| 744 | (+ reply-action | ||
| 745 | ?\x30 ; 30: valid drop site | ||
| 746 | ?\x700) ; 700: can do copy, move or link | ||
| 747 | ?\x30) ; 30: drop site, but noop. | ||
| 748 | 2 my-byteorder)) | ||
| 749 | (reply (append | ||
| 750 | (list | ||
| 751 | (+ ?\x80 ; 0x80 indicates a reply. | ||
| 752 | (if first-move | ||
| 753 | 3 ; First time, reply is SITE_ENTER. | ||
| 754 | 2)) ; Not first time, reply is DRAG_MOTION. | ||
| 755 | my-byteorder) | ||
| 756 | reply-flags | ||
| 757 | timestamp | ||
| 758 | x | ||
| 759 | y))) | ||
| 760 | (x-send-client-message frame | ||
| 761 | dnd-source | ||
| 762 | frame | ||
| 763 | "_MOTIF_DRAG_AND_DROP_MESSAGE" | ||
| 764 | 8 | ||
| 765 | reply))) | ||
| 766 | |||
| 767 | ((eq message-type 'XmOPERATION_CHANGED) | ||
| 768 | (let* ((state (x-dnd-get-state-for-frame frame)) | ||
| 769 | (timestamp (x-dnd-motif-value-to-list | ||
| 770 | (x-dnd-get-motif-value data 4 4 source-byteorder) | ||
| 771 | 4 my-byteorder)) | ||
| 772 | (dnd-source (aref state 6)) | ||
| 773 | (action-type (x-dnd-maybe-call-test-function | ||
| 774 | window | ||
| 775 | source-action)) | ||
| 776 | (reply-action (car (rassoc (car action-type) | ||
| 777 | x-dnd-motif-to-action))) | ||
| 778 | (reply-flags | ||
| 779 | (x-dnd-motif-value-to-list | ||
| 780 | (if reply-action | ||
| 781 | (+ reply-action | ||
| 782 | ?\x30 ; 30: valid drop site | ||
| 783 | ?\x700) ; 700: can do copy, move or link | ||
| 784 | ?\x30) ; 30: drop site, but noop | ||
| 785 | 2 my-byteorder)) | ||
| 786 | (reply (append | ||
| 787 | (list | ||
| 788 | (+ ?\x80 ; 0x80 indicates a reply. | ||
| 789 | 8) ; 8 is OPERATION_CHANGED | ||
| 790 | my-byteorder) | ||
| 791 | reply-flags | ||
| 792 | timestamp))) | ||
| 793 | (x-send-client-message frame | ||
| 794 | dnd-source | ||
| 795 | frame | ||
| 796 | "_MOTIF_DRAG_AND_DROP_MESSAGE" | ||
| 797 | 8 | ||
| 798 | reply))) | ||
| 799 | |||
| 800 | ((eq message-type 'XmDROP_START) | ||
| 801 | (let* ((x (x-dnd-motif-value-to-list | ||
| 802 | (x-dnd-get-motif-value data 8 2 source-byteorder) | ||
| 803 | 2 my-byteorder)) | ||
| 804 | (y (x-dnd-motif-value-to-list | ||
| 805 | (x-dnd-get-motif-value data 10 2 source-byteorder) | ||
| 806 | 2 my-byteorder)) | ||
| 807 | (selection-atom (x-dnd-get-motif-value | ||
| 808 | data 12 4 source-byteorder)) | ||
| 809 | (atom-name (x-get-atom-name selection-atom)) | ||
| 810 | (dnd-source (x-dnd-get-motif-value | ||
| 811 | data 16 4 source-byteorder)) | ||
| 812 | (action-type (x-dnd-maybe-call-test-function | ||
| 813 | window | ||
| 814 | source-action)) | ||
| 815 | (reply-action (car (rassoc (car action-type) | ||
| 816 | x-dnd-motif-to-action))) | ||
| 817 | (reply-flags | ||
| 818 | (x-dnd-motif-value-to-list | ||
| 819 | (if reply-action | ||
| 820 | (+ reply-action | ||
| 821 | ?\x30 ; 30: valid drop site | ||
| 822 | ?\x700) ; 700: can do copy, move or link | ||
| 823 | (+ ?\x30 ; 30: drop site, but noop. | ||
| 824 | ?\x200)) ; 200: drop cancel. | ||
| 825 | 2 my-byteorder)) | ||
| 826 | (reply (append | ||
| 827 | (list | ||
| 828 | (+ ?\x80 ; 0x80 indicates a reply. | ||
| 829 | 5) ; DROP_START. | ||
| 830 | my-byteorder) | ||
| 831 | reply-flags | ||
| 832 | x | ||
| 833 | y)) | ||
| 834 | (timestamp (x-dnd-get-motif-value | ||
| 835 | data 4 4 source-byteorder)) | ||
| 836 | action) | ||
| 837 | |||
| 838 | (x-send-client-message frame | ||
| 839 | dnd-source | ||
| 840 | frame | ||
| 841 | "_MOTIF_DRAG_AND_DROP_MESSAGE" | ||
| 842 | 8 | ||
| 843 | reply) | ||
| 844 | (setq action | ||
| 845 | (when (and reply-action atom-name) | ||
| 846 | (let* ((value (x-get-selection-internal | ||
| 847 | (intern atom-name) | ||
| 848 | (intern (x-dnd-current-type window))))) | ||
| 849 | (when value | ||
| 850 | (condition-case info | ||
| 851 | (x-dnd-drop-data event frame window value | ||
| 852 | (x-dnd-current-type window)) | ||
| 853 | (error | ||
| 854 | (message "Error: %s" info) | ||
| 855 | nil)))))) | ||
| 856 | (x-get-selection-internal | ||
| 857 | (intern atom-name) | ||
| 858 | (if action 'XmTRANSFER_SUCCESS 'XmTRANSFER_FAILURE) | ||
| 859 | timestamp) | ||
| 860 | (x-dnd-forget-drop frame))) | ||
| 861 | |||
| 862 | (t (error "Unknown Motif DND message %s %s" message data))))) | ||
| 863 | |||
| 864 | |||
| 865 | ;;; | ||
| 866 | |||
| 867 | |||
| 600 | (provide 'x-dnd) | 868 | (provide 'x-dnd) |
| 601 | 869 | ||
| 602 | ;;; arch-tag: b621fb7e-50da-4323-850b-5fc71ae64621 | 870 | ;;; arch-tag: b621fb7e-50da-4323-850b-5fc71ae64621 |