aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2022-03-18 09:21:39 +0000
committerPo Lu2022-03-18 09:22:13 +0000
commit2b05a06786e7b5adf9d4329959da49d9b40c2bef (patch)
tree43afa72bbceb0a45cc92ea65cd84f29fbd74d6cd
parentff89d27c07de4ac2efc695b06e8aa1faec5d65d1 (diff)
downloademacs-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.el24
-rw-r--r--src/haikuselect.c55
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.
53The functions should accept a single argument VALUE, describing 54The functions should accept a single argument VALUE, describing
54the value of the drag-and-drop selection, and return a list of 55the value of the drag-and-drop selection, and return a list of
55two elements TYPE and DATA, where TYPE is a string containing the 56two elements TYPE and DATA, where TYPE is a string containing the
56MIME type of DATA, and DATA is a unibyte string, or nil if the 57MIME type of DATA, and DATA is a unibyte string, or nil if the
57data could not be converted.") 58data could not be converted.
59
60DATA can optionally have a text property `type', which specifies
61the 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);