1 /*  This file is part of the KDE project
2     Copyright (C) 2009 Colin Guthrie <cguthrie@mandriva.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.), Nokia Corporation
10     (or its successors, if any) and the KDE Free Qt Foundation, which shall
11     act as a proxy defined in Section 6 of version 3 of the license.
12 
13     This library is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16     Lesser General Public License for more details.
17 
18     You should have received a copy of the GNU Lesser General Public
19     License along with this library.  If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifndef PHONON_PULSESUPPORT_H
24 #define PHONON_PULSESUPPORT_H
25 
26 #include "phonon_export.h"
27 #include "phononnamespace.h"
28 #include "objectdescription.h"
29 
30 #include <QtCore/QtGlobal>
31 #include <QtCore/QSet>
32 
33 
34 namespace Phonon
35 {
36     class PulseStream;
37     class PHONON_EXPORT PulseSupport : public QObject
38     {
39         Q_OBJECT
40         public:
41             /**
42              * \returns the instance pointer or null, see note.
43              * \note If \param allowNull is \c true and the instance was already
44              *       shut down this function instead returns to indicate that
45              *       the instance was already shut down.
46              *       If \param allowNull is \c false and the instance was already
47              *       shut down a dummy instance is returned instead. This case
48              *       will furthermore result in a qWarning being printed, so
49              *       when possible and sensible null handling should be done
50              *       to prevent this.
51              */
52             static PulseSupport *getInstanceOrNull(bool allowNull = false);
53             /** This function behaves like getInstanceOrNull(false). \see getInstanceOrNull */
54             static PulseSupport *getInstance();
55             static void shutdown();
56 
57             /**
58              * Whether or not PulseSupport is actively able to intercept calls.
59              *
60              * This is:
61              *   - isUsable()
62              *   - isRequested()
63              *   - has been enabled by the backend
64              *
65              * @return \c true if usable, requested and enabled
66              */
67             bool isActive();
68 
69             /**
70              * Whether or not pulseaudio is used. This does not mean it is
71              * meant to intercept calls meant for the backend. It simply
72              * indicates that the backend is using pulseaudio.
73              *
74              * This is:
75              *   - isUsable()
76              *   - isRequested()
77              *
78              * @return \c true if pulesaudio can be used, \c false otherwise
79              *
80              * @since 4.9.0
81              */
82             bool isUsed();
83 
84             /**
85              * Whether or not pulseaudio can be used.
86              *
87              * This is
88              *   - pulseaudiod is running
89              *   - pulseaudiod can be connected to
90              *
91              * @return \c true if pulseaudio can be used
92              */
93             bool isUsable() const;
94 
95             /**
96              * Whether or not the backend has requested that it wants to use
97              * pulseaudio. This does *not* mean the backend wants pulseaudio
98              * support to intercept calls.
99              *
100              * @return \c true if the backend has requested to use pulseaudio.
101              *
102              * @since 4.9.0
103              */
104             bool isRequested() const;
105 
106             /**
107              * Backends can use this to request pulseaudio usage, without
108              * enabling the interception.
109              *
110              * @see enable for requesting pulseaudio and forcing interception
111              *
112              * @param requested whether or not the backend would like the
113              *                  frontend to use pulseaudio (e.g. list devices)
114              *
115              * @since 4.9.0
116              */
117             void request(bool requested);
118 
119             /**
120              * Enable pulse support. This implies a backend request.
121              * @param enabled
122              */
123             void enable(bool enabled = true);
124 
125             QList<int> objectDescriptionIndexes(ObjectDescriptionType type) const;
126             QHash<QByteArray, QVariant> objectDescriptionProperties(ObjectDescriptionType type, int index) const;
127             QList<int> objectIndexesByCategory(ObjectDescriptionType type, Category category) const;
128             QList<int> objectIndexesByCategory(ObjectDescriptionType type, CaptureCategory category) const;
129 
130             void setOutputDevicePriorityForCategory(Category category, QList<int> order);
131             void setCaptureDevicePriorityForCategory(CaptureCategory category, QList<int> order);
132 
133             PHONON_DEPRECATED void setCaptureDevicePriorityForCategory(Category category, QList<int> order);
134 
135             PulseStream *registerOutputStream(QString streamUuid, Category category);
136             PulseStream *registerCaptureStream(QString streamUuid, CaptureCategory category);
137             PHONON_DEPRECATED PulseStream *registerCaptureStream(QString streamUuid, Category category);
138 
139             /**
140              * Whenever possible this function should be used to get Phonon
141              * specific PulseAudio stream properties and set them on specific
142              * streams. When precisely setting them per stream is not possible
143              * the envrionment setup function PulseSupport::setupStreamEnvironment
144              * should be called as close to stream creation as possible. The
145              * more time passes between setup and stream creation the more
146              * likely race conditions between setup of more than one AudioOutput
147              * will appear.
148              *
149              * \param streamUuid the AudioOutputs' stream UUID set by the frontend through
150              *                   AudioOutputInterface47::setStreamUuid
151              *
152              * \returns a hash of all properties set by setupStreamEnvironment
153              *
154              * \see setupStreamEnvironment
155              * \since 4.7.0
156              */
157             QHash<QString, QString> streamProperties(QString streamUuid) const;
158 
159             /**
160              * Sets PulseAudio override properties in the process' envrionment.
161              * Manually setting the properties on a per-stream basis is
162              * preferred as envrionment overrides are subject to race conditions
163              * when creating more than one stream around the same time.
164              *
165              * \param streamUuid the AudioOutputs' stream UUID set by the frontend
166              *                   through AudioOutputInterface47::setStreamUuid
167              *
168              * \see streamProperties
169              * \since 4.7.0
170              */
171             void setupStreamEnvironment(QString streamUuid);
172 
173             void emitObjectDescriptionChanged(ObjectDescriptionType);
174 
175             bool setOutputName(QString streamUuid, QString name);
176             bool setOutputDevice(QString streamUuid, int device);
177             bool setOutputVolume(QString streamUuid, qreal volume);
178             bool setOutputMute(QString streamUuid, bool mute);
179             bool setCaptureDevice(QString streamUuid, int device);
180             // NB Capture Volume/Mute not set until PA supports per-source-output volumes/mutes
181             //    or phonon supports capture properly... which ever comes first.
182             void clearStreamCache(QString streamUuid);
183 
184             static void debug();
185         public Q_SLOTS:
186             void connectToDaemon();
187 
188         Q_SIGNALS:
189             void objectDescriptionChanged(ObjectDescriptionType);
190 
191         private:
192             PulseSupport();
193             ~PulseSupport();
194 
195             bool mEnabled;
196             bool m_requested;
197     };
198 } // namespace Phonon
199 
200 
201 #endif // PHONON_PULSESUPPORT_H
202