Bug 1449490 - [Wayland] Implement gtk_clipboard_request_text() by nsRetrievalContextWayland::GetClipboardText(), r?jhorak draft
authorMartin Stransky <stransky@redhat.com>
Thu, 05 Apr 2018 13:00:58 +0200
changeset 779208 3fdef728eacdcc976da660e8d96d3622f2e105a0
parent 779146 30d72755b1749953d438199456f1524ce84ab5e5
push id105696
push userstransky@redhat.com
push dateMon, 09 Apr 2018 13:42:18 +0000
reviewersjhorak
bugs1449490
milestone61.0a1
Bug 1449490 - [Wayland] Implement gtk_clipboard_request_text() by nsRetrievalContextWayland::GetClipboardText(), r?jhorak MozReview-Commit-ID: 6qcXcA2qUmG
widget/gtk/nsClipboardWayland.cpp
widget/gtk/nsClipboardWayland.h
--- a/widget/gtk/nsClipboardWayland.cpp
+++ b/widget/gtk/nsClipboardWayland.cpp
@@ -33,16 +33,24 @@
 #include <string.h>
 #include <fcntl.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkwayland.h>
 #include <errno.h>
 
 #include "wayland/gtk-primary-selection-client-protocol.h"
 
+const char*
+nsRetrievalContextWayland::sTextMimeTypes[TEXT_MIME_TYPES_NUM] =
+{
+    "text/plain;charset=utf-8",
+    "UTF8_STRING",
+    "COMPOUND_TEXT"
+};
+
 void
 DataOffer::AddMIMEType(const char *aMimeType)
 {
     GdkAtom atom = gdk_atom_intern(aMimeType, FALSE);
     mTargetMIMETypes.AppendElement(atom);
 }
 
 GdkAtom*
@@ -59,16 +67,27 @@ DataOffer::GetTargets(int* aTargetNum)
     for (int32_t j = 0; j < length; j++) {
         targetList[j] = mTargetMIMETypes[j];
     }
 
     *aTargetNum = length;
     return targetList;
 }
 
+bool
+DataOffer::HasTarget(const char *aMimeType)
+{
+    int length = mTargetMIMETypes.Length();
+    for (int32_t j = 0; j < length; j++) {
+        if (mTargetMIMETypes[j] == gdk_atom_intern(aMimeType, FALSE))
+            return true;
+    }
+    return false;
+}
+
 char*
 DataOffer::GetData(wl_display* aDisplay, const char* aMimeType,
                    uint32_t* aContentLength)
 {
     int pipe_fd[2];
     if (pipe(pipe_fd) == -1)
         return nullptr;
 
@@ -694,16 +713,35 @@ nsRetrievalContextWayland::GetClipboardD
                 aMimeType, &mClipboardDataLength);
         }
     }
 
     *aContentLength = mClipboardDataLength;
     return reinterpret_cast<const char*>(mClipboardData);
 }
 
+const char*
+nsRetrievalContextWayland::GetClipboardText(int32_t aWhichClipboard)
+{
+    GdkAtom selection = GetSelectionAtom(aWhichClipboard);
+    DataOffer* dataOffer = (selection == GDK_SELECTION_PRIMARY) ?
+                            mPrimaryOffer : mClipboardOffer;
+    if (!dataOffer)
+        return nullptr;
+
+    for (unsigned int i = 0; i < sizeof(sTextMimeTypes); i++) {
+        if (dataOffer->HasTarget(sTextMimeTypes[i])) {
+            uint32_t unused;
+            return GetClipboardData(sTextMimeTypes[i], aWhichClipboard,
+                                    &unused);
+        }
+    }
+    return nullptr;
+}
+
 void nsRetrievalContextWayland::ReleaseClipboardData(const char* aClipboardData)
 {
     NS_ASSERTION(aClipboardData == mClipboardData,
         "Releasing unknown clipboard data!");
     g_free((void*)aClipboardData);
 
     mClipboardData = nullptr;
     mClipboardDataLength = 0;
--- a/widget/gtk/nsClipboardWayland.h
+++ b/widget/gtk/nsClipboardWayland.h
@@ -18,16 +18,18 @@
 struct FastTrackClipboard;
 
 class DataOffer
 {
 public:
     void AddMIMEType(const char *aMimeType);
 
     GdkAtom* GetTargets(int* aTargetNum);
+    bool  HasTarget(const char *aMimeType);
+
     char* GetData(wl_display* aDisplay, const char* aMimeType,
                   uint32_t* aContentLength);
 
     virtual ~DataOffer() {};
 private:
     virtual bool RequestDataTransfer(const char* aMimeType, int fd) = 0;
 
     nsTArray<GdkAtom> mTargetMIMETypes;
@@ -60,16 +62,17 @@ private:
 class nsRetrievalContextWayland : public nsRetrievalContext
 {
 public:
     nsRetrievalContextWayland();
 
     virtual const char* GetClipboardData(const char* aMimeType,
                                          int32_t aWhichClipboard,
                                          uint32_t* aContentLength) override;
+    virtual const char* GetClipboardText(int32_t aWhichClipboard) override;
     virtual void ReleaseClipboardData(const char* aClipboardData) override;
 
     virtual GdkAtom* GetTargets(int32_t aWhichClipboard,
                                 int* aTargetNum) override;
     virtual bool HasSelectionSupport(void) override;
 
     void RegisterDataOffer(wl_data_offer *aWaylandDataOffer);
     void RegisterDataOffer(gtk_primary_selection_offer *aPrimaryDataOffer);
@@ -99,11 +102,16 @@ private:
     // Data offers provided by Wayland data device
     GHashTable*                 mActiveOffers;
     nsAutoPtr<DataOffer>        mClipboardOffer;
     nsAutoPtr<DataOffer>        mPrimaryOffer;
 
     int                         mClipboardRequestNumber;
     char*                       mClipboardData;
     uint32_t                    mClipboardDataLength;
+
+    // Mime types used for text data at Gtk+, see request_text_received_func()
+    // at gtkclipboard.c.
+    #define TEXT_MIME_TYPES_NUM 3
+    static const char* sTextMimeTypes[TEXT_MIME_TYPES_NUM];
 };
 
 #endif /* __nsClipboardWayland_h_ */