Warning, file /plasma/plasma-workspace/libtaskmanager/declarative/screencasting.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "screencasting.h"
0008 #include "qwayland-zkde-screencast-unstable-v1.h"
0009 #include <QDebug>
0010 #include <QGuiApplication>
0011 #include <QPointer>
0012 #include <QScreen>
0013 #include <QWaylandClientExtensionTemplate>
0014 #include <qpa/qplatformnativeinterface.h>
0015 #include <qtwaylandclientversion.h>
0016 
0017 class ScreencastingStreamPrivate : public QtWayland::zkde_screencast_stream_unstable_v1
0018 {
0019 public:
0020     ScreencastingStreamPrivate(ScreencastingStream *q)
0021         : q(q)
0022     {
0023     }
0024     ~ScreencastingStreamPrivate()
0025     {
0026         close();
0027         q->deleteLater();
0028     }
0029 
0030     void zkde_screencast_stream_unstable_v1_created(uint32_t node) override
0031     {
0032         m_nodeId = node;
0033         Q_EMIT q->created(node);
0034     }
0035 
0036     void zkde_screencast_stream_unstable_v1_closed() override
0037     {
0038         Q_EMIT q->closed();
0039     }
0040 
0041     void zkde_screencast_stream_unstable_v1_failed(const QString &error) override
0042     {
0043         Q_EMIT q->failed(error);
0044     }
0045 
0046     uint m_nodeId = 0;
0047     QPointer<ScreencastingStream> q;
0048 };
0049 
0050 ScreencastingStream::ScreencastingStream(QObject *parent)
0051     : QObject(parent)
0052     , d(new ScreencastingStreamPrivate(this))
0053 {
0054 }
0055 
0056 ScreencastingStream::~ScreencastingStream() = default;
0057 
0058 quint32 ScreencastingStream::nodeId() const
0059 {
0060     return d->m_nodeId;
0061 }
0062 
0063 class ScreencastingPrivate : public QWaylandClientExtensionTemplate<ScreencastingPrivate>, public QtWayland::zkde_screencast_unstable_v1
0064 {
0065 public:
0066     ScreencastingPrivate(Screencasting *q)
0067         : QWaylandClientExtensionTemplate<ScreencastingPrivate>(ZKDE_SCREENCAST_UNSTABLE_V1_STREAM_REGION_SINCE_VERSION)
0068         , q(q)
0069     {
0070 #if QTWAYLANDCLIENT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
0071         initialize();
0072 #else
0073         // QWaylandClientExtensionTemplate invokes this with a QueuedConnection but we want it called immediately
0074         QMetaObject::invokeMethod(this, "addRegistryListener", Qt::DirectConnection);
0075 #endif
0076 
0077         if (!isInitialized()) {
0078             qWarning() << "Remember requesting the interface on your desktop file: X-KDE-Wayland-Interfaces=zkde_screencast_unstable_v1";
0079         }
0080         Q_ASSERT(isInitialized());
0081     }
0082 
0083     ~ScreencastingPrivate()
0084     {
0085         if (isActive()) {
0086             destroy();
0087         }
0088     }
0089 
0090     Screencasting *const q;
0091 };
0092 
0093 Screencasting::Screencasting(QObject *parent)
0094     : QObject(parent)
0095     , d(new ScreencastingPrivate(this))
0096 {
0097 }
0098 
0099 Screencasting::~Screencasting() = default;
0100 
0101 ScreencastingStream *Screencasting::createOutputStream(const QString &outputName, Screencasting::CursorMode mode)
0102 {
0103     if (!d->isActive()) {
0104         return nullptr;
0105     }
0106 
0107     wl_output *output = nullptr;
0108     for (auto screen : qGuiApp->screens()) {
0109         if (screen->name() == outputName) {
0110             output = (wl_output *)QGuiApplication::platformNativeInterface()->nativeResourceForScreen("output", screen);
0111         }
0112     }
0113 
0114     if (!output) {
0115         return nullptr;
0116     }
0117 
0118     auto stream = new ScreencastingStream(this);
0119     stream->setObjectName(outputName);
0120     stream->d->init(d->stream_output(output, mode));
0121     return stream;
0122 }
0123 
0124 ScreencastingStream *Screencasting::createWindowStream(const QString &uuid, CursorMode mode)
0125 {
0126     if (!d->isActive()) {
0127         return nullptr;
0128     }
0129     auto stream = new ScreencastingStream(this);
0130     stream->d->init(d->stream_window(uuid, mode));
0131     return stream;
0132 }
0133 
0134 void Screencasting::destroy()
0135 {
0136     d.reset(nullptr);
0137 }