File indexing completed on 2024-04-28 12:31:49
0001 /* This file is part of the KDE project 0002 Copyright (C) 2006-2008 Matthias Kretz <kretz@kde.org> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Lesser General Public 0006 License as published by the Free Software Foundation; either 0007 version 2.1 of the License, or (at your option) version 3, or any 0008 later version accepted by the membership of KDE e.V. (or its 0009 successor approved by the membership of KDE e.V.), Nokia Corporation 0010 (or its successors, if any) and the KDE Free Qt Foundation, which shall 0011 act as a proxy defined in Section 6 of version 3 of the license. 0012 0013 This library is distributed in the hope that it will be useful, 0014 but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 Lesser General Public License for more details. 0017 0018 You should have received a copy of the GNU Lesser General Public 0019 License along with this library. If not, see <http://www.gnu.org/licenses/>. 0020 0021 */ 0022 0023 #include "globalconfig.h" 0024 #include "globalconfig_p.h" 0025 0026 #include "factory_p.h" 0027 #include "phonondefs_p.h" 0028 #include "platformplugin.h" 0029 #include "backendinterface.h" 0030 #include "qsettingsgroup_p.h" 0031 #include "phononnamespace_p.h" 0032 #include "phononnamespace.h" 0033 #include "pulsesupport.h" 0034 0035 #include <QList> 0036 #include <QVariant> 0037 0038 namespace Phonon 0039 { 0040 0041 GlobalConfigPrivate::GlobalConfigPrivate() : config(QLatin1String("kde.org"), QLatin1String("libphonon")) 0042 { 0043 } 0044 0045 GlobalConfig::GlobalConfig() 0046 : k_ptr(new GlobalConfigPrivate) 0047 { 0048 } 0049 0050 GlobalConfig::~GlobalConfig() 0051 { 0052 delete k_ptr; 0053 } 0054 0055 enum WhatToFilter { 0056 FilterAdvancedDevices = 1, 0057 FilterHardwareDevices = 2, 0058 FilterUnavailableDevices = 4 0059 }; 0060 0061 static void filter(ObjectDescriptionType type, BackendInterface *backendIface, QList<int> *list, int whatToFilter) 0062 { 0063 QMutableListIterator<int> it(*list); 0064 while (it.hasNext()) { 0065 QHash<QByteArray, QVariant> properties; 0066 if (backendIface) 0067 properties = backendIface->objectDescriptionProperties(type, it.next()); 0068 else 0069 properties = PulseSupport::getInstance()->objectDescriptionProperties(type, it.next()); 0070 QVariant var; 0071 if (whatToFilter & FilterAdvancedDevices) { 0072 var = properties.value("isAdvanced"); 0073 if (var.isValid() && var.toBool()) { 0074 it.remove(); 0075 continue; 0076 } 0077 } 0078 if (whatToFilter & FilterHardwareDevices) { 0079 var = properties.value("isHardwareDevice"); 0080 if (var.isValid() && var.toBool()) { 0081 it.remove(); 0082 continue; 0083 } 0084 } 0085 if (whatToFilter & FilterUnavailableDevices) { 0086 var = properties.value("available"); 0087 if (var.isValid() && !var.toBool()) { 0088 it.remove(); 0089 continue; 0090 } 0091 } 0092 } 0093 } 0094 0095 #ifndef QT_NO_PHONON_SETTINGSGROUP 0096 static QList<int> sortDevicesByCategoryPriority(const GlobalConfig *config, const QSettingsGroup *backendConfig, ObjectDescriptionType type, Category category, QList<int> &defaultList) 0097 { 0098 Q_ASSERT(config); Q_UNUSED(config); 0099 Q_ASSERT(backendConfig); 0100 Q_ASSERT(type == AudioOutputDeviceType); 0101 0102 if (defaultList.size() <= 1) { 0103 // nothing to sort 0104 return defaultList; 0105 } else { 0106 // make entries unique 0107 QSet<int> seen; 0108 QMutableListIterator<int> it(defaultList); 0109 while (it.hasNext()) { 0110 if (seen.contains(it.next())) { 0111 it.remove(); 0112 } else { 0113 seen.insert(it.value()); 0114 } 0115 } 0116 } 0117 0118 QList<int> deviceList; 0119 PulseSupport *pulse = PulseSupport::getInstance(); 0120 if (pulse->isUsed()) { 0121 deviceList = pulse->objectIndexesByCategory(type, category); 0122 } else { 0123 QString categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(category)); 0124 if (!backendConfig->hasKey(categoryKey)) { 0125 // no list in config for the given category 0126 categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(NoCategory)); 0127 if (!backendConfig->hasKey(categoryKey)) { 0128 // no list in config for NoCategory 0129 return defaultList; 0130 } 0131 } 0132 0133 //Now the list from d->config 0134 deviceList = backendConfig->value(categoryKey, QList<int>()); 0135 } 0136 0137 //if there are devices in d->config that the backend doesn't report, remove them from the list 0138 QMutableListIterator<int> i(deviceList); 0139 while (i.hasNext()) { 0140 if (0 == defaultList.removeAll(i.next())) { 0141 i.remove(); 0142 } 0143 } 0144 0145 //if the backend reports more devices that are not in d->config append them to the list 0146 deviceList += defaultList; 0147 0148 return deviceList; 0149 } 0150 0151 static QList<int> sortDevicesByCategoryPriority(const GlobalConfig *config, const QSettingsGroup *backendConfig, ObjectDescriptionType type, CaptureCategory category, QList<int> &defaultList) 0152 { 0153 Q_ASSERT(config); Q_UNUSED(config); 0154 Q_ASSERT(backendConfig); 0155 Q_ASSERT(type == AudioCaptureDeviceType || type == VideoCaptureDeviceType); 0156 0157 if (defaultList.size() <= 1) { 0158 // nothing to sort 0159 return defaultList; 0160 } else { 0161 // make entries unique 0162 QSet<int> seen; 0163 QMutableListIterator<int> it(defaultList); 0164 while (it.hasNext()) { 0165 if (seen.contains(it.next())) { 0166 it.remove(); 0167 } else { 0168 seen.insert(it.value()); 0169 } 0170 } 0171 } 0172 0173 QList<int> deviceList; 0174 PulseSupport *pulse = PulseSupport::getInstance(); 0175 if (pulse->isUsed()) { 0176 deviceList = pulse->objectIndexesByCategory(type, category); 0177 } else { 0178 QString categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(category)); 0179 if (!backendConfig->hasKey(categoryKey)) { 0180 // no list in config for the given category 0181 categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(NoCategory)); 0182 if (!backendConfig->hasKey(categoryKey)) { 0183 // no list in config for NoCategory 0184 return defaultList; 0185 } 0186 } 0187 0188 //Now the list from d->config 0189 deviceList = backendConfig->value(categoryKey, QList<int>()); 0190 } 0191 0192 //if there are devices in d->config that the backend doesn't report, remove them from the list 0193 QMutableListIterator<int> i(deviceList); 0194 while (i.hasNext()) { 0195 if (0 == defaultList.removeAll(i.next())) { 0196 i.remove(); 0197 } 0198 } 0199 0200 //if the backend reports more devices that are not in d->config append them to the list 0201 deviceList += defaultList; 0202 0203 return deviceList; 0204 } 0205 0206 bool GlobalConfig::hideAdvancedDevices() const 0207 { 0208 P_D(const GlobalConfig); 0209 //The devices need to be stored independently for every backend 0210 const QSettingsGroup generalGroup(&d->config, QLatin1String("General")); 0211 return generalGroup.value(QLatin1String("HideAdvancedDevices"), true); 0212 } 0213 0214 void GlobalConfig::setHideAdvancedDevices(bool hide) 0215 { 0216 P_D(GlobalConfig); 0217 QSettingsGroup generalGroup(&d->config, QLatin1String("General")); 0218 generalGroup.setValue(QLatin1String("HideAdvancedDevices"), hide); 0219 } 0220 #endif // QT_NO_PHONON_SETTINGSGROUP 0221 0222 static bool isHiddenAudioOutputDevice(const GlobalConfig *config, int i) 0223 { 0224 Q_ASSERT(config); 0225 0226 #ifndef QT_NO_PHONON_SETTINGSGROUP 0227 if (!config->hideAdvancedDevices()) 0228 return false; 0229 #endif // QT_NO_PHONON_SETTINGSGROUP 0230 0231 AudioOutputDevice ad = AudioOutputDevice::fromIndex(i); 0232 const QVariant var = ad.property("isAdvanced"); 0233 return (var.isValid() && var.toBool()); 0234 } 0235 0236 #ifndef PHONON_NO_AUDIOCAPTURE 0237 static bool isHiddenAudioCaptureDevice(const GlobalConfig *config, int i) 0238 { 0239 Q_ASSERT(config); 0240 0241 #ifndef QT_NO_PHONON_SETTINGSGROUP 0242 if (!config->hideAdvancedDevices()) 0243 return false; 0244 #endif // QT_NO_PHONON_SETTINGSGROUP 0245 0246 AudioCaptureDevice ad = AudioCaptureDevice::fromIndex(i); 0247 const QVariant var = ad.property("isAdvanced"); 0248 return (var.isValid() && var.toBool()); 0249 } 0250 #endif 0251 0252 #ifndef PHONON_NO_VIDEOCAPTURE 0253 static bool isHiddenVideoCaptureDevice(const GlobalConfig *config, int i) 0254 { 0255 Q_ASSERT(config); 0256 0257 #ifndef QT_NO_PHONON_SETTINGSGROUP 0258 if (!config->hideAdvancedDevices()) 0259 return false; 0260 #endif // QT_NO_PHONON_SETTINGSGROUP 0261 0262 VideoCaptureDevice vd = VideoCaptureDevice::fromIndex(i); 0263 const QVariant var = vd.property("isAdvanced"); 0264 return (var.isValid() && var.toBool()); 0265 } 0266 #endif 0267 0268 static QList<int> reindexList(const GlobalConfig *config, ObjectDescriptionType type, Category category, QList<int>newOrder) 0269 { 0270 Q_ASSERT(config); 0271 Q_ASSERT(type == AudioOutputDeviceType); 0272 Q_UNUSED(type); 0273 0274 /*QString sb; 0275 sb = QString("(Size %1)").arg(currentList.size()); 0276 foreach (int i, currentList) 0277 sb += QString("%1, ").arg(i); 0278 fprintf(stderr, "=== Reindex Current: %s\n", sb.toUtf8().constData()); 0279 sb = QString("(Size %1)").arg(newOrder.size()); 0280 foreach (int i, newOrder) 0281 sb += QString("%1, ").arg(i); 0282 fprintf(stderr, "=== Reindex Before : %s\n", sb.toUtf8().constData());*/ 0283 0284 int override = GlobalConfig::ShowUnavailableDevices | GlobalConfig::ShowAdvancedDevices; 0285 QList<int> currentList = config->audioOutputDeviceListFor(category, override); 0286 0287 0288 QList<int> newList; 0289 0290 foreach (int i, newOrder) { 0291 int found = currentList.indexOf(i); 0292 if (found < 0) { 0293 // It's not in the list, so something is odd (e.g. client error). Ignore it. 0294 continue; 0295 } 0296 0297 // Iterate through the list from this point onward. If there are hidden devices 0298 // immediately following, take them too. 0299 newList.append(currentList.takeAt(found)); 0300 0301 while (found < currentList.size()) { 0302 bool hidden = isHiddenAudioOutputDevice(config, currentList.at(found)); 0303 if (!hidden) 0304 break; 0305 0306 newList.append(currentList.takeAt(found)); 0307 } 0308 } 0309 0310 // If there are any devices left in.. just tack them on the end. 0311 if (currentList.size() > 0) 0312 newList += currentList; 0313 0314 /*sb = QString("(Size %1)").arg(newList.size()); 0315 foreach (int i, newList) 0316 sb += QString("%1, ").arg(i); 0317 fprintf(stderr, "=== Reindex After : %s\n", sb.toUtf8().constData());*/ 0318 return newList; 0319 } 0320 0321 static QList<int> reindexList(const GlobalConfig *config, ObjectDescriptionType type, CaptureCategory category, QList<int>newOrder) 0322 { 0323 Q_ASSERT(config); 0324 Q_ASSERT(type == AudioCaptureDeviceType || type == VideoCaptureDeviceType); 0325 0326 QList<int> currentList; 0327 int override = GlobalConfig::ShowUnavailableDevices | GlobalConfig::ShowAdvancedDevices; 0328 0329 switch (type) { 0330 #ifndef PHONON_NO_AUDIOCAPTURE 0331 case AudioCaptureDeviceType: 0332 currentList = config->audioCaptureDeviceListFor(category, override); 0333 break; 0334 #endif 0335 0336 #ifndef PHONON_NO_VIDEOCAPTURE 0337 case VideoCaptureDeviceType: 0338 currentList = config->videoCaptureDeviceListFor(category, override); 0339 break; 0340 #endif 0341 0342 default: ; 0343 } 0344 0345 QList<int> newList; 0346 0347 foreach (int i, newOrder) { 0348 int found = currentList.indexOf(i); 0349 if (found < 0) { 0350 // It's not in the list, so something is odd (e.g. client error). Ignore it. 0351 continue; 0352 } 0353 0354 // Iterate through the list from this point onward. If there are hidden devices 0355 // immediately following, take them too. 0356 newList.append(currentList.takeAt(found)); 0357 0358 while (found < currentList.size()) { 0359 bool hidden = true; 0360 0361 switch (type) { 0362 #ifndef PHONON_NO_AUDIOCAPTURE 0363 case AudioCaptureDeviceType: 0364 hidden = isHiddenAudioCaptureDevice(config, currentList.at(found)); 0365 break; 0366 #endif 0367 0368 #ifndef PHONON_NO_VIDEOCAPTURE 0369 case VideoCaptureDeviceType: 0370 hidden = isHiddenVideoCaptureDevice(config, currentList.at(found)); 0371 break; 0372 #endif 0373 0374 default: ; 0375 } 0376 0377 if (!hidden) 0378 break; 0379 0380 newList.append(currentList.takeAt(found)); 0381 } 0382 } 0383 0384 // If there are any devices left in.. just tack them on the end. 0385 if (currentList.size() > 0) 0386 newList += currentList; 0387 0388 return newList; 0389 } 0390 0391 void GlobalConfig::setAudioOutputDeviceListFor(Category category, QList<int> order) 0392 { 0393 PulseSupport *pulse = PulseSupport::getInstance(); 0394 if (pulse->isUsed()) { 0395 pulse->setOutputDevicePriorityForCategory(category, order); 0396 return; 0397 } 0398 0399 #ifndef QT_NO_PHONON_SETTINGSGROUP 0400 P_D(GlobalConfig); 0401 QSettingsGroup backendConfig(&d->config, QLatin1String("AudioOutputDevice")); // + Factory::identifier()); 0402 0403 order = reindexList(this, AudioOutputDeviceType, category, order); 0404 0405 const QList<int> noCategoryOrder = audioOutputDeviceListFor(NoCategory, ShowUnavailableDevices|ShowAdvancedDevices); 0406 if (category != NoCategory && order == noCategoryOrder) { 0407 backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category)); 0408 } else { 0409 backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order); 0410 } 0411 #endif //QT_NO_PHONON_SETTINGSGROUP 0412 } 0413 0414 QList<int> GlobalConfig::audioOutputDeviceListFor(Category category, int override) const 0415 { 0416 P_D(const GlobalConfig); 0417 0418 #ifndef QT_NO_PHONON_SETTINGSGROUP 0419 const bool hide = ((override & AdvancedDevicesFromSettings) 0420 ? hideAdvancedDevices() 0421 : static_cast<bool>(override & HideAdvancedDevices)); 0422 #else 0423 const bool hide = !((override & AdvancedDevicesFromSettings) && static_cast<bool>(override & HideAdvancedDevices)); 0424 #endif 0425 0426 QList<int> defaultList; 0427 0428 PulseSupport *pulse = PulseSupport::getInstance(); 0429 if (pulse->isUsed()) { 0430 defaultList = pulse->objectDescriptionIndexes(AudioOutputDeviceType); 0431 if (hide || (override & HideUnavailableDevices)) { 0432 filter(AudioOutputDeviceType, nullptr, &defaultList, 0433 (hide ? FilterAdvancedDevices : 0) 0434 | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) 0435 ); 0436 } 0437 } else { 0438 BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()); 0439 0440 #ifndef QT_NO_PHONON_PLATFORMPLUGIN 0441 if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { 0442 // the platform plugin lists the audio devices for the platform 0443 // this list already is in default order (as defined by the platform plugin) 0444 defaultList = platformPlugin->objectDescriptionIndexes(AudioOutputDeviceType); 0445 if (hide) { 0446 QMutableListIterator<int> it(defaultList); 0447 while (it.hasNext()) { 0448 AudioOutputDevice objDesc = AudioOutputDevice::fromIndex(it.next()); 0449 const QVariant var = objDesc.property("isAdvanced"); 0450 if (var.isValid() && var.toBool()) { 0451 it.remove(); 0452 } 0453 } 0454 } 0455 } 0456 #endif //QT_NO_PHONON_PLATFORMPLUGIN 0457 0458 // lookup the available devices directly from the backend 0459 if (backendIface) { 0460 // this list already is in default order (as defined by the backend) 0461 QList<int> list = backendIface->objectDescriptionIndexes(AudioOutputDeviceType); 0462 if (hide || !defaultList.isEmpty() || (override & HideUnavailableDevices)) { 0463 filter(AudioOutputDeviceType, backendIface, &list, 0464 (hide ? FilterAdvancedDevices : 0) 0465 // the platform plugin maybe already provided the hardware devices? 0466 | (defaultList.isEmpty() ? 0 : FilterHardwareDevices) 0467 | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) 0468 ); 0469 } 0470 defaultList += list; 0471 } 0472 } 0473 0474 #ifndef QT_NO_PHONON_SETTINGSGROUP 0475 const QSettingsGroup backendConfig(&d->config, QLatin1String("AudioOutputDevice")); // + Factory::identifier()); 0476 return sortDevicesByCategoryPriority(this, &backendConfig, AudioOutputDeviceType, category, defaultList); 0477 #else //QT_NO_PHONON_SETTINGSGROUP 0478 return defaultList; 0479 #endif //QT_NO_PHONON_SETTINGSGROUP 0480 } 0481 0482 0483 int GlobalConfig::audioOutputDeviceFor(Category category, int override) const 0484 { 0485 #ifndef QT_NO_PHONON_SETTINGSGROUP 0486 QList<int> ret = audioOutputDeviceListFor(category, override); 0487 if (!ret.isEmpty()) 0488 return ret.first(); 0489 #endif //QT_NO_PHONON_SETTINGSGROUP 0490 return -1; 0491 } 0492 0493 QHash<QByteArray, QVariant> GlobalConfig::audioOutputDeviceProperties(int index) const 0494 { 0495 return deviceProperties(AudioOutputDeviceType, index); 0496 } 0497 0498 0499 #ifndef PHONON_NO_AUDIOCAPTURE 0500 void GlobalConfig::setAudioCaptureDeviceListFor(CaptureCategory category, QList<int> order) 0501 { 0502 0503 PulseSupport *pulse = PulseSupport::getInstance(); 0504 if (pulse->isUsed()) { 0505 pulse->setCaptureDevicePriorityForCategory(category, order); 0506 return; 0507 } 0508 0509 #ifndef QT_NO_PHONON_SETTINGSGROUP 0510 P_D(GlobalConfig); 0511 QSettingsGroup backendConfig(&d->config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier()); 0512 0513 order = reindexList(this, AudioCaptureDeviceType, category, order); 0514 0515 const QList<int> noCategoryOrder = audioCaptureDeviceListFor(NoCaptureCategory, ShowUnavailableDevices|ShowAdvancedDevices); 0516 if (category != NoCaptureCategory && order == noCategoryOrder) { 0517 backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category)); 0518 } else { 0519 backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order); 0520 } 0521 #endif //QT_NO_PHONON_SETTINGSGROUP 0522 } 0523 0524 QList<int> GlobalConfig::audioCaptureDeviceListFor(CaptureCategory category, int override) const 0525 { 0526 P_D(const GlobalConfig); 0527 0528 #ifndef QT_NO_PHONON_SETTINGSGROUP 0529 const bool hide = ((override & AdvancedDevicesFromSettings) 0530 ? hideAdvancedDevices() 0531 : static_cast<bool>(override & HideAdvancedDevices)); 0532 #else 0533 const bool hide = !((override & AdvancedDevicesFromSettings) && static_cast<bool>(override & HideAdvancedDevices)); 0534 #endif 0535 0536 QList<int> defaultList; 0537 0538 PulseSupport *pulse = PulseSupport::getInstance(); 0539 if (pulse->isUsed()) { 0540 defaultList = pulse->objectDescriptionIndexes(AudioCaptureDeviceType); 0541 if (hide || (override & HideUnavailableDevices)) { 0542 filter(AudioCaptureDeviceType, nullptr, &defaultList, 0543 (hide ? FilterAdvancedDevices : 0) 0544 | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) 0545 ); 0546 } 0547 } else { 0548 BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()); 0549 0550 #ifndef QT_NO_PHONON_PLATFORMPLUGIN 0551 if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { 0552 // the platform plugin lists the audio devices for the platform 0553 // this list already is in default order (as defined by the platform plugin) 0554 defaultList += platformPlugin->objectDescriptionIndexes(AudioCaptureDeviceType); 0555 if (hide) { 0556 QMutableListIterator<int> it(defaultList); 0557 while (it.hasNext()) { 0558 AudioCaptureDevice objDesc = AudioCaptureDevice::fromIndex(it.next()); 0559 const QVariant var = objDesc.property("isAdvanced"); 0560 if (var.isValid() && var.toBool()) { 0561 it.remove(); 0562 } 0563 } 0564 } 0565 } 0566 #endif //QT_NO_PHONON_PLATFORMPLUGIN 0567 0568 // lookup the available devices directly from the backend 0569 if (backendIface) { 0570 // this list already is in default order (as defined by the backend) 0571 QList<int> list = backendIface->objectDescriptionIndexes(AudioCaptureDeviceType); 0572 if (hide || !defaultList.isEmpty() || (override & HideUnavailableDevices)) { 0573 filter(AudioCaptureDeviceType, backendIface, &list, 0574 (hide ? FilterAdvancedDevices : 0) 0575 // the platform plugin maybe already provided the hardware devices? 0576 | (defaultList.isEmpty() ? 0 : FilterHardwareDevices) 0577 | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) 0578 ); 0579 } 0580 defaultList += list; 0581 } 0582 } 0583 0584 #ifndef QT_NO_PHONON_SETTINGSGROUP 0585 const QSettingsGroup backendConfig(&d->config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier()); 0586 return sortDevicesByCategoryPriority(this, &backendConfig, AudioCaptureDeviceType, category, defaultList); 0587 #else //QT_NO_PHONON_SETTINGSGROUP 0588 #ifndef QT_NO_PHONON_PLATFORMPLUGIN 0589 return defaultList; 0590 #else //QT_NO_PHONON_PLATFORMPLUGIN 0591 return QList<int>(); 0592 #endif //QT_NO_PHONON_PLATFORMPLUGIN 0593 #endif //QT_NO_PHONON_SETTINGSGROUP 0594 } 0595 0596 int GlobalConfig::audioCaptureDeviceFor(CaptureCategory category, int override) const 0597 { 0598 QList<int> ret = audioCaptureDeviceListFor(category, override); 0599 if (ret.isEmpty()) 0600 return -1; 0601 return ret.first(); 0602 } 0603 0604 QHash<QByteArray, QVariant> GlobalConfig::audioCaptureDeviceProperties(int index) const 0605 { 0606 return deviceProperties(AudioCaptureDeviceType, index); 0607 } 0608 0609 void GlobalConfig::setAudioCaptureDeviceListFor(Category category, QList<int> order) 0610 { 0611 CaptureCategory cat = categoryToCaptureCategory(category); 0612 setAudioCaptureDeviceListFor(cat, order); 0613 } 0614 0615 QList<int> GlobalConfig::audioCaptureDeviceListFor(Category category, int override) const 0616 { 0617 CaptureCategory cat = categoryToCaptureCategory(category); 0618 return audioCaptureDeviceListFor(cat, override); 0619 } 0620 0621 int GlobalConfig::audioCaptureDeviceFor(Category category, int override) const 0622 { 0623 CaptureCategory cat = categoryToCaptureCategory(category); 0624 return audioCaptureDeviceFor(cat, override); 0625 } 0626 0627 #endif //PHONON_NO_AUDIOCAPTURE 0628 0629 0630 #ifndef PHONON_NO_VIDEOCAPTURE 0631 void GlobalConfig::setVideoCaptureDeviceListFor(CaptureCategory category, QList<int> order) 0632 { 0633 #ifndef QT_NO_PHONON_SETTINGSGROUP 0634 P_D(GlobalConfig); 0635 QSettingsGroup backendConfig(&d->config, QLatin1String("VideoCaptureDevice")); // + Factory::identifier()); 0636 0637 order = reindexList(this, VideoCaptureDeviceType, category, order); 0638 0639 const QList<int> noCategoryOrder = videoCaptureDeviceListFor(NoCaptureCategory, ShowUnavailableDevices|ShowAdvancedDevices); 0640 if (category != NoCaptureCategory && order == noCategoryOrder) { 0641 backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category)); 0642 } else { 0643 backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order); 0644 } 0645 #endif //QT_NO_PHONON_SETTINGSGROUP 0646 } 0647 0648 QList<int> GlobalConfig::videoCaptureDeviceListFor(CaptureCategory category, int override) const 0649 { 0650 P_D(const GlobalConfig); 0651 0652 #ifndef QT_NO_PHONON_SETTINGSGROUP 0653 const bool hide = ((override & AdvancedDevicesFromSettings) 0654 ? hideAdvancedDevices() 0655 : static_cast<bool>(override & HideAdvancedDevices)); 0656 #else 0657 const bool hide = !((override & AdvancedDevicesFromSettings) && static_cast<bool>(override & HideAdvancedDevices)); 0658 #endif 0659 0660 //First we lookup the available devices directly from the backend 0661 BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()); 0662 if (!backendIface) { 0663 return QList<int>(); 0664 } 0665 0666 // this list already is in default order (as defined by the backend) 0667 QList<int> defaultList = backendIface->objectDescriptionIndexes(VideoCaptureDeviceType); 0668 0669 #ifndef QT_NO_PHONON_PLATFORMPLUGIN 0670 if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { 0671 // the platform plugin lists the video devices for the platform 0672 // this list already is in default order (as defined by the platform plugin) 0673 defaultList += platformPlugin->objectDescriptionIndexes(VideoCaptureDeviceType); 0674 if (hide) { 0675 QMutableListIterator<int> it(defaultList); 0676 while (it.hasNext()) { 0677 VideoCaptureDevice objDesc = VideoCaptureDevice::fromIndex(it.next()); 0678 const QVariant var = objDesc.property("isAdvanced"); 0679 if (var.isValid() && var.toBool()) { 0680 it.remove(); 0681 } 0682 } 0683 } 0684 } 0685 #endif //QT_NO_PHONON_PLATFORMPLUGIN 0686 0687 #ifndef QT_NO_PHONON_SETTINGSGROUP 0688 if (hideAdvancedDevices() || (override & HideUnavailableDevices)) { 0689 filter(VideoCaptureDeviceType, backendIface, &defaultList, 0690 (hideAdvancedDevices() ? FilterAdvancedDevices : 0) | 0691 ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) 0692 ); 0693 } 0694 0695 //The devices need to be stored independently for every backend 0696 const QSettingsGroup backendConfig(&d->config, QLatin1String("VideoCaptureDevice")); // + Factory::identifier()); 0697 return sortDevicesByCategoryPriority(this, &backendConfig, VideoCaptureDeviceType, category, defaultList); 0698 #else // QT_NO_PHONON_SETTINGSGROUP 0699 return defaultList; 0700 #endif // QT_NO_PHONON_SETTINGSGROUP 0701 } 0702 0703 int GlobalConfig::videoCaptureDeviceFor(CaptureCategory category, int override) const 0704 { 0705 QList<int> ret = videoCaptureDeviceListFor(category, override); 0706 if (ret.isEmpty()) 0707 return -1; 0708 return ret.first(); 0709 } 0710 0711 QHash<QByteArray, QVariant> GlobalConfig::videoCaptureDeviceProperties(int index) const 0712 { 0713 return deviceProperties(VideoCaptureDeviceType, index); 0714 } 0715 0716 void GlobalConfig::setVideoCaptureDeviceListFor(Category category, QList<int> order) 0717 { 0718 CaptureCategory cat = categoryToCaptureCategory(category); 0719 setVideoCaptureDeviceListFor(cat, order); 0720 } 0721 0722 QList<int> GlobalConfig::videoCaptureDeviceListFor(Category category, int override) const 0723 { 0724 CaptureCategory cat = categoryToCaptureCategory(category); 0725 return videoCaptureDeviceListFor(cat, override); 0726 } 0727 0728 int GlobalConfig::videoCaptureDeviceFor(Category category, int override) const 0729 { 0730 CaptureCategory cat = categoryToCaptureCategory(category); 0731 return videoCaptureDeviceFor(cat, override); 0732 } 0733 0734 #endif // PHONON_NO_VIDEOCAPTURE 0735 0736 QHash<QByteArray, QVariant> GlobalConfig::deviceProperties(ObjectDescriptionType deviceType, int index) const 0737 { 0738 QList<int> indices; 0739 QHash<QByteArray, QVariant> props; 0740 0741 // Try a pulseaudio device 0742 PulseSupport *pulse = PulseSupport::getInstance(); 0743 if (pulse->isUsed()) { 0744 // Check the index before passing it to PulseSupport 0745 indices = pulse->objectDescriptionIndexes(deviceType); 0746 if (indices.contains(index)) 0747 props = pulse->objectDescriptionProperties(deviceType, index); 0748 } 0749 if (!props.isEmpty()) 0750 return props; 0751 0752 #ifndef QT_NO_PHONON_PLATFORMPLUGIN 0753 // Try a device from the platform 0754 if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) 0755 props = platformPlugin->objectDescriptionProperties(deviceType, index); 0756 if (!props.isEmpty()) 0757 return props; 0758 #endif //QT_NO_PHONON_PLATFORMPLUGIN 0759 0760 // Try a device from the backend 0761 BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()); 0762 if (backendIface) 0763 props = backendIface->objectDescriptionProperties(deviceType, index); 0764 if (!props.isEmpty()) 0765 return props; 0766 0767 return props; 0768 } 0769 0770 0771 } // namespace Phonon