File indexing completed on 2024-11-10 04:57:06
0001 /* 0002 SPDX-FileCopyrightText: 2018-2020 Red Hat Inc 0003 SPDX-FileCopyrightText: 2020 Aleix Pol Gonzalez <aleixpol@kde.org> 0004 SPDX-FileContributor: Jan Grulich <jgrulich@redhat.com> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "pipewirecore.h" 0010 #include "kwinscreencast_logging.h" 0011 #include <cerrno> 0012 0013 #include <KLocalizedString> 0014 0015 #include <QSocketNotifier> 0016 0017 namespace KWin 0018 { 0019 0020 PipeWireCore::PipeWireCore() 0021 { 0022 pw_init(nullptr, nullptr); 0023 pwCoreEvents.version = PW_VERSION_CORE_EVENTS; 0024 pwCoreEvents.error = &PipeWireCore::onCoreError; 0025 } 0026 0027 PipeWireCore::~PipeWireCore() 0028 { 0029 if (pwMainLoop) { 0030 pw_loop_leave(pwMainLoop); 0031 } 0032 0033 if (pwCore) { 0034 pw_core_disconnect(pwCore); 0035 } 0036 0037 if (pwContext) { 0038 pw_context_destroy(pwContext); 0039 } 0040 0041 if (pwMainLoop) { 0042 pw_loop_destroy(pwMainLoop); 0043 } 0044 } 0045 0046 void PipeWireCore::onCoreError(void *data, uint32_t id, int seq, int res, const char *message) 0047 { 0048 qCWarning(KWIN_SCREENCAST) << "PipeWire remote error: " << message; 0049 if (id == PW_ID_CORE && res == -EPIPE) { 0050 PipeWireCore *pw = static_cast<PipeWireCore *>(data); 0051 Q_EMIT pw->pipewireFailed(QString::fromUtf8(message)); 0052 } 0053 } 0054 0055 bool PipeWireCore::init() 0056 { 0057 pwMainLoop = pw_loop_new(nullptr); 0058 if (!pwMainLoop) { 0059 qCWarning(KWIN_SCREENCAST, "Failed to create PipeWire loop: %s", strerror(errno)); 0060 m_error = i18n("Failed to start main PipeWire loop"); 0061 return false; 0062 } 0063 pw_loop_enter(pwMainLoop); 0064 0065 QSocketNotifier *notifier = new QSocketNotifier(pw_loop_get_fd(pwMainLoop), QSocketNotifier::Read, this); 0066 connect(notifier, &QSocketNotifier::activated, this, [this] { 0067 int result = pw_loop_iterate(pwMainLoop, 0); 0068 if (result < 0) { 0069 qCWarning(KWIN_SCREENCAST) << "pipewire_loop_iterate failed: " << result; 0070 } 0071 }); 0072 0073 pwContext = pw_context_new(pwMainLoop, nullptr, 0); 0074 if (!pwContext) { 0075 qCWarning(KWIN_SCREENCAST) << "Failed to create PipeWire context"; 0076 m_error = i18n("Failed to create PipeWire context"); 0077 return false; 0078 } 0079 0080 pwCore = pw_context_connect(pwContext, nullptr, 0); 0081 if (!pwCore) { 0082 qCWarning(KWIN_SCREENCAST) << "Failed to connect PipeWire context"; 0083 m_error = i18n("Failed to connect PipeWire context"); 0084 return false; 0085 } 0086 0087 if (pw_loop_iterate(pwMainLoop, 0) < 0) { 0088 qCWarning(KWIN_SCREENCAST) << "Failed to start main PipeWire loop"; 0089 m_error = i18n("Failed to start main PipeWire loop"); 0090 return false; 0091 } 0092 0093 pw_core_add_listener(pwCore, &coreListener, &pwCoreEvents, this); 0094 return true; 0095 } 0096 0097 } // namespace KWin 0098 0099 #include "moc_pipewirecore.cpp"