diff options
| author | Po Lu <luangruo@yahoo.com> | 2021-11-24 12:48:01 +0000 |
|---|---|---|
| committer | Po Lu <luangruo@yahoo.com> | 2021-11-24 12:58:39 +0000 |
| commit | fc35928ec2b3be40ff7323515f948fc82ca487ca (patch) | |
| tree | 0882f12fdad3aab03d56e923905d8c25582ad282 /src | |
| parent | 7878c7f596d69efb68501503da391ed645ae151e (diff) | |
Make `yank-media' work on Haiku
This works with what WebPositive does with images, at least. I don't
know about other programs, but Haiku doesn't seem to standardize this
very well.
* lisp/term/haiku-win.el (haiku--selection-type-to-mime): Handle
regular symbols.
(gui-backend-get-selection): Handle special type `TARGETS'.
(gui-backend-set-selection): Always clear clipboard.
* src/haiku_select.cc (BClipboard_get_targets): New function.
(BClipboard_set_data): New argument `clear'. All callers
changed.
(BClipboard_set_system_data)
(BClipboard_set_primary_selection_data)
(BClipboard_set_secondary_selection_data): New argument `clear'.
(BClipboard_system_targets, BClipboard_primary_targets)
(BClipboard_secondary_targets): New functions.
* src/haikuselect.c (haiku_selection_data_1): New function.
(Fhaiku_selection_targets): New function.
(Fhaiku_selection_put): Allow controlling if the clipboard is
cleared.
(syms_of_haikuselect): New symbols and subrs.
* src/haikuselect.h (BClipboard_set_system_data)
(BClipboard_set_primary_selection_data)
(BClipboard_set_secondary_selection_data): New argument `clear'.
(BClipboard_system_targets, BClipboard_primary_targets)
(BClipboard_secondary_targets): New functions.
Diffstat (limited to 'src')
| -rw-r--r-- | src/haiku_select.cc | 92 | ||||
| -rw-r--r-- | src/haikuselect.c | 60 | ||||
| -rw-r--r-- | src/haikuselect.h | 16 |
3 files changed, 149 insertions, 19 deletions
diff --git a/src/haiku_select.cc b/src/haiku_select.cc index 8d345ca6617..6cd6ee879e5 100644 --- a/src/haiku_select.cc +++ b/src/haiku_select.cc @@ -64,12 +64,62 @@ BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len) } static void +BClipboard_get_targets (BClipboard *cb, char **buf, int buf_size) +{ + BMessage *data; + char *name; + int32 count_found; + type_code type; + int32 i; + int index; + + if (!cb->Lock ()) + { + buf[0] = NULL; + return; + } + + data = cb->Data (); + index = 0; + + if (!data) + { + buf[0] = NULL; + cb->Unlock (); + return; + } + + for (i = 0; (data->GetInfo (B_ANY_TYPE, i, &name, + &type, &count_found) + == B_OK); ++i) + { + if (type == B_MIME_TYPE) + { + if (index < (buf_size - 1)) + { + buf[index++] = strdup (name); + + if (!buf[index - 1]) + break; + } + } + } + + buf[index] = NULL; + + cb->Unlock (); +} + +static void BClipboard_set_data (BClipboard *cb, const char *type, const char *dat, - ssize_t len) + ssize_t len, bool clear) { if (!cb->Lock ()) return; - cb->Clear (); + + if (clear) + cb->Clear (); + BMessage *mdat = cb->Data (); if (!mdat) { @@ -78,7 +128,13 @@ BClipboard_set_data (BClipboard *cb, const char *type, const char *dat, } if (dat) - mdat->AddData (type, B_MIME_TYPE, dat, len); + { + if (mdat->ReplaceData (type, B_MIME_TYPE, dat, len) + == B_NAME_NOT_FOUND) + mdat->AddData (type, B_MIME_TYPE, dat, len); + } + else + mdat->RemoveName (type); cb->Commit (); cb->Unlock (); } @@ -112,32 +168,32 @@ BClipboard_find_secondary_selection_data (const char *type, ssize_t *len) void BClipboard_set_system_data (const char *type, const char *data, - ssize_t len) + ssize_t len, bool clear) { if (!system_clipboard) return; - BClipboard_set_data (system_clipboard, type, data, len); + BClipboard_set_data (system_clipboard, type, data, len, clear); } void BClipboard_set_primary_selection_data (const char *type, const char *data, - ssize_t len) + ssize_t len, bool clear) { if (!primary) return; - BClipboard_set_data (primary, type, data, len); + BClipboard_set_data (primary, type, data, len, clear); } void BClipboard_set_secondary_selection_data (const char *type, const char *data, - ssize_t len) + ssize_t len, bool clear) { if (!secondary) return; - BClipboard_set_data (secondary, type, data, len); + BClipboard_set_data (secondary, type, data, len, clear); } void @@ -147,6 +203,24 @@ BClipboard_free_data (void *ptr) } void +BClipboard_system_targets (char **buf, int len) +{ + BClipboard_get_targets (system_clipboard, buf, len); +} + +void +BClipboard_primary_targets (char **buf, int len) +{ + BClipboard_get_targets (primary, buf, len); +} + +void +BClipboard_secondary_targets (char **buf, int len) +{ + BClipboard_get_targets (secondary, buf, len); +} + +void init_haiku_select (void) { system_clipboard = new BClipboard ("system"); diff --git a/src/haikuselect.c b/src/haikuselect.c index 3f0441e0779..38cceb1de74 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c @@ -24,6 +24,46 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #include "haikuselect.h" #include "haikuterm.h" +static Lisp_Object +haiku_selection_data_1 (Lisp_Object clipboard) +{ + Lisp_Object result = Qnil; + char *targets[256]; + + block_input (); + if (EQ (clipboard, QPRIMARY)) + BClipboard_primary_targets ((char **) &targets, 256); + else if (EQ (clipboard, QSECONDARY)) + BClipboard_secondary_targets ((char **) &targets, 256); + else if (EQ (clipboard, QCLIPBOARD)) + BClipboard_system_targets ((char **) &targets, 256); + else + { + unblock_input (); + signal_error ("Bad clipboard", clipboard); + } + + for (int i = 0; targets[i]; ++i) + { + result = Fcons (build_unibyte_string (targets[i]), + result); + free (targets[i]); + } + unblock_input (); + + return result; +} + +DEFUN ("haiku-selection-targets", Fhaiku_selection_targets, + Shaiku_selection_targets, 1, 1, 0, + doc: /* Find the types of data available from CLIPBOARD. +CLIPBOARD should be the symbol `PRIMARY', `SECONDARY' or `CLIPBOARD'. +Return the available types as a list of strings. */) + (Lisp_Object clipboard) +{ + return haiku_selection_data_1 (clipboard); +} + DEFUN ("haiku-selection-data", Fhaiku_selection_data, Shaiku_selection_data, 2, 2, 0, doc: /* Retrieve content typed as NAME from the clipboard @@ -78,15 +118,17 @@ fetch. */) } DEFUN ("haiku-selection-put", Fhaiku_selection_put, Shaiku_selection_put, - 3, 3, 0, + 3, 4, 0, doc: /* Add or remove content from the clipboard CLIPBOARD. CLIPBOARD is the symbol `PRIMARY', `SECONDARY' or `CLIPBOARD'. NAME is a MIME type denoting the type of the data to add. DATA is the string that will be placed in the clipboard, or nil if the content is -to be removed. If NAME is the string `text/utf-8' or the string -`text/plain', encode it as UTF-8 before storing it into the +to be removed. If NAME is the string "text/utf-8" or the string +"text/plain", encode it as UTF-8 before storing it into the clipboard. +CLEAR, if non-nil, means to erase all the previous contents of the clipboard. */) - (Lisp_Object clipboard, Lisp_Object name, Lisp_Object data) + (Lisp_Object clipboard, Lisp_Object name, Lisp_Object data, + Lisp_Object clear) { CHECK_SYMBOL (clipboard); CHECK_STRING (name); @@ -105,11 +147,13 @@ clipboard. */) ptrdiff_t len = !NILP (data) ? SBYTES (data) : 0; if (EQ (clipboard, QPRIMARY)) - BClipboard_set_primary_selection_data (SSDATA (name), dat, len); + BClipboard_set_primary_selection_data (SSDATA (name), dat, len, + !NILP (clear)); else if (EQ (clipboard, QSECONDARY)) - BClipboard_set_secondary_selection_data (SSDATA (name), dat, len); + BClipboard_set_secondary_selection_data (SSDATA (name), dat, len, + !NILP (clear)); else if (EQ (clipboard, QCLIPBOARD)) - BClipboard_set_system_data (SSDATA (name), dat, len); + BClipboard_set_system_data (SSDATA (name), dat, len, !NILP (clear)); else { unblock_input (); @@ -128,7 +172,9 @@ syms_of_haikuselect (void) DEFSYM (QSTRING, "STRING"); DEFSYM (QUTF8_STRING, "UTF8_STRING"); DEFSYM (Qforeign_selection, "foreign-selection"); + DEFSYM (QTARGETS, "TARGETS"); defsubr (&Shaiku_selection_data); defsubr (&Shaiku_selection_put); + defsubr (&Shaiku_selection_targets); } diff --git a/src/haikuselect.h b/src/haikuselect.h index 542d550d64e..1a3a945f98d 100644 --- a/src/haikuselect.h +++ b/src/haikuselect.h @@ -46,15 +46,25 @@ extern "C" BClipboard_find_secondary_selection_data (const char *type, ssize_t *len); extern void - BClipboard_set_system_data (const char *type, const char *data, ssize_t len); + BClipboard_set_system_data (const char *type, const char *data, ssize_t len, + bool clear); extern void BClipboard_set_primary_selection_data (const char *type, const char *data, - ssize_t len); + ssize_t len, bool clear); extern void BClipboard_set_secondary_selection_data (const char *type, const char *data, - ssize_t len); + ssize_t len, bool clear); + + extern void + BClipboard_system_targets (char **buf, int len); + + extern void + BClipboard_primary_targets (char **buf, int len); + + extern void + BClipboard_secondary_targets (char **buf, int len); /* Free the returned data. */ extern void BClipboard_free_data (void *ptr); |
