File indexing completed on 2024-04-21 05:44:59
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 <QGuiApplication> 0010 #include <QLoggingCategory> 0011 #include <QPointer> 0012 #include <QRect> 0013 #include <QtWaylandClient/QWaylandClientExtensionTemplate> 0014 #include <QtWaylandClientVersion> 0015 #include <qpa/qplatformnativeinterface.h> 0016 #include <qscreen.h> 0017 0018 using namespace KWayland::Client; 0019 0020 class ScreencastingStreamPrivate : public QtWayland::zkde_screencast_stream_unstable_v1 0021 { 0022 public: 0023 explicit ScreencastingStreamPrivate(ScreencastingStream *q) 0024 : q(q) 0025 { 0026 } 0027 ~ScreencastingStreamPrivate() override 0028 { 0029 if (isInitialized()) { 0030 close(); 0031 } 0032 q->deleteLater(); 0033 } 0034 Q_DISABLE_COPY_MOVE(ScreencastingStreamPrivate) 0035 0036 void zkde_screencast_stream_unstable_v1_created(uint32_t node) override 0037 { 0038 m_nodeId = node; 0039 Q_EMIT q->created(node); 0040 } 0041 0042 void zkde_screencast_stream_unstable_v1_closed() override 0043 { 0044 Q_EMIT q->closed(); 0045 } 0046 0047 void zkde_screencast_stream_unstable_v1_failed(const QString &error) override 0048 { 0049 Q_EMIT q->failed(error); 0050 } 0051 0052 std::optional<uint> m_nodeId; 0053 QPointer<ScreencastingStream> q; 0054 }; 0055 0056 ScreencastingStream::ScreencastingStream(QObject *parent) 0057 : QObject(parent) 0058 , d(new ScreencastingStreamPrivate(this)) 0059 { 0060 } 0061 0062 ScreencastingStream::~ScreencastingStream() = default; 0063 0064 quint32 ScreencastingStream::nodeId() const 0065 { 0066 Q_ASSERT(d->m_nodeId.has_value()); 0067 return d->m_nodeId.value_or(0); 0068 } 0069 0070 class ScreencastingPrivate : public QWaylandClientExtensionTemplate<ScreencastingPrivate>, public QtWayland::zkde_screencast_unstable_v1 0071 { 0072 public: 0073 explicit ScreencastingPrivate(Screencasting *q) 0074 : QWaylandClientExtensionTemplate<ScreencastingPrivate>(ZKDE_SCREENCAST_UNSTABLE_V1_STREAM_REGION_SINCE_VERSION) 0075 , q(q) 0076 { 0077 #if QTWAYLANDCLIENT_VERSION >= QT_VERSION_CHECK(6, 2, 0) 0078 initialize(); 0079 #else 0080 // QWaylandClientExtensionTemplate invokes this with a QueuedConnection but 0081 // we want it called immediately 0082 QMetaObject::invokeMethod(this, "addRegistryListener", Qt::DirectConnection); 0083 #endif 0084 0085 if (!isInitialized()) { 0086 qWarning() << "Remember requesting the interface on your desktop file: " 0087 "X-KDE-Wayland-Interfaces=zkde_screencast_unstable_v1"; 0088 } 0089 Q_ASSERT(isInitialized()); 0090 } 0091 0092 ~ScreencastingPrivate() override 0093 { 0094 destroy(); 0095 } 0096 Q_DISABLE_COPY_MOVE(ScreencastingPrivate) 0097 0098 Screencasting *const q; 0099 }; 0100 0101 Screencasting::Screencasting(QObject *parent) 0102 : QObject(parent) 0103 , d(new ScreencastingPrivate(this)) 0104 { 0105 } 0106 0107 Screencasting::~Screencasting() = default; 0108 0109 ScreencastingStream *Screencasting::createRegionStream(const QRect &geometry, qreal scaling, CursorMode mode) 0110 { 0111 Q_ASSERT(d->QWaylandClientExtension::version() >= ZKDE_SCREENCAST_UNSTABLE_V1_STREAM_REGION_SINCE_VERSION); 0112 auto stream = new ScreencastingStream(this); 0113 stream->setObjectName(QStringLiteral("region-%1,%2 (%3x%4)").arg(geometry.x()).arg(geometry.y()).arg(geometry.width()).arg(geometry.height())); 0114 stream->d->init(d->stream_region(geometry.x(), geometry.y(), geometry.width(), geometry.height(), wl_fixed_from_double(scaling), mode)); 0115 return stream; 0116 } 0117 0118 void Screencasting::destroy() 0119 { 0120 d.reset(nullptr); 0121 }