File indexing completed on 2024-12-08 07:20:47

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