File indexing completed on 2023-10-01 08:27:23

0001 /*
0002     SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #ifndef DEVICE_P_H
0007 #define DEVICE_P_H
0008 
0009 #include <pulse/proplist.h>
0010 
0011 #include <QHash>
0012 #include <QVector>
0013 
0014 #include "device.h"
0015 #include "port.h"
0016 #include "port_p.h"
0017 #include "volumeobject_p.h"
0018 
0019 namespace PulseAudioQt
0020 {
0021 class DevicePrivate
0022 {
0023 public:
0024     explicit DevicePrivate(Device *q);
0025 
0026     Device *q;
0027 
0028     QString m_description;
0029     QString m_formFactor;
0030     quint32 m_cardIndex = -1;
0031     QList<Port *> m_ports;
0032     quint32 m_activePortIndex = -1;
0033     Device::State m_state = Device::UnknownState;
0034 
0035     Device::State stateFromPaState(int value) const;
0036 
0037     template<typename PAInfo>
0038     void updateDevice(const PAInfo *info)
0039     {
0040         q->VolumeObject::d->updateVolumeObject(info);
0041 
0042         if (m_description != info->description) {
0043             m_description = info->description;
0044             Q_EMIT q->descriptionChanged();
0045         }
0046         const char *form_factor = pa_proplist_gets(info->proplist, PA_PROP_DEVICE_FORM_FACTOR);
0047         if (form_factor) {
0048             QString formFactor = QString::fromUtf8(form_factor);
0049             if (m_formFactor != formFactor) {
0050                 m_formFactor = formFactor;
0051                 Q_EMIT q->formFactorChanged();
0052             }
0053         }
0054 
0055         m_cardIndex = info->card;
0056         Q_EMIT q->cardIndexChanged();
0057 
0058         QStringList newPorts;
0059         QStringList existingPorts;
0060 
0061         // Build list of existing ports
0062         for (const Port *port : qAsConst(m_ports)) {
0063             existingPorts << port->name();
0064         }
0065 
0066         // Add new ports from the updated port list and re/set port info
0067         for (auto **it = info->ports; it && *it != nullptr; ++it) {
0068             const QString name = QString::fromUtf8((*it)->name);
0069             newPorts << name;
0070 
0071             Port *port = nullptr;
0072 
0073             if (existingPorts.contains(name)) {
0074                 port = m_ports[existingPorts.indexOf(name)];
0075             } else {
0076                 port = new Port(q);
0077                 m_ports << port;
0078             }
0079 
0080             port->d->setInfo(*it);
0081         }
0082 
0083         // Remove ports that are not in the updated port list
0084         for (Port *port : qAsConst(m_ports)) {
0085             if (!newPorts.contains(port->name())) {
0086                 m_ports.removeOne(port);
0087                 delete port;
0088             }
0089         }
0090 
0091         // Set active port
0092         for (Port *port : qAsConst(m_ports)) {
0093             if (info->active_port->name == port->name()) {
0094                 m_activePortIndex = m_ports.indexOf(port);
0095             }
0096         }
0097 
0098         Q_EMIT q->portsChanged();
0099         Q_EMIT q->activePortIndexChanged();
0100 
0101         Device::State infoState = stateFromPaState(info->state);
0102         if (infoState != m_state) {
0103             m_state = infoState;
0104             Q_EMIT q->stateChanged();
0105         }
0106     }
0107 };
0108 
0109 } // namespace PulseAudioQt
0110 
0111 #endif