1 /* This file is part of the KDE project
2 Copyright (C) 2006-2008 Matthias Kretz <kretz@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), Nokia Corporation
10 (or its successors, if any) and the KDE Free Qt Foundation, which shall
11 act as a proxy defined in Section 6 of version 3 of the license.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library. If not, see <http://www.gnu.org/licenses/>.
20
21 */
22
23 #include "globalconfig.h"
24 #include "globalconfig_p.h"
25
26 #include "factory_p.h"
27 #include "phonondefs_p.h"
28 #include "platformplugin.h"
29 #include "backendinterface.h"
30 #include "qsettingsgroup_p.h"
31 #include "phononnamespace_p.h"
32 #include "phononnamespace.h"
33 #include "pulsesupport.h"
34
35 #include <QtCore/QList>
36 #include <QtCore/QVariant>
37
38 namespace Phonon
39 {
40
GlobalConfigPrivate()41 GlobalConfigPrivate::GlobalConfigPrivate() : config(QLatin1String("kde.org"), QLatin1String("libphonon"))
42 {
43 }
44
GlobalConfig()45 GlobalConfig::GlobalConfig()
46 : k_ptr(new GlobalConfigPrivate)
47 {
48 }
49
~GlobalConfig()50 GlobalConfig::~GlobalConfig()
51 {
52 delete k_ptr;
53 }
54
55 enum WhatToFilter {
56 FilterAdvancedDevices = 1,
57 FilterHardwareDevices = 2,
58 FilterUnavailableDevices = 4
59 };
60
filter(ObjectDescriptionType type,BackendInterface * backendIface,QList<int> * list,int whatToFilter)61 static void filter(ObjectDescriptionType type, BackendInterface *backendIface, QList<int> *list, int whatToFilter)
62 {
63 QMutableListIterator<int> it(*list);
64 while (it.hasNext()) {
65 QHash<QByteArray, QVariant> properties;
66 if (backendIface)
67 properties = backendIface->objectDescriptionProperties(type, it.next());
68 else
69 properties = PulseSupport::getInstance()->objectDescriptionProperties(type, it.next());
70 QVariant var;
71 if (whatToFilter & FilterAdvancedDevices) {
72 var = properties.value("isAdvanced");
73 if (var.isValid() && var.toBool()) {
74 it.remove();
75 continue;
76 }
77 }
78 if (whatToFilter & FilterHardwareDevices) {
79 var = properties.value("isHardwareDevice");
80 if (var.isValid() && var.toBool()) {
81 it.remove();
82 continue;
83 }
84 }
85 if (whatToFilter & FilterUnavailableDevices) {
86 var = properties.value("available");
87 if (var.isValid() && !var.toBool()) {
88 it.remove();
89 continue;
90 }
91 }
92 }
93 }
94
95 #ifndef QT_NO_PHONON_SETTINGSGROUP
sortDevicesByCategoryPriority(const GlobalConfig * config,const QSettingsGroup * backendConfig,ObjectDescriptionType type,Category category,QList<int> & defaultList)96 static QList<int> sortDevicesByCategoryPriority(const GlobalConfig *config, const QSettingsGroup *backendConfig, ObjectDescriptionType type, Category category, QList<int> &defaultList)
97 {
98 Q_ASSERT(config); Q_UNUSED(config);
99 Q_ASSERT(backendConfig);
100 Q_ASSERT(type == AudioOutputDeviceType);
101
102 if (defaultList.size() <= 1) {
103 // nothing to sort
104 return defaultList;
105 } else {
106 // make entries unique
107 QSet<int> seen;
108 QMutableListIterator<int> it(defaultList);
109 while (it.hasNext()) {
110 if (seen.contains(it.next())) {
111 it.remove();
112 } else {
113 seen.insert(it.value());
114 }
115 }
116 }
117
118 QList<int> deviceList;
119 PulseSupport *pulse = PulseSupport::getInstance();
120 if (pulse->isUsed()) {
121 deviceList = pulse->objectIndexesByCategory(type, category);
122 } else {
123 QString categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(category));
124 if (!backendConfig->hasKey(categoryKey)) {
125 // no list in config for the given category
126 categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(NoCategory));
127 if (!backendConfig->hasKey(categoryKey)) {
128 // no list in config for NoCategory
129 return defaultList;
130 }
131 }
132
133 //Now the list from d->config
134 deviceList = backendConfig->value(categoryKey, QList<int>());
135 }
136
137 //if there are devices in d->config that the backend doesn't report, remove them from the list
138 QMutableListIterator<int> i(deviceList);
139 while (i.hasNext()) {
140 if (0 == defaultList.removeAll(i.next())) {
141 i.remove();
142 }
143 }
144
145 //if the backend reports more devices that are not in d->config append them to the list
146 deviceList += defaultList;
147
148 return deviceList;
149 }
150
sortDevicesByCategoryPriority(const GlobalConfig * config,const QSettingsGroup * backendConfig,ObjectDescriptionType type,CaptureCategory category,QList<int> & defaultList)151 static QList<int> sortDevicesByCategoryPriority(const GlobalConfig *config, const QSettingsGroup *backendConfig, ObjectDescriptionType type, CaptureCategory category, QList<int> &defaultList)
152 {
153 Q_ASSERT(config); Q_UNUSED(config);
154 Q_ASSERT(backendConfig);
155 Q_ASSERT(type == AudioCaptureDeviceType || type == VideoCaptureDeviceType);
156
157 if (defaultList.size() <= 1) {
158 // nothing to sort
159 return defaultList;
160 } else {
161 // make entries unique
162 QSet<int> seen;
163 QMutableListIterator<int> it(defaultList);
164 while (it.hasNext()) {
165 if (seen.contains(it.next())) {
166 it.remove();
167 } else {
168 seen.insert(it.value());
169 }
170 }
171 }
172
173 QList<int> deviceList;
174 PulseSupport *pulse = PulseSupport::getInstance();
175 if (pulse->isUsed()) {
176 deviceList = pulse->objectIndexesByCategory(type, category);
177 } else {
178 QString categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(category));
179 if (!backendConfig->hasKey(categoryKey)) {
180 // no list in config for the given category
181 categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(NoCategory));
182 if (!backendConfig->hasKey(categoryKey)) {
183 // no list in config for NoCategory
184 return defaultList;
185 }
186 }
187
188 //Now the list from d->config
189 deviceList = backendConfig->value(categoryKey, QList<int>());
190 }
191
192 //if there are devices in d->config that the backend doesn't report, remove them from the list
193 QMutableListIterator<int> i(deviceList);
194 while (i.hasNext()) {
195 if (0 == defaultList.removeAll(i.next())) {
196 i.remove();
197 }
198 }
199
200 //if the backend reports more devices that are not in d->config append them to the list
201 deviceList += defaultList;
202
203 return deviceList;
204 }
205
hideAdvancedDevices() const206 bool GlobalConfig::hideAdvancedDevices() const
207 {
208 P_D(const GlobalConfig);
209 //The devices need to be stored independently for every backend
210 const QSettingsGroup generalGroup(&d->config, QLatin1String("General"));
211 return generalGroup.value(QLatin1String("HideAdvancedDevices"), true);
212 }
213
setHideAdvancedDevices(bool hide)214 void GlobalConfig::setHideAdvancedDevices(bool hide)
215 {
216 P_D(GlobalConfig);
217 QSettingsGroup generalGroup(&d->config, QLatin1String("General"));
218 generalGroup.setValue(QLatin1String("HideAdvancedDevices"), hide);
219 }
220 #endif // QT_NO_PHONON_SETTINGSGROUP
221
isHiddenAudioOutputDevice(const GlobalConfig * config,int i)222 static bool isHiddenAudioOutputDevice(const GlobalConfig *config, int i)
223 {
224 Q_ASSERT(config);
225
226 #ifndef QT_NO_PHONON_SETTINGSGROUP
227 if (!config->hideAdvancedDevices())
228 return false;
229 #endif // QT_NO_PHONON_SETTINGSGROUP
230
231 AudioOutputDevice ad = AudioOutputDevice::fromIndex(i);
232 const QVariant var = ad.property("isAdvanced");
233 return (var.isValid() && var.toBool());
234 }
235
236 #ifndef PHONON_NO_AUDIOCAPTURE
isHiddenAudioCaptureDevice(const GlobalConfig * config,int i)237 static bool isHiddenAudioCaptureDevice(const GlobalConfig *config, int i)
238 {
239 Q_ASSERT(config);
240
241 #ifndef QT_NO_PHONON_SETTINGSGROUP
242 if (!config->hideAdvancedDevices())
243 return false;
244 #endif // QT_NO_PHONON_SETTINGSGROUP
245
246 AudioCaptureDevice ad = AudioCaptureDevice::fromIndex(i);
247 const QVariant var = ad.property("isAdvanced");
248 return (var.isValid() && var.toBool());
249 }
250 #endif
251
252 #ifndef PHONON_NO_VIDEOCAPTURE
isHiddenVideoCaptureDevice(const GlobalConfig * config,int i)253 static bool isHiddenVideoCaptureDevice(const GlobalConfig *config, int i)
254 {
255 Q_ASSERT(config);
256
257 #ifndef QT_NO_PHONON_SETTINGSGROUP
258 if (!config->hideAdvancedDevices())
259 return false;
260 #endif // QT_NO_PHONON_SETTINGSGROUP
261
262 VideoCaptureDevice vd = VideoCaptureDevice::fromIndex(i);
263 const QVariant var = vd.property("isAdvanced");
264 return (var.isValid() && var.toBool());
265 }
266 #endif
267
reindexList(const GlobalConfig * config,ObjectDescriptionType type,Category category,QList<int> newOrder)268 static QList<int> reindexList(const GlobalConfig *config, ObjectDescriptionType type, Category category, QList<int>newOrder)
269 {
270 Q_ASSERT(config);
271 Q_ASSERT(type == AudioOutputDeviceType);
272 Q_UNUSED(type);
273
274 /*QString sb;
275 sb = QString("(Size %1)").arg(currentList.size());
276 foreach (int i, currentList)
277 sb += QString("%1, ").arg(i);
278 fprintf(stderr, "=== Reindex Current: %s\n", sb.toUtf8().constData());
279 sb = QString("(Size %1)").arg(newOrder.size());
280 foreach (int i, newOrder)
281 sb += QString("%1, ").arg(i);
282 fprintf(stderr, "=== Reindex Before : %s\n", sb.toUtf8().constData());*/
283
284 int override = GlobalConfig::ShowUnavailableDevices | GlobalConfig::ShowAdvancedDevices;
285 QList<int> currentList = config->audioOutputDeviceListFor(category, override);
286
287
288 QList<int> newList;
289
290 foreach (int i, newOrder) {
291 int found = currentList.indexOf(i);
292 if (found < 0) {
293 // It's not in the list, so something is odd (e.g. client error). Ignore it.
294 continue;
295 }
296
297 // Iterate through the list from this point onward. If there are hidden devices
298 // immediately following, take them too.
299 newList.append(currentList.takeAt(found));
300
301 while (found < currentList.size()) {
302 bool hidden = isHiddenAudioOutputDevice(config, currentList.at(found));
303 if (!hidden)
304 break;
305
306 newList.append(currentList.takeAt(found));
307 }
308 }
309
310 // If there are any devices left in.. just tack them on the end.
311 if (currentList.size() > 0)
312 newList += currentList;
313
314 /*sb = QString("(Size %1)").arg(newList.size());
315 foreach (int i, newList)
316 sb += QString("%1, ").arg(i);
317 fprintf(stderr, "=== Reindex After : %s\n", sb.toUtf8().constData());*/
318 return newList;
319 }
320
reindexList(const GlobalConfig * config,ObjectDescriptionType type,CaptureCategory category,QList<int> newOrder)321 static QList<int> reindexList(const GlobalConfig *config, ObjectDescriptionType type, CaptureCategory category, QList<int>newOrder)
322 {
323 Q_ASSERT(config);
324 Q_ASSERT(type == AudioCaptureDeviceType || type == VideoCaptureDeviceType);
325
326 QList<int> currentList;
327 int override = GlobalConfig::ShowUnavailableDevices | GlobalConfig::ShowAdvancedDevices;
328
329 switch (type) {
330 #ifndef PHONON_NO_AUDIOCAPTURE
331 case AudioCaptureDeviceType:
332 currentList = config->audioCaptureDeviceListFor(category, override);
333 break;
334 #endif
335
336 #ifndef PHONON_NO_VIDEOCAPTURE
337 case VideoCaptureDeviceType:
338 currentList = config->videoCaptureDeviceListFor(category, override);
339 break;
340 #endif
341
342 default: ;
343 }
344
345 QList<int> newList;
346
347 foreach (int i, newOrder) {
348 int found = currentList.indexOf(i);
349 if (found < 0) {
350 // It's not in the list, so something is odd (e.g. client error). Ignore it.
351 continue;
352 }
353
354 // Iterate through the list from this point onward. If there are hidden devices
355 // immediately following, take them too.
356 newList.append(currentList.takeAt(found));
357
358 while (found < currentList.size()) {
359 bool hidden = true;
360
361 switch (type) {
362 #ifndef PHONON_NO_AUDIOCAPTURE
363 case AudioCaptureDeviceType:
364 hidden = isHiddenAudioCaptureDevice(config, currentList.at(found));
365 break;
366 #endif
367
368 #ifndef PHONON_NO_VIDEOCAPTURE
369 case VideoCaptureDeviceType:
370 hidden = isHiddenVideoCaptureDevice(config, currentList.at(found));
371 break;
372 #endif
373
374 default: ;
375 }
376
377 if (!hidden)
378 break;
379
380 newList.append(currentList.takeAt(found));
381 }
382 }
383
384 // If there are any devices left in.. just tack them on the end.
385 if (currentList.size() > 0)
386 newList += currentList;
387
388 return newList;
389 }
390
setAudioOutputDeviceListFor(Category category,QList<int> order)391 void GlobalConfig::setAudioOutputDeviceListFor(Category category, QList<int> order)
392 {
393 PulseSupport *pulse = PulseSupport::getInstance();
394 if (pulse->isUsed()) {
395 pulse->setOutputDevicePriorityForCategory(category, order);
396 return;
397 }
398
399 #ifndef QT_NO_PHONON_SETTINGSGROUP
400 P_D(GlobalConfig);
401 QSettingsGroup backendConfig(&d->config, QLatin1String("AudioOutputDevice")); // + Factory::identifier());
402
403 order = reindexList(this, AudioOutputDeviceType, category, order);
404
405 const QList<int> noCategoryOrder = audioOutputDeviceListFor(NoCategory, ShowUnavailableDevices|ShowAdvancedDevices);
406 if (category != NoCategory && order == noCategoryOrder) {
407 backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category));
408 } else {
409 backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order);
410 }
411 #endif //QT_NO_PHONON_SETTINGSGROUP
412 }
413
audioOutputDeviceListFor(Category category,int override) const414 QList<int> GlobalConfig::audioOutputDeviceListFor(Category category, int override) const
415 {
416 P_D(const GlobalConfig);
417
418 #ifndef QT_NO_PHONON_SETTINGSGROUP
419 const bool hide = ((override & AdvancedDevicesFromSettings)
420 ? hideAdvancedDevices()
421 : static_cast<bool>(override & HideAdvancedDevices));
422 #else
423 const bool hide = !((override & AdvancedDevicesFromSettings) && static_cast<bool>(override & HideAdvancedDevices));
424 #endif
425
426 QList<int> defaultList;
427
428 PulseSupport *pulse = PulseSupport::getInstance();
429 if (pulse->isUsed()) {
430 defaultList = pulse->objectDescriptionIndexes(AudioOutputDeviceType);
431 if (hide || (override & HideUnavailableDevices)) {
432 filter(AudioOutputDeviceType, NULL, &defaultList,
433 (hide ? FilterAdvancedDevices : 0)
434 | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0)
435 );
436 }
437 } else {
438 BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend());
439
440 #ifndef QT_NO_PHONON_PLATFORMPLUGIN
441 if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) {
442 // the platform plugin lists the audio devices for the platform
443 // this list already is in default order (as defined by the platform plugin)
444 defaultList = platformPlugin->objectDescriptionIndexes(AudioOutputDeviceType);
445 if (hide) {
446 QMutableListIterator<int> it(defaultList);
447 while (it.hasNext()) {
448 AudioOutputDevice objDesc = AudioOutputDevice::fromIndex(it.next());
449 const QVariant var = objDesc.property("isAdvanced");
450 if (var.isValid() && var.toBool()) {
451 it.remove();
452 }
453 }
454 }
455 }
456 #endif //QT_NO_PHONON_PLATFORMPLUGIN
457
458 // lookup the available devices directly from the backend
459 if (backendIface) {
460 // this list already is in default order (as defined by the backend)
461 QList<int> list = backendIface->objectDescriptionIndexes(AudioOutputDeviceType);
462 if (hide || !defaultList.isEmpty() || (override & HideUnavailableDevices)) {
463 filter(AudioOutputDeviceType, backendIface, &list,
464 (hide ? FilterAdvancedDevices : 0)
465 // the platform plugin maybe already provided the hardware devices?
466 | (defaultList.isEmpty() ? 0 : FilterHardwareDevices)
467 | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0)
468 );
469 }
470 defaultList += list;
471 }
472 }
473
474 #ifndef QT_NO_PHONON_SETTINGSGROUP
475 const QSettingsGroup backendConfig(&d->config, QLatin1String("AudioOutputDevice")); // + Factory::identifier());
476 return sortDevicesByCategoryPriority(this, &backendConfig, AudioOutputDeviceType, category, defaultList);
477 #else //QT_NO_PHONON_SETTINGSGROUP
478 return defaultList;
479 #endif //QT_NO_PHONON_SETTINGSGROUP
480 }
481
482
audioOutputDeviceFor(Category category,int override) const483 int GlobalConfig::audioOutputDeviceFor(Category category, int override) const
484 {
485 #ifndef QT_NO_PHONON_SETTINGSGROUP
486 QList<int> ret = audioOutputDeviceListFor(category, override);
487 if (!ret.isEmpty())
488 return ret.first();
489 #endif //QT_NO_PHONON_SETTINGSGROUP
490 return -1;
491 }
492
audioOutputDeviceProperties(int index) const493 QHash<QByteArray, QVariant> GlobalConfig::audioOutputDeviceProperties(int index) const
494 {
495 return deviceProperties(AudioOutputDeviceType, index);
496 }
497
498
499 #ifndef PHONON_NO_AUDIOCAPTURE
setAudioCaptureDeviceListFor(CaptureCategory category,QList<int> order)500 void GlobalConfig::setAudioCaptureDeviceListFor(CaptureCategory category, QList<int> order)
501 {
502
503 PulseSupport *pulse = PulseSupport::getInstance();
504 if (pulse->isUsed()) {
505 pulse->setCaptureDevicePriorityForCategory(category, order);
506 return;
507 }
508
509 #ifndef QT_NO_PHONON_SETTINGSGROUP
510 P_D(GlobalConfig);
511 QSettingsGroup backendConfig(&d->config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier());
512
513 order = reindexList(this, AudioCaptureDeviceType, category, order);
514
515 const QList<int> noCategoryOrder = audioCaptureDeviceListFor(NoCaptureCategory, ShowUnavailableDevices|ShowAdvancedDevices);
516 if (category != NoCaptureCategory && order == noCategoryOrder) {
517 backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category));
518 } else {
519 backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order);
520 }
521 #endif //QT_NO_PHONON_SETTINGSGROUP
522 }
523
audioCaptureDeviceListFor(CaptureCategory category,int override) const524 QList<int> GlobalConfig::audioCaptureDeviceListFor(CaptureCategory category, int override) const
525 {
526 P_D(const GlobalConfig);
527
528 #ifndef QT_NO_PHONON_SETTINGSGROUP
529 const bool hide = ((override & AdvancedDevicesFromSettings)
530 ? hideAdvancedDevices()
531 : static_cast<bool>(override & HideAdvancedDevices));
532 #else
533 const bool hide = !((override & AdvancedDevicesFromSettings) && static_cast<bool>(override & HideAdvancedDevices));
534 #endif
535
536 QList<int> defaultList;
537
538 PulseSupport *pulse = PulseSupport::getInstance();
539 if (pulse->isUsed()) {
540 defaultList = pulse->objectDescriptionIndexes(AudioCaptureDeviceType);
541 if (hide || (override & HideUnavailableDevices)) {
542 filter(AudioCaptureDeviceType, NULL, &defaultList,
543 (hide ? FilterAdvancedDevices : 0)
544 | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0)
545 );
546 }
547 } else {
548 BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend());
549
550 #ifndef QT_NO_PHONON_PLATFORMPLUGIN
551 if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) {
552 // the platform plugin lists the audio devices for the platform
553 // this list already is in default order (as defined by the platform plugin)
554 defaultList += platformPlugin->objectDescriptionIndexes(AudioCaptureDeviceType);
555 if (hide) {
556 QMutableListIterator<int> it(defaultList);
557 while (it.hasNext()) {
558 AudioCaptureDevice objDesc = AudioCaptureDevice::fromIndex(it.next());
559 const QVariant var = objDesc.property("isAdvanced");
560 if (var.isValid() && var.toBool()) {
561 it.remove();
562 }
563 }
564 }
565 }
566 #endif //QT_NO_PHONON_PLATFORMPLUGIN
567
568 // lookup the available devices directly from the backend
569 if (backendIface) {
570 // this list already is in default order (as defined by the backend)
571 QList<int> list = backendIface->objectDescriptionIndexes(AudioCaptureDeviceType);
572 if (hide || !defaultList.isEmpty() || (override & HideUnavailableDevices)) {
573 filter(AudioCaptureDeviceType, backendIface, &list,
574 (hide ? FilterAdvancedDevices : 0)
575 // the platform plugin maybe already provided the hardware devices?
576 | (defaultList.isEmpty() ? 0 : FilterHardwareDevices)
577 | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0)
578 );
579 }
580 defaultList += list;
581 }
582 }
583
584 #ifndef QT_NO_PHONON_SETTINGSGROUP
585 const QSettingsGroup backendConfig(&d->config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier());
586 return sortDevicesByCategoryPriority(this, &backendConfig, AudioCaptureDeviceType, category, defaultList);
587 #else //QT_NO_PHONON_SETTINGSGROUP
588 #ifndef QT_NO_PHONON_PLATFORMPLUGIN
589 return defaultList;
590 #else //QT_NO_PHONON_PLATFORMPLUGIN
591 return QList<int>();
592 #endif //QT_NO_PHONON_PLATFORMPLUGIN
593 #endif //QT_NO_PHONON_SETTINGSGROUP
594 }
595
audioCaptureDeviceFor(CaptureCategory category,int override) const596 int GlobalConfig::audioCaptureDeviceFor(CaptureCategory category, int override) const
597 {
598 QList<int> ret = audioCaptureDeviceListFor(category, override);
599 if (ret.isEmpty())
600 return -1;
601 return ret.first();
602 }
603
audioCaptureDeviceProperties(int index) const604 QHash<QByteArray, QVariant> GlobalConfig::audioCaptureDeviceProperties(int index) const
605 {
606 return deviceProperties(AudioCaptureDeviceType, index);
607 }
608
setAudioCaptureDeviceListFor(Category category,QList<int> order)609 void GlobalConfig::setAudioCaptureDeviceListFor(Category category, QList<int> order)
610 {
611 CaptureCategory cat = categoryToCaptureCategory(category);
612 setAudioCaptureDeviceListFor(cat, order);
613 }
614
audioCaptureDeviceListFor(Category category,int override) const615 QList<int> GlobalConfig::audioCaptureDeviceListFor(Category category, int override) const
616 {
617 CaptureCategory cat = categoryToCaptureCategory(category);
618 return audioCaptureDeviceListFor(cat, override);
619 }
620
audioCaptureDeviceFor(Category category,int override) const621 int GlobalConfig::audioCaptureDeviceFor(Category category, int override) const
622 {
623 CaptureCategory cat = categoryToCaptureCategory(category);
624 return audioCaptureDeviceFor(cat, override);
625 }
626
627 #endif //PHONON_NO_AUDIOCAPTURE
628
629
630 #ifndef PHONON_NO_VIDEOCAPTURE
setVideoCaptureDeviceListFor(CaptureCategory category,QList<int> order)631 void GlobalConfig::setVideoCaptureDeviceListFor(CaptureCategory category, QList<int> order)
632 {
633 #ifndef QT_NO_PHONON_SETTINGSGROUP
634 P_D(GlobalConfig);
635 QSettingsGroup backendConfig(&d->config, QLatin1String("VideoCaptureDevice")); // + Factory::identifier());
636
637 order = reindexList(this, VideoCaptureDeviceType, category, order);
638
639 const QList<int> noCategoryOrder = videoCaptureDeviceListFor(NoCaptureCategory, ShowUnavailableDevices|ShowAdvancedDevices);
640 if (category != NoCaptureCategory && order == noCategoryOrder) {
641 backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category));
642 } else {
643 backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order);
644 }
645 #endif //QT_NO_PHONON_SETTINGSGROUP
646 }
647
videoCaptureDeviceListFor(CaptureCategory category,int override) const648 QList<int> GlobalConfig::videoCaptureDeviceListFor(CaptureCategory category, int override) const
649 {
650 P_D(const GlobalConfig);
651
652 #ifndef QT_NO_PHONON_SETTINGSGROUP
653 const bool hide = ((override & AdvancedDevicesFromSettings)
654 ? hideAdvancedDevices()
655 : static_cast<bool>(override & HideAdvancedDevices));
656 #else
657 const bool hide = !((override & AdvancedDevicesFromSettings) && static_cast<bool>(override & HideAdvancedDevices));
658 #endif
659
660 //First we lookup the available devices directly from the backend
661 BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend());
662 if (!backendIface) {
663 return QList<int>();
664 }
665
666 // this list already is in default order (as defined by the backend)
667 QList<int> defaultList = backendIface->objectDescriptionIndexes(VideoCaptureDeviceType);
668
669 #ifndef QT_NO_PHONON_PLATFORMPLUGIN
670 if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) {
671 // the platform plugin lists the video devices for the platform
672 // this list already is in default order (as defined by the platform plugin)
673 defaultList += platformPlugin->objectDescriptionIndexes(VideoCaptureDeviceType);
674 if (hide) {
675 QMutableListIterator<int> it(defaultList);
676 while (it.hasNext()) {
677 VideoCaptureDevice objDesc = VideoCaptureDevice::fromIndex(it.next());
678 const QVariant var = objDesc.property("isAdvanced");
679 if (var.isValid() && var.toBool()) {
680 it.remove();
681 }
682 }
683 }
684 }
685 #endif //QT_NO_PHONON_PLATFORMPLUGIN
686
687 #ifndef QT_NO_PHONON_SETTINGSGROUP
688 if (hideAdvancedDevices() || (override & HideUnavailableDevices)) {
689 filter(VideoCaptureDeviceType, backendIface, &defaultList,
690 (hideAdvancedDevices() ? FilterAdvancedDevices : 0) |
691 ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0)
692 );
693 }
694
695 //The devices need to be stored independently for every backend
696 const QSettingsGroup backendConfig(&d->config, QLatin1String("VideoCaptureDevice")); // + Factory::identifier());
697 return sortDevicesByCategoryPriority(this, &backendConfig, VideoCaptureDeviceType, category, defaultList);
698 #else // QT_NO_PHONON_SETTINGSGROUP
699 return defaultList;
700 #endif // QT_NO_PHONON_SETTINGSGROUP
701 }
702
videoCaptureDeviceFor(CaptureCategory category,int override) const703 int GlobalConfig::videoCaptureDeviceFor(CaptureCategory category, int override) const
704 {
705 QList<int> ret = videoCaptureDeviceListFor(category, override);
706 if (ret.isEmpty())
707 return -1;
708 return ret.first();
709 }
710
videoCaptureDeviceProperties(int index) const711 QHash<QByteArray, QVariant> GlobalConfig::videoCaptureDeviceProperties(int index) const
712 {
713 return deviceProperties(VideoCaptureDeviceType, index);
714 }
715
setVideoCaptureDeviceListFor(Category category,QList<int> order)716 void GlobalConfig::setVideoCaptureDeviceListFor(Category category, QList<int> order)
717 {
718 CaptureCategory cat = categoryToCaptureCategory(category);
719 setVideoCaptureDeviceListFor(cat, order);
720 }
721
videoCaptureDeviceListFor(Category category,int override) const722 QList<int> GlobalConfig::videoCaptureDeviceListFor(Category category, int override) const
723 {
724 CaptureCategory cat = categoryToCaptureCategory(category);
725 return videoCaptureDeviceListFor(cat, override);
726 }
727
videoCaptureDeviceFor(Category category,int override) const728 int GlobalConfig::videoCaptureDeviceFor(Category category, int override) const
729 {
730 CaptureCategory cat = categoryToCaptureCategory(category);
731 return videoCaptureDeviceFor(cat, override);
732 }
733
734 #endif // PHONON_NO_VIDEOCAPTURE
735
deviceProperties(ObjectDescriptionType deviceType,int index) const736 QHash<QByteArray, QVariant> GlobalConfig::deviceProperties(ObjectDescriptionType deviceType, int index) const
737 {
738 QList<int> indices;
739 QHash<QByteArray, QVariant> props;
740
741 // Try a pulseaudio device
742 PulseSupport *pulse = PulseSupport::getInstance();
743 if (pulse->isUsed()) {
744 // Check the index before passing it to PulseSupport
745 indices = pulse->objectDescriptionIndexes(deviceType);
746 if (indices.contains(index))
747 props = pulse->objectDescriptionProperties(deviceType, index);
748 }
749 if (!props.isEmpty())
750 return props;
751
752 #ifndef QT_NO_PHONON_PLATFORMPLUGIN
753 // Try a device from the platform
754 if (PlatformPlugin *platformPlugin = Factory::platformPlugin())
755 props = platformPlugin->objectDescriptionProperties(deviceType, index);
756 if (!props.isEmpty())
757 return props;
758 #endif //QT_NO_PHONON_PLATFORMPLUGIN
759
760 // Try a device from the backend
761 BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend());
762 if (backendIface)
763 props = backendIface->objectDescriptionProperties(deviceType, index);
764 if (!props.isEmpty())
765 return props;
766
767 return props;
768 }
769
770
771 } // namespace Phonon
772