File indexing completed on 2024-05-12 05:38:09

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         initialize();
0071 
0072         if (!isInitialized()) {
0073             qWarning() << "Remember requesting the interface on your desktop file: X-KDE-Wayland-Interfaces=zkde_screencast_unstable_v1";
0074         }
0075         Q_ASSERT(isInitialized());
0076     }
0077 
0078     ~ScreencastingPrivate()
0079     {
0080         if (isActive()) {
0081             destroy();
0082         }
0083     }
0084 
0085     Screencasting *const q;
0086 };
0087 
0088 Screencasting::Screencasting(QObject *parent)
0089     : QObject(parent)
0090     , d(new ScreencastingPrivate(this))
0091 {
0092 }
0093 
0094 Screencasting::~Screencasting() = default;
0095 
0096 ScreencastingStream *Screencasting::createOutputStream(const QString &outputName, Screencasting::CursorMode mode)
0097 {
0098     if (!d->isActive()) {
0099         return nullptr;
0100     }
0101 
0102     wl_output *output = nullptr;
0103     for (auto screen : qGuiApp->screens()) {
0104         if (screen->name() == outputName) {
0105             output = (wl_output *)QGuiApplication::platformNativeInterface()->nativeResourceForScreen("output", screen);
0106         }
0107     }
0108 
0109     if (!output) {
0110         return nullptr;
0111     }
0112 
0113     auto stream = new ScreencastingStream(this);
0114     stream->setObjectName(outputName);
0115     stream->d->init(d->stream_output(output, mode));
0116     return stream;
0117 }
0118 
0119 ScreencastingStream *Screencasting::createWindowStream(const QString &uuid, CursorMode mode)
0120 {
0121     if (!d->isActive()) {
0122         return nullptr;
0123     }
0124     auto stream = new ScreencastingStream(this);
0125     stream->d->init(d->stream_window(uuid, mode));
0126     return stream;
0127 }
0128 
0129 void Screencasting::destroy()
0130 {
0131     d.reset(nullptr);
0132 }