Changeset View
Changeset View
Standalone View
Standalone View
src/server/dataoffer_interface.cpp
Show All 11 Lines | |||||
12 | This library is distributed in the hope that it will be useful, | 12 | This library is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | Lesser General Public License for more details. | 15 | Lesser General Public License for more details. | ||
16 | 16 | | |||
17 | You should have received a copy of the GNU Lesser General Public | 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/>. | 18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | #include "dataoffer_interface.h" | 20 | #include "dataoffer_interface_p.h" | ||
21 | #include "datadevice_interface.h" | 21 | #include "datadevice_interface.h" | ||
22 | #include "datasource_interface.h" | 22 | #include "datasource_interface.h" | ||
23 | #include "resource_p.h" | | |||
24 | // Qt | 23 | // Qt | ||
25 | #include <QStringList> | 24 | #include <QStringList> | ||
26 | // Wayland | 25 | // Wayland | ||
27 | #include <wayland-server.h> | 26 | #include <wayland-server.h> | ||
28 | 27 | | |||
29 | namespace KWayland | 28 | namespace KWayland | ||
30 | { | 29 | { | ||
31 | namespace Server | 30 | namespace Server | ||
32 | { | 31 | { | ||
33 | 32 | | |||
34 | class DataOfferInterface::Private : public Resource::Private | | |||
35 | { | | |||
36 | public: | | |||
37 | Private(DataSourceInterface *source, DataDeviceInterface *parentInterface, DataOfferInterface *q, wl_resource *parentResource); | | |||
38 | ~Private(); | | |||
39 | DataSourceInterface *source; | | |||
40 | DataDeviceInterface *dataDevice; | | |||
41 | | ||||
42 | private: | | |||
43 | DataOfferInterface *q_func() { | | |||
44 | return reinterpret_cast<DataOfferInterface *>(q); | | |||
45 | } | | |||
46 | void receive(const QString &mimeType, qint32 fd); | | |||
47 | static void acceptCallback(wl_client *client, wl_resource *resource, uint32_t serial, const char *mimeType); | | |||
48 | static void receiveCallback(wl_client *client, wl_resource *resource, const char *mimeType, int32_t fd); | | |||
49 | | ||||
50 | static const struct wl_data_offer_interface s_interface; | | |||
51 | }; | | |||
52 | | ||||
53 | #ifndef DOXYGEN_SHOULD_SKIP_THIS | 33 | #ifndef DOXYGEN_SHOULD_SKIP_THIS | ||
54 | const struct wl_data_offer_interface DataOfferInterface::Private::s_interface = { | 34 | const struct wl_data_offer_interface DataOfferInterface::Private::s_interface = { | ||
55 | acceptCallback, | 35 | acceptCallback, | ||
56 | receiveCallback, | 36 | receiveCallback, | ||
57 | resourceDestroyedCallback | 37 | resourceDestroyedCallback, | ||
38 | finishCallback, | ||||
39 | setActionsCallback | ||||
58 | }; | 40 | }; | ||
59 | #endif | 41 | #endif | ||
60 | 42 | | |||
61 | DataOfferInterface::Private::Private(DataSourceInterface *source, DataDeviceInterface *parentInterface, DataOfferInterface *q, wl_resource *parentResource) | 43 | DataOfferInterface::Private::Private(DataSourceInterface *source, DataDeviceInterface *parentInterface, DataOfferInterface *q, wl_resource *parentResource) | ||
62 | : Resource::Private(q, nullptr, parentResource, &wl_data_offer_interface, &s_interface) | 44 | : Resource::Private(q, nullptr, parentResource, &wl_data_offer_interface, &s_interface) | ||
63 | , source(source) | 45 | , source(source) | ||
64 | , dataDevice(parentInterface) | 46 | , dataDevice(parentInterface) | ||
65 | { | 47 | { | ||
Show All 19 Lines | 65 | { | |||
85 | cast<Private>(resource)->receive(QString::fromUtf8(mimeType), fd); | 67 | cast<Private>(resource)->receive(QString::fromUtf8(mimeType), fd); | ||
86 | } | 68 | } | ||
87 | 69 | | |||
88 | void DataOfferInterface::Private::receive(const QString &mimeType, qint32 fd) | 70 | void DataOfferInterface::Private::receive(const QString &mimeType, qint32 fd) | ||
89 | { | 71 | { | ||
90 | source->requestData(mimeType, fd); | 72 | source->requestData(mimeType, fd); | ||
91 | } | 73 | } | ||
92 | 74 | | |||
75 | void DataOfferInterface::Private::finishCallback(wl_client *client, wl_resource *resource) | ||||
76 | { | ||||
77 | Q_UNUSED(client) | ||||
78 | auto p = cast<Private>(resource); | ||||
79 | if (!p->source) { | ||||
80 | return; | ||||
81 | } | ||||
82 | p->source->dndFinished(); | ||||
83 | // TODO: It is a client error to perform other requests than wl_data_offer.destroy after this one | ||||
84 | } | ||||
85 | | ||||
86 | void DataOfferInterface::Private::setActionsCallback(wl_client *client, wl_resource *resource, uint32_t dnd_actions, uint32_t preferred_action) | ||||
87 | { | ||||
88 | // TODO: check it's drag and drop, otherwise send error | ||||
89 | Q_UNUSED(client) | ||||
90 | DataDeviceManagerInterface::DnDActions supportedActions; | ||||
91 | if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) { | ||||
92 | supportedActions |= DataDeviceManagerInterface::DnDAction::Copy; | ||||
93 | } | ||||
94 | if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) { | ||||
95 | supportedActions |= DataDeviceManagerInterface::DnDAction::Move; | ||||
96 | } | ||||
97 | if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) { | ||||
98 | supportedActions |= DataDeviceManagerInterface::DnDAction::Ask; | ||||
99 | } | ||||
100 | // verify that the no other actions are sent | ||||
101 | if (dnd_actions & ~(WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)) { | ||||
102 | wl_resource_post_error(resource, WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK, "Invalid action mask"); | ||||
103 | return; | ||||
104 | } | ||||
105 | if (preferred_action != WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY && | ||||
106 | preferred_action != WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE && | ||||
107 | preferred_action != WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK && | ||||
108 | preferred_action != WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE) { | ||||
109 | wl_resource_post_error(resource, WL_DATA_OFFER_ERROR_INVALID_ACTION, "Invalid preferred action"); | ||||
110 | return; | ||||
111 | } | ||||
112 | | ||||
113 | DataDeviceManagerInterface::DnDAction preferredAction = DataDeviceManagerInterface::DnDAction::None; | ||||
114 | if (preferred_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) { | ||||
115 | preferredAction = DataDeviceManagerInterface::DnDAction::Copy; | ||||
116 | } else if (preferred_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) { | ||||
117 | preferredAction = DataDeviceManagerInterface::DnDAction::Move; | ||||
118 | } else if (preferred_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) { | ||||
119 | preferredAction = DataDeviceManagerInterface::DnDAction::Ask; | ||||
120 | } | ||||
121 | | ||||
122 | auto p = cast<Private>(resource); | ||||
123 | p->supportedDnDActions = supportedActions; | ||||
124 | p->preferredDnDAction = preferredAction; | ||||
125 | emit p->q_func()->dragAndDropActionsChanged(); | ||||
126 | } | ||||
127 | | ||||
128 | void DataOfferInterface::Private::sendSourceActions() | ||||
129 | { | ||||
130 | if (!source) { | ||||
131 | return; | ||||
132 | } | ||||
133 | if (wl_resource_get_version(resource) < WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION) { | ||||
134 | return; | ||||
135 | } | ||||
136 | uint32_t wlActions = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; | ||||
137 | const auto actions = source->supportedDragAndDropActions(); | ||||
138 | if (actions.testFlag(DataDeviceManagerInterface::DnDAction::Copy)) { | ||||
139 | wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; | ||||
140 | } | ||||
141 | if (actions.testFlag(DataDeviceManagerInterface::DnDAction::Move)) { | ||||
142 | wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; | ||||
143 | } | ||||
144 | if (actions.testFlag(DataDeviceManagerInterface::DnDAction::Ask)) { | ||||
145 | wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; | ||||
146 | } | ||||
147 | wl_data_offer_send_source_actions(resource, wlActions); | ||||
148 | } | ||||
149 | | ||||
93 | DataOfferInterface::DataOfferInterface(DataSourceInterface *source, DataDeviceInterface *parentInterface, wl_resource *parentResource) | 150 | DataOfferInterface::DataOfferInterface(DataSourceInterface *source, DataDeviceInterface *parentInterface, wl_resource *parentResource) | ||
94 | : Resource(new Private(source, parentInterface, this, parentResource)) | 151 | : Resource(new Private(source, parentInterface, this, parentResource)) | ||
95 | { | 152 | { | ||
96 | Q_ASSERT(source); | 153 | Q_ASSERT(source); | ||
97 | connect(source, &DataSourceInterface::mimeTypeOffered, this, | 154 | connect(source, &DataSourceInterface::mimeTypeOffered, this, | ||
98 | [this](const QString &mimeType) { | 155 | [this](const QString &mimeType) { | ||
99 | Q_D(); | 156 | Q_D(); | ||
100 | if (!d->resource) { | 157 | if (!d->resource) { | ||
Show All 20 Lines | 174 | { | |||
121 | } | 178 | } | ||
122 | } | 179 | } | ||
123 | 180 | | |||
124 | DataOfferInterface::Private *DataOfferInterface::d_func() const | 181 | DataOfferInterface::Private *DataOfferInterface::d_func() const | ||
125 | { | 182 | { | ||
126 | return reinterpret_cast<DataOfferInterface::Private*>(d.data()); | 183 | return reinterpret_cast<DataOfferInterface::Private*>(d.data()); | ||
127 | } | 184 | } | ||
128 | 185 | | |||
186 | DataDeviceManagerInterface::DnDActions DataOfferInterface::supportedDragAndDropActions() const | ||||
187 | { | ||||
188 | Q_D(); | ||||
189 | return d->supportedDnDActions; | ||||
190 | } | ||||
191 | | ||||
192 | DataDeviceManagerInterface::DnDAction DataOfferInterface::preferredDragAndDropAction() const | ||||
193 | { | ||||
194 | Q_D(); | ||||
195 | return d->preferredDnDAction; | ||||
196 | } | ||||
197 | | ||||
198 | void DataOfferInterface::dndAction(DataDeviceManagerInterface::DnDAction action) | ||||
199 | { | ||||
200 | Q_D(); | ||||
201 | if (wl_resource_get_version(d->resource) < WL_DATA_OFFER_ACTION_SINCE_VERSION) { | ||||
202 | return; | ||||
203 | } | ||||
204 | uint32_t wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; | ||||
205 | if (action == DataDeviceManagerInterface::DnDAction::Copy) { | ||||
206 | wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; | ||||
207 | } else if (action == DataDeviceManagerInterface::DnDAction::Move ) { | ||||
208 | wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; | ||||
209 | } else if (action == DataDeviceManagerInterface::DnDAction::Ask) { | ||||
210 | wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; | ||||
211 | } | ||||
212 | wl_data_offer_send_action(d->resource, wlAction); | ||||
213 | } | ||||
214 | | ||||
129 | } | 215 | } | ||
130 | } | 216 | } |