Changeset View
Changeset View
Standalone View
Standalone View
src/server/screencasting_interface.cpp
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | SPDX-FileCopyrightText: 2016 Oleg Chernovskiy <kanedias@xaker.ru> | ||||
3 | | ||||
4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL | ||||
5 | */ | ||||
6 | | ||||
7 | #include "screencasting_interface.h" | ||||
8 | #include "display.h" | ||||
9 | #include <QDebug> | ||||
10 | | ||||
11 | #include "qwayland-server-org-kde-kwin-screencast-unstable-v1.h" | ||||
12 | | ||||
13 | using namespace KWayland::Server; | ||||
14 | | ||||
15 | static int s_version = 1; | ||||
16 | | ||||
17 | class KWayland::Server::ScreencastingSourcePrivate | ||||
18 | { | ||||
19 | public: | ||||
20 | ScreencastingSourcePrivate(const QString &description, const QString &iconName, bool isOutput, const QRect &geometry, std::function<void(const ScreencastingSource &,wl_resource *r)> call) | ||||
21 | : sourceId(0) | ||||
22 | , description(description) | ||||
23 | , iconName(iconName) | ||||
24 | , isOutput(isOutput) | ||||
25 | , geometry(geometry) | ||||
26 | , call(call) | ||||
27 | {} | ||||
28 | | ||||
29 | quint32 sourceId; | ||||
30 | const QString description; | ||||
31 | const QString iconName; | ||||
32 | const bool isOutput; | ||||
33 | const QRect geometry; | ||||
34 | const std::function<void(const ScreencastingSource &,wl_resource *r)> call; | ||||
35 | }; | ||||
36 | | ||||
37 | ScreencastingSource::ScreencastingSource() | ||||
38 | : d(new ScreencastingSourcePrivate({}, {}, false, {}, [] (const ScreencastingSource &, wl_resource *) {})) | ||||
39 | {} | ||||
40 | | ||||
41 | ScreencastingSource::ScreencastingSource(const QString &description, const QString &iconName, bool isOutput, const QRect &geometry, std::function<void(const ScreencastingSource &,wl_resource *r)> call) | ||||
42 | : d(new ScreencastingSourcePrivate(description, iconName, isOutput, geometry, call)) | ||||
43 | {} | ||||
44 | | ||||
45 | ScreencastingSource::ScreencastingSource(const ScreencastingSource& other) | ||||
46 | : d(other.d) | ||||
47 | {} | ||||
48 | | ||||
49 | ScreencastingSource::~ScreencastingSource() = default; | ||||
50 | | ||||
51 | quint32 ScreencastingSource::sourceId() const | ||||
52 | { | ||||
53 | return d->sourceId; | ||||
54 | } | ||||
55 | | ||||
56 | QString ScreencastingSource::description() const | ||||
57 | { | ||||
58 | return d->description; | ||||
59 | } | ||||
60 | | ||||
61 | QString ScreencastingSource::iconName() const | ||||
62 | { | ||||
63 | return d->iconName; | ||||
64 | } | ||||
65 | | ||||
66 | bool ScreencastingSource::isOutput() const | ||||
67 | { | ||||
68 | return d->isOutput; | ||||
69 | } | ||||
70 | | ||||
71 | QRect ScreencastingSource::geometry() const | ||||
72 | { | ||||
73 | return d->geometry; | ||||
74 | } | ||||
75 | | ||||
76 | bool ScreencastingSource::operator!=(const ScreencastingSource &other) const | ||||
77 | { | ||||
78 | return d != other.d; | ||||
79 | } | ||||
80 | | ||||
81 | void KWayland::Server::ScreencastingSource::call(wl_resource* r) | ||||
82 | { | ||||
83 | d->call(*this, r); | ||||
84 | } | ||||
85 | | ||||
86 | class KWayland::Server::ScreencastingInterfacePrivate : public QtWaylandServer::org_kde_kwin_screencast_unstable_v1 | ||||
87 | { | ||||
88 | public: | ||||
89 | ScreencastingInterfacePrivate(Display *display, ScreencastingInterface* q) | ||||
90 | : QtWaylandServer::org_kde_kwin_screencast_unstable_v1(*display, s_version) | ||||
91 | , q(q) | ||||
92 | {} | ||||
93 | | ||||
94 | void org_kde_kwin_screencast_unstable_v1_bind_resource(Resource *resource) override { | ||||
95 | for (auto source : qAsConst(m_sources)) { | ||||
96 | sendSource(resource, source); | ||||
97 | } | ||||
98 | send_done(resource->handle); | ||||
99 | } | ||||
100 | | ||||
101 | void org_kde_kwin_screencast_unstable_v1_create(Resource *resource, uint32_t sourceId) override { | ||||
102 | auto it = std::find_if(m_sources.begin(), m_sources.end(), [sourceId] (const ScreencastingSource &source) { return source.sourceId() == sourceId; }); | ||||
103 | if (it == m_sources.end()) { | ||||
104 | q->sendFailed(resource->handle, sourceId, QObject::tr("Source %1 does not exist").arg(sourceId)); | ||||
105 | return; | ||||
106 | } | ||||
107 | | ||||
108 | it->call(resource->handle); | ||||
109 | } | ||||
110 | | ||||
111 | void org_kde_kwin_screencast_unstable_v1_close(Resource *, uint32_t nodeId) override { | ||||
112 | Q_EMIT q->stop(nodeId); | ||||
113 | } | ||||
114 | | ||||
115 | void sendSource(Resource* resource, const ScreencastingSource &source) { | ||||
116 | const QRect geometry = source.geometry(); | ||||
117 | send_addSource(resource->handle, source.sourceId(), source.description(), source.iconName(), source.isOutput(), geometry.x(), geometry.y(), geometry.width(), geometry.height()); | ||||
118 | } | ||||
119 | | ||||
120 | void initSource(ScreencastingSource &source) { | ||||
121 | static quint32 id = 0; | ||||
122 | auto f = [] (const ScreencastingSource &source) { return source.sourceId() == id; }; | ||||
123 | while (id == 0 || std::find_if(m_sources.cbegin(), m_sources.cend(), f) != m_sources.cend()) { | ||||
124 | ++id; | ||||
125 | } | ||||
126 | source.d->sourceId = id; | ||||
127 | } | ||||
128 | | ||||
129 | QVector<ScreencastingSource> m_sources; | ||||
130 | ScreencastingInterface *const q; | ||||
131 | }; | ||||
132 | | ||||
133 | ScreencastingInterface::ScreencastingInterface(Display *display, QObject *parent) | ||||
134 | : QObject(parent) | ||||
135 | , d(new ScreencastingInterfacePrivate(display, this)) | ||||
136 | { | ||||
137 | } | ||||
138 | | ||||
139 | ScreencastingInterface::~ScreencastingInterface() = default; | ||||
140 | | ||||
141 | void ScreencastingInterface::addSource(const ScreencastingSource &source) | ||||
142 | { | ||||
143 | Q_ASSERT(source.sourceId() == 0); | ||||
144 | | ||||
145 | ScreencastingSource ourSource = source; | ||||
146 | d->initSource(ourSource); | ||||
147 | | ||||
148 | d->m_sources << source; | ||||
149 | | ||||
150 | for (auto r : d->resourceMap()) { | ||||
151 | d->sendSource(r, ourSource); | ||||
152 | } | ||||
153 | } | ||||
154 | | ||||
155 | void ScreencastingInterface::removeSource(const ScreencastingSource &sourceToRemove) | ||||
156 | { | ||||
157 | auto it = std::find_if(d->m_sources.begin(), d->m_sources.end(), [&sourceToRemove] (const ScreencastingSource &source) { return source.sourceId() == sourceToRemove.sourceId(); }); | ||||
158 | if (it == d->m_sources.end()) { | ||||
159 | return; | ||||
160 | } | ||||
161 | | ||||
162 | d->m_sources.erase(it); | ||||
163 | | ||||
164 | for (auto r : d->resourceMap()) { | ||||
165 | d->send_removeSource(r->handle, sourceToRemove.sourceId()); | ||||
166 | } | ||||
167 | } | ||||
168 | | ||||
169 | void ScreencastingInterface::sendCreated(wl_resource *resource, quint32 nodeid, quint32 sourceid) | ||||
170 | { | ||||
171 | d->send_created(resource, nodeid, sourceid); | ||||
172 | } | ||||
173 | | ||||
174 | void ScreencastingInterface::sendFailed(wl_resource* resource, quint32 sourceid, const QString& error) | ||||
175 | { | ||||
176 | d->send_failed(resource, sourceid, error); | ||||
177 | } | ||||
178 | | ||||
179 | void KWayland::Server::ScreencastingInterface::sendClosed(wl_resource* resource, quint32 nodeid) | ||||
180 | { | ||||
181 | d->send_closed(resource, nodeid); | ||||
182 | } |