GCC Code Coverage Report


Directory: ./
File: server/data_offer.cpp
Date: 2024-01-22 17:25:27
Exec Total Coverage
Lines: 87 106 82.1%
Branches: 28 70 40.0%

Line Branch Exec Source
1 /********************************************************************
2 Copyright © 2020 Roman Gilg <subdiff@gmail.com>
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 "data_offer.h"
21 #include "data_offer_p.h"
22
23 #include "data_device.h"
24 #include "data_source.h"
25 #include "selection_p.h"
26
27 #include <wayland-server.h>
28
29 namespace Wrapland::Server
30 {
31
32 const struct wl_data_offer_interface data_offer::Private::s_interface = {
33 acceptCallback,
34 receive_callback,
35 destroyCallback,
36 finishCallback,
37 setActionsCallback,
38 };
39
40 60 data_offer::Private::Private(Client* client,
41 30 uint32_t version,
42 data_source* source,
43 data_offer* q_ptr)
44 60 : Wayland::Resource<data_offer>(client,
45 30 version,
46 0,
47 &wl_data_offer_interface,
48 &s_interface,
49 30 q_ptr)
50 30 , source(source)
51 30 , q_ptr{q_ptr}
52 30 {
53 // TODO(unknown author): connect to new selections.
54 30 }
55
56 void data_offer::Private::acceptCallback([[maybe_unused]] wl_client* wlClient,
57 wl_resource* wlResource,
58 [[maybe_unused]] uint32_t serial,
59 char const* mimeType)
60 {
61 // TODO(unknown author): verify serial?
62 auto priv = get_handle(wlResource)->d_ptr;
63 if (!priv->source) {
64 return;
65 }
66 priv->source->accept(mimeType ? mimeType : std::string());
67 }
68
69 1 void data_offer::Private::receive_callback(wl_client* /*wlClient*/,
70 wl_resource* wlResource,
71 char const* mimeType,
72 int32_t fd)
73 {
74 1 auto handle = Resource::get_handle(wlResource);
75 1 receive_mime_type_offer(handle->d_ptr->source, mimeType, fd);
76 1 }
77
78 2 void data_offer::Private::finishCallback([[maybe_unused]] wl_client* wlClient,
79 wl_resource* wlResource)
80 {
81 2 auto priv = get_handle(wlResource)->d_ptr;
82
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!priv->source) {
83 return;
84 }
85 2 priv->source->send_dnd_finished();
86 // TODO(unknown author): It is a client error to perform other requests than
87 // wl_data_offer.destroy after this one.
88 2 }
89
90 4 void data_offer::Private::setActionsCallback(wl_client* wlClient,
91 wl_resource* wlResource,
92 uint32_t dnd_actions,
93 uint32_t preferred_action)
94 {
95 // TODO(unknown author): check it's drag and drop, otherwise send error
96 Q_UNUSED(wlClient)
97 // verify that the no other actions are sent
98
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
8 if (dnd_actions
99 4 & ~(WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE
100 | WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)) {
101 wl_resource_post_error(
102 wlResource, WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK, "Invalid action mask");
103 return;
104 }
105
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
4 if (preferred_action != WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY
106
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 && preferred_action != WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 && preferred_action != WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK
108 && preferred_action != WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE) {
109 wl_resource_post_error(
110 wlResource, WL_DATA_OFFER_ERROR_INVALID_ACTION, "Invalid preferred action");
111 return;
112 }
113
114 4 Server::dnd_actions supportedActions;
115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) {
116 4 supportedActions |= dnd_action::copy;
117 4 }
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) {
119 4 supportedActions |= dnd_action::move;
120 4 }
121
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) {
122 supportedActions |= dnd_action::ask;
123 }
124 4 dnd_action preferredAction = dnd_action::none;
125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (preferred_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) {
126 preferredAction = dnd_action::copy;
127
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 } else if (preferred_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) {
128 4 preferredAction = dnd_action::move;
129
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
4 } else if (preferred_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) {
130 preferredAction = dnd_action::ask;
131 }
132
133 4 auto priv = get_handle(wlResource)->d_ptr;
134
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (priv->supportedDnDActions != supportedActions
135
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 || priv->preferredDnDAction != preferredAction) {
136 4 priv->supportedDnDActions = supportedActions;
137 4 priv->preferredDnDAction = preferredAction;
138 4 Q_EMIT priv->q_ptr->dnd_actions_changed();
139 4 }
140 4 }
141
142 7 void data_offer::Private::send_source_actions()
143 {
144
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 assert(source);
145
146 7 uint32_t wlActions = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
147 7 auto const actions = source->supported_dnd_actions();
148
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
7 if (actions.testFlag(dnd_action::copy)) {
149 5 wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
150 5 }
151
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
7 if (actions.testFlag(dnd_action::move)) {
152 5 wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
153 5 }
154
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (actions.testFlag(dnd_action::ask)) {
155 wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
156 }
157 7 send<wl_data_offer_send_source_actions, WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION>(wlActions);
158 7 }
159
160 30 data_offer::data_offer(Client* client, uint32_t version, data_source* source)
161
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 : d_ptr(new Private(client, version, source, this))
162 30 {
163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 assert(source);
164
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
31 connect(source, &data_source::mime_type_offered, this, [this](std::string const& mimeType) {
165 1 d_ptr->send<wl_data_offer_send_offer>(mimeType.c_str());
166 1 });
167
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 QObject::connect(
168 47 source, &data_source::resourceDestroyed, this, [this] { d_ptr->source = nullptr; });
169 30 }
170
171 30 void data_offer::send_all_offers()
172 {
173
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 27 times.
57 for (auto const& mimeType : d_ptr->source->mime_types()) {
174
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 d_ptr->send<wl_data_offer_send_offer>(mimeType.c_str());
175 }
176 30 }
177
178 4 dnd_actions data_offer::supported_dnd_actions() const
179 {
180 4 return d_ptr->supportedDnDActions;
181 }
182
183 4 dnd_action data_offer::preferred_dnd_action() const
184 {
185 4 return d_ptr->preferredDnDAction;
186 }
187
188 7 void data_offer::send_source_actions()
189 {
190 7 d_ptr->send_source_actions();
191 7 }
192
193 4 void data_offer::send_action(dnd_action action)
194 {
195 4 uint32_t wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (action == dnd_action::copy) {
197 wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
198
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 } else if (action == dnd_action::move) {
199 4 wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
200
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
4 } else if (action == dnd_action::ask) {
201 wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
202 }
203 4 d_ptr->send<wl_data_offer_send_action, WL_DATA_OFFER_ACTION_SINCE_VERSION>(wlAction);
204 4 }
205
206 }
207