1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "datadevice.h"
namespace MockCompositor {
bool DataDeviceManager::isClean()
{
for (auto *device : qAsConst(m_dataDevices)) {
// The client should not leak selection offers, i.e. if this fails, there is a missing
// data_offer.destroy request
if (!device->m_sentSelectionOffers.empty())
return false;
}
return true;
}
DataDevice *DataDeviceManager::deviceFor(Seat *seat)
{
Q_ASSERT(seat);
if (auto *device = m_dataDevices.value(seat, nullptr))
return device;
auto *device = new DataDevice(this, seat);
m_dataDevices[seat] = device;
return device;
}
void DataDeviceManager::data_device_manager_get_data_device(Resource *resource, uint32_t id, wl_resource *seatResource)
{
auto *seat = fromResource<Seat>(seatResource);
QVERIFY(seat);
auto *device = deviceFor(seat);
device->add(resource->client(), id, resource->version());
}
void DataDeviceManager::data_device_manager_create_data_source(Resource *resource, uint32_t id)
{
new QtWaylandServer::wl_data_source(resource->client(), id, 1);
}
DataDevice::~DataDevice()
{
// If the client(s) hasn't deleted the wayland object, just ignore subsequent events
for (auto *r : resourceMap())
wl_resource_set_implementation(r->handle, nullptr, nullptr, nullptr);
}
DataOffer *DataDevice::sendDataOffer(wl_client *client, const QStringList &mimeTypes)
{
Q_ASSERT(client);
auto *offer = new DataOffer(this, client, m_manager->m_version);
m_offers << offer;
for (auto *resource : resourceMap().values(client))
wl_data_device::send_data_offer(resource->handle, offer->resource()->handle);
for (const auto &mimeType : mimeTypes)
offer->send_offer(mimeType);
return offer;
}
void DataDevice::sendSelection(DataOffer *offer)
{
auto *client = offer->resource()->client();
for (auto *resource : resourceMap().values(client))
wl_data_device::send_selection(resource->handle, offer->resource()->handle);
m_sentSelectionOffers << offer;
}
void DataDevice::sendEnter(Surface *surface, const QPoint &position)
{
uint serial = m_manager->m_compositor->nextSerial();
Resource *resource = resourceMap().value(surface->resource()->client());
for (DataOffer *offer: m_offers)
wl_data_device::send_enter(resource->handle, serial, surface->resource()->handle, position.x(), position.y(), offer->resource()->handle);
}
void DataDevice::sendMotion(Surface *surface, const QPoint &position)
{
uint32_t time = m_manager->m_compositor->nextSerial();
Resource *resource = resourceMap().value(surface->resource()->client());
wl_data_device::send_motion(resource->handle, time, position.x(), position.y());
}
void DataDevice::sendDrop(Surface *surface)
{
Resource *resource = resourceMap().value(surface->resource()->client());
wl_data_device::send_drop(resource->handle);
}
void DataDevice::sendLeave(Surface *surface)
{
Resource *resource = resourceMap().value(surface->resource()->client());
wl_data_device::send_leave(resource->handle);
}
void DataOffer::data_offer_destroy_resource(Resource *resource)
{
Q_UNUSED(resource);
delete this;
}
void DataOffer::data_offer_receive(Resource *resource, const QString &mime_type, int32_t fd)
{
Q_UNUSED(resource);
emit receive(mime_type, fd);
}
void DataOffer::data_offer_destroy(QtWaylandServer::wl_data_offer::Resource *resource)
{
bool removed = m_dataDevice->m_sentSelectionOffers.removeOne(this);
if (!removed)
removed = m_dataDevice->m_offers.removeOne(this);
QVERIFY(removed);
wl_resource_destroy(resource->handle);
}
} // namespace MockCompositor
|