GCC Code Coverage Report


Directory: ./
File: server/primary_selection.cpp
Date: 2024-01-22 17:25:27
Exec Total Coverage
Lines: 160 172 93.0%
Branches: 38 74 51.4%

Line Branch Exec Source
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 #include "primary_selection_p.h"
8
9 #include "client.h"
10 #include "data_control_v1_p.h"
11 #include "display.h"
12 #include "seat_p.h"
13 #include "selection_p.h"
14
15 namespace Wrapland::Server
16 {
17
18 const struct zwp_primary_selection_device_manager_v1_interface
19 primary_selection_device_manager::Private::s_interface
20 = {
21 cb<create_source>,
22 cb<get_device>,
23 resourceDestroyCallback,
24 };
25
26 49 primary_selection_device_manager::Private::Private(Display* display,
27 primary_selection_device_manager* q_ptr)
28 49 : device_manager<primary_selection_device_manager_global>(
29 49 q_ptr,
30 49 display,
31 &zwp_primary_selection_device_manager_v1_interface,
32 &s_interface)
33 49 {
34
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 create();
35 49 }
36
37 49 primary_selection_device_manager::primary_selection_device_manager(Display* display)
38
2/4
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
49 : d_ptr(new Private(display, this))
39 49 {
40 49 }
41
42 98 primary_selection_device_manager::~primary_selection_device_manager() = default;
43
44 11 void primary_selection_device_manager::create_source(Client* client, uint32_t version, uint32_t id)
45 {
46
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 auto src_res = new primary_selection_source_res(client, version, id);
47 // TODO(romangg): Catch oom.
48
49 11 Q_EMIT source_created(src_res->src());
50 11 }
51
52 14 void primary_selection_device_manager::get_device(Client* client,
53 uint32_t version,
54 uint32_t id,
55 Seat* seat)
56 {
57
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 auto device = new primary_selection_device(client, version, id, seat);
58
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (!device) {
59 return;
60 }
61
62 7 seat->d_ptr->primary_selection_devices.register_device(device);
63 7 Q_EMIT device_created(device);
64 7 }
65
66 const struct zwp_primary_selection_device_v1_interface
67 primary_selection_device::Private::s_interface
68 = {
69 set_selection_callback,
70 destroyCallback,
71 };
72
73
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
14 primary_selection_device::Private::Private(Client* client,
74 uint32_t version,
75 uint32_t id,
76 Seat* seat,
77 primary_selection_device* q_ptr)
78 14 : Wayland::Resource<primary_selection_device>(client,
79 7 version,
80 7 id,
81 &zwp_primary_selection_device_v1_interface,
82 &s_interface,
83 7 q_ptr)
84 7 , m_seat(seat)
85 7 {
86 7 }
87
88 14 primary_selection_device::Private::~Private() = default;
89
90 11 void primary_selection_device::Private::set_selection_callback(wl_client* /*wlClient*/,
91 wl_resource* wlResource,
92 wl_resource* wlSource,
93 uint32_t /*id*/)
94 {
95 // TODO(unknown author): verify serial
96 11 auto handle = Resource::get_handle(wlResource);
97 11 set_selection(handle, handle->d_ptr, wlSource);
98 11 }
99
100 18 void primary_selection_device::send_selection(Wrapland::Server::primary_selection_source* source)
101 {
102
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 5 times.
18 if (!source) {
103 5 send_clear_selection();
104 5 return;
105 }
106
107 13 auto offer = d_ptr->sendDataOffer(source);
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!offer) {
109 return;
110 }
111
112 13 d_ptr->send<zwp_primary_selection_device_v1_send_selection>(offer->d_ptr->resource);
113 18 }
114
115 5 void primary_selection_device::send_clear_selection()
116 {
117 5 d_ptr->send<zwp_primary_selection_device_v1_send_selection>(nullptr);
118 5 }
119
120 primary_selection_offer*
121 13 primary_selection_device::Private::sendDataOffer(primary_selection_source* source)
122 {
123
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (!source) {
124 // A data offer can only exist together with a source.
125 return nullptr;
126 }
127
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 auto offer = new primary_selection_offer(client->handle, version, source);
129
130
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (!offer->d_ptr->resource) {
131 delete offer;
132 return nullptr;
133 }
134
135 13 send<zwp_primary_selection_device_v1_send_data_offer>(offer->d_ptr->resource);
136 13 offer->send_offer();
137 13 return offer;
138 13 }
139
140 7 primary_selection_device::primary_selection_device(Client* client,
141 uint32_t version,
142 uint32_t id,
143 Seat* seat)
144
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 : d_ptr(new Private(client, version, id, seat, this))
145 7 {
146 7 }
147
148 14 primary_selection_device::~primary_selection_device() = default;
149
150 20 primary_selection_source* primary_selection_device::selection()
151 {
152 20 return d_ptr->selection;
153 }
154
155 14 Client* primary_selection_device::client() const
156 {
157 14 return d_ptr->client->handle;
158 }
159
160 2 Seat* primary_selection_device::seat() const
161 {
162 2 return d_ptr->m_seat;
163 }
164
165 const struct zwp_primary_selection_offer_v1_interface primary_selection_offer::Private::s_interface
166 = {
167 receive_callback,
168 destroyCallback,
169 };
170
171 13 primary_selection_offer::Private::Private(Client* client,
172 uint32_t version,
173 primary_selection_source* source,
174 primary_selection_offer* q_ptr)
175 26 : Wayland::Resource<primary_selection_offer>(client,
176 13 version,
177 0,
178 &zwp_primary_selection_offer_v1_interface,
179 &s_interface,
180 13 q_ptr)
181 13 , source(source)
182 13 {
183 13 }
184
185 26 primary_selection_offer::Private::~Private() = default;
186
187 1 void primary_selection_offer::Private::receive_callback(wl_client* /*wlClient*/,
188 wl_resource* wlResource,
189 char const* mimeType,
190 int32_t fd)
191 {
192 1 auto handle = Resource::get_handle(wlResource);
193 1 receive_mime_type_offer(handle->d_ptr->source, mimeType, fd);
194 1 }
195
196 13 primary_selection_offer::primary_selection_offer(Client* client,
197 uint32_t version,
198 primary_selection_source* source)
199
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 : d_ptr(new Private(client, version, source, this))
200 13 {
201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 assert(source);
202
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
26 QObject::connect(source,
203 &primary_selection_source::mime_type_offered,
204 this,
205 14 [this](std::string const& mimeType) {
206 1 d_ptr->send<zwp_primary_selection_offer_v1_send_offer>(mimeType.c_str());
207 1 });
208
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
19 QObject::connect(source, &primary_selection_source::resourceDestroyed, this, [this] {
209 6 d_ptr->source = nullptr;
210 6 });
211 13 }
212
213 26 primary_selection_offer::~primary_selection_offer() = default;
214
215 13 void primary_selection_offer::send_offer()
216 {
217
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 12 times.
25 for (auto const& mimeType : d_ptr->source->mime_types()) {
218
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 d_ptr->send<zwp_primary_selection_offer_v1_send_offer>(mimeType.c_str());
219 }
220 13 }
221
222 13 primary_selection_source::Private::Private(primary_selection_source* q_ptr)
223 13 : q_ptr{q_ptr}
224 {
225 13 }
226
227 13 primary_selection_source::primary_selection_source()
228
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 : d_ptr(new primary_selection_source::Private(this))
229 13 {
230 13 }
231
232 11 primary_selection_source_res_impl::primary_selection_source_res_impl(
233 Client* client,
234 uint32_t version,
235 uint32_t id,
236 primary_selection_source_res* q_ptr)
237 22 : Wayland::Resource<primary_selection_source_res>(client,
238 11 version,
239 11 id,
240 &zwp_primary_selection_source_v1_interface,
241 &s_interface,
242 11 q_ptr)
243 11 , q_ptr{q_ptr}
244 11 {
245 11 }
246
247 const struct zwp_primary_selection_source_v1_interface
248 primary_selection_source_res_impl::s_interface
249 = {
250 offer_callback,
251 destroyCallback,
252 };
253
254 10 void primary_selection_source_res_impl::offer_callback(wl_client* /*wlClient*/,
255 wl_resource* wlResource,
256 char const* mimeType)
257 {
258 10 auto handle = Resource::get_handle(wlResource);
259 10 offer_mime_type(handle->src_priv(), mimeType);
260 10 }
261
262 11 primary_selection_source_res::primary_selection_source_res(Client* client,
263 uint32_t version,
264 uint32_t id)
265
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
11 : pub_src{new primary_selection_source}
266
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
11 , impl{new primary_selection_source_res_impl(client, version, id, this)}
267 11 {
268
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 QObject::connect(this,
269 &primary_selection_source_res::resourceDestroyed,
270
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 src(),
271 11 &primary_selection_source::resourceDestroyed);
272
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 src_priv()->res = this;
273 11 }
274
275 8 void primary_selection_source_res::cancel() const
276 {
277 8 impl->send<zwp_primary_selection_source_v1_send_cancelled>();
278 8 impl->client->flush();
279 8 }
280
281 1 void primary_selection_source_res::request_data(std::string const& mimeType, qint32 fd) const
282 {
283 1 impl->send<zwp_primary_selection_source_v1_send_send>(mimeType.c_str(), fd);
284 1 close(fd);
285 1 }
286
287 31 primary_selection_source* primary_selection_source_res::src() const
288 {
289 31 return src_priv()->q_ptr;
290 }
291
292 52 primary_selection_source::Private* primary_selection_source_res::src_priv() const
293 {
294 52 return pub_src->d_ptr.get();
295 }
296
297 21 std::vector<std::string> primary_selection_source::mime_types() const
298 {
299 21 return d_ptr->mimeTypes;
300 }
301
302 9 void primary_selection_source::cancel() const
303 {
304 18 std::visit([](auto&& res) { res->cancel(); }, d_ptr->res);
305 9 }
306
307 2 void primary_selection_source::request_data(std::string const& mimeType, qint32 fd) const
308 {
309 4 std::visit([&](auto&& res) { res->request_data(mimeType, fd); }, d_ptr->res);
310 2 }
311
312 template<class... Ts>
313 // NOLINTNEXTLINE(fuchsia-multiple-inheritance)
314 struct overload : Ts... {
315 using Ts::operator()...;
316 };
317 template<class... Ts>
318 overload(Ts...) -> overload<Ts...>;
319
320 Client* primary_selection_source::client() const
321 {
322 Client* cl{nullptr};
323
324 std::visit(overload{[&](primary_selection_source_res* res) { cl = res->impl->client->handle; },
325 [&](data_control_source_v1_res* res) { cl = res->impl->client->handle; },
326 [&](primary_selection_source_ext* /*unused*/) {}},
327 d_ptr->res);
328
329 return cl;
330 }
331
332 1 primary_selection_source_ext::Private::Private(primary_selection_source_ext* q_ptr)
333
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 : pub_src{new primary_selection_source}
334 1 , q_ptr{q_ptr}
335 {
336 1 pub_src->d_ptr->res = q_ptr;
337 1 }
338
339 1 primary_selection_source_ext::primary_selection_source_ext()
340
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 : d_ptr{new Private(this)}
341 1 {
342 1 }
343
344 1 primary_selection_source_ext::~primary_selection_source_ext()
345 1 {
346
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 Q_EMIT d_ptr->pub_src->resourceDestroyed();
347 1 }
348
349 1 void primary_selection_source_ext::offer(std::string const& mime_typ)
350 {
351 1 offer_mime_type(d_ptr->pub_src->d_ptr.get(), mime_typ.c_str());
352 1 }
353
354 1 primary_selection_source* primary_selection_source_ext::src() const
355 {
356 1 return d_ptr->pub_src.get();
357 }
358
359 }
360