2020-03-15 15:19:28 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
|
2014-11-04 14:10:22 +00:00
|
|
|
|
2020-03-15 15:19:28 +00:00
|
|
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
|
|
*/
|
2014-11-04 14:10:22 +00:00
|
|
|
#include "datasource_interface.h"
|
2014-11-14 08:45:02 +00:00
|
|
|
#include "datadevicemanager_interface.h"
|
2016-09-12 06:57:07 +00:00
|
|
|
#include "clientconnection.h"
|
2014-11-14 08:45:02 +00:00
|
|
|
#include "resource_p.h"
|
2014-11-04 14:10:22 +00:00
|
|
|
// Qt
|
|
|
|
#include <QStringList>
|
|
|
|
// Wayland
|
|
|
|
#include <wayland-server.h>
|
2014-11-27 10:23:37 +00:00
|
|
|
// system
|
|
|
|
#include <unistd.h>
|
2014-11-04 14:10:22 +00:00
|
|
|
|
2020-04-29 14:56:38 +00:00
|
|
|
namespace KWaylandServer
|
2014-11-04 14:10:22 +00:00
|
|
|
{
|
|
|
|
|
2014-11-14 08:45:02 +00:00
|
|
|
class DataSourceInterface::Private : public Resource::Private
|
2014-11-04 14:10:22 +00:00
|
|
|
{
|
|
|
|
public:
|
2014-11-20 15:40:14 +00:00
|
|
|
Private(DataSourceInterface *q, DataDeviceManagerInterface *parent, wl_resource *parentResource);
|
2014-11-04 14:10:22 +00:00
|
|
|
~Private();
|
|
|
|
|
|
|
|
QStringList mimeTypes;
|
2017-12-26 20:55:11 +00:00
|
|
|
DataDeviceManagerInterface::DnDActions supportedDnDActions = DataDeviceManagerInterface::DnDAction::None;
|
2014-11-04 14:10:22 +00:00
|
|
|
|
|
|
|
private:
|
2014-11-14 09:55:06 +00:00
|
|
|
DataSourceInterface *q_func() {
|
|
|
|
return reinterpret_cast<DataSourceInterface *>(q);
|
|
|
|
}
|
2014-11-04 14:10:22 +00:00
|
|
|
void offer(const QString &mimeType);
|
|
|
|
|
|
|
|
static void offerCallback(wl_client *client, wl_resource *resource, const char *mimeType);
|
2017-11-26 15:31:57 +00:00
|
|
|
static void setActionsCallback(wl_client *client, wl_resource *resource, uint32_t dnd_actions);
|
2014-11-04 14:10:22 +00:00
|
|
|
|
|
|
|
const static struct wl_data_source_interface s_interface;
|
|
|
|
};
|
|
|
|
|
2020-01-23 11:20:45 +00:00
|
|
|
#ifndef K_DOXYGEN
|
2014-11-04 14:10:22 +00:00
|
|
|
const struct wl_data_source_interface DataSourceInterface::Private::s_interface = {
|
|
|
|
offerCallback,
|
2017-11-26 15:31:57 +00:00
|
|
|
resourceDestroyedCallback,
|
|
|
|
setActionsCallback
|
2014-11-04 14:10:22 +00:00
|
|
|
};
|
2015-09-09 14:39:50 +00:00
|
|
|
#endif
|
2014-11-04 14:10:22 +00:00
|
|
|
|
2014-11-20 15:40:14 +00:00
|
|
|
DataSourceInterface::Private::Private(DataSourceInterface *q, DataDeviceManagerInterface *parent, wl_resource *parentResource)
|
|
|
|
: Resource::Private(q, parent, parentResource, &wl_data_source_interface, &s_interface)
|
2014-11-04 14:10:22 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-11-14 08:45:02 +00:00
|
|
|
DataSourceInterface::Private::~Private() = default;
|
2014-11-04 14:10:22 +00:00
|
|
|
|
|
|
|
void DataSourceInterface::Private::offerCallback(wl_client *client, wl_resource *resource, const char *mimeType)
|
|
|
|
{
|
|
|
|
Q_UNUSED(client)
|
2014-11-14 09:20:43 +00:00
|
|
|
cast<Private>(resource)->offer(QString::fromUtf8(mimeType));
|
2014-11-04 14:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DataSourceInterface::Private::offer(const QString &mimeType)
|
|
|
|
{
|
|
|
|
mimeTypes << mimeType;
|
2014-11-14 09:55:06 +00:00
|
|
|
Q_Q(DataSourceInterface);
|
2014-11-04 14:10:22 +00:00
|
|
|
emit q->mimeTypeOffered(mimeType);
|
|
|
|
}
|
|
|
|
|
2017-11-26 15:31:57 +00:00
|
|
|
void DataSourceInterface::Private::setActionsCallback(wl_client *client, wl_resource *resource, uint32_t dnd_actions)
|
|
|
|
{
|
|
|
|
Q_UNUSED(client)
|
|
|
|
DataDeviceManagerInterface::DnDActions supportedActions;
|
|
|
|
if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) {
|
|
|
|
supportedActions |= DataDeviceManagerInterface::DnDAction::Copy;
|
|
|
|
}
|
|
|
|
if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) {
|
|
|
|
supportedActions |= DataDeviceManagerInterface::DnDAction::Move;
|
|
|
|
}
|
|
|
|
if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) {
|
|
|
|
supportedActions |= DataDeviceManagerInterface::DnDAction::Ask;
|
|
|
|
}
|
|
|
|
// verify that the no other actions are sent
|
|
|
|
if (dnd_actions & ~(WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)) {
|
|
|
|
wl_resource_post_error(resource, WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK, "Invalid action mask");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto p = cast<Private>(resource);
|
|
|
|
if (p->supportedDnDActions!= supportedActions) {
|
|
|
|
p->supportedDnDActions = supportedActions;
|
|
|
|
emit p->q_func()->supportedDragAndDropActionsChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 15:40:14 +00:00
|
|
|
DataSourceInterface::DataSourceInterface(DataDeviceManagerInterface *parent, wl_resource *parentResource)
|
|
|
|
: Resource(new Private(this, parent, parentResource))
|
2014-11-04 14:10:22 +00:00
|
|
|
{
|
2017-12-26 20:55:11 +00:00
|
|
|
if (wl_resource_get_version(parentResource) < WL_DATA_SOURCE_ACTION_SINCE_VERSION) {
|
|
|
|
Q_D();
|
|
|
|
d->supportedDnDActions = DataDeviceManagerInterface::DnDAction::Copy;
|
|
|
|
}
|
2014-11-04 14:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DataSourceInterface::~DataSourceInterface() = default;
|
|
|
|
|
|
|
|
void DataSourceInterface::accept(const QString &mimeType)
|
|
|
|
{
|
2014-11-14 08:45:02 +00:00
|
|
|
Q_D();
|
2014-11-04 14:10:22 +00:00
|
|
|
// TODO: does this require a sanity check on the possible mimeType?
|
2014-11-14 08:45:02 +00:00
|
|
|
wl_data_source_send_target(d->resource, mimeType.isEmpty() ? nullptr : mimeType.toUtf8().constData());
|
2014-11-04 14:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DataSourceInterface::requestData(const QString &mimeType, qint32 fd)
|
|
|
|
{
|
2014-11-14 08:45:02 +00:00
|
|
|
Q_D();
|
2014-11-04 14:10:22 +00:00
|
|
|
// TODO: does this require a sanity check on the possible mimeType?
|
2016-10-12 06:08:28 +00:00
|
|
|
if (d->resource) {
|
|
|
|
wl_data_source_send_send(d->resource, mimeType.toUtf8().constData(), int32_t(fd));
|
|
|
|
}
|
2014-11-27 10:23:37 +00:00
|
|
|
close(fd);
|
2014-11-04 14:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DataSourceInterface::cancel()
|
|
|
|
{
|
2014-11-14 08:45:02 +00:00
|
|
|
Q_D();
|
2016-09-12 06:57:07 +00:00
|
|
|
if (!d->resource) {
|
|
|
|
return;
|
|
|
|
}
|
2014-11-14 08:45:02 +00:00
|
|
|
wl_data_source_send_cancelled(d->resource);
|
2016-09-12 06:57:07 +00:00
|
|
|
client()->flush();
|
2014-11-04 14:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QStringList DataSourceInterface::mimeTypes() const
|
|
|
|
{
|
2014-11-14 08:45:02 +00:00
|
|
|
Q_D();
|
2014-11-04 14:10:22 +00:00
|
|
|
return d->mimeTypes;
|
|
|
|
}
|
|
|
|
|
2014-11-05 14:22:15 +00:00
|
|
|
DataSourceInterface *DataSourceInterface::get(wl_resource *native)
|
|
|
|
{
|
2014-11-14 14:13:06 +00:00
|
|
|
return Private::get<DataSourceInterface>(native);
|
2014-11-05 14:22:15 +00:00
|
|
|
}
|
|
|
|
|
2014-11-14 08:45:02 +00:00
|
|
|
DataSourceInterface::Private *DataSourceInterface::d_func() const
|
|
|
|
{
|
|
|
|
return reinterpret_cast<DataSourceInterface::Private*>(d.data());
|
|
|
|
}
|
|
|
|
|
2017-11-26 15:31:57 +00:00
|
|
|
DataDeviceManagerInterface::DnDActions DataSourceInterface::supportedDragAndDropActions() const
|
|
|
|
{
|
|
|
|
Q_D();
|
|
|
|
return d->supportedDnDActions;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DataSourceInterface::dropPerformed()
|
|
|
|
{
|
|
|
|
Q_D();
|
|
|
|
if (wl_resource_get_version(d->resource) < WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
wl_data_source_send_dnd_drop_performed(d->resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DataSourceInterface::dndFinished()
|
|
|
|
{
|
|
|
|
Q_D();
|
|
|
|
if (wl_resource_get_version(d->resource) < WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
wl_data_source_send_dnd_finished(d->resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DataSourceInterface::dndAction(DataDeviceManagerInterface::DnDAction action)
|
|
|
|
{
|
|
|
|
Q_D();
|
|
|
|
if (wl_resource_get_version(d->resource) < WL_DATA_SOURCE_ACTION_SINCE_VERSION) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint32_t wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
|
|
|
|
if (action == DataDeviceManagerInterface::DnDAction::Copy) {
|
|
|
|
wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
|
|
|
} else if (action == DataDeviceManagerInterface::DnDAction::Move ) {
|
|
|
|
wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
|
|
|
} else if (action == DataDeviceManagerInterface::DnDAction::Ask) {
|
|
|
|
wlAction = WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
|
|
|
}
|
|
|
|
wl_data_source_send_action(d->resource, wlAction);
|
|
|
|
}
|
|
|
|
|
2014-11-05 14:22:15 +00:00
|
|
|
}
|