1 /*  This file is part of the KDE project
2     Copyright (C) 2004-2007 Matthias Kretz <kretz@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.), 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_FACTORY_P_H
24 #define PHONON_FACTORY_P_H
25 
26 #include "phonon_export.h"
27 
28 #include <QObject>
29 #include <QFileInfo>
30 #include <QPluginLoader>
31 #include <QStringList>
32 
33 class QUrl;
34 class QIcon;
35 
36 namespace Phonon
37 {
38     class PlatformPlugin;
39     class MediaNodePrivate;
40     class AbstractMediaStream;
41 
42     /**
43      * \internal
44      */
45     struct Q_DECL_HIDDEN BackendDescriptor {
46         explicit BackendDescriptor(const QString &path = QString())
isValidBackendDescriptor47             : isValid(false)
48         {
49             QFileInfo info(path);
50             if (!info.exists()) {
51                 return;
52             }
53 
54             QPluginLoader loader(path);
55 
56             iid = loader.metaData().value(QLatin1String("IID")).toString();
57 
58             const QJsonObject metaData = loader.metaData().value(QLatin1String("MetaData")).toObject();
59             name = metaData.value(QLatin1String("Name")).toString();
60             icon = metaData.value(QLatin1String("Icon")).toString();
61             version = metaData.value(QLatin1String("Version")).toString();
62             website = metaData.value(QLatin1String("Website")).toString();
63             initialPreference = metaData.value(QLatin1String("InitialPreference")).toInt();
64 
65             pluginPath = path;
66             pluginName = info.baseName();
67 
68             if (name.isEmpty()) {
69                 name = pluginName;
70             }
71 
72             if (iid.isEmpty()) {
73                 return; // Not valid.
74             }
75 
76             isValid = true;
77         }
78 
79         bool isValid;
80 
81         QString iid;
82 
83         QString name;
84         QString icon;
85         QString version;
86         QString website;
87         int initialPreference; // Initial preference declared by the backend; larger is better
88         int weight = -1; // Weight assinged by user configuration
89 
90         QString pluginPath;
91         QString pluginName; // basename of the file. "legacy" name used for PHONON_BACKEND
92 
93         /** Implemented for sorting */
94         bool operator <(const BackendDescriptor &rhs) const
95         {
96             if (weight >= 0) {
97                 // If we have a weight the preference doesn't matter.
98                 // User configured weight always wins against initial preference.
99                 return (weight < rhs.weight);
100             }
101 
102             return this->initialPreference < rhs.initialPreference;
103         }
104     };
105 
106 /**
107  * \internal
108  * \brief Factory to access the preferred Backend.
109  *
110  * This class is used internally to get the backend's implementation.
111  * It keeps track of the objects that were created. When a
112  * request for a backend change comes, it asks all frontend objects to delete
113  * their backend objects and then checks whether they were all deleted. Only
114  * then the old backend is unloaded and the new backend is loaded.
115  *
116  * \author Matthias Kretz <kretz@kde.org>
117  */
118 namespace Factory
119 {
120     /**
121      * Emits signals for Phonon::Factory.
122      */
123     class Sender : public QObject
124     {
125         Q_OBJECT
126         Q_SIGNALS:
127             /**
128              * Emitted after the backend has successfully been changed.
129              */
130             void backendChanged();
131 
132             /**
133              * \copydoc BackendCapabilities::Notifier::availableAudioOutputDevicesChanged
134              */
135             void availableAudioOutputDevicesChanged();
136 
137             /**
138              * \copydoc BackendCapabilities::Notifier::availableAudioCaptureDevicesChanged
139              */
140             void availableAudioCaptureDevicesChanged();
141 
142             /**
143              * \copydoc BackendCapabilities::Notifier::availableVideoCaptureDevicesChanged
144              */
145             void availableVideoCaptureDevicesChanged();
146     };
147 
148     PHONON_EXPORT QList<BackendDescriptor> findBackends();
149 
150     /**
151      * Returns a pointer to the object emitting the signals.
152      *
153      * \see Sender::backendChanged()
154      */
155     PHONON_EXPORT Sender *sender();
156 
157     /**
158      * Create a new backend object for a MediaObject.
159      *
160      * \return a pointer to the MediaObject the backend provides.
161      */
162     QObject *createMediaObject(QObject *parent = 0);
163     /**
164      * Create a new backend object for a Effect.
165      *
166      * \return a pointer to the Effect the backend provides.
167      */
168 #ifndef QT_NO_PHONON_EFFECT
169     QObject *createEffect(int effectId, QObject *parent = 0);
170 #endif //QT_NO_PHONON_EFFECT
171     /**
172      * Create a new backend object for a VolumeFaderEffect.
173      *
174      * \return a pointer to the VolumeFaderEffect the backend provides.
175      */
176 #ifndef QT_NO_PHONON_VOLUMEFADEREFFECT
177     QObject *createVolumeFaderEffect(QObject *parent = 0);
178 #endif //QT_NO_PHONON_VOLUMEFADEREFFECT
179     /**
180      * Create a new backend object for a AudioOutput.
181      *
182      * \return a pointer to the AudioOutput the backend provides.
183      */
184     QObject *createAudioOutput(QObject *parent = 0);
185     /**
186      * Create a new backend object for a VideoWidget.
187      *
188      * \return a pointer to the VideoWidget the backend provides.
189      */
190 #ifndef QT_NO_PHONON_VIDEO
191     QObject *createVideoWidget(QObject *parent = 0);
192     QObject *createVideoGraphicsObject(QObject *parent = 0);
193 #endif //QT_NO_PHONON_VIDEO
194 
195     /**
196     * Create a new backend object for a AudioDataOutput.
197     *
198     * \return a pointer to the AudioDataOutput the backend provides.
199     */
200     PHONON_EXPORT QObject *createAudioDataOutput(QObject *parent = 0);
201 
202     /**
203      * \return a pointer to the backend interface.
204      */
205     PHONON_EXPORT QObject *backend(bool createWhenNull = true);
206 
207     /**
208      * Unique identifier for the Backend. Can be used in configuration files
209      * for example.
210      */
211     QString identifier();
212 
213     /**
214      * Get the name of the Backend. It's the name from the .desktop file.
215      */
216     PHONON_EXPORT QString backendName();
217 
218     /**
219      * Get the comment of the Backend. It's the comment from the .desktop file.
220      */
221     QString backendComment();
222 
223     /**
224      * Get the version of the Backend. It's the version from the .desktop file.
225      *
226      * The version is especially interesting if there are several versions
227      * available for binary incompatible versions of the backend's media
228      * framework.
229      */
230     QString backendVersion();
231 
232     /**
233      * Get the icon (name) of the Backend. It's the icon from the .desktop file.
234      */
235     QString backendIcon();
236 
237     /**
238      * Get the website of the Backend. It's the website from the .desktop file.
239      */
240     QString backendWebsite();
241 
242     /**
243      * registers the backend object
244      */
245     PHONON_EXPORT QObject *registerQObject(QObject *o);
246 
247     bool isMimeTypeAvailable(const QString &mimeType);
248 
249     PHONON_EXPORT void registerFrontendObject(MediaNodePrivate *);
250     PHONON_EXPORT void deregisterFrontendObject(MediaNodePrivate *);
251 
252     PHONON_EXPORT void setBackend(QObject *);
253     //PHONON_EXPORT void createBackend(const QString &library, const QString &version = QString());
254 
255     PHONON_EXPORT PlatformPlugin *platformPlugin();
256 
257 //X    It is probably better if we can get away with internal handling of
258 //X    freeing the soundcard device when it's not needed anymore and
259 //X    providing an IPC method to stop all MediaObjects -> free all
260 //X    devices
261 //X    /**
262 //X     * \internal
263 //X     * This is called when the application needs to free the soundcard
264 //X     * device(s).
265 //X     */
266 //X    void freeSoundcardDevices();
267 } // namespace Factory
268 } // namespace Phonon
269 
270 
271 #endif // PHONON_FACTORY_P_H
272 // vim: sw=4 ts=4
273