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