emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master fc35928: Make `yank-media' work on Haiku


From: Po Lu
Subject: master fc35928: Make `yank-media' work on Haiku
Date: Wed, 24 Nov 2021 08:00:32 -0500 (EST)

branch: master
commit fc35928ec2b3be40ff7323515f948fc82ca487ca
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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.
---
 lisp/term/haiku-win.el |  8 +++--
 src/haiku_select.cc    | 92 +++++++++++++++++++++++++++++++++++++++++++++-----
 src/haikuselect.c      | 60 ++++++++++++++++++++++++++++----
 src/haikuselect.h      | 16 +++++++--
 4 files changed, 155 insertions(+), 21 deletions(-)

diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el
index 36af10d..7861cfb 100644
--- a/lisp/term/haiku-win.el
+++ b/lisp/term/haiku-win.el
@@ -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))
diff --git a/src/haiku_select.cc b/src/haiku_select.cc
index 8d345ca..6cd6ee8 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 3f0441e..38cceb1 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 542d550..1a3a945 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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]