File indexing completed on 2024-11-03 04:21:36
0001 /* 0002 SPDX-FileCopyrightText: 2016 David Rosca <nowrep@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "server.h" 0008 #include "server_p.h" 0009 0010 #include "context.h" 0011 #include "context_p.h" 0012 #include "debug.h" 0013 #include "sink.h" 0014 #include "source.h" 0015 0016 namespace PulseAudioQt 0017 { 0018 Server::Server(Context *context) 0019 : QObject(context) 0020 , d(new ServerPrivate(this)) 0021 { 0022 Q_ASSERT(context); 0023 0024 connect(&context->d->m_sinks, &MapBaseQObject::added, this, &Server::updateDefaultDevices); 0025 connect(&context->d->m_sinks, &MapBaseQObject::removed, this, &Server::updateDefaultDevices); 0026 connect(&context->d->m_sources, &MapBaseQObject::added, this, &Server::updateDefaultDevices); 0027 connect(&context->d->m_sources, &MapBaseQObject::removed, this, &Server::updateDefaultDevices); 0028 } 0029 0030 Server::~Server() 0031 { 0032 delete d; 0033 } 0034 0035 ServerPrivate::ServerPrivate(Server *q) 0036 : q(q) 0037 , m_defaultSink(nullptr) 0038 , m_defaultSource(nullptr) 0039 { 0040 } 0041 0042 ServerPrivate::~ServerPrivate() 0043 { 0044 } 0045 0046 Sink *Server::defaultSink() const 0047 { 0048 return d->m_defaultSink; 0049 } 0050 0051 void Server::setDefaultSink(Sink *sink) 0052 { 0053 Q_ASSERT(sink); 0054 Context::instance()->setDefaultSink(sink->name()); 0055 } 0056 0057 Source *Server::defaultSource() const 0058 { 0059 return d->m_defaultSource; 0060 } 0061 0062 void Server::setDefaultSource(Source *source) 0063 { 0064 Q_ASSERT(source); 0065 Context::instance()->setDefaultSource(source->name()); 0066 } 0067 0068 void Server::reset() 0069 { 0070 if (d->m_defaultSink) { 0071 d->m_defaultSink = nullptr; 0072 Q_EMIT defaultSinkChanged(d->m_defaultSink); 0073 } 0074 0075 if (d->m_defaultSource) { 0076 d->m_defaultSource = nullptr; 0077 Q_EMIT defaultSourceChanged(d->m_defaultSource); 0078 } 0079 } 0080 0081 void ServerPrivate::update(const pa_server_info *info) 0082 { 0083 m_defaultSinkName = QString::fromUtf8(info->default_sink_name); 0084 m_defaultSourceName = QString::fromUtf8(info->default_source_name); 0085 0086 const bool isPw = QString::fromUtf8(info->server_name).contains("PipeWire"); 0087 0088 if (isPw != m_isPipeWire) { 0089 m_isPipeWire = isPw; 0090 Q_EMIT q->isPipeWireChanged(); 0091 } 0092 0093 q->updateDefaultDevices(); 0094 0095 Q_EMIT q->updated(); 0096 } 0097 0098 /** @private */ 0099 template<typename Type, typename Vector> 0100 static Type *findByName(const Vector &vector, const QString &name) 0101 { 0102 Type *out = nullptr; 0103 if (name.isEmpty()) { 0104 return out; 0105 } 0106 for (Type *t : vector) { 0107 out = t; 0108 if (out->name() == name) { 0109 return out; 0110 } 0111 } 0112 qCWarning(PULSEAUDIOQT) << "No object for name" << name; 0113 return out; 0114 } 0115 0116 void Server::updateDefaultDevices() 0117 { 0118 Sink *sink = findByName<Sink>(Context::instance()->d->m_sinks.data(), d->m_defaultSinkName); 0119 Source *source = findByName<Source>(Context::instance()->d->m_sources.data(), d->m_defaultSourceName); 0120 0121 if (d->m_defaultSink != sink) { 0122 qCDebug(PULSEAUDIOQT) << "Default sink changed" << sink; 0123 d->m_defaultSink = sink; 0124 Q_EMIT defaultSinkChanged(d->m_defaultSink); 0125 } 0126 0127 if (d->m_defaultSource != source) { 0128 qCDebug(PULSEAUDIOQT) << "Default source changed" << source; 0129 d->m_defaultSource = source; 0130 Q_EMIT defaultSourceChanged(d->m_defaultSource); 0131 } 0132 } 0133 0134 bool Server::isPipeWire() const 0135 { 0136 return d->m_isPipeWire; 0137 } 0138 0139 } // PulseAudioQt