File indexing completed on 2024-03-24 17:11:15

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 "context.h"
0009 #include "debug.h"
0010 #include "sink.h"
0011 #include "source.h"
0012 
0013 namespace QPulseAudio
0014 {
0015 Server::Server(Context *context)
0016     : QObject(context)
0017 {
0018     Q_ASSERT(context);
0019 
0020     connect(&context->sinks(), &MapBaseQObject::added, this, &Server::updateDefaultDevices);
0021     connect(&context->sinks(), &MapBaseQObject::removed, this, &Server::updateDefaultDevices);
0022     connect(&context->sources(), &MapBaseQObject::added, this, &Server::updateDefaultDevices);
0023     connect(&context->sources(), &MapBaseQObject::removed, this, &Server::updateDefaultDevices);
0024 }
0025 
0026 Sink *Server::defaultSink() const
0027 {
0028     return m_defaultSink;
0029 }
0030 
0031 void Server::setDefaultSink(Sink *sink)
0032 {
0033     Q_ASSERT(sink);
0034     Context::instance()->setDefaultSink(sink->name());
0035 }
0036 
0037 Source *Server::defaultSource() const
0038 {
0039     return m_defaultSource;
0040 }
0041 
0042 void Server::setDefaultSource(Source *source)
0043 {
0044     Q_ASSERT(source);
0045     Context::instance()->setDefaultSource(source->name());
0046 }
0047 
0048 void Server::reset()
0049 {
0050     if (m_defaultSink) {
0051         m_defaultSink = nullptr;
0052         Q_EMIT defaultSinkChanged(m_defaultSink);
0053     }
0054 
0055     if (m_defaultSource) {
0056         m_defaultSource = nullptr;
0057         Q_EMIT defaultSourceChanged(m_defaultSource);
0058     }
0059 }
0060 
0061 void Server::update(const pa_server_info *info)
0062 {
0063     m_defaultSinkName = QString::fromUtf8(info->default_sink_name);
0064     m_defaultSourceName = QString::fromUtf8(info->default_source_name);
0065     m_isPipeWire = QString::fromUtf8(info->server_name).contains("PipeWire");
0066 
0067     updateDefaultDevices();
0068 
0069     Q_EMIT updated();
0070 }
0071 
0072 template<typename Type, typename Map>
0073 static Type *findByName(const Map &map, const QString &name)
0074 {
0075     Type *out = nullptr;
0076     if (name.isEmpty()) {
0077         return out;
0078     }
0079     QMapIterator<quint32, Type *> it(map);
0080     while (it.hasNext()) {
0081         it.next();
0082         out = it.value();
0083         if (out->name() == name) {
0084             return out;
0085         }
0086     }
0087     qCWarning(PLASMAPA) << "No object for name" << name;
0088     return out;
0089 }
0090 
0091 void Server::updateDefaultDevices()
0092 {
0093     Sink *sink = findByName<Sink>(Context::instance()->sinks().data(), m_defaultSinkName);
0094     auto *source = findByName<Source>(Context::instance()->sources().data(), m_defaultSourceName);
0095 
0096     if (m_defaultSink != sink) {
0097         qCDebug(PLASMAPA) << "Default sink changed" << sink;
0098         m_defaultSink = sink;
0099         Q_EMIT defaultSinkChanged(m_defaultSink);
0100     }
0101 
0102     if (m_defaultSource != source) {
0103         qCDebug(PLASMAPA) << "Default source changed" << source;
0104         m_defaultSource = source;
0105         Q_EMIT defaultSourceChanged(m_defaultSource);
0106     }
0107 }
0108 
0109 bool Server::isPipeWire() const
0110 {
0111     return m_isPipeWire;
0112 }
0113 
0114 } // QPulseAudio