diff options
| author | Po Lu | 2022-03-18 09:21:39 +0000 |
|---|---|---|
| committer | Po Lu | 2022-03-18 09:22:13 +0000 |
| commit | 2b05a06786e7b5adf9d4329959da49d9b40c2bef (patch) | |
| tree | 43afa72bbceb0a45cc92ea65cd84f29fbd74d6cd | |
| parent | ff89d27c07de4ac2efc695b06e8aa1faec5d65d1 (diff) | |
| download | emacs-2b05a06786e7b5adf9d4329959da49d9b40c2bef.tar.gz emacs-2b05a06786e7b5adf9d4329959da49d9b40c2bef.zip | |
Implement drag-and-drop of files on Haiku
* lisp/term/haiku-win.el (haiku-dnd-selection-converters): Add
new selection converter.
(haiku-dnd-convert-uri-list): New function.
(x-begin-drag): Allow selection converters to change message
field type.
* src/haikuselect.c (haiku_lisp_to_message): Perform more error
checking.
| -rw-r--r-- | lisp/term/haiku-win.el | 24 | ||||
| -rw-r--r-- | src/haikuselect.c | 55 |
2 files changed, 56 insertions, 23 deletions
diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index 83f70edd2c3..632177f843e 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el | |||
| @@ -48,13 +48,18 @@ | |||
| 48 | (defvar haiku-dnd-selection-value nil | 48 | (defvar haiku-dnd-selection-value nil |
| 49 | "The local value of the special `XdndSelection' selection.") | 49 | "The local value of the special `XdndSelection' selection.") |
| 50 | 50 | ||
| 51 | (defvar haiku-dnd-selection-converters '((STRING . haiku-dnd-convert-string)) | 51 | (defvar haiku-dnd-selection-converters '((STRING . haiku-dnd-convert-string) |
| 52 | (text/uri-list . haiku-dnd-convert-uri-list)) | ||
| 52 | "Alist of X selection types to functions that act as selection converters. | 53 | "Alist of X selection types to functions that act as selection converters. |
| 53 | The functions should accept a single argument VALUE, describing | 54 | The functions should accept a single argument VALUE, describing |
| 54 | the value of the drag-and-drop selection, and return a list of | 55 | the value of the drag-and-drop selection, and return a list of |
| 55 | two elements TYPE and DATA, where TYPE is a string containing the | 56 | two elements TYPE and DATA, where TYPE is a string containing the |
| 56 | MIME type of DATA, and DATA is a unibyte string, or nil if the | 57 | MIME type of DATA, and DATA is a unibyte string, or nil if the |
| 57 | data could not be converted.") | 58 | data could not be converted. |
| 59 | |||
| 60 | DATA can optionally have a text property `type', which specifies | ||
| 61 | the type of DATA inside the system message (see the doc string of | ||
| 62 | `haiku-drag-message' for more details).") | ||
| 58 | 63 | ||
| 59 | (defun haiku-dnd-convert-string (value) | 64 | (defun haiku-dnd-convert-string (value) |
| 60 | "Convert VALUE to a UTF-8 string and appropriate MIME type. | 65 | "Convert VALUE to a UTF-8 string and appropriate MIME type. |
| @@ -64,6 +69,12 @@ VALUE as a unibyte string, or nil if VALUE was not a string." | |||
| 64 | (list "text/plain" (string-to-unibyte | 69 | (list "text/plain" (string-to-unibyte |
| 65 | (encode-coding-string value 'utf-8))))) | 70 | (encode-coding-string value 'utf-8))))) |
| 66 | 71 | ||
| 72 | (defun haiku-dnd-convert-uri-list (value) | ||
| 73 | "Convert VALUE to a file system reference if it is a file name." | ||
| 74 | (when (and (stringp value) | ||
| 75 | (file-exists-p value)) | ||
| 76 | (list "refs" (propertize (expand-file-name value) 'type 'ref)))) | ||
| 77 | |||
| 67 | (declare-function x-open-connection "haikufns.c") | 78 | (declare-function x-open-connection "haikufns.c") |
| 68 | (declare-function x-handle-args "common-win") | 79 | (declare-function x-handle-args "common-win") |
| 69 | (declare-function haiku-selection-data "haikuselect.c") | 80 | (declare-function haiku-selection-data "haikuselect.c") |
| @@ -199,9 +210,12 @@ take effect on menu items until the menu bar is updated again." | |||
| 199 | (let ((field (cdr (assoc (car selection-result) message)))) | 210 | (let ((field (cdr (assoc (car selection-result) message)))) |
| 200 | (unless (cadr field) | 211 | (unless (cadr field) |
| 201 | ;; Add B_MIME_TYPE to the message if the type was not | 212 | ;; Add B_MIME_TYPE to the message if the type was not |
| 202 | ;; previously defined. | 213 | ;; previously specified, or the type if it was. |
| 203 | (push 1296649541 (alist-get (car selection-result) message | 214 | (push (or (get-text-property 0 'type |
| 204 | nil nil #'equal)))) | 215 | (cadr selection-result)) |
| 216 | 1296649541) | ||
| 217 | (alist-get (car selection-result) message | ||
| 218 | nil nil #'equal)))) | ||
| 205 | (push (cadr selection-result) | 219 | (push (cadr selection-result) |
| 206 | (cdr (alist-get (car selection-result) message | 220 | (cdr (alist-get (car selection-result) message |
| 207 | nil nil #'equal)))))))) | 221 | nil nil #'equal)))))))) |
diff --git a/src/haikuselect.c b/src/haikuselect.c index 807cbc24939..8192a1ad5b9 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c | |||
| @@ -351,6 +351,7 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) | |||
| 351 | int8 char_data; | 351 | int8 char_data; |
| 352 | bool bool_data; | 352 | bool bool_data; |
| 353 | intmax_t t4; | 353 | intmax_t t4; |
| 354 | int rc; | ||
| 354 | 355 | ||
| 355 | CHECK_LIST (obj); | 356 | CHECK_LIST (obj); |
| 356 | for (tem = obj; CONSP (tem); tem = XCDR (tem)) | 357 | for (tem = obj; CONSP (tem); tem = XCDR (tem)) |
| @@ -390,10 +391,13 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) | |||
| 390 | short_data = XFIXNUM (data); | 391 | short_data = XFIXNUM (data); |
| 391 | 392 | ||
| 392 | block_input (); | 393 | block_input (); |
| 393 | be_add_message_data (message, SSDATA (name), | 394 | rc = be_add_message_data (message, SSDATA (name), |
| 394 | type_code, &short_data, | 395 | type_code, &short_data, |
| 395 | sizeof short_data); | 396 | sizeof short_data); |
| 396 | unblock_input (); | 397 | unblock_input (); |
| 398 | |||
| 399 | if (rc) | ||
| 400 | signal_error ("Failed to add short", data); | ||
| 397 | break; | 401 | break; |
| 398 | 402 | ||
| 399 | case 'LONG': | 403 | case 'LONG': |
| @@ -417,10 +421,13 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) | |||
| 417 | } | 421 | } |
| 418 | 422 | ||
| 419 | block_input (); | 423 | block_input (); |
| 420 | be_add_message_data (message, SSDATA (name), | 424 | rc = be_add_message_data (message, SSDATA (name), |
| 421 | type_code, &long_data, | 425 | type_code, &long_data, |
| 422 | sizeof long_data); | 426 | sizeof long_data); |
| 423 | unblock_input (); | 427 | unblock_input (); |
| 428 | |||
| 429 | if (rc) | ||
| 430 | signal_error ("Failed to add long", data); | ||
| 424 | break; | 431 | break; |
| 425 | 432 | ||
| 426 | case 'LLNG': | 433 | case 'LLNG': |
| @@ -443,10 +450,13 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) | |||
| 443 | } | 450 | } |
| 444 | 451 | ||
| 445 | block_input (); | 452 | block_input (); |
| 446 | be_add_message_data (message, SSDATA (name), | 453 | rc = be_add_message_data (message, SSDATA (name), |
| 447 | type_code, &llong_data, | 454 | type_code, &llong_data, |
| 448 | sizeof llong_data); | 455 | sizeof llong_data); |
| 449 | unblock_input (); | 456 | unblock_input (); |
| 457 | |||
| 458 | if (rc) | ||
| 459 | signal_error ("Failed to add llong", data); | ||
| 450 | break; | 460 | break; |
| 451 | 461 | ||
| 452 | case 'CHAR': | 462 | case 'CHAR': |
| @@ -456,30 +466,39 @@ haiku_lisp_to_message (Lisp_Object obj, void *message) | |||
| 456 | char_data = XFIXNUM (data); | 466 | char_data = XFIXNUM (data); |
| 457 | 467 | ||
| 458 | block_input (); | 468 | block_input (); |
| 459 | be_add_message_data (message, SSDATA (name), | 469 | rc = be_add_message_data (message, SSDATA (name), |
| 460 | type_code, &char_data, | 470 | type_code, &char_data, |
| 461 | sizeof char_data); | 471 | sizeof char_data); |
| 462 | unblock_input (); | 472 | unblock_input (); |
| 473 | |||
| 474 | if (rc) | ||
| 475 | signal_error ("Failed to add char", data); | ||
| 463 | break; | 476 | break; |
| 464 | 477 | ||
| 465 | case 'BOOL': | 478 | case 'BOOL': |
| 466 | bool_data = !NILP (data); | 479 | bool_data = !NILP (data); |
| 467 | 480 | ||
| 468 | block_input (); | 481 | block_input (); |
| 469 | be_add_message_data (message, SSDATA (name), | 482 | rc = be_add_message_data (message, SSDATA (name), |
| 470 | type_code, &bool_data, | 483 | type_code, &bool_data, |
| 471 | sizeof bool_data); | 484 | sizeof bool_data); |
| 472 | unblock_input (); | 485 | unblock_input (); |
| 486 | |||
| 487 | if (rc) | ||
| 488 | signal_error ("Failed to add bool", data); | ||
| 473 | break; | 489 | break; |
| 474 | 490 | ||
| 475 | default: | 491 | default: |
| 476 | CHECK_STRING (data); | 492 | CHECK_STRING (data); |
| 477 | 493 | ||
| 478 | block_input (); | 494 | block_input (); |
| 479 | be_add_message_data (message, SSDATA (name), | 495 | rc = be_add_message_data (message, SSDATA (name), |
| 480 | type_code, SDATA (data), | 496 | type_code, SDATA (data), |
| 481 | SBYTES (data)); | 497 | SBYTES (data)); |
| 482 | unblock_input (); | 498 | unblock_input (); |
| 499 | |||
| 500 | if (rc) | ||
| 501 | signal_error ("Failed to add", data); | ||
| 483 | } | 502 | } |
| 484 | } | 503 | } |
| 485 | CHECK_LIST_END (t2, t1); | 504 | CHECK_LIST_END (t2, t1); |