1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3  */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 
8 #ifndef __nsClipboardWayland_h_
9 #define __nsClipboardWayland_h_
10 
11 #include <gtk/gtk.h>
12 #include <gdk/gdkwayland.h>
13 #include <nsTArray.h>
14 
15 #include "mozilla/UniquePtr.h"
16 #include "nsClipboard.h"
17 #include "nsWaylandDisplay.h"
18 
19 struct FastTrackClipboard;
20 
21 class DataOffer {
22  public:
23   void AddMIMEType(const char* aMimeType);
24 
25   GdkAtom* GetTargets(int* aTargetNum);
26   bool HasTarget(const char* aMimeType);
27 
28   char* GetData(wl_display* aDisplay, const char* aMimeType,
29                 uint32_t* aContentLength);
30 
31   virtual ~DataOffer() = default;
32 
33  private:
34   virtual bool RequestDataTransfer(const char* aMimeType, int fd) = 0;
35 
36  protected:
37   nsTArray<GdkAtom> mTargetMIMETypes;
38 };
39 
40 class WaylandDataOffer : public DataOffer {
41  public:
42   explicit WaylandDataOffer(wl_data_offer* aWaylandDataOffer);
43 
44   void DragOfferAccept(const char* aMimeType, uint32_t aTime);
45   void SetDragStatus(GdkDragAction aPreferredAction, uint32_t aTime);
46 
47   GdkDragAction GetSelectedDragAction();
48   void SetSelectedDragAction(uint32_t aWaylandAction);
49 
50   void SetAvailableDragActions(uint32_t aWaylandActions);
51   GdkDragAction GetAvailableDragActions();
52 
53   void SetWaylandDragContext(nsWaylandDragContext* aDragContext);
54   nsWaylandDragContext* GetWaylandDragContext();
55 
56   virtual ~WaylandDataOffer();
57 
58  private:
59   bool RequestDataTransfer(const char* aMimeType, int fd) override;
60 
61   wl_data_offer* mWaylandDataOffer;
62   RefPtr<nsWaylandDragContext> mDragContext;
63   uint32_t mSelectedDragAction;
64   uint32_t mAvailableDragActions;
65 };
66 
67 class PrimaryDataOffer : public DataOffer {
68  public:
69   explicit PrimaryDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer);
70   explicit PrimaryDataOffer(zwp_primary_selection_offer_v1* aPrimaryDataOffer);
SetAvailableDragActions(uint32_t aWaylandActions)71   void SetAvailableDragActions(uint32_t aWaylandActions){};
72 
73   virtual ~PrimaryDataOffer();
74 
75  private:
76   bool RequestDataTransfer(const char* aMimeType, int fd) override;
77 
78   gtk_primary_selection_offer* mPrimaryDataOfferGtk;
79   zwp_primary_selection_offer_v1* mPrimaryDataOfferZwpV1;
80 };
81 
82 class nsWaylandDragContext : public nsISupports {
83   NS_DECL_ISUPPORTS
84 
85  public:
86   nsWaylandDragContext(WaylandDataOffer* aWaylandDataOffer,
87                        wl_display* aDisplay);
88 
89   void DropDataEnter(GtkWidget* aGtkWidget, uint32_t aTime, nscoord aX,
90                      nscoord aY);
91   void DropMotion(uint32_t aTime, nscoord aX, nscoord aY);
92   void GetLastDropInfo(uint32_t* aTime, nscoord* aX, nscoord* aY);
93 
94   void SetDragStatus(GdkDragAction aPreferredAction);
95   GdkDragAction GetAvailableDragActions();
96 
GetWidget()97   GtkWidget* GetWidget() { return mGtkWidget; }
98   GList* GetTargets();
99   char* GetData(const char* aMimeType, uint32_t* aContentLength);
100 
101  private:
102   virtual ~nsWaylandDragContext() = default;
103 
104   mozilla::UniquePtr<WaylandDataOffer> mDataOffer;
105   wl_display* mDisplay;
106   uint32_t mTime;
107   GtkWidget* mGtkWidget;
108   nscoord mX, mY;
109 };
110 
111 class nsRetrievalContextWayland : public nsRetrievalContext {
112  public:
113   nsRetrievalContextWayland();
114 
115   virtual const char* GetClipboardData(const char* aMimeType,
116                                        int32_t aWhichClipboard,
117                                        uint32_t* aContentLength) override;
118   virtual const char* GetClipboardText(int32_t aWhichClipboard) override;
119   virtual void ReleaseClipboardData(const char* aClipboardData) override;
120 
121   virtual GdkAtom* GetTargets(int32_t aWhichClipboard,
122                               int* aTargetNum) override;
123   virtual bool HasSelectionSupport(void) override;
124 
125   void RegisterNewDataOffer(wl_data_offer* aWaylandDataOffer);
126   void RegisterNewDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer);
127   void RegisterNewDataOffer(zwp_primary_selection_offer_v1* aPrimaryDataOffer);
128 
129   void SetClipboardDataOffer(wl_data_offer* aWaylandDataOffer);
130   void SetPrimaryDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer);
131   void SetPrimaryDataOffer(zwp_primary_selection_offer_v1* aPrimaryDataOffer);
132   void AddDragAndDropDataOffer(wl_data_offer* aWaylandDataOffer);
133   nsWaylandDragContext* GetDragContext();
134 
135   void ClearDragAndDropDataOffer();
136 
137   void TransferFastTrackClipboard(ClipboardDataType aDataType,
138                                   int aClipboardRequestNumber,
139                                   GtkSelectionData* aSelectionData);
140 
141   virtual ~nsRetrievalContextWayland() override;
142 
143  private:
144   bool mInitialized;
145   RefPtr<mozilla::widget::nsWaylandDisplay> mDisplay;
146 
147   // Data offers provided by Wayland data device
148   GHashTable* mActiveOffers;
149   mozilla::UniquePtr<DataOffer> mClipboardOffer;
150   mozilla::UniquePtr<DataOffer> mPrimaryOffer;
151   RefPtr<nsWaylandDragContext> mDragContext;
152 
153   int mClipboardRequestNumber;
154   char* mClipboardData;
155   uint32_t mClipboardDataLength;
156 
157 // Mime types used for text data at Gtk+, see request_text_received_func()
158 // at gtkclipboard.c.
159 #define TEXT_MIME_TYPES_NUM 3
160   static const char* sTextMimeTypes[TEXT_MIME_TYPES_NUM];
161 };
162 
163 #endif /* __nsClipboardWayland_h_ */
164