Commit fc35928e authored by Po Lu's avatar Po Lu
Browse files

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.
parent 7878c7f5
Pipeline #14181 failed
......@@ -86,15 +86,19 @@ If TYPE is nil, return \"text/plain\"."
(cond
((memq type '(TEXT COMPOUND_TEXT STRING UTF8_STRING)) "text/plain")
((stringp type) type)
((symbolp type) (symbol-name type))
(t "text/plain")))
(cl-defmethod gui-backend-get-selection (type data-type
&context (window-system haiku))
(haiku-selection-data type (haiku--selection-type-to-mime data-type)))
(if (eq data-type 'TARGETS)
(apply #'vector (mapcar #'intern
(haiku-selection-targets type)))
(haiku-selection-data type (haiku--selection-type-to-mime data-type))))
(cl-defmethod gui-backend-set-selection (type value
&context (window-system haiku))
(haiku-selection-put type "text/plain" value))
(haiku-selection-put type "text/plain" value t))
(cl-defmethod gui-backend-selection-exists-p (selection
&context (window-system haiku))
......
......@@ -63,13 +63,63 @@ BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len)
return strndup (ptr, bt);
}
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
......@@ -146,6 +202,24 @@ BClipboard_free_data (void *ptr)
std::free (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)
{
......
......@@ -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);
}
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment