File indexing completed on 2024-04-28 05:36:52
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 "screencast_debug.h" 0010 0011 #include <KWayland/Client/output.h> 0012 #include <KWayland/Client/plasmawindowmanagement.h> 0013 #include <KWayland/Client/registry.h> 0014 #include <QDebug> 0015 #include <QRect> 0016 0017 #include <QGuiApplication> 0018 #include <qpa/qplatformnativeinterface.h> 0019 0020 using namespace KWayland::Client; 0021 0022 class ScreencastingStreamPrivate : public QtWayland::zkde_screencast_stream_unstable_v1 0023 { 0024 public: 0025 ScreencastingStreamPrivate(ScreencastingStream *q) 0026 : q(q) 0027 { 0028 } 0029 ~ScreencastingStreamPrivate() override 0030 { 0031 close(); 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 uint m_nodeid = 0; 0052 QRect m_geometry; 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 return d->m_nodeid; 0067 } 0068 0069 QRect ScreencastingStream::geometry() const 0070 { 0071 return d->m_geometry; 0072 } 0073 0074 class ScreencastingPrivate : public QtWayland::zkde_screencast_unstable_v1 0075 { 0076 public: 0077 ScreencastingPrivate(Registry *registry, int id, int version, Screencasting *q) 0078 : QtWayland::zkde_screencast_unstable_v1(*registry, id, version) 0079 , q(q) 0080 { 0081 } 0082 0083 ScreencastingPrivate(::zkde_screencast_unstable_v1 *screencasting, Screencasting *q) 0084 : QtWayland::zkde_screencast_unstable_v1(screencasting) 0085 , q(q) 0086 { 0087 } 0088 0089 ~ScreencastingPrivate() override 0090 { 0091 destroy(); 0092 } 0093 0094 Screencasting *const q; 0095 }; 0096 0097 Screencasting::Screencasting(QObject *parent) 0098 : QObject(parent) 0099 { 0100 } 0101 0102 Screencasting::Screencasting(Registry *registry, int id, int version, QObject *parent) 0103 : QObject(parent) 0104 , d(new ScreencastingPrivate(registry, id, version, this)) 0105 { 0106 } 0107 0108 Screencasting::~Screencasting() = default; 0109 0110 ScreencastingStream *Screencasting::createOutputStream(QScreen *screen, CursorMode mode) 0111 { 0112 auto stream = new ScreencastingStream(this); 0113 stream->setObjectName(screen->name()); 0114 0115 auto native = qGuiApp->platformNativeInterface(); 0116 auto *output = reinterpret_cast<wl_output *>(native->nativeResourceForScreen(QByteArrayLiteral("output"), screen)); 0117 if (!output) { 0118 qCWarning(XdgDesktopPortalKdeScreenCast) << "Could not find a matching Wayland output for screen" << screen->name(); 0119 return nullptr; 0120 } 0121 0122 stream->d->init(d->stream_output(output, mode)); 0123 stream->d->m_geometry = screen->geometry(); 0124 return stream; 0125 } 0126 0127 ScreencastingStream *Screencasting::createWindowStream(const QString &uuid, CursorMode mode) 0128 { 0129 auto stream = new ScreencastingStream(this); 0130 stream->d->init(d->stream_window(uuid, mode)); 0131 return stream; 0132 } 0133 0134 ScreencastingStream *Screencasting::createRegionStream(const QRect &g, qreal scale, CursorMode mode) 0135 { 0136 auto stream = new ScreencastingStream(this); 0137 stream->d->init(d->stream_region(g.x(), g.y(), g.width(), g.height(), wl_fixed_from_double(scale), mode)); 0138 stream->d->m_geometry = g; 0139 return stream; 0140 } 0141 0142 ScreencastingStream *Screencasting::createVirtualOutputStream(const QString &name, const QSize &s, qreal scale, Screencasting::CursorMode mode) 0143 { 0144 auto stream = new ScreencastingStream(this); 0145 stream->d->init(d->stream_virtual_output(name, s.width(), s.height(), wl_fixed_from_double(scale), mode)); 0146 stream->d->m_geometry = QRect(QPoint(0, 0), s); 0147 return stream; 0148 } 0149 0150 void Screencasting::setup(::zkde_screencast_unstable_v1 *screencasting) 0151 { 0152 d.reset(new ScreencastingPrivate(screencasting, this)); 0153 } 0154 0155 void Screencasting::destroy() 0156 { 0157 d.reset(nullptr); 0158 }