diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c51fa5..e6cddfc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,41 +1,59 @@ include_directories(${PULSEAUDIO_INCLUDE_DIR} ${GLIB2_INCLUDE_DIR} ${GCONF_INCLUDE_DIRS} ${GOBJECT_INCLUDE_DIRS}) -set(SRC_LIST +set(cpp_SRCS card.cpp client.cpp context.cpp device.cpp maps.cpp operation.cpp port.cpp profile.cpp pulseaudio.cpp pulseobject.cpp sink.cpp sinkinput.cpp modulemanager.cpp gconfitem.cpp source.cpp sourceoutput.cpp stream.cpp volumeobject.cpp debug.cpp server.cpp streamrestore.cpp module.cpp + qml/globalactioncollection.cpp + qml/plugin.cpp + qml/volumeosd.cpp + qml/volumefeedback.cpp ) -add_library(QPulseAudioPrivate SHARED ${SRC_LIST}) -target_link_libraries(QPulseAudioPrivate +set(qml_SRCS + qml/qmldir + qml/PulseObjectFilterModel.qml +) + +set_property(SOURCE qml/dbus/osdService.xml APPEND PROPERTY CLASSNAME OsdServiceInterface) +qt5_add_dbus_interface(dbus_SRCS qml/dbus/osdService.xml osdservice) + +add_library(plasma-volume-declarative SHARED ${dbus_SRCS} ${cpp_SRCS} ${qml_SRCS}) +target_link_libraries(plasma-volume-declarative Qt5::Core Qt5::Gui + Qt5::DBus + Qt5::Quick + KF5::GlobalAccel ${PULSEAUDIO_LIBRARY} ${PULSEAUDIO_MAINLOOP_LIBRARY} ${GCONF_LDFLAGS} ${GOBJECT_LDFLAGS} + ${CANBERRA_LIBRARIES} ) -install(TARGETS QPulseAudioPrivate ${INSTALL_TARGETS_DEFAULT_ARGS}) + +set(PRIVATE_QML_INSTALL_DIR ${QML_INSTALL_DIR}/org/kde/plasma/private/volume) +install(TARGETS plasma-volume-declarative DESTINATION ${PRIVATE_QML_INSTALL_DIR}) +install(FILES ${qml_SRCS} DESTINATION ${PRIVATE_QML_INSTALL_DIR}) add_subdirectory(kcm) -add_subdirectory(qml) diff --git a/src/card.h b/src/card.h index 0de2e0b..fe03a96 100644 --- a/src/card.h +++ b/src/card.h @@ -1,111 +1,111 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef CARD_H #define CARD_H #include #include #include #include "profile.h" #include "port.h" #include "pulseobject.h" namespace QPulseAudio { class CardPort : public Port { Q_OBJECT Q_PROPERTY(QVariantMap properties READ properties NOTIFY propertiesChanged) public: CardPort(QObject *parent = nullptr) : Port(parent) {} virtual ~CardPort() {} // int direction; /**< A #pa_direction enum, indicating the direction of this port. */ // uint32_t n_profiles; /**< Number of entries in profile array */ // pa_card_profile_info** profiles; /**< \deprecated Superseded by profiles2 */ // int64_t latency_offset; /**< Latency offset of the port that gets added to the sink/source latency when the port is active. \since 3.0 */ // pa_card_profile_info2** profiles2; /**< Array of pointers to available profiles, or NULL. Array is terminated by an entry set to NULL. \since 5.0 */ void update(const pa_card_port_info *info) { setInfo(info); m_properties.clear(); void *it = nullptr; while (const char *key = pa_proplist_iterate(info->proplist, &it)) { Q_ASSERT(key); const char *value = pa_proplist_gets(info->proplist, key); if (!value) { qCDebug(PLASMAPA) << "property" << key << "not a string"; continue; } Q_ASSERT(value); m_properties.insert(QString::fromUtf8(key), QString::fromUtf8(value)); } emit propertiesChanged(); } QVariantMap properties() const { return m_properties; } signals: void propertiesChanged(); private: QVariantMap m_properties; }; -class Q_DECL_EXPORT Card : public PulseObject +class Card : public PulseObject { Q_OBJECT Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QList profiles READ profiles NOTIFY profilesChanged) Q_PROPERTY(quint32 activeProfileIndex READ activeProfileIndex WRITE setActiveProfileIndex NOTIFY activeProfileIndexChanged) Q_PROPERTY(QList ports READ ports NOTIFY portsChanged) public: Card(QObject *parent); void update(const pa_card_info *info); QString name() const; QList profiles() const; quint32 activeProfileIndex() const; void setActiveProfileIndex(quint32 profileIndex); QList ports() const; signals: void nameChanged(); void profilesChanged(); void activeProfileIndexChanged(); void portsChanged(); private: QString m_name; QList m_profiles; quint32 m_activeProfileIndex; QList m_ports; }; } // QPulseAudio #endif // CARD_H diff --git a/src/client.h b/src/client.h index 3b9050e..5a0b291 100644 --- a/src/client.h +++ b/src/client.h @@ -1,54 +1,54 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef CLIENT_H #define CLIENT_H #include #include #include "pulseobject.h" namespace QPulseAudio { -class Q_DECL_EXPORT Client : public PulseObject +class Client : public PulseObject { Q_OBJECT Q_PROPERTY(QString name READ name NOTIFY nameChanged) public: Client(QObject *parent); virtual ~Client(); void update(const pa_client_info *info); QString name() const; signals: void nameChanged(); private: QString m_name; }; } // QPulseAudio #endif // CLIENT_H diff --git a/src/context.h b/src/context.h index 5627de2..7b41b10 100644 --- a/src/context.h +++ b/src/context.h @@ -1,180 +1,180 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef CONTEXT_H #define CONTEXT_H #include #include #include #include #include #include #include #include "maps.h" #include "operation.h" namespace QPulseAudio { class Server; -class Q_DECL_EXPORT Context : public QObject +class Context : public QObject { Q_OBJECT public: Context(QObject *parent = nullptr); ~Context(); static Context *instance(); static const qint64 NormalVolume = PA_VOLUME_NORM; static const qint64 MinimalVolume = 0; static const qint64 MaximalVolume = (PA_VOLUME_NORM / 100.0) * 150; void ref(); void unref(); bool isValid() { return m_context && m_mainloop; } const SinkMap &sinks() const { return m_sinks; } const SinkInputMap &sinkInputs() const { return m_sinkInputs; } const SourceMap &sources() const { return m_sources; } const SourceOutputMap &sourceOutputs() const { return m_sourceOutputs; } const ClientMap &clients() const { return m_clients; } const CardMap &cards() const { return m_cards; } const ModuleMap &modules() const { return m_modules; } const StreamRestoreMap &streamRestores() const { return m_streamRestores; } Server *server() const { return m_server; } void subscribeCallback(pa_context *context, pa_subscription_event_type_t type, uint32_t index); void contextStateCallback(pa_context *context); void sinkCallback(const pa_sink_info *info); void sinkInputCallback(const pa_sink_input_info *info); void sourceCallback(const pa_source_info *info); void sourceOutputCallback(const pa_source_output_info *info); void clientCallback(const pa_client_info *info); void cardCallback(const pa_card_info *info); void moduleCallback(const pa_module_info *info); void streamRestoreCallback(const pa_ext_stream_restore_info *info); void serverCallback(const pa_server_info *info); void setCardProfile(quint32 index, const QString &profile); void setDefaultSink(const QString &name); void setDefaultSource(const QString &name); void streamRestoreWrite(const pa_ext_stream_restore_info *info); template void setGenericVolume(quint32 index, int channel, qint64 newVolume, pa_cvolume cVolume, PAFunction pa_set_volume) { if (!m_context) { return; } newVolume = qBound(0, newVolume, PA_VOLUME_MAX); pa_cvolume newCVolume = cVolume; if (channel == -1) { // -1 all channels for (int i = 0; i < newCVolume.channels; ++i) { newCVolume.values[i] = newVolume; } } else { Q_ASSERT(newCVolume.channels > channel); newCVolume.values[channel] = newVolume; } if (!PAOperation(pa_set_volume(m_context, index, &newCVolume, nullptr, nullptr))) { qCWarning(PLASMAPA) << "pa_set_volume failed"; return; } } template void setGenericMute(quint32 index, bool mute, PAFunction pa_set_mute) { if (!m_context) { return; } if (!PAOperation(pa_set_mute(m_context, index, mute, nullptr, nullptr))) { qCWarning(PLASMAPA) << "pa_set_mute failed"; return; } } template void setGenericPort(quint32 index, const QString &portName, PAFunction pa_set_port) { if (!m_context) { return; } if (!PAOperation(pa_set_port(m_context, index, portName.toUtf8().constData(), nullptr, nullptr))) { qCWarning(PLASMAPA) << "pa_set_port failed"; return; } } template void setGenericDeviceForStream(quint32 streamIndex, quint32 deviceIndex, PAFunction pa_move_stream_to_device) { if (!m_context) { return; } if (!PAOperation(pa_move_stream_to_device(m_context, streamIndex, deviceIndex, nullptr, nullptr))) { qCWarning(PLASMAPA) << "pa_move_stream_to_device failed"; return; } } private: void connectToDaemon(); void reset(); // Don't forget to add things to reset(). SinkMap m_sinks; SinkInputMap m_sinkInputs; SourceMap m_sources; SourceOutputMap m_sourceOutputs; ClientMap m_clients; CardMap m_cards; ModuleMap m_modules; StreamRestoreMap m_streamRestores; Server *m_server; pa_context *m_context; pa_glib_mainloop *m_mainloop; int m_references; static Context* s_context; }; } // QPulseAudio #endif // CONTEXT_H diff --git a/src/device.h b/src/device.h index f60d8e4..f97e2b0 100644 --- a/src/device.h +++ b/src/device.h @@ -1,133 +1,133 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef DEVICE_H #define DEVICE_H #include #include #include "volumeobject.h" #include "port.h" #include "pulseobject.h" namespace QPulseAudio { -class Q_DECL_EXPORT Device : public VolumeObject +class Device : public VolumeObject { Q_OBJECT Q_PROPERTY(State state READ state NOTIFY stateChanged) Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QString description READ description NOTIFY descriptionChanged) Q_PROPERTY(quint32 cardIndex READ cardIndex NOTIFY cardIndexChanged) Q_PROPERTY(QList ports READ ports NOTIFY portsChanged) Q_PROPERTY(quint32 activePortIndex READ activePortIndex WRITE setActivePortIndex NOTIFY activePortIndexChanged) Q_PROPERTY(bool default READ isDefault WRITE setDefault NOTIFY defaultChanged) public: enum State { InvalidState = 0, RunningState, IdleState, SuspendedState, UnknownState }; Q_ENUMS(State); virtual ~Device() {} template void updateDevice(const PAInfo *info) { updateVolumeObject(info); if (m_name != info->name) { m_name = info->name; emit nameChanged(); } if (m_description != info->description) { m_description = info->description; emit descriptionChanged(); } m_cardIndex = info->card; emit cardIndexChanged(); // TODO: this rebuilds the entire port list on every update. would be // nicer if it actually removed what needs removing updates what needs // updating and adds what needs adding. Alas, this is a tad more // involved. qDeleteAll(m_ports); m_ports.clear(); for (auto **ports = info->ports; ports && *ports != nullptr; ++ports) { Port *port = new Port(this); port->setInfo(*ports); m_ports.append(port); if (info->active_port == *ports) { m_activePortIndex = m_ports.length() - 1; } } emit portsChanged(); emit activePortIndexChanged(); State infoState = stateFromPaState(info->state); if (infoState != m_state) { m_state = infoState; emit stateChanged(); } } State state() const; QString name() const; QString description() const; quint32 cardIndex() const; QList ports() const; quint32 activePortIndex() const; virtual void setActivePortIndex(quint32 port_index) = 0; virtual bool isDefault() const = 0; virtual void setDefault(bool enable) = 0; signals: void stateChanged(); void nameChanged(); void descriptionChanged(); void cardIndexChanged(); void portsChanged(); void activePortIndexChanged(); void defaultChanged(); protected: Device(QObject *parent); private: State stateFromPaState(int value) const; QString m_name; QString m_description; quint32 m_cardIndex = -1; QList m_ports; quint32 m_activePortIndex = -1; State m_state = UnknownState; }; } // QPulseAudio #endif // DEVICE_H diff --git a/src/maps.h b/src/maps.h index a1ae964..a9e6655 100644 --- a/src/maps.h +++ b/src/maps.h @@ -1,175 +1,175 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef MAPS_H #define MAPS_H #include "debug.h" #include #include #include #include namespace QPulseAudio { // Used for typedefs. class Card; class Client; class Sink; class SinkInput; class Source; class SourceOutput; class StreamRestore; class Module; /** * @see MapBase * This class is nothing more than the QObject base since moc cannot handle * templates. */ -class Q_DECL_EXPORT MapBaseQObject : public QObject +class MapBaseQObject : public QObject { Q_OBJECT public: virtual int count() const = 0; virtual QObject *objectAt(int index) const = 0; virtual int indexOfObject(QObject *object) const = 0; signals: void added(int index); void removed(int index); }; /** * Maps a specific index to a specific object pointer. * This is used to give the unique arbitrary PulseAudio index of a PulseObject a * serialized list index. Namely it enables us to translate a discrete list * index to a pulse index to an object, and any permutation thereof. */ template -class Q_DECL_EXPORT MapBase : public MapBaseQObject +class MapBase : public MapBaseQObject { public: virtual ~MapBase() {} const QMap &data() const { return m_data; } int count() const Q_DECL_OVERRIDE { return m_data.count(); } int indexOfObject(QObject *object) const Q_DECL_OVERRIDE { int index = 0; QMapIterator it(m_data); while (it.hasNext()) { it.next(); if (it.value() == object) { return index; } index++; } return -1; } QObject *objectAt(int index) const Q_DECL_OVERRIDE { return (m_data.constBegin() + index).value(); } void reset() { while (!m_data.isEmpty()) { removeEntry(m_data.lastKey()); } m_pendingRemovals.clear(); } void insert(Type *object) { Q_ASSERT(!m_data.contains(object->index())); m_data.insert(object->index(), object); const int modelIndex = m_data.keys().indexOf(object->index()); Q_ASSERT(modelIndex >= 0); emit added(modelIndex); } // Context is passed in as parent because context needs to include the maps // so we'd cause a circular dep if we were to try to use the instance here. // Plus that's weird separation anyway. void updateEntry(const PAInfo *info, QObject *parent) { Q_ASSERT(info); if (m_pendingRemovals.remove(info->index)) { // Was already removed again. return; } const bool isNew = !m_data.contains(info->index); auto *obj = m_data.value(info->index, nullptr); if (!obj) { obj = new Type(parent); } obj->update(info); m_data.insert(info->index, obj); if (isNew) { const int modelIndex = m_data.keys().indexOf(info->index); Q_ASSERT(modelIndex >= 0); emit added(modelIndex); } } void removeEntry(quint32 index) { if (!m_data.contains(index)) { m_pendingRemovals.insert(index); } else { const int modelIndex = m_data.keys().indexOf(index); delete m_data.take(index); emit removed(modelIndex); } } protected: QMap m_data; QSet m_pendingRemovals; }; typedef MapBase SinkMap; typedef MapBase SinkInputMap; typedef MapBase SourceMap; typedef MapBase SourceOutputMap; typedef MapBase ClientMap; typedef MapBase CardMap; typedef MapBase ModuleMap; typedef MapBase StreamRestoreMap; } // QPulseAudio #endif // MAPS_H diff --git a/src/module.h b/src/module.h index 975f3d4..a4482f5 100644 --- a/src/module.h +++ b/src/module.h @@ -1,59 +1,59 @@ /* Copyright 2017 David Rosca This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef MODULE_H #define MODULE_H #include #include #include #include "pulseobject.h" namespace QPulseAudio { -class Q_DECL_EXPORT Module : public PulseObject +class Module : public PulseObject { Q_OBJECT Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QString argument READ argument NOTIFY argumentChanged) public: Module(QObject *parent); void update(const pa_module_info *info); QString name() const; QString argument() const; signals: void nameChanged(); void argumentChanged(); private: QString m_name; QString m_argument; }; } // QPulseAudio #endif // MODULE_H diff --git a/src/modulemanager.h b/src/modulemanager.h index 1d839a7..b8fcd0b 100644 --- a/src/modulemanager.h +++ b/src/modulemanager.h @@ -1,69 +1,69 @@ /* Copyright 2016 David Edmundson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef MODULEMANAGER_H #define MODULEMANAGER_H #include #include #include "context.h" // Properties need fully qualified classes even with pointers. #include "client.h" class GConfItem; namespace QPulseAudio { class GConfModule; -class Q_DECL_EXPORT ModuleManager : public QObject +class ModuleManager : public QObject { Q_OBJECT Q_PROPERTY(bool combineSinks READ combineSinks WRITE setCombineSinks NOTIFY combineSinksChanged) Q_PROPERTY(bool switchOnConnect READ switchOnConnect WRITE setSwitchOnConnect NOTIFY switchOnConnectChanged) Q_PROPERTY(QStringList loadedModules READ loadedModules NOTIFY loadedModulesChanged) public: ModuleManager(QObject *parent = nullptr); ~ModuleManager(); bool combineSinks() const; void setCombineSinks(bool combineSinks); bool switchOnConnect() const; void setSwitchOnConnect(bool switchOnConnect); QStringList loadedModules() const; Q_SIGNALS: void combineSinksChanged(); void switchOnConnectChanged(); void loadedModulesChanged(); private: void updateLoadedModules(); GConfModule *m_combineSinks; GConfModule *m_switchOnConnect; GConfModule *m_deviceManager; QStringList m_loadedModules; }; } // QPulseAudio #endif // STREAM_H diff --git a/src/port.h b/src/port.h index a009788..b1b473e 100644 --- a/src/port.h +++ b/src/port.h @@ -1,79 +1,79 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef PORT_H #define PORT_H #include "profile.h" #include namespace QPulseAudio { -class Q_DECL_EXPORT Port : public Profile +class Port : public Profile { Q_OBJECT Q_PROPERTY(Availability availability READ availability NOTIFY availabilityChanged) public: enum Availability { Unknown, Available, Unavailable }; Q_ENUM(Availability) Port(QObject *parent); virtual ~Port(); template void setInfo(const PAInfo *info) { Profile::setInfo(info); Availability newAvailability; switch (info->available) { case PA_PORT_AVAILABLE_NO: newAvailability = Unavailable; break; case PA_PORT_AVAILABLE_YES: newAvailability = Available; break; default: newAvailability = Unknown; } if (m_availability != newAvailability) { m_availability = newAvailability; emit availabilityChanged(); } } Availability availability() const; signals: void availabilityChanged(); private: Availability m_availability; }; } // QPulseAudio #endif // PORT_H diff --git a/src/profile.h b/src/profile.h index f2c991a..fba28d9 100644 --- a/src/profile.h +++ b/src/profile.h @@ -1,80 +1,80 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef PROFILE_H #define PROFILE_H #include #include namespace QPulseAudio { -class Q_DECL_EXPORT Profile : public QObject +class Profile : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QString description READ description NOTIFY descriptionChanged) Q_PROPERTY(quint32 priority READ priority NOTIFY priorityChanged) public: Profile(QObject *parent); virtual ~Profile(); template void setInfo(const PAInfo *info) { // Description is optional. Name not so much as we need some ID. Q_ASSERT(info->name); QString infoName = QString::fromUtf8(info->name); if (m_name != infoName) { m_name = infoName; emit nameChanged(); } if (info->description) { QString infoDescription = QString::fromUtf8(info->description); if (m_description != infoDescription) { m_description = infoDescription; emit descriptionChanged(); } } if (m_priority != info->priority) { m_priority = info->priority; emit priorityChanged(); } } QString name() const; QString description() const; quint32 priority() const; signals: void nameChanged(); void descriptionChanged(); void priorityChanged(); private: QString m_name; QString m_description; quint32 m_priority; }; } // QPulseAudio #endif // PROFILE_H diff --git a/src/pulseaudio.h b/src/pulseaudio.h index 9594b90..97b02c8 100644 --- a/src/pulseaudio.h +++ b/src/pulseaudio.h @@ -1,156 +1,156 @@ /* Copyright 2014-2015 Harald Sitter Copyright 2016 David Rosca This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef PULSEAUDIO_H #define PULSEAUDIO_H #include #include "maps.h" namespace QPulseAudio { class Context; -class Q_DECL_EXPORT AbstractModel : public QAbstractListModel +class AbstractModel : public QAbstractListModel { Q_OBJECT public: enum ItemRole { PulseObjectRole = Qt::UserRole + 1 }; QHash roleNames() const Q_DECL_FINAL; int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_FINAL; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; bool setData(const QModelIndex &index, const QVariant &value, int role) Q_DECL_FINAL; Q_INVOKABLE int role(const QByteArray &roleName) const; protected: AbstractModel(const MapBaseQObject *map, QObject *parent); void initRoleNames(const QMetaObject &qobjectMetaObject); Context *context() const; private slots: void propertyChanged(); private: void onDataAdded(int index); void onDataRemoved(int index); QMetaMethod propertyChangedMetaMethod() const; const MapBaseQObject *m_map; QHash m_roles; QHash m_objectProperties; QHash m_signalIndexToProperties; private: // Prevent leaf-classes from default constructing as we want to enforce // them passing us a context or explicit nullptrs. AbstractModel() {} }; -class Q_DECL_EXPORT CardModel : public AbstractModel +class CardModel : public AbstractModel { Q_OBJECT public: CardModel(QObject *parent = nullptr); }; -class Q_DECL_EXPORT SinkModel : public AbstractModel +class SinkModel : public AbstractModel { Q_OBJECT Q_PROPERTY(QPulseAudio::Sink *defaultSink READ defaultSink NOTIFY defaultSinkChanged) Q_PROPERTY(QPulseAudio::Sink *preferredSink READ preferredSink NOTIFY preferredSinkChanged) public: enum ItemRole { SortByDefaultRole = PulseObjectRole + 1 }; Q_ENUMS(ItemRole) SinkModel(QObject *parent = nullptr); Sink *defaultSink() const; Sink *preferredSink() const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; signals: void defaultSinkChanged(); void preferredSinkChanged(); private: void sinkAdded(int index); void sinkRemoved(int index); void updatePreferredSink(); Sink *findPreferredSink() const; Sink *m_preferredSink; }; -class Q_DECL_EXPORT SinkInputModel : public AbstractModel +class SinkInputModel : public AbstractModel { Q_OBJECT public: SinkInputModel(QObject *parent = nullptr); }; -class Q_DECL_EXPORT SourceModel : public AbstractModel +class SourceModel : public AbstractModel { Q_OBJECT Q_PROPERTY(QPulseAudio::Source *defaultSource READ defaultSource NOTIFY defaultSourceChanged) public: enum ItemRole { SortByDefaultRole = PulseObjectRole + 1 }; Q_ENUMS(ItemRole) SourceModel(QObject *parent = nullptr); Source *defaultSource() const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; signals: void defaultSourceChanged(); }; -class Q_DECL_EXPORT SourceOutputModel : public AbstractModel +class SourceOutputModel : public AbstractModel { Q_OBJECT public: SourceOutputModel(QObject *parent = nullptr); }; -class Q_DECL_EXPORT StreamRestoreModel : public AbstractModel +class StreamRestoreModel : public AbstractModel { Q_OBJECT public: StreamRestoreModel(QObject *parent = nullptr); }; -class Q_DECL_EXPORT ModuleModel : public AbstractModel +class ModuleModel : public AbstractModel { Q_OBJECT public: ModuleModel(QObject *parent = nullptr); }; } // QPulseAudio #endif // PULSEAUDIO_H diff --git a/src/pulseobject.h b/src/pulseobject.h index 9aa780e..11ca3d4 100644 --- a/src/pulseobject.h +++ b/src/pulseobject.h @@ -1,83 +1,83 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef PULSEOBJECT_H #define PULSEOBJECT_H #include "debug.h" #include #include namespace QPulseAudio { class Context; -class Q_DECL_EXPORT PulseObject : public QObject +class PulseObject : public QObject { Q_OBJECT Q_PROPERTY(quint32 index READ index CONSTANT) Q_PROPERTY(QString iconName READ iconName CONSTANT) Q_PROPERTY(QVariantMap properties READ properties NOTIFY propertiesChanged) public: template void updatePulseObject(PAInfo *info) { m_index = info->index; m_properties.clear(); void *it = nullptr; while (const char *key = pa_proplist_iterate(info->proplist, &it)) { Q_ASSERT(key); const char *value = pa_proplist_gets(info->proplist, key); if (!value) { qCDebug(PLASMAPA) << "property" << key << "not a string"; continue; } Q_ASSERT(value); m_properties.insert(QString::fromUtf8(key), QString::fromUtf8(value)); } emit propertiesChanged(); } quint32 index() const; QString iconName() const; QVariantMap properties() const; signals: void propertiesChanged(); protected: PulseObject(QObject *parent); virtual ~PulseObject(); Context *context() const; quint32 m_index; QVariantMap m_properties; private: // Ensure that we get properly parented. PulseObject(); }; } // QPulseAudio #endif // PULSEOBJECT_H diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt deleted file mode 100644 index 3265bca..0000000 --- a/src/qml/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -set(qml_SRCS - qmldir - PulseObjectFilterModel.qml -) - -set(cpp_SRCS - globalactioncollection.cpp - plugin.cpp - volumeosd.cpp - volumefeedback.cpp -) - -set_property(SOURCE dbus/osdService.xml APPEND PROPERTY CLASSNAME OsdServiceInterface) -qt5_add_dbus_interface(dbus_SRCS dbus/osdService.xml osdservice) - -add_library(plasma-volume-declarative SHARED ${dbus_SRCS} ${cpp_SRCS} ${qml_SRCS}) -target_link_libraries(plasma-volume-declarative - Qt5::DBus - Qt5::Quick - KF5::GlobalAccel - QPulseAudioPrivate - ${CANBERRA_LIBRARIES} -) - -set(PRIVATE_QML_INSTALL_DIR ${QML_INSTALL_DIR}/org/kde/plasma/private/volume) -install(TARGETS plasma-volume-declarative DESTINATION ${PRIVATE_QML_INSTALL_DIR}) -install(FILES ${qml_SRCS} DESTINATION ${PRIVATE_QML_INSTALL_DIR}) diff --git a/src/server.h b/src/server.h index e9d0e08..dfd713f 100644 --- a/src/server.h +++ b/src/server.h @@ -1,65 +1,65 @@ /* Copyright 2016 David Rosca This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef SERVER_H #define SERVER_H #include #include namespace QPulseAudio { class Sink; class Source; class Context; -class Q_DECL_EXPORT Server : public QObject +class Server : public QObject { Q_OBJECT public: explicit Server(Context *context); Sink *defaultSink() const; void setDefaultSink(Sink *sink); Source *defaultSource() const; void setDefaultSource(Source *source); void reset(); void update(const pa_server_info *info); signals: void defaultSinkChanged(Sink *sink); void defaultSourceChanged(Source *source); private: void updateDefaultDevices(); QString m_defaultSinkName; QString m_defaultSourceName; Sink *m_defaultSink; Source *m_defaultSource; }; } // QPulseAudio #endif // CONTEXT_H diff --git a/src/sink.h b/src/sink.h index 91bc573..fceab76 100644 --- a/src/sink.h +++ b/src/sink.h @@ -1,47 +1,47 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef SINK_H #define SINK_H #include "device.h" namespace QPulseAudio { -class Q_DECL_EXPORT Sink : public Device +class Sink : public Device { Q_OBJECT public: Sink(QObject *parent); void update(const pa_sink_info *info); void setVolume(qint64 volume) Q_DECL_OVERRIDE; void setMuted(bool muted) Q_DECL_OVERRIDE; void setActivePortIndex(quint32 port_index) Q_DECL_OVERRIDE; void setChannelVolume(int channel, qint64 volume) Q_DECL_OVERRIDE; bool isDefault() const Q_DECL_OVERRIDE; void setDefault(bool enable) Q_DECL_OVERRIDE; }; } // QPulseAudio #endif // SINK_H diff --git a/src/sinkinput.h b/src/sinkinput.h index 6104eab..192a7b9 100644 --- a/src/sinkinput.h +++ b/src/sinkinput.h @@ -1,47 +1,47 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef SINKINPUT_H #define SINKINPUT_H #include "stream.h" namespace QPulseAudio { -class Q_DECL_EXPORT SinkInput : public Stream +class SinkInput : public Stream { Q_OBJECT public: SinkInput(QObject *parent); void update(const pa_sink_input_info *info); void setSinkIndex(quint32 sinkIndex); void setVolume(qint64 volume) Q_DECL_OVERRIDE; void setMuted(bool muted) Q_DECL_OVERRIDE; void setChannelVolume(int channel, qint64 volume) Q_DECL_OVERRIDE; void setDeviceIndex(quint32 deviceIndex) Q_DECL_OVERRIDE; }; } // QPulseAudio #endif // SINKINPUT_H diff --git a/src/source.h b/src/source.h index d506215..928e272 100644 --- a/src/source.h +++ b/src/source.h @@ -1,47 +1,47 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef SOURCE_H #define SOURCE_H #include "device.h" namespace QPulseAudio { -class Q_DECL_EXPORT Source : public Device +class Source : public Device { Q_OBJECT public: Source(QObject *parent); void update(const pa_source_info *info); void setVolume(qint64 volume) Q_DECL_OVERRIDE; void setMuted(bool muted) Q_DECL_OVERRIDE; void setActivePortIndex(quint32 port_index) Q_DECL_OVERRIDE; void setChannelVolume(int channel, qint64 volume) Q_DECL_OVERRIDE; bool isDefault() const Q_DECL_OVERRIDE; void setDefault(bool enable) Q_DECL_OVERRIDE; }; } // QPulseAudio #endif // SOURCE_H diff --git a/src/sourceoutput.h b/src/sourceoutput.h index 32a9ba5..a8b74d6 100644 --- a/src/sourceoutput.h +++ b/src/sourceoutput.h @@ -1,45 +1,45 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef SOURCEOUTPUT_H #define SOURCEOUTPUT_H #include "stream.h" namespace QPulseAudio { -class Q_DECL_EXPORT SourceOutput : public Stream +class SourceOutput : public Stream { Q_OBJECT public: SourceOutput(QObject *parent); void update(const pa_source_output_info *info); void setVolume(qint64 volume) Q_DECL_OVERRIDE; void setMuted(bool muted) Q_DECL_OVERRIDE; void setChannelVolume(int channel, qint64 volume) Q_DECL_OVERRIDE; void setDeviceIndex(quint32 deviceIndex) Q_DECL_OVERRIDE; }; } // QPulseAudio #endif // SOURCEOUTPUT_H diff --git a/src/stream.h b/src/stream.h index ad7dcc5..e9aa94b 100644 --- a/src/stream.h +++ b/src/stream.h @@ -1,108 +1,108 @@ /* Copyright 2014-2015 Harald Sitter This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef STREAM_H #define STREAM_H #include #include #include "volumeobject.h" #include "pulseobject.h" #include "context.h" // Properties need fully qualified classes even with pointers. #include "client.h" namespace QPulseAudio { -class Q_DECL_EXPORT Stream : public VolumeObject +class Stream : public VolumeObject { Q_OBJECT Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QPulseAudio::Client *client READ client NOTIFY clientChanged) Q_PROPERTY(bool virtualStream READ isVirtualStream NOTIFY virtualStreamChanged) Q_PROPERTY(quint32 deviceIndex READ deviceIndex WRITE setDeviceIndex NOTIFY deviceIndexChanged) Q_PROPERTY(bool corked READ isCorked NOTIFY corkedChanged) public: template void updateStream(const PAInfo *info) { updateVolumeObject(info); if (m_name != QString::fromUtf8(info->name)) { m_name = QString::fromUtf8(info->name); emit nameChanged(); } if (m_hasVolume != info->has_volume) { m_hasVolume = info->has_volume; emit hasVolumeChanged(); } if (m_volumeWritable != info->volume_writable) { m_volumeWritable = info->volume_writable; emit isVolumeWritableChanged(); } if (m_clientIndex != info->client) { m_clientIndex = info->client; emit clientChanged(); } if (m_virtualStream != (info->client == PA_INVALID_INDEX)) { m_virtualStream = info->client == PA_INVALID_INDEX; emit virtualStreamChanged(); } if (m_corked != info->corked) { m_corked = info->corked; emit corkedChanged(); } } QString name() const; Client *client() const; bool isVirtualStream() const; quint32 deviceIndex() const; bool isCorked() const; virtual void setDeviceIndex(quint32 deviceIndex) = 0; signals: void nameChanged(); void clientChanged(); void virtualStreamChanged(); void deviceIndexChanged(); void corkedChanged(); protected: Stream(QObject *parent); virtual ~Stream(); quint32 m_deviceIndex; private: QString m_name; quint32 m_clientIndex; bool m_virtualStream; bool m_corked; }; } // QPulseAudio #endif // STREAM_H diff --git a/src/streamrestore.h b/src/streamrestore.h index fb8c974..6cfe689 100644 --- a/src/streamrestore.h +++ b/src/streamrestore.h @@ -1,101 +1,101 @@ /* Copyright 2016 David Rosca This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef STREAMRESTORE_H #define STREAMRESTORE_H #include "pulseobject.h" #include namespace QPulseAudio { -class Q_DECL_EXPORT StreamRestore : public PulseObject +class StreamRestore : public PulseObject { Q_OBJECT Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QString device READ device WRITE setDevice NOTIFY deviceChanged) Q_PROPERTY(qint64 volume READ volume WRITE setVolume NOTIFY volumeChanged) Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) Q_PROPERTY(bool hasVolume READ hasVolume CONSTANT) Q_PROPERTY(bool volumeWritable READ isVolumeWritable CONSTANT) Q_PROPERTY(QStringList channels READ channels NOTIFY channelsChanged) Q_PROPERTY(QList channelVolumes READ channelVolumes NOTIFY channelVolumesChanged) Q_PROPERTY(quint32 deviceIndex READ deviceIndex WRITE setDeviceIndex NOTIFY deviceIndexChanged) public: StreamRestore(quint32 index, const QVariantMap &properties, QObject *parent); void update(const pa_ext_stream_restore_info *info); QString name() const; QString device() const; void setDevice(const QString &device); qint64 volume() const; void setVolume(qint64 volume); bool isMuted() const; void setMuted(bool muted); bool hasVolume() const; bool isVolumeWritable() const; QStringList channels() const; QList channelVolumes() const; quint32 deviceIndex() const; void setDeviceIndex(quint32 deviceIndex); Q_INVOKABLE void setChannelVolume(int channel, qint64 volume); signals: void nameChanged(); void deviceChanged(); void volumeChanged(); void mutedChanged(); void channelsChanged(); void channelVolumesChanged(); void deviceIndexChanged(); private: void writeChanges(const pa_cvolume &volume, const pa_channel_map &channelMap, bool muted, const QString &device); QString m_name; QString m_device; pa_cvolume m_volume; pa_channel_map m_channelMap; QStringList m_channels; bool m_muted; struct { bool valid = false; pa_cvolume volume; pa_channel_map channelMap; bool muted; QString device; } m_cache; }; } // QPulseAudio #endif // STREAMRESTORE_H