diff options
author | Justin McPherson <justin.mcpherson@nokia.com> | 2010-03-25 03:50:08 (GMT) |
---|---|---|
committer | Justin McPherson <justin.mcpherson@nokia.com> | 2010-03-25 03:50:08 (GMT) |
commit | 490cd29001670b37204dcf5e24398073f610fabd (patch) | |
tree | ec00612f0dc799bd112809ed385de78a6600b919 | |
parent | 444e8812eec42abd2dcc5e47826f9a4793a34f66 (diff) | |
download | Qt-490cd29001670b37204dcf5e24398073f610fabd.zip Qt-490cd29001670b37204dcf5e24398073f610fabd.tar.gz Qt-490cd29001670b37204dcf5e24398073f610fabd.tar.bz2 |
Update Phonon core to 4.4.0
23 files changed, 571 insertions, 217 deletions
diff --git a/src/3rdparty/phonon/phonon/CMakeLists.txt b/src/3rdparty/phonon/phonon/CMakeLists.txt index 11d7913..ace934a 100644 --- a/src/3rdparty/phonon/phonon/CMakeLists.txt +++ b/src/3rdparty/phonon/phonon/CMakeLists.txt @@ -8,6 +8,30 @@ endif (PHONON_BUILD_EXAMPLES) add_subdirectory(experimental) +set(PULSEAUDIO_MINIMUM_VERSION "0.9.15") +macro_optional_find_package(PulseAudio) +if (PULSEAUDIO_FOUND) + # PULSEAUDIO_DEVICE_MANAGER feature check could be moved to FindPulseAudio.cmake, hint hint. -- Rex + macro_ensure_version("0.9.21" "${PULSEAUDIO_VERSION}" PULSEAUDIO_DEVICE_MANAGER) +endif (PULSEAUDIO_FOUND) +macro_log_feature(PULSEAUDIO_FOUND "PulseAudio" "A cross-platform, networked sound server." "http://www.pulseaudio.org" FALSE "" "Allows audio playback via the PulseAudio soundserver when it is running") +macro_optional_find_package(GLIB2) +macro_log_feature(GLIB2_FOUND "GLib2" "GLib 2 is required to compile the pulseaudio for Phonon" "http://www.gtk.org/download/" FALSE) + + +if (GLIB2_FOUND AND PULSEAUDIO_FOUND) + add_definitions(-DHAVE_PULSEAUDIO) + include_directories(${GLIB2_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIR}) + if (PULSEAUDIO_DEVICE_MANAGER) + add_definitions(-DHAVE_PULSEAUDIO_DEVICE_MANAGER) + endif(PULSEAUDIO_DEVICE_MANAGER) +else(GLIB2_FOUND AND PULSEAUDIO_FOUND) + set(PULSEAUDIO_INCLUDE_DIR "") + set(PULSEAUDIO_LIBRARY "") + set(PULSEAUDIO_MAINLOOP_LIBRARY "") +endif(GLIB2_FOUND AND PULSEAUDIO_FOUND) + + set(phonon_LIB_SRCS objectdescription.cpp objectdescriptionmodel.cpp @@ -35,9 +59,12 @@ set(phonon_LIB_SRCS videowidget.cpp videoplayer.cpp seekslider.cpp + swiftslider.cpp volumeslider.cpp effectwidget.cpp iodevicestream.cpp + audiodataoutput.cpp + pulsesupport.cpp ) if (QT_QTDBUS_FOUND) @@ -50,6 +77,10 @@ endif (QT_QTDBUS_FOUND) add_definitions(-DPHONON_LIBRARY_PATH="${PLUGIN_INSTALL_DIR}/plugins") automoc4_add_library(phonon SHARED ${phonon_LIB_SRCS}) target_link_libraries(phonon ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY}) +if (GLIB2_FOUND AND PULSEAUDIO_FOUND) +target_link_libraries(phonon ${GLIB2_LIBRARIES} ${GOBJECT_LIBRARIES} ${PULSEAUDIO_LIBRARY} ${PULSEAUDIO_MAINLOOP_LIBRARY}) +endif (GLIB2_FOUND AND PULSEAUDIO_FOUND) + if (QT_QTDBUS_FOUND) target_link_libraries(phonon ${QT_QTDBUS_LIBRARY}) endif (QT_QTDBUS_FOUND) @@ -99,6 +130,10 @@ install(FILES volumeslider.h effectwidget.h platformplugin.h + audiodataoutput.h + audiodataoutputinterface.h + globalconfig.h + pulsesupport.h DESTINATION ${INCLUDE_INSTALL_DIR}/phonon COMPONENT Devel) install(FILES org.kde.Phonon.AudioOutput.xml DESTINATION ${DBUS_INTERFACES_INSTALL_DIR}) diff --git a/src/3rdparty/phonon/phonon/audiooutput.cpp b/src/3rdparty/phonon/phonon/audiooutput.cpp index 0f6a49b..932a875 100644 --- a/src/3rdparty/phonon/phonon/audiooutput.cpp +++ b/src/3rdparty/phonon/phonon/audiooutput.cpp @@ -24,10 +24,11 @@ #include "factory_p.h" #include "objectdescription.h" #include "audiooutputadaptor_p.h" -#include "globalconfig_p.h" +#include "globalconfig.h" #include "audiooutputinterface.h" #include "phononnamespace_p.h" #include "platform_p.h" +#include "pulsesupport.h" #include <QtCore/qmath.h> @@ -42,8 +43,12 @@ QT_BEGIN_NAMESPACE namespace Phonon { -static inline bool callSetOutputDevice(MediaNodePrivate *const d, int index) +static inline bool callSetOutputDevice(AudioOutputPrivate *const d, int index) { + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) + return pulse->setOutputDevice(d->getStreamUuid(), index); + Iface<IFACES2> iface(d); if (iface) { return iface->setOutputDevice(AudioOutputDevice::fromIndex(index)); @@ -51,8 +56,12 @@ static inline bool callSetOutputDevice(MediaNodePrivate *const d, int index) return Iface<IFACES0>::cast(d)->setOutputDevice(index); } -static inline bool callSetOutputDevice(MediaNodePrivate *const d, const AudioOutputDevice &dev) +static inline bool callSetOutputDevice(AudioOutputPrivate *const d, const AudioOutputDevice &dev) { + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) + return pulse->setOutputDevice(d->getStreamUuid(), dev.index()); + Iface<IFACES2> iface(d); if (iface) { return iface->setOutputDevice(dev); @@ -89,16 +98,20 @@ void AudioOutputPrivate::init(Phonon::Category c) #endif category = c; - - // select hardware device according to the category - device = AudioOutputDevice::fromIndex(GlobalConfig().audioOutputDeviceFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices)); + streamUuid = QUuid::createUuid().toString(); + PulseSupport *pulse = PulseSupport::getInstance(); + pulse->setStreamPropList(category, streamUuid); + q->connect(pulse, SIGNAL(usingDevice(QString,int)), SLOT(_k_deviceChanged(QString,int))); createBackendObject(); q->connect(Factory::sender(), SIGNAL(availableAudioOutputDevicesChanged()), SLOT(_k_deviceListChanged())); } - +QString AudioOutputPrivate::getStreamUuid() +{ + return streamUuid; +} void AudioOutputPrivate::createBackendObject() { @@ -106,6 +119,7 @@ void AudioOutputPrivate::createBackendObject() return; Q_Q(AudioOutput); m_backendObject = Factory::createAudioOutput(q); + device = AudioOutputDevice::fromIndex(GlobalConfig().audioOutputDeviceFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices)); if (m_backendObject) { setupBackendObject(); } @@ -220,21 +234,21 @@ bool AudioOutput::setOutputDevice(const AudioOutputDevice &newAudioOutputDevice) { K_D(AudioOutput); if (!newAudioOutputDevice.isValid()) { - d->outputDeviceOverridden = false; + d->outputDeviceOverridden = d->forceMove = false; const int newIndex = GlobalConfig().audioOutputDeviceFor(d->category); if (newIndex == d->device.index()) { return true; } d->device = AudioOutputDevice::fromIndex(newIndex); } else { - d->outputDeviceOverridden = true; + d->outputDeviceOverridden = d->forceMove = true; if (d->device == newAudioOutputDevice) { return true; } d->device = newAudioOutputDevice; } if (k_ptr->backendObject()) { - return callSetOutputDevice(k_ptr, d->device.index()); + return callSetOutputDevice(d, d->device.index()); } return true; } @@ -261,7 +275,10 @@ void AudioOutputPrivate::setupBackendObject() #ifndef QT_NO_PHONON_SETTINGSGROUP // if the output device is not available and the device was not explicitly set - if (!callSetOutputDevice(this, device) && !outputDeviceOverridden) { + // There is no need to set the output device initially if PA is used as + // we know it will not work (stream doesn't exist yet) and that this will be + // handled by _k_deviceChanged() + if (!PulseSupport::getInstance()->isActive() && !callSetOutputDevice(this, device) && !outputDeviceOverridden) { // fall back in the preference list of output devices QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices); if (deviceList.isEmpty()) { @@ -306,10 +323,14 @@ void AudioOutputPrivate::_k_revertFallback() void AudioOutputPrivate::_k_audioDeviceFailed() { + if (PulseSupport::getInstance()->isActive()) + return; + +#ifndef QT_NO_PHONON_SETTINGSGROUP + pDebug() << Q_FUNC_INFO; // outputDeviceIndex identifies a failing device // fall back in the preference list of output devices -#ifndef QT_NO_PHONON_SETTINGSGROUP const QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices); for (int i = 0; i < deviceList.count(); ++i) { const int devIndex = deviceList.at(i); @@ -331,8 +352,15 @@ void AudioOutputPrivate::_k_audioDeviceFailed() void AudioOutputPrivate::_k_deviceListChanged() { - pDebug() << Q_FUNC_INFO; + if (PulseSupport::getInstance()->isActive()) + return; + #ifndef QT_NO_PHONON_SETTINGSGROUP + pDebug() << Q_FUNC_INFO; + // Check to see if we have an override and do not change to a higher priority device if the overridden device is still present. + if (outputDeviceOverridden && device.property("available").toBool()) { + return; + } // let's see if there's a usable device higher in the preference list const QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings); DeviceChangeType changeType = HigherPreferenceChange; @@ -361,6 +389,36 @@ void AudioOutputPrivate::_k_deviceListChanged() #endif //QT_NO_PHONON_SETTINGSGROUP } +void AudioOutputPrivate::_k_deviceChanged(QString inStreamUuid, int deviceIndex) +{ + // Note that this method is only used by PulseAudio at present. + if (inStreamUuid == streamUuid) { + // 1. Check to see if we are overridden. If we are, and devices do not match, + // then try and apply our own device as the output device. + // We only do this the first time + if (outputDeviceOverridden && forceMove) { + forceMove = false; + const AudioOutputDevice ¤tDevice = AudioOutputDevice::fromIndex(deviceIndex); + if (currentDevice != device) { + if (!callSetOutputDevice(this, device)) { + // What to do if we are overridden and cannot change to our preferred device? + } + } + } + // 2. If we are not overridden, then we need to update our perception of what + // device we are using. If the devices do not match, something lower in the + // stack is overriding our preferences (e.g. a per-application stream preference, + // specific application move, priority list changed etc. etc.) + else if (!outputDeviceOverridden) { + const AudioOutputDevice ¤tDevice = AudioOutputDevice::fromIndex(deviceIndex); + if (currentDevice != device) { + // The device is not what we think it is, so lets say what is happening. + handleAutomaticDeviceChange(currentDevice, SoundSystemChange); + } + } + } +} + static struct { int first; @@ -405,11 +463,33 @@ void AudioOutputPrivate::handleAutomaticDeviceChange(const AudioOutputDevice &de g_lastFallback.second = 0; } break; + case SoundSystemChange: + { +#ifndef QT_NO_PHONON_PLATFORMPLUGIN + if (device1.property("available").toBool()) { + const QString text = AudioOutput::tr("<html>Switching to the audio playback device <b>%1</b><br/>" + "which has higher preference or is specifically configured for this stream.</html>").arg(device2.name()); + Platform::notification("AudioDeviceFallback", text, + QStringList(AudioOutput::tr("Revert back to device '%1'").arg(device1.name())), + q, SLOT(_k_revertFallback())); + } else { + const QString &text = + AudioOutput::tr("<html>The audio playback device <b>%1</b> does not work.<br/>" + "Falling back to <b>%2</b>.</html>").arg(device1.name()).arg(device2.name()); + Platform::notification("AudioDeviceFallback", text); + } +#endif //QT_NO_PHONON_PLATFORMPLUGIN + //outputDeviceOverridden = true; + g_lastFallback.first = 0; + g_lastFallback.second = 0; + } + break; } } AudioOutputPrivate::~AudioOutputPrivate() { + PulseSupport::getInstance()->clearStreamCache(streamUuid); #ifndef QT_NO_DBUS if (adaptor) { emit adaptor->outputDestroyed(); diff --git a/src/3rdparty/phonon/phonon/audiooutput.h b/src/3rdparty/phonon/phonon/audiooutput.h index 4edf135..513a863 100644 --- a/src/3rdparty/phonon/phonon/audiooutput.h +++ b/src/3rdparty/phonon/phonon/audiooutput.h @@ -169,6 +169,7 @@ namespace Phonon Q_PRIVATE_SLOT(k_func(), void _k_revertFallback()) Q_PRIVATE_SLOT(k_func(), void _k_audioDeviceFailed()) Q_PRIVATE_SLOT(k_func(), void _k_deviceListChanged()) + Q_PRIVATE_SLOT(k_func(), void _k_deviceChanged(QString streamUuid, int device)) }; } //namespace Phonon diff --git a/src/3rdparty/phonon/phonon/audiooutput_p.h b/src/3rdparty/phonon/phonon/audiooutput_p.h index fdee299..01dc48f 100644 --- a/src/3rdparty/phonon/phonon/audiooutput_p.h +++ b/src/3rdparty/phonon/phonon/audiooutput_p.h @@ -46,6 +46,7 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate return 0; } void init(Phonon::Category c); + QString getStreamUuid(); protected: @@ -58,6 +59,7 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate #endif deviceBeforeFallback(-1), outputDeviceOverridden(false), + forceMove(false), muted(false) { } @@ -66,7 +68,8 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate enum DeviceChangeType { FallbackChange, - HigherPreferenceChange + HigherPreferenceChange, + SoundSystemChange }; void handleAutomaticDeviceChange(const AudioOutputDevice &newDev, DeviceChangeType type); @@ -74,17 +77,20 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate void _k_revertFallback(); void _k_audioDeviceFailed(); void _k_deviceListChanged(); + void _k_deviceChanged(QString streamUuid, int deviceIndex); private: QString name; Phonon::AudioOutputDevice device; qreal volume; + QString streamUuid; #ifndef QT_NO_DBUS Phonon::AudioOutputAdaptor *adaptor; #endif Category category; int deviceBeforeFallback; bool outputDeviceOverridden; + bool forceMove; bool muted; }; } //namespace Phonon diff --git a/src/3rdparty/phonon/phonon/audiooutputinterface.h b/src/3rdparty/phonon/phonon/audiooutputinterface.h index 80ba11c..cce12b2 100644 --- a/src/3rdparty/phonon/phonon/audiooutputinterface.h +++ b/src/3rdparty/phonon/phonon/audiooutputinterface.h @@ -64,7 +64,7 @@ class AudioOutputInterface40 * A value of 0.0 means muted, 1.0 means unchanged, 2.0 means double voltage (i.e. all * samples are multiplied by 2). * - * Everytime the volume in the backend changes it should emit volumeChanged(qreal), also + * Every time the volume in the backend changes it should emit volumeChanged(qreal), also * inside this function. */ virtual void setVolume(qreal) = 0; diff --git a/src/3rdparty/phonon/phonon/backendcapabilities.cpp b/src/3rdparty/phonon/phonon/backendcapabilities.cpp index fbeb020..8dad589 100644 --- a/src/3rdparty/phonon/phonon/backendcapabilities.cpp +++ b/src/3rdparty/phonon/phonon/backendcapabilities.cpp @@ -26,7 +26,7 @@ #include "phonondefs_p.h" #include "backendinterface.h" #include "factory_p.h" -#include "globalconfig_p.h" +#include "globalconfig.h" #include "globalstatic_p.h" #include "objectdescription.h" diff --git a/src/3rdparty/phonon/phonon/factory.cpp b/src/3rdparty/phonon/phonon/factory.cpp index 9967c971..24be0f3 100644 --- a/src/3rdparty/phonon/phonon/factory.cpp +++ b/src/3rdparty/phonon/phonon/factory.cpp @@ -134,30 +134,24 @@ bool FactoryPrivate::createBackend() continue; } - QStringList plugins(dir.entryList(QDir::Files)); + QStringList plugins(dir.entryList(QDir::Files)); #ifdef Q_OS_SYMBIAN /* On Symbian OS we might have two plugins, one which uses Symbian - * MMF framework("phonon_mmf"), and one which uses Real Networks's + * MMF framework("mmf"), and one which uses Real Networks's * Helix("hxphonon"). We prefer the latter because it's more * sophisticated, so we make sure the Helix backend is attempted * to be loaded first, and the MMF backend is used for backup. */ { - - const int hxphonon = plugins.indexOf(QLatin1String("hxphonon")); - if (hxphonon != -1) - plugins.move(hxphonon, 0); - - // Code for debugging the MMF backend. - if(hxphonon != -1) { - qDebug() << "Found hxphonon backend and removed it from the lookup list."; - plugins.removeAll(QLatin1String("hxphonon")); - } + const int helix = plugins.indexof(QLatin1String("hxphonon")); + if (helix != -1) + plugins.move(helix, 0); } #endif - for (int i = 0; i < plugins.count(); ++i) { - QPluginLoader pluginLoader(libPath + plugins.at(i)); + const QStringList files = dir.entryList(QDir::Files); + for (int i = 0; i < files.count(); ++i) { + QPluginLoader pluginLoader(libPath + files.at(i)); if (!pluginLoader.load()) { pDebug() << Q_FUNC_INFO << " load failed:" << pluginLoader.errorString(); @@ -350,6 +344,7 @@ FACTORY_IMPL(AudioOutput) #ifndef QT_NO_PHONON_VIDEO FACTORY_IMPL(VideoWidget) #endif //QT_NO_PHONON_VIDEO +FACTORY_IMPL(AudioDataOutput) #undef FACTORY_IMPL @@ -469,7 +464,7 @@ GET_STRING_PROPERTY(backendWebsite) QObject *Factory::registerQObject(QObject *o) { if (o) { - QObject::connect(o, SIGNAL(destroyed(QObject*)), globalFactory, SLOT(objectDestroyed(QObject*)), Qt::DirectConnection); + QObject::connect(o, SIGNAL(destroyed(QObject *)), globalFactory, SLOT(objectDestroyed(QObject *)), Qt::DirectConnection); globalFactory->objects.append(o); } return o; diff --git a/src/3rdparty/phonon/phonon/factory_p.h b/src/3rdparty/phonon/phonon/factory_p.h index dee2b56..41b8c5b 100644 --- a/src/3rdparty/phonon/phonon/factory_p.h +++ b/src/3rdparty/phonon/phonon/factory_p.h @@ -122,6 +122,13 @@ namespace Factory #endif //QT_NO_PHONON_VIDEO /** + * Create a new backend object for a AudioDataOutput. + * + * \return a pointer to the AudioDataOutput the backend provides. + */ + PHONON_EXPORT QObject *createAudioDataOutput(QObject *parent = 0); + + /** * \return a pointer to the backend interface. */ PHONON_EXPORT QObject *backend(bool createWhenNull = true); diff --git a/src/3rdparty/phonon/phonon/globalconfig.cpp b/src/3rdparty/phonon/phonon/globalconfig.cpp index 3b77a18..be751ce 100644 --- a/src/3rdparty/phonon/phonon/globalconfig.cpp +++ b/src/3rdparty/phonon/phonon/globalconfig.cpp @@ -20,6 +20,7 @@ */ +#include "globalconfig.h" #include "globalconfig_p.h" #include "factory_p.h" @@ -29,6 +30,7 @@ #include "backendinterface.h" #include "qsettingsgroup_p.h" #include "phononnamespace_p.h" +#include "pulsesupport.h" #include <QtCore/QList> #include <QtCore/QVariant> @@ -38,15 +40,18 @@ QT_BEGIN_NAMESPACE namespace Phonon { +GlobalConfigPrivate::GlobalConfigPrivate() : config(QLatin1String("kde.org"), QLatin1String("libphonon")) +{ +} + GlobalConfig::GlobalConfig() -#ifndef QT_NO_SETTINGS - : m_config(QLatin1String("kde.org"), QLatin1String("libphonon")) -#endif //QT_NO_SETTINGS + : k_ptr(new GlobalConfigPrivate) { } GlobalConfig::~GlobalConfig() { + delete k_ptr; } enum WhatToFilter { @@ -59,7 +64,11 @@ static void filter(ObjectDescriptionType type, BackendInterface *backendIface, Q { QMutableListIterator<int> it(*list); while (it.hasNext()) { - const QHash<QByteArray, QVariant> properties = backendIface->objectDescriptionProperties(type, it.next()); + QHash<QByteArray, QVariant> properties; + if (backendIface) + properties = backendIface->objectDescriptionProperties(type, it.next()); + else + properties = PulseSupport::getInstance()->objectDescriptionProperties(type, it.next()); QVariant var; if (whatToFilter & FilterAdvancedDevices) { var = properties.value("isAdvanced"); @@ -73,6 +82,7 @@ static void filter(ObjectDescriptionType type, BackendInterface *backendIface, Q if (var.isValid() && var.toBool()) { it.remove(); continue; +#ifndef QT_NO_PHONON_SETTINGSGROUP } } if (whatToFilter & FilterUnavailableDevices) { @@ -85,9 +95,12 @@ static void filter(ObjectDescriptionType type, BackendInterface *backendIface, Q } } -#ifndef QT_NO_PHONON_SETTINGSGROUP -static QList<int> listSortedByConfig(const QSettingsGroup &backendConfig, Phonon::Category category, QList<int> &defaultList) +static QList<int> sortDevicesByCategoryPriority(const GlobalConfig *config, const QSettingsGroup *backendConfig, ObjectDescriptionType type, Phonon::Category category, QList<int> &defaultList) { + Q_ASSERT(config); + Q_ASSERT(backendConfig); + Q_ASSERT(type == AudioOutputDeviceType || type == AudioCaptureDeviceType); + if (defaultList.size() <= 1) { // nothing to sort return defaultList; @@ -104,20 +117,26 @@ static QList<int> listSortedByConfig(const QSettingsGroup &backendConfig, Phonon } } - QString categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(category)); - if (!backendConfig.hasKey(categoryKey)) { - // no list in config for the given category - categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(Phonon::NoCategory)); - if (!backendConfig.hasKey(categoryKey)) { - // no list in config for NoCategory - return defaultList; + QList<int> deviceList; + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) { + deviceList = pulse->objectIndexesByCategory(type, category); + } else { + QString categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(category)); + if (!backendConfig->hasKey(categoryKey)) { + // no list in config for the given category + categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(Phonon::NoCategory)); + if (!backendConfig->hasKey(categoryKey)) { + // no list in config for NoCategory + return defaultList; + } } - } - //Now the list from m_config - QList<int> deviceList = backendConfig.value(categoryKey, QList<int>()); + //Now the list from d->config + deviceList = backendConfig->value(categoryKey, QList<int>()); + } - //if there are devices in m_config that the backend doesn't report, remove them from the list + //if there are devices in d->config that the backend doesn't report, remove them from the list QMutableListIterator<int> i(deviceList); while (i.hasNext()) { if (0 == defaultList.removeAll(i.next())) { @@ -125,58 +144,198 @@ static QList<int> listSortedByConfig(const QSettingsGroup &backendConfig, Phonon } } - //if the backend reports more devices that are not in m_config append them to the list + //if the backend reports more devices that are not in d->config append them to the list deviceList += defaultList; return deviceList; } + +bool GlobalConfig::hideAdvancedDevices() const +{ + K_D(const GlobalConfig); + //The devices need to be stored independently for every backend + const QSettingsGroup generalGroup(&d->config, QLatin1String("General")); + return generalGroup.value(QLatin1String("HideAdvancedDevices"), true); +} + +void GlobalConfig::setHideAdvancedDevices(bool hide) +{ + K_D(GlobalConfig); + QSettingsGroup generalGroup(&d->config, QLatin1String("General")); + generalGroup.setValue(QLatin1String("HideAdvancedDevices"), hide); +} + +static bool isHiddenAudioOutputDevice(const GlobalConfig *config, int i) +{ + Q_ASSERT(config); + + if (!config->hideAdvancedDevices()) + return false; + + AudioOutputDevice ad = AudioOutputDevice::fromIndex(i); + const QVariant var = ad.property("isAdvanced"); + return (var.isValid() && var.toBool()); +} + +#ifndef QT_NO_PHONON_AUDIOCAPTURE +static bool isHiddenAudioCaptureDevice(const GlobalConfig *config, int i) +{ + Q_ASSERT(config); + + if (!config->hideAdvancedDevices()) + return false; + + AudioCaptureDevice ad = AudioCaptureDevice::fromIndex(i); + const QVariant var = ad.property("isAdvanced"); + return (var.isValid() && var.toBool()); +} +#endif + +static QList<int> reindexList(const GlobalConfig *config, Phonon::Category category, QList<int>newOrder, bool output) +{ + Q_ASSERT(config); +#ifdef QT_NO_PHONON_AUDIOCAPTURE + Q_ASSERT(output); +#endif + + /*QString sb; + sb = QString("(Size %1)").arg(currentList.size()); + foreach (int i, currentList) + sb += QString("%1, ").arg(i); + fprintf(stderr, "=== Reindex Current: %s\n", sb.toUtf8().constData()); + sb = QString("(Size %1)").arg(newOrder.size()); + foreach (int i, newOrder) + sb += QString("%1, ").arg(i); + fprintf(stderr, "=== Reindex Before : %s\n", sb.toUtf8().constData());*/ + + QList<int> currentList; + if (output) + currentList = config->audioOutputDeviceListFor(category, GlobalConfig::ShowUnavailableDevices|GlobalConfig::ShowAdvancedDevices); +#ifndef QT_NO_PHONON_AUDIOCAPTURE + else + currentList = config->audioCaptureDeviceListFor(category, GlobalConfig::ShowUnavailableDevices|GlobalConfig::ShowAdvancedDevices); +#endif + + QList<int> newList; + + foreach (int i, newOrder) { + int found = currentList.indexOf(i); + if (found < 0) { + // It's not in the list, so something is odd (e.g. client error). Ignore it. + continue; + } + + // Iterate through the list from this point onward. If there are hidden devices + // immediately following, take them too. + newList.append(currentList.takeAt(found)); + while (found < currentList.size()) { + bool hidden = true; + if (output) + hidden = isHiddenAudioOutputDevice(config, currentList.at(found)); +#ifndef QT_NO_PHONON_AUDIOCAPTURE + else + hidden = isHiddenAudioCaptureDevice(config, currentList.at(found)); +#endif + + if (!hidden) + break; + newList.append(currentList.takeAt(found)); + } + } + + // If there are any devices left in.. just tack them on the end. + if (currentList.size() > 0) + newList += currentList; + + /*sb = QString("(Size %1)").arg(newList.size()); + foreach (int i, newList) + sb += QString("%1, ").arg(i); + fprintf(stderr, "=== Reindex After : %s\n", sb.toUtf8().constData());*/ + return newList; +} + + +void GlobalConfig::setAudioOutputDeviceListFor(Phonon::Category category, QList<int> order) +{ + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) { + pulse->setOutputDevicePriorityForCategory(category, order); + return; + } + + K_D(GlobalConfig); + QSettingsGroup backendConfig(&d->config, QLatin1String("AudioOutputDevice")); // + Factory::identifier()); + + order = reindexList(this, category, order, true); + + const QList<int> noCategoryOrder = audioOutputDeviceListFor(Phonon::NoCategory, ShowUnavailableDevices|ShowAdvancedDevices); + if (category != Phonon::NoCategory && order == noCategoryOrder) { + backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category)); + } else { + backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order); + } +} #endif //QT_NO_PHONON_SETTINGSGROUP #ifndef QT_NO_PHONON_SETTINGSGROUP QList<int> GlobalConfig::audioOutputDeviceListFor(Phonon::Category category, int override) const { - //The devices need to be stored independently for every backend - const QSettingsGroup backendConfig(&m_config, QLatin1String("AudioOutputDevice")); // + Factory::identifier()); - const QSettingsGroup generalGroup(&m_config, QLatin1String("General")); - const bool hideAdvancedDevices = ((override & AdvancedDevicesFromSettings) - ? generalGroup.value(QLatin1String("HideAdvancedDevices"), true) + K_D(const GlobalConfig); + + const bool hide = ((override & AdvancedDevicesFromSettings) + ? hideAdvancedDevices() : static_cast<bool>(override & HideAdvancedDevices)); QList<int> defaultList; + + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) { + defaultList = pulse->objectDescriptionIndexes(Phonon::AudioOutputDeviceType); + if (hide || (override & HideUnavailableDevices)) { + filter(AudioOutputDeviceType, NULL, &defaultList, + (hide ? FilterAdvancedDevices : 0) + | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) + ); + } + } else { + BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()); + #ifndef QT_NO_PHONON_PLATFORMPLUGIN - if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { - // the platform plugin lists the audio devices for the platform - // this list already is in default order (as defined by the platform plugin) - defaultList = platformPlugin->objectDescriptionIndexes(Phonon::AudioOutputDeviceType); - if (hideAdvancedDevices) { - QMutableListIterator<int> it(defaultList); - while (it.hasNext()) { - AudioOutputDevice objDesc = AudioOutputDevice::fromIndex(it.next()); - const QVariant var = objDesc.property("isAdvanced"); - if (var.isValid() && var.toBool()) { - it.remove(); + if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { + // the platform plugin lists the audio devices for the platform + // this list already is in default order (as defined by the platform plugin) + defaultList = platformPlugin->objectDescriptionIndexes(Phonon::AudioOutputDeviceType); + if (hide) { + QMutableListIterator<int> it(defaultList); + while (it.hasNext()) { + AudioOutputDevice objDesc = AudioOutputDevice::fromIndex(it.next()); + const QVariant var = objDesc.property("isAdvanced"); + if (var.isValid() && var.toBool()) { + it.remove(); + } } } } - } #endif //QT_NO_PHONON_PLATFORMPLUGIN - // lookup the available devices directly from the backend (mostly for virtual devices) - if (BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend())) { - // this list already is in default order (as defined by the backend) - QList<int> list = backendIface->objectDescriptionIndexes(Phonon::AudioOutputDeviceType); - if (hideAdvancedDevices || !defaultList.isEmpty() || (override & HideUnavailableDevices)) { - filter(AudioOutputDeviceType, backendIface, &list, - (hideAdvancedDevices ? FilterAdvancedDevices : 0) - // the platform plugin already provided the hardware devices - | (defaultList.isEmpty() ? 0 : FilterHardwareDevices) - | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) - ); + // lookup the available devices directly from the backend + if (backendIface) { + // this list already is in default order (as defined by the backend) + QList<int> list = backendIface->objectDescriptionIndexes(Phonon::AudioOutputDeviceType); + if (hide || !defaultList.isEmpty() || (override & HideUnavailableDevices)) { + filter(AudioOutputDeviceType, backendIface, &list, + (hide ? FilterAdvancedDevices : 0) + // the platform plugin maybe already provided the hardware devices? + | (defaultList.isEmpty() ? 0 : FilterHardwareDevices) + | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) + ); + } + defaultList += list; } - defaultList += list; } - return listSortedByConfig(backendConfig, category, defaultList); + const QSettingsGroup backendConfig(&d->config, QLatin1String("AudioOutputDevice")); // + Factory::identifier()); + return sortDevicesByCategoryPriority(this, &backendConfig, AudioOutputDeviceType, category, defaultList); } #endif //QT_NO_PHONON_SETTINGSGROUP int GlobalConfig::audioOutputDeviceFor(Phonon::Category category, int override) const @@ -190,54 +349,89 @@ int GlobalConfig::audioOutputDeviceFor(Phonon::Category category, int override) } #ifndef QT_NO_PHONON_AUDIOCAPTURE -QList<int> GlobalConfig::audioCaptureDeviceListFor(Phonon::Category category, int override) const +void GlobalConfig::setAudioCaptureDeviceListFor(Phonon::Category category, QList<int> order) { #ifndef QT_NO_PHONON_SETTINGSGROUP - //The devices need to be stored independently for every backend - const QSettingsGroup backendConfig(&m_config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier()); - const QSettingsGroup generalGroup(&m_config, QLatin1String("General")); - const bool hideAdvancedDevices = ((override & AdvancedDevicesFromSettings) - ? generalGroup.value(QLatin1String("HideAdvancedDevices"), true) + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) { + pulse->setCaptureDevicePriorityForCategory(category, order); + return; + } + + K_D(GlobalConfig); + QSettingsGroup backendConfig(&d->config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier()); + + order = reindexList(this, category, order, false); + + const QList<int> noCategoryOrder = audioCaptureDeviceListFor(Phonon::NoCategory, ShowUnavailableDevices|ShowAdvancedDevices); + if (category != Phonon::NoCategory && order == noCategoryOrder) { + backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category)); + } else { + backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order); + } +} + +QList<int> GlobalConfig::audioCaptureDeviceListFor(Phonon::Category category, int override) const +{ + K_D(const GlobalConfig); + + const bool hide = ((override & AdvancedDevicesFromSettings) + ? hideAdvancedDevices() : static_cast<bool>(override & HideAdvancedDevices)); QList<int> defaultList; + + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) { + defaultList = pulse->objectDescriptionIndexes(Phonon::AudioCaptureDeviceType); + if (hide || (override & HideUnavailableDevices)) { + filter(AudioCaptureDeviceType, NULL, &defaultList, + (hide ? FilterAdvancedDevices : 0) + | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) + ); + } + } else { + BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()); + #ifndef QT_NO_PHONON_PLATFORMPLUGIN - if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { - // the platform plugin lists the audio devices for the platform - // this list already is in default order (as defined by the platform plugin) - defaultList = platformPlugin->objectDescriptionIndexes(Phonon::AudioCaptureDeviceType); - if (hideAdvancedDevices) { - QMutableListIterator<int> it(defaultList); - while (it.hasNext()) { - AudioCaptureDevice objDesc = AudioCaptureDevice::fromIndex(it.next()); - const QVariant var = objDesc.property("isAdvanced"); - if (var.isValid() && var.toBool()) { - it.remove(); +#else //QT_NO_SETTINGSGROUP + return QList<int>(); +#endif //QT_NO_SETTINGSGROUP + if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { + // the platform plugin lists the audio devices for the platform + // this list already is in default order (as defined by the platform plugin) + defaultList = platformPlugin->objectDescriptionIndexes(Phonon::AudioCaptureDeviceType); + if (hide) { + QMutableListIterator<int> it(defaultList); + while (it.hasNext()) { + AudioCaptureDevice objDesc = AudioCaptureDevice::fromIndex(it.next()); + const QVariant var = objDesc.property("isAdvanced"); + if (var.isValid() && var.toBool()) { + it.remove(); + } } } } - } #endif //QT_NO_PHONON_PLATFORMPLUGIN - // lookup the available devices directly from the backend (mostly for virtual devices) - if (BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend())) { - // this list already is in default order (as defined by the backend) - QList<int> list = backendIface->objectDescriptionIndexes(Phonon::AudioCaptureDeviceType); - if (hideAdvancedDevices || !defaultList.isEmpty() || (override & HideUnavailableDevices)) { - filter(AudioCaptureDeviceType, backendIface, &list, - (hideAdvancedDevices ? FilterAdvancedDevices : 0) - // the platform plugin already provided the hardware devices - | (defaultList.isEmpty() ? 0 : FilterHardwareDevices) - | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) - ); + // lookup the available devices directly from the backend + if (backendIface) { + // this list already is in default order (as defined by the backend) + QList<int> list = backendIface->objectDescriptionIndexes(Phonon::AudioCaptureDeviceType); + if (hide || !defaultList.isEmpty() || (override & HideUnavailableDevices)) { + filter(AudioCaptureDeviceType, backendIface, &list, + (hide ? FilterAdvancedDevices : 0) + // the platform plugin maybe already provided the hardware devices? + | (defaultList.isEmpty() ? 0 : FilterHardwareDevices) + | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) + ); + } + defaultList += list; } - defaultList += list; } - return listSortedByConfig(backendConfig, category, defaultList); -#else //QT_NO_SETTINGSGROUP - return QList<int>(); -#endif //QT_NO_SETTINGSGROUP + const QSettingsGroup backendConfig(&d->config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier()); + return sortDevicesByCategoryPriority(this, &backendConfig, AudioCaptureDeviceType, category, defaultList); } int GlobalConfig::audioCaptureDeviceFor(Phonon::Category category, int override) const diff --git a/src/3rdparty/phonon/phonon/globalconfig_p.h b/src/3rdparty/phonon/phonon/globalconfig_p.h index ec70b6f..090ca6b 100644 --- a/src/3rdparty/phonon/phonon/globalconfig_p.h +++ b/src/3rdparty/phonon/phonon/globalconfig_p.h @@ -26,40 +26,19 @@ Copyright (C) 2006-2008 Matthias Kretz <kretz@kde.org> #include <QtCore/QSettings> #include "phonon_export.h" -#include "phononnamespace.h" QT_BEGIN_HEADER QT_BEGIN_NAMESPACE namespace Phonon { - class PHONON_EXPORT GlobalConfig + class GlobalConfigPrivate { - public: - GlobalConfig(); - virtual ~GlobalConfig(); + public: + GlobalConfigPrivate(); + virtual ~GlobalConfigPrivate() {} - enum DevicesToHideFlag { - ShowUnavailableDevices = 0, - ShowAdvancedDevices = 0, - HideAdvancedDevices = 1, - AdvancedDevicesFromSettings = 2, - HideUnavailableDevices = 4 - }; -#ifndef QT_NO_PHONON_SETTINGSGROUP - QList<int> audioOutputDeviceListFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; -#endif //QT_NO_PHONON_SETTINGSGROUP - int audioOutputDeviceFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; - -#ifndef QT_NO_PHONON_AUDIOCAPTURE - QList<int> audioCaptureDeviceListFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; - int audioCaptureDeviceFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; -#endif //QT_NO_PHONON_AUDIOCAPTURE - - protected: -#ifndef QT_NO_SETTINGS - QSettings m_config; -#endif //QT_NO_SETTINGS + QSettings config; }; } // namespace Phonon diff --git a/src/3rdparty/phonon/phonon/mediaobject.cpp b/src/3rdparty/phonon/phonon/mediaobject.cpp index 41e8dc2..13d303c 100644 --- a/src/3rdparty/phonon/phonon/mediaobject.cpp +++ b/src/3rdparty/phonon/phonon/mediaobject.cpp @@ -453,9 +453,9 @@ void MediaObjectPrivate::setupBackendObject() //pDebug() << Q_FUNC_INFO; #ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM - QObject::connect(m_backendObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)), q, SLOT(_k_stateChanged(Phonon::State,Phonon::State))); + QObject::connect(m_backendObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), q, SLOT(_k_stateChanged(Phonon::State, Phonon::State))); #else - QObject::connect(m_backendObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)), q, SIGNAL(stateChanged(Phonon::State,Phonon::State))); + QObject::connect(m_backendObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), q, SIGNAL(stateChanged(Phonon::State, Phonon::State))); #endif // QT_NO_PHONON_ABSTRACTMEDIASTREAM QObject::connect(m_backendObject, SIGNAL(tick(qint64)), q, SIGNAL(tick(qint64))); QObject::connect(m_backendObject, SIGNAL(seekableChanged(bool)), q, SIGNAL(seekableChanged(bool))); @@ -467,10 +467,10 @@ void MediaObjectPrivate::setupBackendObject() QObject::connect(m_backendObject, SIGNAL(aboutToFinish()), q, SLOT(_k_aboutToFinish())); QObject::connect(m_backendObject, SIGNAL(prefinishMarkReached(qint32)), q, SIGNAL(prefinishMarkReached(qint32))); QObject::connect(m_backendObject, SIGNAL(totalTimeChanged(qint64)), q, SIGNAL(totalTimeChanged(qint64))); - QObject::connect(m_backendObject, SIGNAL(metaDataChanged(QMultiMap<QString,QString>)), - q, SLOT(_k_metaDataChanged(QMultiMap<QString,QString>))); - QObject::connect(m_backendObject, SIGNAL(currentSourceChanged(MediaSource)), - q, SLOT(_k_currentSourceChanged(MediaSource))); + QObject::connect(m_backendObject, SIGNAL(metaDataChanged(const QMultiMap<QString, QString> &)), + q, SLOT(_k_metaDataChanged(const QMultiMap<QString, QString> &))); + QObject::connect(m_backendObject, SIGNAL(currentSourceChanged(const MediaSource&)), + q, SLOT(_k_currentSourceChanged(const MediaSource&))); // set up attributes pINTERFACE_CALL(setTickInterval(tickInterval)); diff --git a/src/3rdparty/phonon/phonon/objectdescription.cpp b/src/3rdparty/phonon/phonon/objectdescription.cpp index e058b89..55e74b5 100644 --- a/src/3rdparty/phonon/phonon/objectdescription.cpp +++ b/src/3rdparty/phonon/phonon/objectdescription.cpp @@ -29,6 +29,7 @@ #include <QtCore/QStringList> #include "backendinterface.h" #include "platformplugin.h" +#include "pulsesupport.h" QT_BEGIN_NAMESPACE @@ -108,27 +109,38 @@ bool ObjectDescriptionData::isValid() const ObjectDescriptionData *ObjectDescriptionData::fromIndex(ObjectDescriptionType type, int index) { - // prefer to get the ObjectDescriptionData from the platform plugin for audio devices + bool is_audio_device = (AudioOutputDeviceType == type || AudioCaptureDeviceType == type); + + PulseSupport *pulse = PulseSupport::getInstance(); + if (is_audio_device && pulse->isActive()) { + QList<int> indexes = pulse->objectDescriptionIndexes(type); + if (indexes.contains(index)) { + QHash<QByteArray, QVariant> properties = pulse->objectDescriptionProperties(type, index); + return new ObjectDescriptionData(index, properties); + } + } else { + BackendInterface *iface = qobject_cast<BackendInterface *>(Factory::backend()); + + // prefer to get the ObjectDescriptionData from the platform plugin for audio devices #ifndef QT_NO_PHONON_PLATFORMPLUGIN - if (type == AudioOutputDeviceType || type == AudioCaptureDeviceType) { - PlatformPlugin *platformPlugin = Factory::platformPlugin(); - if (platformPlugin) { - QList<int> indexes = platformPlugin->objectDescriptionIndexes(type); - if (indexes.contains(index)) { - QHash<QByteArray, QVariant> properties = platformPlugin->objectDescriptionProperties(type, index); - return new ObjectDescriptionData(index, properties); + if (is_audio_device) { + PlatformPlugin *platformPlugin = Factory::platformPlugin(); + if (platformPlugin) { + QList<int> indexes = platformPlugin->objectDescriptionIndexes(type); + if (indexes.contains(index)) { + QHash<QByteArray, QVariant> properties = platformPlugin->objectDescriptionProperties(type, index); + return new ObjectDescriptionData(index, properties); + } } } - } #endif //QT_NO_PHONON_PLATFORMPLUGIN - QObject *b = Factory::backend(); - BackendInterface *iface = qobject_cast<BackendInterface *>(b); - if (iface) { - QList<int> indexes = iface->objectDescriptionIndexes(type); - if (indexes.contains(index)) { - QHash<QByteArray, QVariant> properties = iface->objectDescriptionProperties(type, index); - return new ObjectDescriptionData(index, properties); + if (iface) { + QList<int> indexes = iface->objectDescriptionIndexes(type); + if (indexes.contains(index)) { + QHash<QByteArray, QVariant> properties = iface->objectDescriptionProperties(type, index); + return new ObjectDescriptionData(index, properties); + } } } return new ObjectDescriptionData(0); // invalid diff --git a/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp b/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp index bf5be6d..741a74c 100644 --- a/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp +++ b/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp @@ -362,6 +362,7 @@ QStringList ObjectDescriptionModelData::mimeTypes(ObjectDescriptionType type) co return QStringList(QLatin1String("application/x-phonon-objectdescription") + QString::number(static_cast<int>(type))); } +#if !defined(Q_CC_MSVC) || _MSC_VER > 1300 || defined(Q_CC_INTEL) || defined(Q_CC_MINGW) #define INSTANTIATE_META_FUNCTIONS(type) \ template const QMetaObject *ObjectDescriptionModel<type>::metaObject() const; \ template void *ObjectDescriptionModel<type>::qt_metacast(const char *) @@ -371,6 +372,7 @@ INSTANTIATE_META_FUNCTIONS(AudioCaptureDeviceType); INSTANTIATE_META_FUNCTIONS(EffectType); INSTANTIATE_META_FUNCTIONS(AudioChannelType); INSTANTIATE_META_FUNCTIONS(SubtitleType); +#endif /*INSTANTIATE_META_FUNCTIONS(VideoOutputDeviceType); INSTANTIATE_META_FUNCTIONS(VideoCaptureDeviceType); INSTANTIATE_META_FUNCTIONS(AudioCodecType); diff --git a/src/3rdparty/phonon/phonon/objectdescriptionmodel.h b/src/3rdparty/phonon/phonon/objectdescriptionmodel.h index 8fd622f..a1540e8 100644 --- a/src/3rdparty/phonon/phonon/objectdescriptionmodel.h +++ b/src/3rdparty/phonon/phonon/objectdescriptionmodel.h @@ -35,6 +35,18 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_PHONON_OBJECTDESCRIPTIONMODEL +/* MinGW 3.4.x gives an ICE when trying to instantiate one of the + ObjectDescriptionModel<foo> classes because it can't handle + half exported classes correct. gcc 4.3.x has a fix for this but + we currently there's no official gcc 4.3 on windows available. + Because of this we need this little hack + */ +#if defined(Q_CC_MINGW) +#define PHONON_EXPORT_ODM +#else +#define PHONON_EXPORT_ODM PHONON_EXPORT +#endif + namespace Phonon { class ObjectDescriptionModelDataPrivate; @@ -139,21 +151,6 @@ namespace Phonon ObjectDescriptionModelDataPrivate *const d; }; -/* Required to ensure template class vtables are exported on both symbian -and existing builds. */ -#if defined(Q_OS_SYMBIAN) && defined(Q_CC_RVCT) -// RVCT compiler (2.2.686) requires the export declaration to be on the class to export vtables -// MWC compiler works both ways -// GCCE compiler is unknown (it can't compile QtCore yet) -#define PHONON_TEMPLATE_CLASS_EXPORT PHONON_EXPORT -#define PHONON_TEMPLATE_CLASS_MEMBER_EXPORT -#else -// Windows builds (at least) do not support export declaration on templated class -// But if you export a member function, the vtable is implicitly exported -#define PHONON_TEMPLATE_CLASS_EXPORT -#define PHONON_TEMPLATE_CLASS_MEMBER_EXPORT PHONON_EXPORT -#endif - /** \class ObjectDescriptionModel objectdescriptionmodel.h Phonon/ObjectDescriptionModel * \short The ObjectDescriptionModel class provides a model from * a list of ObjectDescription objects. @@ -190,17 +187,16 @@ and existing builds. */ * \author Matthias Kretz <kretz@kde.org> */ template<ObjectDescriptionType type> - class PHONON_TEMPLATE_CLASS_EXPORT ObjectDescriptionModel : public QAbstractListModel + class ObjectDescriptionModel : public QAbstractListModel { public: Q_OBJECT_CHECK - /** \internal */ - static PHONON_TEMPLATE_CLASS_MEMBER_EXPORT const QMetaObject staticMetaObject; + static PHONON_EXPORT const QMetaObject staticMetaObject; /** \internal */ - PHONON_TEMPLATE_CLASS_MEMBER_EXPORT const QMetaObject *metaObject() const; + PHONON_EXPORT_ODM const QMetaObject *metaObject() const; /** \internal */ - PHONON_TEMPLATE_CLASS_MEMBER_EXPORT void *qt_metacast(const char *_clname); + PHONON_EXPORT_ODM void *qt_metacast(const char *_clname); //int qt_metacall(QMetaObject::Call _c, int _id, void **_a); /** diff --git a/src/3rdparty/phonon/phonon/path.cpp b/src/3rdparty/phonon/phonon/path.cpp index 51c33b2..1c25b89 100644 --- a/src/3rdparty/phonon/phonon/path.cpp +++ b/src/3rdparty/phonon/phonon/path.cpp @@ -310,8 +310,8 @@ bool PathPrivate::executeTransaction( const QList<QObjectPair> &disconnections, if (!transaction) return false; - QList<QObjectPair>::const_iterator it = disconnections.constBegin(); - for(;it != disconnections.constEnd();++it) { + QList<QObjectPair>::const_iterator it = disconnections.begin(); + for(;it != disconnections.end();++it) { const QObjectPair &pair = *it; if (!backend->disconnectNodes(pair.first, pair.second)) { @@ -327,8 +327,8 @@ bool PathPrivate::executeTransaction( const QList<QObjectPair> &disconnections, } } - for(it = connections.constBegin(); it != connections.constEnd(); ++it) { - const QObjectPair pair = *it; + for(it = connections.begin(); it != connections.end();++it) { + const QObjectPair &pair = *it; if (!backend->connectNodes(pair.first, pair.second)) { //Error: a connection failed QList<QObjectPair>::const_iterator it2 = connections.begin(); diff --git a/src/3rdparty/phonon/phonon/phonondefs.h b/src/3rdparty/phonon/phonon/phonondefs.h index 15a1815..765eb1c 100644 --- a/src/3rdparty/phonon/phonon/phonondefs.h +++ b/src/3rdparty/phonon/phonon/phonondefs.h @@ -29,6 +29,11 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +#ifdef PHONON_BACKEND_VERSION_4_4 +# ifndef PHONON_BACKEND_VERSION_4_3 +# define PHONON_BACKEND_VERSION_4_3 +# endif +#endif #ifdef PHONON_BACKEND_VERSION_4_3 # ifndef PHONON_BACKEND_VERSION_4_2 # define PHONON_BACKEND_VERSION_4_2 diff --git a/src/3rdparty/phonon/phonon/seekslider.cpp b/src/3rdparty/phonon/phonon/seekslider.cpp index 41baf2d..b5b25f0 100644 --- a/src/3rdparty/phonon/phonon/seekslider.cpp +++ b/src/3rdparty/phonon/phonon/seekslider.cpp @@ -72,12 +72,12 @@ void SeekSlider::setMediaObject(MediaObject *media) d->media = media; if (media) { - connect(media, SIGNAL(stateChanged(Phonon::State,Phonon::State)), + connect(media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), SLOT(_k_stateChanged(Phonon::State))); connect(media, SIGNAL(totalTimeChanged(qint64)), SLOT(_k_length(qint64))); connect(media, SIGNAL(tick(qint64)), SLOT(_k_tick(qint64))); connect(media, SIGNAL(seekableChanged(bool)), SLOT(_k_seekableChanged(bool))); - connect(media, SIGNAL(currentSourceChanged(Phonon::MediaSource)), SLOT(_k_currentSourceChanged())); + connect(media, SIGNAL(currentSourceChanged(const Phonon::MediaSource&)), SLOT(_k_currentSourceChanged())); d->_k_stateChanged(media->state()); d->_k_seekableChanged(media->isSeekable()); d->_k_length(media->totalTime()); diff --git a/src/3rdparty/phonon/phonon/seekslider_p.h b/src/3rdparty/phonon/phonon/seekslider_p.h index c87a4b0..911ab25 100644 --- a/src/3rdparty/phonon/phonon/seekslider_p.h +++ b/src/3rdparty/phonon/phonon/seekslider_p.h @@ -24,8 +24,8 @@ #define SEEKSLIDER_P_H #include "seekslider.h" +#include "swiftslider_p.h" #include <QtGui/QBoxLayout> -#include <QtGui/QSlider> #include <QtGui/QLabel> #include <QtGui/QPixmap> #include <QtGui/QIcon> @@ -84,7 +84,7 @@ class SeekSliderPrivate void _k_currentSourceChanged(); QBoxLayout layout; - QSlider slider; + SwiftSlider slider; QLabel iconLabel; QPointer<MediaObject> media; bool ticking; diff --git a/src/3rdparty/phonon/phonon/videowidget.cpp b/src/3rdparty/phonon/phonon/videowidget.cpp index a9e83a6..4575dfd 100644 --- a/src/3rdparty/phonon/phonon/videowidget.cpp +++ b/src/3rdparty/phonon/phonon/videowidget.cpp @@ -28,8 +28,9 @@ #include "phononnamespace_p.h" #include <QtGui/QAction> - -#define PHONON_INTERFACENAME VideoWidgetInterface +#define IFACES4 VideoWidgetInterface44 +#define IFACES0 VideoWidgetInterface, IFACES4 +#define PHONON_INTERFACENAME IFACES0 QT_BEGIN_NAMESPACE @@ -48,6 +49,8 @@ VideoWidget::VideoWidget(QWidget *parent) setMouseTracking(true); } + + VideoWidget::VideoWidget(VideoWidgetPrivate &dd, QWidget *parent) : QWidget(parent), Phonon::AbstractVideoOutput(dd) @@ -98,6 +101,15 @@ PHONON_INTERFACE_SETTER(setHue, hue, qreal) PHONON_INTERFACE_GETTER(qreal, saturation, d->saturation) PHONON_INTERFACE_SETTER(setSaturation, saturation, qreal) + +QImage VideoWidget::snapshot() const { + K_D(const VideoWidget); + ConstIface<IFACES4> iface(d); + if(iface) return iface->snapshot(); + return QImage(); // TODO not implemented in VideoInterface +} + + void VideoWidget::setFullScreen(bool newFullScreen) { pDebug() << Q_FUNC_INFO << newFullScreen; diff --git a/src/3rdparty/phonon/phonon/videowidget.h b/src/3rdparty/phonon/phonon/videowidget.h index 1d95490..804e61a 100644 --- a/src/3rdparty/phonon/phonon/videowidget.h +++ b/src/3rdparty/phonon/phonon/videowidget.h @@ -172,6 +172,7 @@ class AbstractVideoOutput; qreal contrast() const; qreal hue() const; qreal saturation() const; + QImage snapshot() const; //TODO: bar colors property public Q_SLOTS: diff --git a/src/3rdparty/phonon/phonon/videowidgetinterface.h b/src/3rdparty/phonon/phonon/videowidgetinterface.h index 3e6fd22..0c33956 100644 --- a/src/3rdparty/phonon/phonon/videowidgetinterface.h +++ b/src/3rdparty/phonon/phonon/videowidgetinterface.h @@ -53,8 +53,21 @@ class VideoWidgetInterface //X virtual int overlayCapabilities() const = 0; //X virtual bool createOverlay(QWidget *widget, int type) = 0; }; + +class VideoWidgetInterface44 : public VideoWidgetInterface +{ + public: + virtual QImage snapshot() const = 0; +}; } +#ifdef PHONON_BACKEND_VERSION_4_4 +namespace Phonon { typedef VideoWidgetInterface44 VideoWidgetInterfaceLatest; } +#else +namespace Phonon { typedef VideoWidgetInterface VideoWidgetInterfaceLatest; } +#endif + +Q_DECLARE_INTERFACE(Phonon::VideoWidgetInterface44, "VideoWidgetInterface44.phonon.kde.org") Q_DECLARE_INTERFACE(Phonon::VideoWidgetInterface, "VideoWidgetInterface3.phonon.kde.org") #endif //QT_NO_PHONON_VIDEO diff --git a/src/3rdparty/phonon/phonon/volumeslider_p.h b/src/3rdparty/phonon/phonon/volumeslider_p.h index 3827659..623275f 100644 --- a/src/3rdparty/phonon/phonon/volumeslider_p.h +++ b/src/3rdparty/phonon/phonon/volumeslider_p.h @@ -24,8 +24,8 @@ #define VOLUMESLIDER_P_H #include "volumeslider.h" +#include "swiftslider_p.h" #include <QtGui/QBoxLayout> -#include <QtGui/QSlider> #include <QtGui/QLabel> #include <QtGui/QPixmap> #include <QtGui/QToolButton> @@ -83,7 +83,7 @@ class VolumeSliderPrivate private: QBoxLayout layout; - QSlider slider; + SwiftSlider slider; QToolButton muteButton; QIcon volumeIcon; QIcon mutedIcon; diff --git a/src/phonon/phonon.pro b/src/phonon/phonon.pro index 0469839..7f79d0b 100644 --- a/src/phonon/phonon.pro +++ b/src/phonon/phonon.pro @@ -2,8 +2,8 @@ TARGET = phonon include(../qbase.pri) PHONON_MAJOR_VERSION = $${QT_MAJOR_VERSION} -PHONON_MINOR_VERSION = 3 -PHONON_PATCH_VERSION = 1 +PHONON_MINOR_VERSION = 4 +PHONON_PATCH_VERSION = 0 VERSION = $${PHONON_MAJOR_VERSION}.$${PHONON_MINOR_VERSION}.$${PHONON_PATCH_VERSION} DEPENDPATH += . @@ -21,6 +21,9 @@ HEADERS += $$PHONON_DIR/abstractaudiooutput.h \ $$PHONON_DIR/abstractvideooutput.h \ $$PHONON_DIR/abstractvideooutput_p.h \ $$PHONON_DIR/addoninterface.h \ + $$PHONON_DIR/audiodataoutput_p.h \ + $$PHONON_DIR/audiodataoutput.h \ + $$PHONON_DIR/audiodataoutputinterface.h \ $$PHONON_DIR/audiooutput.h \ $$PHONON_DIR/audiooutput_p.h \ $$PHONON_DIR/audiooutputinterface.h \ @@ -36,6 +39,7 @@ HEADERS += $$PHONON_DIR/abstractaudiooutput.h \ $$PHONON_DIR/effectwidget_p.h \ $$PHONON_DIR/factory_p.h \ $$PHONON_DIR/frontendinterface_p.h \ + $$PHONON_DIR/globalconfig.h \ $$PHONON_DIR/globalconfig_p.h \ $$PHONON_DIR/iodevicestream_p.h \ $$PHONON_DIR/mediacontroller.h \ @@ -53,6 +57,7 @@ HEADERS += $$PHONON_DIR/abstractaudiooutput.h \ $$PHONON_DIR/objectdescriptionmodel_p.h \ $$PHONON_DIR/path.h \ $$PHONON_DIR/path_p.h \ + $$PHONON_DIR/pulsesupport.h \ $$PHONON_DIR/phonondefs.h \ $$PHONON_DIR/phonondefs_p.h \ $$PHONON_DIR/phononnamespace.h \ @@ -64,6 +69,7 @@ HEADERS += $$PHONON_DIR/abstractaudiooutput.h \ $$PHONON_DIR/seekslider_p.h \ $$PHONON_DIR/streaminterface.h \ $$PHONON_DIR/streaminterface_p.h \ + $$PHONON_DIR/swiftslider_p.h \ $$PHONON_DIR/videoplayer.h \ $$PHONON_DIR/videowidget.h \ $$PHONON_DIR/videowidget_p.h \ @@ -73,35 +79,39 @@ HEADERS += $$PHONON_DIR/abstractaudiooutput.h \ $$PHONON_DIR/volumefaderinterface.h \ $$PHONON_DIR/volumeslider.h \ $$PHONON_DIR/volumeslider_p.h -SOURCES += $$PHONON_DIR/objectdescription.cpp \ - $$PHONON_DIR/objectdescriptionmodel.cpp \ - $$PHONON_DIR/phononnamespace.cpp \ - $$PHONON_DIR/mediasource.cpp \ - $$PHONON_DIR/abstractmediastream.cpp \ - $$PHONON_DIR/streaminterface.cpp \ - $$PHONON_DIR/mediaobject.cpp \ - $$PHONON_DIR/medianode.cpp \ - $$PHONON_DIR/path.cpp \ - $$PHONON_DIR/effectparameter.cpp \ - $$PHONON_DIR/effect.cpp \ - $$PHONON_DIR/volumefadereffect.cpp \ - $$PHONON_DIR/abstractaudiooutput.cpp \ + +SOURCES += $$PHONON_DIR/abstractaudiooutput.cpp \ $$PHONON_DIR/abstractaudiooutput_p.cpp \ - $$PHONON_DIR/audiooutput.cpp \ - $$PHONON_DIR/audiooutputinterface.cpp \ + $$PHONON_DIR/abstractmediastream.cpp \ $$PHONON_DIR/abstractvideooutput.cpp \ $$PHONON_DIR/abstractvideooutput_p.cpp \ + $$PHONON_DIR/audiodataoutput.cpp \ + $$PHONON_DIR/audiooutput.cpp \ + $$PHONON_DIR/audiooutputinterface.cpp \ $$PHONON_DIR/backendcapabilities.cpp \ - $$PHONON_DIR/globalconfig.cpp \ + $$PHONON_DIR/effect.cpp \ + $$PHONON_DIR/effectparameter.cpp \ + $$PHONON_DIR/effectwidget.cpp \ $$PHONON_DIR/factory.cpp \ - $$PHONON_DIR/platform.cpp \ + $$PHONON_DIR/globalconfig.cpp \ + $$PHONON_DIR/iodevicestream.cpp \ $$PHONON_DIR/mediacontroller.cpp \ - $$PHONON_DIR/videowidget.cpp \ - $$PHONON_DIR/videoplayer.cpp \ + $$PHONON_DIR/medianode.cpp \ + $$PHONON_DIR/mediaobject.cpp \ + $$PHONON_DIR/mediasource.cpp \ + $$PHONON_DIR/objectdescription.cpp \ + $$PHONON_DIR/objectdescriptionmodel.cpp \ + $$PHONON_DIR/path.cpp \ + $$PHONON_DIR/phononnamespace.cpp \ + $$PHONON_DIR/platform.cpp \ + $$PHONON_DIR/pulsesupport.cpp \ $$PHONON_DIR/seekslider.cpp \ - $$PHONON_DIR/volumeslider.cpp \ - $$PHONON_DIR/effectwidget.cpp \ - $$PHONON_DIR/iodevicestream.cpp + $$PHONON_DIR/streaminterface.cpp \ + $$PHONON_DIR/swiftslider.cpp \ + $$PHONON_DIR/videoplayer.cpp \ + $$PHONON_DIR/videowidget.cpp \ + $$PHONON_DIR/volumefadereffect.cpp \ + $$PHONON_DIR/volumeslider.cpp contains(QT_CONFIG, dbus) { QT += dbus @@ -114,6 +124,12 @@ contains(QT_CONFIG, dbus) { contains(QT_CONFIG, reduce_exports): CONFIG += hide_symbols +unix:!isEmpty(QT_CFLAGS_PULSEAUDIO) { + DEFINES += HAVE_PULSEAUDIO + QMAKE_CXXFLAGS += $$QT_CFLAGS_PULSEAUDIO + LIBS += $$QT_LIBS_PULSEAUDIO +} + symbian: { # Phonon depends on numeric_limits. Enabling STL support in Qt # would bring in link dependencies, and we don't need that for |