Changeset View
Changeset View
Standalone View
Standalone View
plugins/systemvolume/context.h
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | Copyright 2014-2015 Harald Sitter <sitter@kde.org> | ||||
3 | | ||||
4 | This library is free software; you can redistribute it and/or | ||||
5 | modify it under the terms of the GNU Lesser General Public | ||||
6 | License as published by the Free Software Foundation; either | ||||
7 | version 2.1 of the License, or (at your option) version 3, or any | ||||
8 | later version accepted by the membership of KDE e.V. (or its | ||||
9 | successor approved by the membership of KDE e.V.), which shall | ||||
10 | act as a proxy defined in Section 6 of version 3 of the license. | ||||
11 | | ||||
12 | This library is distributed in the hope that it will be useful, | ||||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
15 | Lesser General Public License for more details. | ||||
16 | | ||||
17 | You should have received a copy of the GNU Lesser General Public | ||||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
19 | */ | ||||
20 | | ||||
21 | #ifndef CONTEXT_H | ||||
22 | #define CONTEXT_H | ||||
23 | | ||||
24 | #include <QMutex> | ||||
25 | #include <QObject> | ||||
26 | #include <QSet> | ||||
27 | | ||||
28 | #include <pulse/mainloop.h> | ||||
29 | #include <pulse/pulseaudio.h> | ||||
30 | #include <pulse/glib-mainloop.h> | ||||
31 | #include <pulse/ext-stream-restore.h> | ||||
32 | | ||||
33 | #include "maps.h" | ||||
34 | #include "operation.h" | ||||
35 | | ||||
36 | namespace QPulseAudio | ||||
37 | { | ||||
38 | | ||||
39 | class Server; | ||||
40 | | ||||
41 | class Context : public QObject | ||||
42 | { | ||||
43 | Q_OBJECT | ||||
44 | public: | ||||
45 | Context(QObject *parent = nullptr); | ||||
46 | ~Context(); | ||||
47 | | ||||
48 | static Context *instance(); | ||||
49 | | ||||
50 | static const qint64 NormalVolume = PA_VOLUME_NORM; | ||||
51 | static const qint64 MinimalVolume = 0; | ||||
52 | static const qint64 MaximalVolume = (PA_VOLUME_NORM / 100.0) * 150; | ||||
53 | | ||||
54 | void ref(); | ||||
55 | void unref(); | ||||
56 | | ||||
57 | bool isValid() { return m_context && m_mainloop; } | ||||
58 | | ||||
59 | const SinkMap &sinks() const { return m_sinks; } | ||||
60 | const SinkInputMap &sinkInputs() const { return m_sinkInputs; } | ||||
61 | const SourceMap &sources() const { return m_sources; } | ||||
62 | const SourceOutputMap &sourceOutputs() const { return m_sourceOutputs; } | ||||
63 | const ClientMap &clients() const { return m_clients; } | ||||
64 | const CardMap &cards() const { return m_cards; } | ||||
65 | const ModuleMap &modules() const { return m_modules; } | ||||
66 | const StreamRestoreMap &streamRestores() const { return m_streamRestores; } | ||||
67 | Server *server() const { return m_server; } | ||||
68 | QString newDefaultSink() const { return m_newDefaultSink; } | ||||
69 | QString newDefaultSource() const { return m_newDefaultSource; } | ||||
70 | | ||||
71 | void subscribeCallback(pa_context *context, pa_subscription_event_type_t type, uint32_t index); | ||||
72 | void contextStateCallback(pa_context *context); | ||||
73 | | ||||
74 | void sinkCallback(const pa_sink_info *info); | ||||
75 | void sinkInputCallback(const pa_sink_input_info *info); | ||||
76 | void sourceCallback(const pa_source_info *info); | ||||
77 | void sourceOutputCallback(const pa_source_output_info *info); | ||||
78 | void clientCallback(const pa_client_info *info); | ||||
79 | void cardCallback(const pa_card_info *info); | ||||
80 | void moduleCallback(const pa_module_info *info); | ||||
81 | void streamRestoreCallback(const pa_ext_stream_restore_info *info); | ||||
82 | void serverCallback(const pa_server_info *info); | ||||
83 | | ||||
84 | void setCardProfile(quint32 index, const QString &profile); | ||||
85 | void setDefaultSink(const QString &name); | ||||
86 | void setDefaultSource(const QString &name); | ||||
87 | void streamRestoreWrite(const pa_ext_stream_restore_info *info); | ||||
88 | | ||||
89 | template <typename PAFunction> | ||||
90 | void setGenericVolume(quint32 index, int channel, qint64 newVolume, | ||||
91 | pa_cvolume cVolume, PAFunction pa_set_volume) | ||||
92 | { | ||||
93 | if (!m_context) { | ||||
94 | return; | ||||
95 | } | ||||
96 | newVolume = qBound<qint64>(0, newVolume, PA_VOLUME_MAX); | ||||
97 | pa_cvolume newCVolume = cVolume; | ||||
98 | if (channel == -1) { // -1 all channels | ||||
99 | const qint64 diff = newVolume - pa_cvolume_avg(&cVolume); | ||||
100 | for (int i = 0; i < newCVolume.channels; ++i) { | ||||
101 | newCVolume.values[i] = qBound<qint64>(0, newCVolume.values[i] + diff, PA_VOLUME_MAX); | ||||
102 | } | ||||
103 | } else { | ||||
104 | Q_ASSERT(newCVolume.channels > channel); | ||||
105 | newCVolume.values[channel] = newVolume; | ||||
106 | } | ||||
107 | if (!PAOperation(pa_set_volume(m_context, index, &newCVolume, nullptr, nullptr))) { | ||||
108 | qCWarning(PLASMAPA) << "pa_set_volume failed"; | ||||
109 | return; | ||||
110 | } | ||||
111 | } | ||||
112 | | ||||
113 | template <typename PAFunction> | ||||
114 | void setGenericMute(quint32 index, bool mute, PAFunction pa_set_mute) | ||||
115 | { | ||||
116 | if (!m_context) { | ||||
117 | return; | ||||
118 | } | ||||
119 | if (!PAOperation(pa_set_mute(m_context, index, mute, nullptr, nullptr))) { | ||||
120 | qCWarning(PLASMAPA) << "pa_set_mute failed"; | ||||
121 | return; | ||||
122 | } | ||||
123 | } | ||||
124 | | ||||
125 | template <typename PAFunction> | ||||
126 | void setGenericPort(quint32 index, const QString &portName, PAFunction pa_set_port) | ||||
127 | { | ||||
128 | if (!m_context) { | ||||
129 | return; | ||||
130 | } | ||||
131 | if (!PAOperation(pa_set_port(m_context, | ||||
132 | index, | ||||
133 | portName.toUtf8().constData(), | ||||
134 | nullptr, | ||||
135 | nullptr))) { | ||||
136 | qCWarning(PLASMAPA) << "pa_set_port failed"; | ||||
137 | return; | ||||
138 | } | ||||
139 | } | ||||
140 | | ||||
141 | template <typename PAFunction> | ||||
142 | void setGenericDeviceForStream(quint32 streamIndex, | ||||
143 | quint32 deviceIndex, | ||||
144 | PAFunction pa_move_stream_to_device) | ||||
145 | { | ||||
146 | if (!m_context) { | ||||
147 | return; | ||||
148 | } | ||||
149 | if (!PAOperation(pa_move_stream_to_device(m_context, | ||||
150 | streamIndex, | ||||
151 | deviceIndex, | ||||
152 | nullptr, | ||||
153 | nullptr))) { | ||||
154 | qCWarning(PLASMAPA) << "pa_move_stream_to_device failed"; | ||||
155 | return; | ||||
156 | } | ||||
157 | } | ||||
158 | | ||||
159 | private: | ||||
160 | void connectToDaemon(); | ||||
161 | void reset(); | ||||
162 | | ||||
163 | // Don't forget to add things to reset(). | ||||
164 | SinkMap m_sinks; | ||||
165 | SinkInputMap m_sinkInputs; | ||||
166 | SourceMap m_sources; | ||||
167 | SourceOutputMap m_sourceOutputs; | ||||
168 | ClientMap m_clients; | ||||
169 | CardMap m_cards; | ||||
170 | ModuleMap m_modules; | ||||
171 | StreamRestoreMap m_streamRestores; | ||||
172 | Server *m_server; | ||||
173 | | ||||
174 | pa_context *m_context; | ||||
175 | pa_glib_mainloop *m_mainloop; | ||||
176 | | ||||
177 | QString m_newDefaultSink; | ||||
178 | QString m_newDefaultSource; | ||||
179 | | ||||
180 | int m_references; | ||||
181 | static Context* s_context; | ||||
182 | }; | ||||
183 | | ||||
184 | } // QPulseAudio | ||||
185 | | ||||
186 | #endif // CONTEXT_H |