Directory: | ./ |
---|---|
File: | src/client/datadevice.cpp |
Date: | 2024-01-22 17:25:27 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 88 | 92 | 95.7% |
Branches: | 24 | 42 | 57.1% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /******************************************************************** | ||
2 | Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 2.1 of the License, or (at your option) version 3, or any | ||
8 | later version accepted by the membership of KDE e.V. (or its | ||
9 | successor approved by the membership of KDE e.V.), which shall | ||
10 | act as a proxy defined in Section 6 of version 3 of the license. | ||
11 | |||
12 | This library is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | Lesser General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU Lesser General Public | ||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | ||
20 | #include "datadevice.h" | ||
21 | #include "dataoffer.h" | ||
22 | #include "datasource.h" | ||
23 | #include "selection_device_p.h" | ||
24 | #include "surface.h" | ||
25 | #include "wayland_pointer_p.h" | ||
26 | // Qt | ||
27 | #include <QPointer> | ||
28 | // Wayland | ||
29 | #include <wayland-client-protocol.h> | ||
30 | |||
31 | namespace Wrapland | ||
32 | { | ||
33 | namespace Client | ||
34 | { | ||
35 | |||
36 | class Q_DECL_HIDDEN DataDevice::Private | ||
37 | { | ||
38 | public: | ||
39 | explicit Private(DataDevice* q); | ||
40 | void setup(wl_data_device* d); | ||
41 | |||
42 | WaylandPointer<wl_data_device, wl_data_device_release> device; | ||
43 | std::unique_ptr<DataOffer> selectionOffer; | ||
44 | struct Drag { | ||
45 | QPointer<DataOffer> offer; | ||
46 | QPointer<Surface> surface; | ||
47 | }; | ||
48 | Drag drag; | ||
49 | |||
50 | void dragEnter(quint32 serial, | ||
51 | QPointer<Surface> const& surface, | ||
52 | QPointF const& relativeToSurface, | ||
53 | wl_data_offer* dataOffer); | ||
54 | void dragLeft(); | ||
55 | static void enterCallback(void* data, | ||
56 | wl_data_device* dataDevice, | ||
57 | uint32_t serial, | ||
58 | wl_surface* surface, | ||
59 | wl_fixed_t x, | ||
60 | wl_fixed_t y, | ||
61 | wl_data_offer* id); | ||
62 | static void leaveCallback(void* data, wl_data_device* dataDevice); | ||
63 | static void motionCallback(void* data, | ||
64 | wl_data_device* dataDevice, | ||
65 | uint32_t time, | ||
66 | wl_fixed_t x, | ||
67 | wl_fixed_t y); | ||
68 | static void dropCallback(void* data, wl_data_device* dataDevice); | ||
69 | |||
70 | static const struct wl_data_device_listener s_listener; | ||
71 | |||
72 | DataDevice* q; | ||
73 | 33 | DataOffer* lastOffer = nullptr; | |
74 | }; | ||
75 | |||
76 | const wl_data_device_listener DataDevice::Private::s_listener = { | ||
77 | data_offer_callback<Private>, | ||
78 | enterCallback, | ||
79 | leaveCallback, | ||
80 | motionCallback, | ||
81 | dropCallback, | ||
82 | selection_callback<Private>, | ||
83 | }; | ||
84 | |||
85 | 7 | void DataDevice::Private::enterCallback(void* data, | |
86 | wl_data_device* dataDevice, | ||
87 | uint32_t serial, | ||
88 | wl_surface* surface, | ||
89 | wl_fixed_t x, | ||
90 | wl_fixed_t y, | ||
91 | wl_data_offer* id) | ||
92 | { | ||
93 | 7 | auto d = reinterpret_cast<Private*>(data); | |
94 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | Q_ASSERT(d->device == dataDevice); |
95 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
14 | d->dragEnter(serial, |
96 | 7 | QPointer<Surface>(Surface::get(surface)), | |
97 |
2/4✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
7 | QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), |
98 | 7 | id); | |
99 | 7 | } | |
100 | |||
101 | 7 | void DataDevice::Private::dragEnter(quint32 serial, | |
102 | QPointer<Surface> const& surface, | ||
103 | QPointF const& relativeToSurface, | ||
104 | wl_data_offer* dataOffer) | ||
105 | { | ||
106 | 7 | drag.surface = surface; | |
107 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | Q_ASSERT(*lastOffer == dataOffer); |
108 | 7 | drag.offer = lastOffer; | |
109 | 7 | lastOffer = nullptr; | |
110 | 7 | Q_EMIT q->dragEntered(serial, relativeToSurface); | |
111 | 7 | } | |
112 | |||
113 | 2 | void DataDevice::Private::leaveCallback(void* data, wl_data_device* dataDevice) | |
114 | { | ||
115 | 2 | auto d = reinterpret_cast<Private*>(data); | |
116 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | Q_ASSERT(d->device == dataDevice); |
117 | 2 | d->dragLeft(); | |
118 | 2 | } | |
119 | |||
120 | 2 | void DataDevice::Private::dragLeft() | |
121 | { | ||
122 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (drag.offer) { |
123 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | delete drag.offer; |
124 | 2 | } | |
125 | 2 | drag = Drag(); | |
126 | 2 | Q_EMIT q->dragLeft(); | |
127 | 2 | } | |
128 | |||
129 | 4 | void DataDevice::Private::motionCallback(void* data, | |
130 | wl_data_device* dataDevice, | ||
131 | uint32_t time, | ||
132 | wl_fixed_t x, | ||
133 | wl_fixed_t y) | ||
134 | { | ||
135 | 4 | auto d = reinterpret_cast<Private*>(data); | |
136 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | Q_ASSERT(d->device == dataDevice); |
137 | 4 | Q_EMIT d->q->dragMotion(QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), time); | |
138 | 4 | } | |
139 | |||
140 | 3 | void DataDevice::Private::dropCallback(void* data, wl_data_device* dataDevice) | |
141 | { | ||
142 | 3 | auto d = reinterpret_cast<Private*>(data); | |
143 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | Q_ASSERT(d->device == dataDevice); |
144 | 3 | Q_EMIT d->q->dropped(); | |
145 | 3 | } | |
146 | |||
147 | 33 | DataDevice::Private::Private(DataDevice* q) | |
148 | 33 | : q(q) | |
149 | { | ||
150 | 33 | } | |
151 | |||
152 | 33 | void DataDevice::Private::setup(wl_data_device* d) | |
153 | { | ||
154 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | Q_ASSERT(d); |
155 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | Q_ASSERT(!device.isValid()); |
156 | 33 | device.setup(d); | |
157 | 33 | wl_data_device_add_listener(device, &s_listener, this); | |
158 | 33 | } | |
159 | |||
160 | 33 | DataDevice::DataDevice(QObject* parent) | |
161 | 33 | : QObject(parent) | |
162 |
2/4✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
|
33 | , d(new Private(this)) |
163 | 33 | { | |
164 | 33 | } | |
165 | |||
166 | 66 | DataDevice::~DataDevice() | |
167 | 66 | { | |
168 |
3/4✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 30 times.
|
33 | if (d->drag.offer) { |
169 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
3 | delete d->drag.offer; |
170 | 3 | } | |
171 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | release(); |
172 | 66 | } | |
173 | |||
174 | 35 | void DataDevice::release() | |
175 | { | ||
176 | 35 | d->device.release(); | |
177 | 35 | } | |
178 | |||
179 | 36 | bool DataDevice::isValid() const | |
180 | { | ||
181 | 36 | return d->device.isValid(); | |
182 | } | ||
183 | |||
184 | 33 | void DataDevice::setup(wl_data_device* dataDevice) | |
185 | { | ||
186 | 33 | d->setup(dataDevice); | |
187 | 33 | } | |
188 | |||
189 | 4 | void DataDevice::startDragInternally(quint32 serial, Surface* origin, Surface* icon) | |
190 | { | ||
191 | 4 | startDrag(serial, nullptr, origin, icon); | |
192 | 4 | } | |
193 | |||
194 | namespace | ||
195 | { | ||
196 | 31 | static wl_data_source* dataSource(DataSource const* source) | |
197 | { | ||
198 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 23 times.
|
31 | if (!source) { |
199 | 8 | return nullptr; | |
200 | } | ||
201 | 23 | return *source; | |
202 | 31 | } | |
203 | } | ||
204 | |||
205 | 13 | void DataDevice::startDrag(quint32 serial, DataSource* source, Surface* origin, Surface* icon) | |
206 | { | ||
207 | 13 | wl_data_device_start_drag( | |
208 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 9 times.
|
13 | d->device, dataSource(source), *origin, icon ? (wl_surface*)*icon : nullptr, serial); |
209 | 13 | } | |
210 | |||
211 | 18 | void DataDevice::setSelection(quint32 serial, DataSource* source) | |
212 | { | ||
213 | 18 | wl_data_device_set_selection(d->device, dataSource(source), serial); | |
214 | 18 | } | |
215 | |||
216 | 6 | DataOffer* DataDevice::offeredSelection() const | |
217 | { | ||
218 | 6 | return d->selectionOffer.get(); | |
219 | } | ||
220 | |||
221 | 4 | QPointer<Surface> DataDevice::dragSurface() const | |
222 | { | ||
223 | 4 | return d->drag.surface; | |
224 | } | ||
225 | |||
226 | 12 | DataOffer* DataDevice::dragOffer() const | |
227 | { | ||
228 | 12 | return d->drag.offer; | |
229 | } | ||
230 | |||
231 | ✗ | DataDevice::operator wl_data_device*() | |
232 | { | ||
233 | ✗ | return d->device; | |
234 | } | ||
235 | |||
236 | ✗ | DataDevice::operator wl_data_device*() const | |
237 | { | ||
238 | ✗ | return d->device; | |
239 | } | ||
240 | |||
241 | } | ||
242 | } | ||
243 |