1 /*
2     SPDX-FileCopyrightText: 2020 Adrien Faveraux <af@brain-networks.fr>
3     SPDX-FileCopyrightText: 2021 Francesco Sorrentino <francesco.sorr@gmail.com>
4 
5     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only
6 */
7 #pragma once
8 
9 #include <QObject>
10 
11 #include <memory>
12 
13 #include <Wrapland/Client/wraplandclient_export.h>
14 
15 struct zwp_primary_selection_device_manager_v1;
16 struct zwp_primary_selection_device_v1;
17 struct zwp_primary_selection_offer_v1;
18 struct zwp_primary_selection_source_v1;
19 class QMimeType;
20 
21 namespace Wrapland::Client
22 {
23 
24 class EventQueue;
25 class PrimarySelectionSource;
26 class PrimarySelectionDevice;
27 class PrimarySelectionOffer;
28 class Seat;
29 class Surface;
30 
31 /**
32  * @short Wrapper for the zwp_primary_selection_device_manager_v1 interface.
33  *
34  * This class provides a convenient wrapper for the zwp_primary_selection_device_manager_v1
35  *interface.
36  *
37  * To use this class one needs to interact with the Registry. There are two
38  * possible ways to create the PrimarySelectionDeviceManager interface:
39  * @code
40  * PrimarySelectionDeviceManager *m = registry->createPrimarySelectionDeviceManager(name, version);
41  * @endcode
42  *
43  * This creates the PrimarySelectionDeviceManager and sets it up directly. As an alternative this
44  * can also be done in a more low level way:
45  * @code
46  * PrimarySelectionDeviceManager *m = new PrimarySelectionDeviceManager;
47  * m->setup(registry->bindPrimarySelectionDeviceManager(name, version));
48  * @endcode
49  *
50  * The PrimarySelectionDeviceManager can be used as a drop-in replacement for any
51  *zwp_primary_selection_device_manager_v1 pointer as it provides matching cast operators.
52  *
53  * @see Registry
54  **/
55 class WRAPLANDCLIENT_EXPORT PrimarySelectionDeviceManager : public QObject
56 {
57     Q_OBJECT
58 public:
59     using device_t = Wrapland::Client::PrimarySelectionDevice;
60     using source_t = Wrapland::Client::PrimarySelectionSource;
61 
62     /**
63      * Creates a new PrimarySelectionDeviceManager.
64      * Note: after construction the object is not yet valid and one needs
65      * to call setup. In order to get a ready to use object prefer using
66      * @c Registry::createPrimarySelectionDeviceManager .
67      **/
68     explicit PrimarySelectionDeviceManager(QObject* parent = nullptr);
69     ~PrimarySelectionDeviceManager() override;
70 
71     /**
72      * @returns @c true if managing a zwp_primary_selection_device_manager_v1.
73      **/
74     bool isValid() const;
75     /**
76      * Setup this PrimarySelectionDeviceManager to manage the @p manager.
77      * When using Registry::createPrimarySelectionDeviceManager there is no need to call this
78      * method.
79      **/
80     void setup(zwp_primary_selection_device_manager_v1* manager);
81     /**
82      * Releases the zwp_primary_selection_device_manager_v1 interface.
83      * After the interface has been released the PrimarySelectionDeviceManager instance is no
84      * longer valid and can be setup with another zwp_primary_selection_device_manager_v1 interface.
85      **/
86     void release();
87 
88     /**
89      * Sets the @p queue to use for creating a PrimarySelectionSource.
90      **/
91     void setEventQueue(EventQueue* queue);
92     /**
93      * @returns The event queue to use for creating a PrimarySelectionSource.
94      **/
95     EventQueue* eventQueue();
96 
97     source_t* createSource(QObject* parent = nullptr);
98 
99     device_t* getDevice(Seat* seat, QObject* parent = nullptr);
100 
101     operator zwp_primary_selection_device_manager_v1*();
102     operator zwp_primary_selection_device_manager_v1*() const;
103 
104 Q_SIGNALS:
105     /**
106      * The corresponding global for this interface on the Registry got removed.
107      *
108      * This signal gets only emitted if the Compositor got created by
109      * Registry::createPrimarySelectionDeviceManager
110      **/
111     void removed();
112 
113 private:
114     class Private;
115     std::unique_ptr<Private> d_ptr;
116 };
117 
118 /**
119  * @short PrimarySelectionDevice allows clients to share data by copy-and-paste and drag-and-drop.
120  *
121  * This class is a convenient wrapper for the zwp_primary_selection_device_v1 interface.
122  * To create a PrimarySelectionDevice call PrimarySelectionDeviceManager::getDevice.
123  *
124  * @see PrimarySelectionDeviceManager
125  **/
126 class WRAPLANDCLIENT_EXPORT PrimarySelectionDevice : public QObject
127 {
128     Q_OBJECT
129 public:
130     using source_t = Wrapland::Client::PrimarySelectionSource;
131     using offer_type = Wrapland::Client::PrimarySelectionOffer;
132 
133     explicit PrimarySelectionDevice(QObject* parent = nullptr);
134     ~PrimarySelectionDevice() override;
135 
136     /**
137      * Setup this PrimarySelectionDevice to manage the @p dataDevice.
138      * When using PrimarySelectionDeviceManager::createPrimarySelectionDevice there is no need to
139      *call this method.
140      **/
141     void setup(zwp_primary_selection_device_v1* dataDevice);
142     /**
143      * Releases the zwp_primary_selection_device_v1 interface.
144      * After the interface has been released the PrimarySelectionDevice instance is no
145      * longer valid and can be setup with another zwp_primary_selection_device_v1 interface.
146      **/
147     void release();
148 
149     /**
150      * @returns @c true if managing a zwp_primary_selection_device_v1.
151      **/
152     bool isValid() const;
153 
154     void startDrag(quint32 serial, source_t* source, Surface* origin, Surface* icon = nullptr);
155     void startDragInternally(quint32 serial, Surface* origin, Surface* icon = nullptr);
156 
157     void setSelection(quint32 serial, source_t* source = nullptr);
158     void clearSelection(quint32 serial);
159 
160     PrimarySelectionOffer* offeredSelection() const;
161 
162     operator zwp_primary_selection_device_v1*();
163     operator zwp_primary_selection_device_v1*() const;
164 
165 Q_SIGNALS:
166     void selectionOffered(Wrapland::Client::PrimarySelectionOffer*);
167     void selectionCleared();
168 
169 private:
170     class Private;
171     std::unique_ptr<Private> d_ptr;
172 };
173 
174 /**
175  * @short Wrapper for the zwp_primary_selection_offer_v1 interface.
176  *
177  * This class is a convenient wrapper for the zwp_primary_selection_offer_v1 interface.
178  * The PrimarySelectionOffer gets created by PrimarySelectionDevice.
179  *
180  * @see PrimarySelectionOfferManager
181  **/
182 class WRAPLANDCLIENT_EXPORT PrimarySelectionOffer : public QObject
183 {
184     Q_OBJECT
185 public:
186     explicit PrimarySelectionOffer(PrimarySelectionDevice* parent,
187                                    zwp_primary_selection_offer_v1* dataOffer);
188     ~PrimarySelectionOffer() override;
189 
190     /**
191      * Releases the zwp_primary_selection_offer_v1 interface.
192      * After the interface has been released the PrimarySelectionOffer instance is no
193      * longer valid and can be setup with another zwp_primary_selection_offer_v1 interface.
194      **/
195     void release();
196 
197     /**
198      * @returns @c true if managing a zwp_primary_selection_offer_v1.
199      **/
200     bool isValid() const;
201 
202     QList<QMimeType> offeredMimeTypes() const;
203 
204     void receive(const QMimeType& mimeType, qint32 fd);
205     void receive(const QString& mimeType, qint32 fd);
206 
207     operator zwp_primary_selection_offer_v1*();
208     operator zwp_primary_selection_offer_v1*() const;
209 
210 Q_SIGNALS:
211     void mimeTypeOffered(const QString&);
212 
213 private:
214     class Private;
215     std::unique_ptr<Private> d_ptr;
216 };
217 
218 /**
219  * @short Wrapper for the zwp_primary_selection_source_v1 interface.
220  *
221  * This class is a convenient wrapper for the zwp_primary_selection_source_v1 interface.
222  * To create a PrimarySelectionSource call
223  *PrimarySelectionDeviceManager::createSource.
224  *
225  * @see PrimarySelectionDeviceManager
226  **/
227 class WRAPLANDCLIENT_EXPORT PrimarySelectionSource : public QObject
228 {
229     Q_OBJECT
230 public:
231     explicit PrimarySelectionSource(QObject* parent = nullptr);
232     ~PrimarySelectionSource() override;
233 
234     /**
235      * Setup this PrimarySelectionSource to manage the @p dataSource.
236      * When using PrimarySelectionDeviceManager::createSource there is no need to
237      *call this method.
238      **/
239     void setup(zwp_primary_selection_source_v1* dataSource);
240     /**
241      * Releases the zwp_primary_selection_source_v1 interface.
242      * After the interface has been released the PrimarySelectionSource instance is no
243      * longer valid and can be setup with another zwp_primary_selection_source_v1 interface.
244      **/
245     void release();
246 
247     /**
248      * @returns @c true if managing a zwp_primary_selection_source_v1.
249      **/
250     bool isValid() const;
251 
252     void offer(const QString& mimeType);
253     void offer(const QMimeType& mimeType);
254 
255     operator zwp_primary_selection_source_v1*();
256     operator zwp_primary_selection_source_v1*() const;
257 
258 Q_SIGNALS:
259     /**
260      * Emitted when a target accepts pointer_focus or motion events. If
261      * a target does not accept any of the offered types, @p mimeType is empty.
262      **/
263     void targetAccepts(const QString& mimeType);
264     /**
265      * Request for data from the client. Send the data as the
266      * specified @p mimeType over the passed file descriptor @p fd, then close
267      * it.
268      **/
269     void sendDataRequested(const QString& mimeType, qint32 fd);
270     /**
271      * This PrimarySelectionSource has been replaced by another PrimarySelectionSource.
272      * The client should clean up and destroy this PrimarySelectionSource.
273      **/
274     void cancelled();
275 
276 private:
277     class Private;
278     std::unique_ptr<Private> d_ptr;
279 };
280 
281 }
282