1 /* This file is part of the KDE project
2 Copyright (C) 2007-2008 Matthias Kretz <kretz@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
20 #include "kdeplatformplugin.h"
21 #include "kiomediastream.h"
23 #include <QtCore/QDir>
24 #include <QtCore/QFile>
25 #include <QtCore/QtPlugin>
26 #include <QtCore/QCoreApplication>
28 #include <kaboutdata.h>
30 #include <kcomponentdata.h>
33 #include <klibloader.h>
35 #include <kmessagebox.h>
36 #include <kmimetype.h>
37 #include <knotification.h>
39 #include <kservicetypetrader.h>
40 #include <kconfiggroup.h>
41 #include <kstandarddirs.h>
42 #include "devicelisting.h"
44 typedef QPair
<QByteArray
, QString
> PhononDeviceAccess
;
45 typedef QList
<PhononDeviceAccess
> PhononDeviceAccessList
;
47 Q_DECLARE_METATYPE(PhononDeviceAccessList
)
52 K_GLOBAL_STATIC_WITH_ARGS(KComponentData
, mainComponentData
, (QCoreApplication::applicationName().isEmpty() ? "Qt Application" : QCoreApplication::applicationName().toUtf8()))
53 K_GLOBAL_STATIC_WITH_ARGS(KComponentData
, phononComponentData
, ("phonon"))
55 static void ensureMainComponentData()
57 if (!KGlobal::hasMainComponent()) {
58 // a pure Qt application does not have a KComponentData object,
61 qAddPostRoutine(mainComponentData
.destroy
);
62 Q_ASSERT(KGlobal::hasMainComponent());
66 static const KComponentData
&componentData()
68 ensureMainComponentData();
69 return *phononComponentData
;
72 KdePlatformPlugin::KdePlatformPlugin()
75 ensureMainComponentData();
76 KGlobal::locale()->insertCatalog(QLatin1String("phonon_kde"));
79 KdePlatformPlugin::~KdePlatformPlugin()
84 AbstractMediaStream
*KdePlatformPlugin::createMediaStream(const QUrl
&url
, QObject
*parent
)
86 return new KioMediaStream(url
, parent
);
89 QIcon
KdePlatformPlugin::icon(const QString
&name
) const
94 void KdePlatformPlugin::notification(const char *notificationName
, const QString
&text
,
95 const QStringList
&actions
, QObject
*receiver
,
96 const char *actionSlot
) const
98 KNotification
*notification
= new KNotification(notificationName
);
99 notification
->setComponentData(componentData());
100 notification
->setText(text
);
101 //notification->setPixmap(...);
102 notification
->addContext(QLatin1String("Application"), KGlobal::mainComponent().componentName());
103 if (!actions
.isEmpty() && receiver
&& actionSlot
) {
104 notification
->setActions(actions
);
105 QObject::connect(notification
, SIGNAL(activated(unsigned int)), receiver
, actionSlot
);
107 notification
->sendEvent();
110 QString
KdePlatformPlugin::applicationName() const
112 ensureMainComponentData();
113 const KAboutData
*ad
= KGlobal::mainComponent().aboutData();
115 const QString programName
= ad
->programName();
116 if (programName
.isEmpty()) {
117 return KGlobal::mainComponent().componentName();
121 return KGlobal::mainComponent().componentName();
124 #undef PHONON_LOAD_BACKEND_GLOBAL
126 QObject
*KdePlatformPlugin::createBackend(KService::Ptr newService
)
129 #ifdef PHONON_LOAD_BACKEND_GLOBAL
130 KLibFactory
*factory
= 0;
131 // This code is in here temporarily until NMM gets fixed.
132 // Currently the NMM backend will fail with undefined symbols if
133 // the backend is not loaded with global symbol resolution
134 QObject
*backend
= 0;
135 factory
= KLibLoader::self()->factory(newService
->library(), QLibrary::ExportExternalSymbolsHint
);
137 errorReason
= KLibLoader::self()->lastErrorMessage();
139 QObject
*backend
= factory
->create
<QObject
>();
141 errorReason
= i18n("create method returned 0");
145 QObject
*backend
= newService
->createInstance
<QObject
>(0, QVariantList(), &errorReason
);
148 const QLatin1String
suffix("/phonon_backend/");
149 const QStringList
libFilter(newService
->library() + QLatin1String(".*"));
150 foreach (QString libPath
, QCoreApplication::libraryPaths()) {
152 const QDir
dir(libPath
);
153 foreach (const QString
&pluginName
, dir
.entryList(libFilter
, QDir::Files
)) {
154 QPluginLoader
pluginLoader(libPath
+ pluginName
);
155 backend
= pluginLoader
.instance();
166 kError(600) << "Can not create backend object from factory for " <<
167 newService
->name() << ", " << newService
->library() << ":\n" << errorReason
;
169 KMessageBox::error(0,
170 i18n("<qt>Unable to use the <b>%1</b> Multimedia Backend:<br/>%2</qt>",
171 newService
->name(), errorReason
));
175 kDebug() << "using backend: " << newService
->name();
179 QObject
*KdePlatformPlugin::createBackend()
181 // Within this process, display the warning about missing backends
183 static bool has_shown
= false;
184 ensureMainComponentData();
185 const KService::List offers
= KServiceTypeTrader::self()->query("PhononBackend",
186 "Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1");
187 if (offers
.isEmpty()) {
189 #if defined(HAVE_KDE4_MULTIMEDIA)
190 KMessageBox::error(0, i18n("Unable to find a Multimedia Backend"));
196 // Flag the warning as not shown, since if the next time the
197 // list of backends is suddenly empty again the user should be
201 KService::List::const_iterator it
= offers
.begin();
202 const KService::List::const_iterator end
= offers
.end();
204 QObject
*backend
= createBackend(*it
);
213 QObject
*KdePlatformPlugin::createBackend(const QString
&library
, const QString
&version
)
215 ensureMainComponentData();
216 QString additionalConstraints
= QLatin1String(" and Library == '") + library
+ QLatin1Char('\'');
217 if (!version
.isEmpty()) {
218 additionalConstraints
+= QLatin1String(" and [X-KDE-PhononBackendInfo-Version] == '")
219 + version
+ QLatin1Char('\'');
221 const KService::List offers
= KServiceTypeTrader::self()->query(QLatin1String("PhononBackend"),
222 QString("Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1%1")
223 .arg(additionalConstraints
));
224 if (offers
.isEmpty()) {
225 KMessageBox::error(0, i18n("Unable to find the requested Multimedia Backend"));
229 KService::List::const_iterator it
= offers
.begin();
230 const KService::List::const_iterator end
= offers
.end();
232 QObject
*backend
= createBackend(*it
);
241 bool KdePlatformPlugin::isMimeTypeAvailable(const QString
&mimeType
) const
243 ensureMainComponentData();
244 const KService::List offers
= KServiceTypeTrader::self()->query("PhononBackend",
245 "Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1");
246 if (!offers
.isEmpty()) {
247 return offers
.first()->hasMimeType(KMimeType::mimeType(mimeType
).data());
252 void KdePlatformPlugin::saveVolume(const QString
&outputName
, qreal volume
)
254 ensureMainComponentData();
255 KConfigGroup
config(KGlobal::config(), "Phonon::AudioOutput");
256 config
.writeEntry(outputName
+ "_Volume", volume
);
259 qreal
KdePlatformPlugin::loadVolume(const QString
&outputName
) const
261 ensureMainComponentData();
262 KConfigGroup
config(KGlobal::config(), "Phonon::AudioOutput");
263 return config
.readEntry
<qreal
>(outputName
+ "_Volume", 1.0);
266 void KdePlatformPlugin::ensureDeviceListingObject() const
269 m_devList
= new DeviceListing
;
270 connect(m_devList
, SIGNAL(objectDescriptionChanged(ObjectDescriptionType
)),
271 SIGNAL(objectDescriptionChanged(ObjectDescriptionType
)));
275 QList
<int> KdePlatformPlugin::objectDescriptionIndexes(ObjectDescriptionType type
) const
278 case AudioOutputDeviceType
:
279 case AudioCaptureDeviceType
:
280 ensureDeviceListingObject();
281 return m_devList
->objectDescriptionIndexes(type
);
287 QHash
<QByteArray
, QVariant
> KdePlatformPlugin::objectDescriptionProperties(ObjectDescriptionType type
, int index
) const
290 case AudioOutputDeviceType
:
291 case AudioCaptureDeviceType
:
292 ensureDeviceListingObject();
293 return m_devList
->objectDescriptionProperties(type
, index
);
295 return QHash
<QByteArray
, QVariant
>();
299 QList
<QPair
<QByteArray
, QString
> > KdePlatformPlugin::deviceAccessListFor(const Phonon::AudioOutputDevice
&deviceDesc
) const
301 const QVariant
&deviceAccessListVariant
= deviceDesc
.property("deviceAccessList");
302 if (deviceAccessListVariant
.isValid()) {
303 return qvariant_cast
<PhononDeviceAccessList
>(deviceAccessListVariant
);
305 PhononDeviceAccessList ret
;
306 const QVariant
&v
= deviceDesc
.property("driver");
308 const QByteArray
&driver
= v
.toByteArray();
309 const QStringList
&deviceIds
= deviceDesc
.property("deviceIds").toStringList();
310 foreach (const QString
&deviceId
, deviceIds
) {
311 ret
<< QPair
<QByteArray
, QString
>(driver
, deviceId
);
317 } // namespace Phonon
319 Q_EXPORT_PLUGIN2(phonon_platform_kde
, Phonon::KdePlatformPlugin
)
321 #include "kdeplatformplugin.moc"
322 // vim: sw=4 sts=4 et tw=100