aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2022-03-23 08:17:49 +0000
committerPo Lu2022-03-23 08:20:14 +0000
commitfed9a353dbe79a7a6acc74c1e223c46e7541e627 (patch)
tree83d46eebdbdaf2cd612a1ba50cb069f8a03452be
parent5f8a3ca9af70af926b284c98c3995e0743256721 (diff)
downloademacs-fed9a353dbe79a7a6acc74c1e223c46e7541e627.tar.gz
emacs-fed9a353dbe79a7a6acc74c1e223c46e7541e627.zip
Allow retrieving some more kinds of clipboard data on Haiku
* src/haiku_select.cc (BClipboard_find_data): Handle NULL characters inside data correctly. (be_lock_clipboard_message, be_unlock_clipboard): New functions. * src/haikuselect.c (Fhaiku_selection_data): Return entire clipboard contents as a message when clipboard is NULL. (haiku_lisp_to_message): Allow quitting when iterating through potentially large or circular lists. * src/haikuselect.h (enum haiku_clipboard): New enum.
-rw-r--r--src/haiku_select.cc47
-rw-r--r--src/haikuselect.c85
-rw-r--r--src/haikuselect.h10
3 files changed, 114 insertions, 28 deletions
diff --git a/src/haiku_select.cc b/src/haiku_select.cc
index 9012639d6af..bccc79da018 100644
--- a/src/haiku_select.cc
+++ b/src/haiku_select.cc
@@ -64,9 +64,17 @@ BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len)
64 if (len) 64 if (len)
65 *len = bt; 65 *len = bt;
66 66
67 cb->Unlock (); 67 void *data = malloc (bt);
68
69 if (!data)
70 {
71 cb->Unlock ();
72 return NULL;
73 }
68 74
69 return strndup (ptr, bt); 75 memcpy (data, ptr, bt);
76 cb->Unlock ();
77 return (char *) data;
70} 78}
71 79
72static void 80static void
@@ -354,3 +362,38 @@ be_add_refs_data (void *message, const char *name,
354 362
355 return msg->AddRef (name, &ref) != B_OK; 363 return msg->AddRef (name, &ref) != B_OK;
356} 364}
365
366int
367be_lock_clipboard_message (enum haiku_clipboard clipboard,
368 void **message_return)
369{
370 BClipboard *board;
371
372 if (clipboard == CLIPBOARD_PRIMARY)
373 board = primary;
374 else if (clipboard == CLIPBOARD_SECONDARY)
375 board = secondary;
376 else
377 board = system_clipboard;
378
379 if (!board->Lock ())
380 return 1;
381
382 *message_return = board->Data ();
383 return 0;
384}
385
386void
387be_unlock_clipboard (enum haiku_clipboard clipboard)
388{
389 BClipboard *board;
390
391 if (clipboard == CLIPBOARD_PRIMARY)
392 board = primary;
393 else if (clipboard == CLIPBOARD_SECONDARY)
394 board = secondary;
395 else
396 board = system_clipboard;
397
398 board->Unlock ();
399}
diff --git a/src/haikuselect.c b/src/haikuselect.c
index 5a90fe37d22..d59b4512a46 100644
--- a/src/haikuselect.c
+++ b/src/haikuselect.c
@@ -71,43 +71,74 @@ DEFUN ("haiku-selection-data", Fhaiku_selection_data, Shaiku_selection_data,
71 2, 2, 0, 71 2, 2, 0,
72 doc: /* Retrieve content typed as NAME from the clipboard 72 doc: /* Retrieve content typed as NAME from the clipboard
73CLIPBOARD. CLIPBOARD is the symbol `PRIMARY', `SECONDARY' or 73CLIPBOARD. CLIPBOARD is the symbol `PRIMARY', `SECONDARY' or
74`CLIPBOARD'. NAME is a MIME type denoting the type of the data to 74`CLIPBOARD'. NAME is a string describing the MIME type denoting the
75fetch. */) 75type of the data to fetch. If NAME is nil, then the entire contents
76of the clipboard will be returned instead, as a serialized system
77message in the format accepted by `haiku-drag-message', which see. */)
76 (Lisp_Object clipboard, Lisp_Object name) 78 (Lisp_Object clipboard, Lisp_Object name)
77{ 79{
78 CHECK_SYMBOL (clipboard);
79 CHECK_STRING (name);
80 char *dat; 80 char *dat;
81 ssize_t len; 81 ssize_t len;
82 Lisp_Object str;
83 void *message;
84 enum haiku_clipboard clipboard_name;
85 int rc;
82 86
83 block_input (); 87 CHECK_SYMBOL (clipboard);
84 if (EQ (clipboard, QPRIMARY)) 88
85 dat = BClipboard_find_primary_selection_data (SSDATA (name), &len); 89 if (!EQ (clipboard, QPRIMARY) && !EQ (clipboard, QSECONDARY)
86 else if (EQ (clipboard, QSECONDARY)) 90 && !EQ (clipboard, QCLIPBOARD))
87 dat = BClipboard_find_secondary_selection_data (SSDATA (name), &len); 91 signal_error ("Invalid clipboard", clipboard);
88 else if (EQ (clipboard, QCLIPBOARD)) 92
89 dat = BClipboard_find_system_data (SSDATA (name), &len); 93 if (!NILP (name))
90 else
91 { 94 {
95 CHECK_STRING (name);
96
97 block_input ();
98 if (EQ (clipboard, QPRIMARY))
99 dat = BClipboard_find_primary_selection_data (SSDATA (name), &len);
100 else if (EQ (clipboard, QSECONDARY))
101 dat = BClipboard_find_secondary_selection_data (SSDATA (name), &len);
102 else
103 dat = BClipboard_find_system_data (SSDATA (name), &len);
92 unblock_input (); 104 unblock_input ();
93 signal_error ("Bad clipboard", clipboard);
94 }
95 unblock_input ();
96 105
97 if (!dat) 106 if (!dat)
98 return Qnil; 107 return Qnil;
99 108
100 Lisp_Object str = make_unibyte_string (dat, len); 109 str = make_unibyte_string (dat, len);
101 110
102 /* `foreign-selection' just means that the selection has to be 111 /* `foreign-selection' just means that the selection has to be
103 decoded by `gui-get-selection'. It has no other meaning, 112 decoded by `gui-get-selection'. It has no other meaning,
104 AFAICT. */ 113 AFAICT. */
105 Fput_text_property (make_fixnum (0), make_fixnum (len), 114 Fput_text_property (make_fixnum (0), make_fixnum (len),
106 Qforeign_selection, Qt, str); 115 Qforeign_selection, Qt, str);
107 116
108 block_input (); 117 block_input ();
109 BClipboard_free_data (dat); 118 BClipboard_free_data (dat);
110 unblock_input (); 119 unblock_input ();
120 }
121 else
122 {
123 if (EQ (clipboard, QPRIMARY))
124 clipboard_name = CLIPBOARD_PRIMARY;
125 else if (EQ (clipboard, QSECONDARY))
126 clipboard_name = CLIPBOARD_SECONDARY;
127 else
128 clipboard_name = CLIPBOARD_CLIPBOARD;
129
130 block_input ();
131 rc = be_lock_clipboard_message (clipboard_name, &message);
132 unblock_input ();
133
134 if (rc)
135 signal_error ("Couldn't open clipboard", clipboard);
136
137 block_input ();
138 str = haiku_message_to_lisp (message);
139 be_unlock_clipboard (clipboard_name);
140 unblock_input ();
141 }
111 142
112 return str; 143 return str;
113} 144}
@@ -359,6 +390,7 @@ haiku_lisp_to_message (Lisp_Object obj, void *message)
359 CHECK_LIST (obj); 390 CHECK_LIST (obj);
360 for (tem = obj; CONSP (tem); tem = XCDR (tem)) 391 for (tem = obj; CONSP (tem); tem = XCDR (tem))
361 { 392 {
393 maybe_quit ();
362 t1 = XCAR (tem); 394 t1 = XCAR (tem);
363 CHECK_CONS (t1); 395 CHECK_CONS (t1);
364 396
@@ -377,6 +409,7 @@ haiku_lisp_to_message (Lisp_Object obj, void *message)
377 CHECK_LIST (t1); 409 CHECK_LIST (t1);
378 for (t2 = XCDR (t1); CONSP (t2); t2 = XCDR (t2)) 410 for (t2 = XCDR (t1); CONSP (t2); t2 = XCDR (t2))
379 { 411 {
412 maybe_quit ();
380 data = XCAR (t2); 413 data = XCAR (t2);
381 414
382 switch (type_code) 415 switch (type_code)
diff --git a/src/haikuselect.h b/src/haikuselect.h
index 4869d9d33c2..42789949182 100644
--- a/src/haikuselect.h
+++ b/src/haikuselect.h
@@ -25,6 +25,13 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
25 25
26#include <SupportDefs.h> 26#include <SupportDefs.h>
27 27
28enum haiku_clipboard
29 {
30 CLIPBOARD_PRIMARY,
31 CLIPBOARD_SECONDARY,
32 CLIPBOARD_CLIPBOARD
33 };
34
28#ifdef __cplusplus 35#ifdef __cplusplus
29#include <stdio.h> 36#include <stdio.h>
30extern "C" 37extern "C"
@@ -93,6 +100,9 @@ extern "C"
93 ssize_t buf_size); 100 ssize_t buf_size);
94 extern int be_add_refs_data (void *message, const char *name, 101 extern int be_add_refs_data (void *message, const char *name,
95 const char *filename); 102 const char *filename);
103 extern int be_lock_clipboard_message (enum haiku_clipboard clipboard,
104 void **message_return);
105 extern void be_unlock_clipboard (enum haiku_clipboard clipboard);
96#ifdef __cplusplus 106#ifdef __cplusplus
97}; 107};
98#endif 108#endif