File indexing completed on 2024-04-28 05:27:35
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 "logging.h" 0009 #include "qwayland-zkde-screencast-unstable-v1.h" 0010 #include <QGuiApplication> 0011 #include <QPointer> 0012 #include <QRect> 0013 #include <QtWaylandClient/QWaylandClientExtensionTemplate> 0014 #include <qpa/qplatformnativeinterface.h> 0015 #include <qscreen.h> 0016 #include <qtwaylandclientversion.h> 0017 0018 using namespace KWayland::Client; 0019 0020 class ScreencastingStreamPrivate : public QtWayland::zkde_screencast_stream_unstable_v1 0021 { 0022 public: 0023 ScreencastingStreamPrivate(ScreencastingStream *q) 0024 : q(q) 0025 { 0026 } 0027 ~ScreencastingStreamPrivate() 0028 { 0029 if (isInitialized()) { 0030 close(); 0031 } 0032 q->deleteLater(); 0033 } 0034 0035 void zkde_screencast_stream_unstable_v1_created(uint32_t node) override 0036 { 0037 m_nodeId = node; 0038 Q_EMIT q->created(node); 0039 } 0040 0041 void zkde_screencast_stream_unstable_v1_closed() override 0042 { 0043 Q_EMIT q->closed(); 0044 } 0045 0046 void zkde_screencast_stream_unstable_v1_failed(const QString &error) override 0047 { 0048 Q_EMIT q->failed(error); 0049 } 0050 0051 std::optional<uint> m_nodeId; 0052 QPointer<ScreencastingStream> q; 0053 }; 0054 0055 ScreencastingStream::ScreencastingStream(QObject *parent) 0056 : QObject(parent) 0057 , d(new ScreencastingStreamPrivate(this)) 0058 { 0059 } 0060 0061 ScreencastingStream::~ScreencastingStream() = default; 0062 0063 quint32 ScreencastingStream::nodeId() const 0064 { 0065 Q_ASSERT(d->m_nodeId.has_value()); 0066 return *d->m_nodeId; 0067 } 0068 0069 class ScreencastingPrivate : public QWaylandClientExtensionTemplate<ScreencastingPrivate>, public QtWayland::zkde_screencast_unstable_v1 0070 { 0071 public: 0072 ScreencastingPrivate(Screencasting *q) 0073 : QWaylandClientExtensionTemplate<ScreencastingPrivate>(ZKDE_SCREENCAST_UNSTABLE_V1_STREAM_REGION_SINCE_VERSION) 0074 , q(q) 0075 { 0076 initialize(); 0077 0078 if (!isInitialized()) { 0079 qWarning() << "Remember requesting the interface on your desktop file: X-KDE-Wayland-Interfaces=zkde_screencast_unstable_v1"; 0080 } 0081 Q_ASSERT(isInitialized()); 0082 } 0083 0084 ~ScreencastingPrivate() 0085 { 0086 destroy(); 0087 } 0088 0089 Screencasting *const q; 0090 }; 0091 0092 Screencasting::Screencasting(QObject *parent) 0093 : QObject(parent) 0094 , d(new ScreencastingPrivate(this)) 0095 { 0096 } 0097 0098 Screencasting::~Screencasting() = default; 0099 0100 ScreencastingStream *Screencasting::createOutputStream(const QString &outputName, Screencasting::CursorMode mode) 0101 { 0102 for (auto screen : qGuiApp->screens()) { 0103 if (screen->name() == outputName) { 0104 return createOutputStream(screen, mode); 0105 } 0106 } 0107 return nullptr; 0108 } 0109 0110 ScreencastingStream *Screencasting::createOutputStream(QScreen *screen, CursorMode mode) 0111 { 0112 wl_output *output = (wl_output *)QGuiApplication::platformNativeInterface()->nativeResourceForScreen("output", screen); 0113 auto stream = new ScreencastingStream(this); 0114 stream->setObjectName(screen->name()); 0115 stream->d->init(d->stream_output(output, mode)); 0116 return stream; 0117 } 0118 0119 ScreencastingStream *Screencasting::createRegionStream(const QRect &geometry, qreal scaling, CursorMode mode) 0120 { 0121 Q_ASSERT(d->QWaylandClientExtension::version() >= ZKDE_SCREENCAST_UNSTABLE_V1_STREAM_REGION_SINCE_VERSION); 0122 auto stream = new ScreencastingStream(this); 0123 stream->setObjectName(QStringLiteral("region-%1,%2 (%3x%4)").arg(geometry.x()).arg(geometry.y()).arg(geometry.width()).arg(geometry.height())); 0124 stream->d->init(d->stream_region(geometry.x(), geometry.y(), geometry.width(), geometry.height(), wl_fixed_from_double(scaling), mode)); 0125 return stream; 0126 } 0127 0128 ScreencastingStream *Screencasting::createWindowStream(const QString &uuid, CursorMode mode) 0129 { 0130 auto stream = new ScreencastingStream(this); 0131 stream->d->init(d->stream_window(uuid, mode)); 0132 return stream; 0133 } 0134 0135 ScreencastingStream *Screencasting::createVirtualMonitorStream(const QString &name, const QSize &size, qreal scale, CursorMode mode) 0136 { 0137 auto stream = new ScreencastingStream(this); 0138 stream->d->init(d->stream_virtual_output(name, size.width(), size.height(), wl_fixed_from_double(scale), mode)); 0139 return stream; 0140 } 0141 0142 void Screencasting::destroy() 0143 { 0144 d.reset(nullptr); 0145 } 0146 0147 #include "moc_screencasting.cpp"