emacs-diffs
[Top][All Lists]
Advanced

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

master be21c95842: Store latin-1 content into the Haiku clipboard as wel


From: Po Lu
Subject: master be21c95842: Store latin-1 content into the Haiku clipboard as well
Date: Sun, 27 Mar 2022 09:40:22 -0400 (EDT)

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

    Store latin-1 content into the Haiku clipboard as well
    
    * lisp/term/haiku-win.el (haiku-normal-selection-encoders): New
    variable.
    (haiku-select-encode-utf-8-string, haiku-select-encode-xstring):
    New functions.
    (gui-backend-set-selection): Use new selection encoder functions
    instead of hard-coding UTF-8.
    (haiku-dnd-handle-drag-n-drop-event): Rename to
    `haiku-drag-and-drop'.
    
    * src/haiku_select.cc (be_lock_clipboard_message): Accept new
    argument `clear'.
    (be_unlock_clipboard): Accept new argument `discard'.
    
    * src/haikuselect.c (Fhaiku_selection_data): Change calls to
    `be_lock_clipboard_message' and `be_unlock_clipboard'.
    (haiku_unwind_clipboard_lock): New function.
    (Fhaiku_selection_put): Accept new meaning of `name' which means
    to set the selection message.
    
    * src/haikuselect.h: Update prototypes.
---
 lisp/term/haiku-win.el | 38 +++++++++++++++++++++++++++++++---
 src/haiku_select.cc    | 12 +++++++++--
 src/haikuselect.c      | 56 +++++++++++++++++++++++++++++++++++++++++++-------
 src/haikuselect.h      |  6 ++++--
 4 files changed, 98 insertions(+), 14 deletions(-)

diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el
index 2f106825c3..fcf3c4e383 100644
--- a/lisp/term/haiku-win.el
+++ b/lisp/term/haiku-win.el
@@ -61,6 +61,17 @@ DATA can optionally have a text property `type', which 
specifies
 the type of DATA inside the system message (see the doc string of
 `haiku-drag-message' for more details).")
 
+(defvar haiku-normal-selection-encoders '(haiku-select-encode-xstring
+                                          haiku-select-encode-utf-8-string)
+  "List of functions which act as selection encoders.
+These functions accept two arguments SELECTION and VALUE, and
+return an association appropriate for a serialized system
+message (or nil if VALUE is not applicable to the encoder) that
+will be put into the system selection SELECTION.  VALUE is the
+content that is being put into the selection by
+`gui-set-selection'.  See the doc string of `haiku-drag-message'
+for more details on the structure of the associations.")
+
 (defun haiku-dnd-convert-string (value)
   "Convert VALUE to a UTF-8 string and appropriate MIME type.
 Return a list of the appropriate MIME type, and UTF-8 data of
@@ -128,6 +139,22 @@ CLIPBOARD should be the symbol `PRIMARY', `SECONDARY' or
 `CLIPBOARD'.  Return the available types as a list of strings."
   (mapcar #'car (haiku-selection-data clipboard nil)))
 
+(defun haiku-select-encode-xstring (_selection value)
+  "Convert VALUE to a system message association.
+VALUE will be encoded as Latin-1 (like on X Windows) and stored
+under the type `text/plain;charset=iso-8859-1'."
+  (when (stringp value)
+    (list "text/plain;charset=iso-8859-1" 1296649541
+          (encode-coding-string value 'iso-latin-1))))
+
+(defun haiku-select-encode-utf-8-string (_selection value)
+  "Convert VALUE to a system message association.
+VALUE will be encoded as UTF-8 and stored under the type
+`text/plain'."
+  (when (stringp value)
+    (list "text/plain" 1296649541
+          (encode-coding-string value 'utf-8-unix))))
+
 (cl-defmethod gui-backend-get-selection (type data-type
                                               &context (window-system haiku))
   (if (eq data-type 'TARGETS)
@@ -141,7 +168,12 @@ CLIPBOARD should be the symbol `PRIMARY', `SECONDARY' or
                                               &context (window-system haiku))
   (if (eq type 'XdndSelection)
       (setq haiku-dnd-selection-value value)
-    (haiku-selection-put type "text/plain" value t)))
+    (let ((message nil))
+      (dolist (encoder haiku-normal-selection-encoders)
+        (let ((result (funcall encoder type value)))
+          (when result
+            (push result message))))
+      (haiku-selection-put type message nil))))
 
 (cl-defmethod gui-backend-selection-exists-p (selection
                                               &context (window-system haiku))
@@ -165,7 +197,7 @@ CLIPBOARD should be the symbol `PRIMARY', `SECONDARY' or
                             (file-name-nondirectory default-filename))
     (error "x-file-dialog on a tty frame")))
 
-(defun haiku-dnd-handle-drag-n-drop-event (event)
+(defun haiku-drag-and-drop (event)
   "Handle specified drag-n-drop EVENT."
   (interactive "e")
   (let* ((string (caddr event))
@@ -189,7 +221,7 @@ CLIPBOARD should be the symbol `PRIMARY', `SECONDARY' or
      (t (message "Don't know how to drop any of: %s" (mapcar #'car string))))))
 
 (define-key special-event-map [drag-n-drop]
-            'haiku-dnd-handle-drag-n-drop-event)
+            'haiku-drag-and-drop)
 
 (defvaralias 'haiku-use-system-tooltips 'use-system-tooltips)
 
diff --git a/src/haiku_select.cc b/src/haiku_select.cc
index 373ad321c4..e047b9b513 100644
--- a/src/haiku_select.cc
+++ b/src/haiku_select.cc
@@ -413,7 +413,7 @@ be_add_message_message (void *message, const char *name,
 
 int
 be_lock_clipboard_message (enum haiku_clipboard clipboard,
-                          void **message_return)
+                          void **message_return, bool clear)
 {
   BClipboard *board;
 
@@ -427,12 +427,15 @@ be_lock_clipboard_message (enum haiku_clipboard clipboard,
   if (!board->Lock ())
     return 1;
 
+  if (clear)
+    board->Clear ();
+
   *message_return = board->Data ();
   return 0;
 }
 
 void
-be_unlock_clipboard (enum haiku_clipboard clipboard)
+be_unlock_clipboard (enum haiku_clipboard clipboard, bool discard)
 {
   BClipboard *board;
 
@@ -443,5 +446,10 @@ be_unlock_clipboard (enum haiku_clipboard clipboard)
   else
     board = system_clipboard;
 
+  if (discard)
+    board->Revert ();
+  else
+    board->Commit ();
+
   board->Unlock ();
 }
diff --git a/src/haikuselect.c b/src/haikuselect.c
index f1aa4f20d9..461482fea1 100644
--- a/src/haikuselect.c
+++ b/src/haikuselect.c
@@ -27,6 +27,8 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 #include <stdlib.h>
 
+static void haiku_lisp_to_message (Lisp_Object, void *);
+
 DEFUN ("haiku-selection-data", Fhaiku_selection_data, Shaiku_selection_data,
        2, 2, 0,
        doc: /* Retrieve content typed as NAME from the clipboard
@@ -88,7 +90,7 @@ message in the format accepted by `haiku-drag-message', which 
see.  */)
        clipboard_name = CLIPBOARD_CLIPBOARD;
 
       block_input ();
-      rc = be_lock_clipboard_message (clipboard_name, &message);
+      rc = be_lock_clipboard_message (clipboard_name, &message, false);
       unblock_input ();
 
       if (rc)
@@ -96,13 +98,19 @@ message in the format accepted by `haiku-drag-message', 
which see.  */)
 
       block_input ();
       str = haiku_message_to_lisp (message);
-      be_unlock_clipboard (clipboard_name);
+      be_unlock_clipboard (clipboard_name, true);
       unblock_input ();
     }
 
   return str;
 }
 
+static void
+haiku_unwind_clipboard_lock (int clipboard)
+{
+  be_unlock_clipboard (clipboard, false);
+}
+
 DEFUN ("haiku-selection-put", Fhaiku_selection_put, Shaiku_selection_put,
        3, 4, 0,
        doc: /* Add or remove content from the clipboard CLIPBOARD.
@@ -110,18 +118,53 @@ 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.  CLEAR, if non-nil, means to erase all the previous
-contents of the clipboard.  */)
+contents of the clipboard.
+
+Alternatively, NAME can be a system message in the format accepted by
+`haiku-drag-message', which will replace the contents of CLIPBOARD.
+In that case, the arguments after NAME are ignored.  */)
   (Lisp_Object clipboard, Lisp_Object name, Lisp_Object data,
    Lisp_Object clear)
 {
+  enum haiku_clipboard clipboard_name;
+  specpdl_ref ref;
+  char *dat;
+  ptrdiff_t len;
+  int rc;
+  void *message;
+
+  if (CONSP (name) || NILP (name))
+    {
+      if (EQ (clipboard, QPRIMARY))
+       clipboard_name = CLIPBOARD_PRIMARY;
+      else if (EQ (clipboard, QSECONDARY))
+       clipboard_name = CLIPBOARD_SECONDARY;
+      else if (EQ (clipboard, QCLIPBOARD))
+       clipboard_name = CLIPBOARD_CLIPBOARD;
+      else
+       signal_error ("Invalid clipboard", clipboard);
+
+      rc = be_lock_clipboard_message (clipboard_name,
+                                     &message, true);
+
+      if (rc)
+       signal_error ("Couldn't open clipboard", clipboard);
+
+      ref = SPECPDL_INDEX ();
+      record_unwind_protect_int (haiku_unwind_clipboard_lock,
+                                clipboard_name);
+      haiku_lisp_to_message (name, message);
+
+      return unbind_to (ref, Qnil);
+    }
+
   CHECK_SYMBOL (clipboard);
   CHECK_STRING (name);
   if (!NILP (data))
     CHECK_STRING (data);
 
-  block_input ();
-  char *dat = !NILP (data) ? SSDATA (data) : NULL;
-  ptrdiff_t len = !NILP (data) ? SBYTES (data) : 0;
+  dat = !NILP (data) ? SSDATA (data) : NULL;
+  len = !NILP (data) ? SBYTES (data) : 0;
 
   if (EQ (clipboard, QPRIMARY))
     BClipboard_set_primary_selection_data (SSDATA (name), dat, len,
@@ -136,7 +179,6 @@ contents of the clipboard.  */)
       unblock_input ();
       signal_error ("Bad clipboard", clipboard);
     }
-  unblock_input ();
 
   return Qnil;
 }
diff --git a/src/haikuselect.h b/src/haikuselect.h
index 01e4ca327d..5d1dd33c8c 100644
--- a/src/haikuselect.h
+++ b/src/haikuselect.h
@@ -107,8 +107,10 @@ extern "C"
   extern int be_add_message_message (void *message, const char *name,
                                     void *data);
   extern int be_lock_clipboard_message (enum haiku_clipboard clipboard,
-                                       void **message_return);
-  extern void be_unlock_clipboard (enum haiku_clipboard clipboard);
+                                       void **message_return,
+                                       bool clear);
+  extern void be_unlock_clipboard (enum haiku_clipboard clipboard,
+                                  bool discard);
 #ifdef __cplusplus
 };
 #endif



reply via email to

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