File indexing completed on 2024-03-24 04:57:18
0001 /* 0002 * KCompactDisc - A CD drive interface for the KDE Project. 0003 * 0004 * Copyright (C) 2005 Shaheedur R. Haque <srhaque@iee.org> 0005 * Copyright (C) 2007 Alexander Kern <alex.kern@gmx.de> 0006 * 0007 * This program is free software; you can redistribute it and/or modify 0008 * it under the terms of the GNU General Public License as published by 0009 * the Free Software Foundation; either version 2, or (at your option) 0010 * any later version. 0011 * 0012 * This program is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 * GNU General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU General Public License 0018 * along with this program; if not, write to the Free Software 0019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "kcompactdisc.h" 0023 #include "kcompactdisc_p.h" 0024 0025 #include <config-alsa.h> 0026 0027 #include <QDBusInterface> 0028 #include <QDBusReply> 0029 #include <QUrl> 0030 #include <QtGlobal> 0031 0032 #include <Solid/Device> 0033 #include <Solid/Block> 0034 #include <Solid/OpticalDrive> 0035 0036 static QMap<QString, QUrl> cdromsNameToDeviceUrl; 0037 static QMap<QString, QString> cdromsNameToUdi; 0038 static QString ___null = QString(); 0039 0040 static void refreshListOfCdromDevices() 0041 { 0042 cdromsNameToDeviceUrl.clear(); 0043 cdromsNameToUdi.clear(); 0044 QString name, type; 0045 QUrl url; 0046 0047 //get a list of all devices that are Cdrom 0048 const auto devices = Solid::Device::listFromType(Solid::DeviceInterface::OpticalDrive); 0049 for (const Solid::Device &device : devices) { 0050 qDebug() << device.udi().toLatin1().constData(); 0051 const Solid::Block *b = device.as<Solid::Block>(); 0052 0053 if(!b) { 0054 continue; 0055 } 0056 0057 const Solid::OpticalDrive *o = device.as<Solid::OpticalDrive>(); 0058 Solid::OpticalDrive::MediumTypes mediumType = o->supportedMedia(); 0059 0060 url = QUrl::fromUserInput(QLatin1String( b->device().toLatin1() )); 0061 //TODO translate them ? 0062 if(mediumType < Solid::OpticalDrive::Cdrw) { 0063 type = QLatin1String( "CD-ROM" ); 0064 } else if(mediumType < Solid::OpticalDrive::Dvd) { 0065 type = QLatin1String( "CDRW" ); 0066 } else if(mediumType < Solid::OpticalDrive::Dvdr) { 0067 type = QLatin1String( "DVD-ROM" ); 0068 } else if(mediumType < Solid::OpticalDrive::Bd) { 0069 type = QLatin1String( "DVDRW" ); 0070 } else if(mediumType < Solid::OpticalDrive::HdDvd) { 0071 type = QLatin1String( "Blu-ray" ); 0072 } else { 0073 type = QLatin1String( "High Density DVD" ); 0074 } 0075 0076 if(!device.vendor().isEmpty()) 0077 name = (QLatin1Char('[') + type + QLatin1String( " - " ) + device.vendor() + QLatin1String( " - " ) + device.product() + QLatin1Char( ']' )); 0078 else 0079 name = (QLatin1Char('[') + type + QLatin1String( " - unknown vendor - " ) + device.product() + QLatin1Char( ']' )); 0080 0081 cdromsNameToDeviceUrl.insert(name, url); 0082 cdromsNameToUdi.insert(name, device.udi()); 0083 } 0084 #if 0 0085 if(cdromsNameToDeviceUrl.empty()) { 0086 cdromsNameToDeviceUrl.insert(QString("Generic CDROM []"), QUrl::fromPath(wm_drive_default_device())); 0087 } 0088 #endif 0089 } 0090 0091 static QMap<QString, QUrl> &getListOfCdromDevicesNamesAndUrl() 0092 { 0093 if(cdromsNameToDeviceUrl.empty()) 0094 refreshListOfCdromDevices(); 0095 0096 return cdromsNameToDeviceUrl; 0097 } 0098 0099 static QMap<QString, QString> &getListOfCdromDevicesNamesAndUdi() 0100 { 0101 if(cdromsNameToUdi.empty()) 0102 refreshListOfCdromDevices(); 0103 0104 return cdromsNameToUdi; 0105 } 0106 0107 QString KCompactDisc::urlToDevice(const QUrl &deviceUrl) 0108 { 0109 if(deviceUrl.scheme() == QLatin1String( "media" ) || deviceUrl.scheme() == QLatin1String( "system" )) { 0110 qDebug() << "Asking mediamanager for " << deviceUrl.fileName(); 0111 0112 QDBusInterface mediamanager( QLatin1String( "org.kde.kded" ), QLatin1String( "/modules/mediamanager" ), QLatin1String( "org.kde.MediaManager" ) ); 0113 QDBusReply<QStringList> reply = mediamanager.call(QLatin1String( "properties" ), deviceUrl.fileName()); 0114 0115 QStringList properties = reply; 0116 if(!reply.isValid() || properties.count() < 6) { 0117 qCritical() << "Invalid reply from mediamanager"; 0118 return deviceUrl.path(); 0119 } else { 0120 qDebug() << "Reply from mediamanager " << properties[5]; 0121 return properties[5]; 0122 } 0123 } else if(deviceUrl.scheme() == QLatin1String( "file" )) { 0124 return deviceUrl.path(); 0125 } else { 0126 return QString(); 0127 } 0128 } 0129 0130 const QStringList KCompactDisc::audioSystems() 0131 { 0132 QStringList list; 0133 0134 list << QLatin1String( "phonon" ) 0135 #if defined(HAVE_ALSA) 0136 << QLatin1String( "alsa" ) 0137 #endif 0138 #if defined(sun) || defined(__sun__) 0139 << QLatin1String( "sun" ) 0140 #endif 0141 ; 0142 return list; 0143 } 0144 0145 const QStringList KCompactDisc::cdromDeviceNames() 0146 { 0147 return getListOfCdromDevicesNamesAndUrl().keys(); 0148 } 0149 0150 const QString KCompactDisc::defaultCdromDeviceName() 0151 { 0152 const QStringList names = getListOfCdromDevicesNamesAndUrl().keys(); 0153 if (!names.isEmpty()) return names[0]; 0154 else return QString(); 0155 } 0156 0157 const QUrl KCompactDisc::defaultCdromDeviceUrl() 0158 { 0159 const QList<QUrl> urls = getListOfCdromDevicesNamesAndUrl().values(); 0160 if (!urls.isEmpty()) return urls[0]; 0161 else return QUrl(); 0162 } 0163 0164 const QUrl KCompactDisc::cdromDeviceUrl(const QString &cdromDeviceName) 0165 { 0166 const QMap<QString, QUrl> &nameUrls = getListOfCdromDevicesNamesAndUrl(); 0167 QUrl result = nameUrls.value(cdromDeviceName); 0168 if (!result.isValid()) 0169 { 0170 const QUrl passedUrl = QUrl::fromLocalFile(cdromDeviceName); 0171 for (const QUrl &url : nameUrls) { 0172 if (url == passedUrl) 0173 { 0174 return passedUrl; 0175 } 0176 } 0177 result = KCompactDisc::defaultCdromDeviceUrl(); 0178 } 0179 return result; 0180 } 0181 0182 const QString KCompactDisc::defaultCdromDeviceUdi() 0183 { 0184 const QStringList udis = getListOfCdromDevicesNamesAndUdi().values(); 0185 if (!udis.isEmpty()) return udis[0]; 0186 else return QString(); 0187 } 0188 0189 const QString KCompactDisc::cdromDeviceUdi(const QString &cdromDeviceName) 0190 { 0191 return getListOfCdromDevicesNamesAndUdi().value(cdromDeviceName, KCompactDisc::defaultCdromDeviceUdi()); 0192 } 0193 0194 KCompactDisc::KCompactDisc(InformationMode infoMode) : 0195 d_ptr(new KCompactDiscPrivate(this, KCompactDisc::defaultCdromDeviceName())) 0196 { 0197 Q_D(KCompactDisc); 0198 d->m_infoMode = infoMode; 0199 } 0200 0201 KCompactDisc::~KCompactDisc() 0202 { 0203 stop(); 0204 delete d_ptr; 0205 } 0206 0207 const QString &KCompactDisc::deviceVendor() 0208 { 0209 Q_D(KCompactDisc); 0210 return d->m_deviceVendor; 0211 } 0212 0213 const QString &KCompactDisc::deviceModel() 0214 { 0215 Q_D(KCompactDisc); 0216 return d->m_deviceModel; 0217 } 0218 0219 const QString &KCompactDisc::deviceRevision() 0220 { 0221 Q_D(KCompactDisc); 0222 return d->m_deviceRevision; 0223 } 0224 0225 const QString &KCompactDisc::deviceName() 0226 { 0227 Q_D(KCompactDisc); 0228 return d->m_deviceName; 0229 } 0230 0231 const QUrl KCompactDisc::deviceUrl() 0232 { 0233 Q_D(KCompactDisc); 0234 return KCompactDisc::cdromDeviceUrl(d->m_deviceName); 0235 } 0236 0237 unsigned KCompactDisc::discId() 0238 { 0239 Q_D(KCompactDisc); 0240 return d->m_discId; 0241 } 0242 0243 const QList<unsigned> &KCompactDisc::discSignature() 0244 { 0245 Q_D(KCompactDisc); 0246 return d->m_trackStartFrames; 0247 } 0248 0249 const QString &KCompactDisc::discArtist() 0250 { 0251 Q_D(KCompactDisc); 0252 if (!d->m_tracks) 0253 return ___null; 0254 return d->m_trackArtists[0]; 0255 } 0256 0257 const QString &KCompactDisc::discTitle() 0258 { 0259 Q_D(KCompactDisc); 0260 if (!d->m_tracks) 0261 return ___null; 0262 return d->m_trackTitles[0]; 0263 } 0264 0265 unsigned KCompactDisc::discLength() 0266 { 0267 Q_D(KCompactDisc); 0268 if (!d->m_tracks) 0269 return 0; 0270 return d->m_discLength; 0271 } 0272 0273 unsigned KCompactDisc::discPosition() 0274 { 0275 Q_D(KCompactDisc); 0276 return d->m_discPosition; 0277 } 0278 0279 KCompactDisc::DiscStatus KCompactDisc::discStatus() 0280 { 0281 Q_D(KCompactDisc); 0282 return d->m_status; 0283 } 0284 0285 QString KCompactDisc::discStatusString(KCompactDisc::DiscStatus status) 0286 { 0287 return KCompactDiscPrivate::discStatusI18n(status); 0288 } 0289 0290 QString KCompactDisc::trackArtist() 0291 { 0292 Q_D(KCompactDisc); 0293 return trackArtist(d->m_track); 0294 } 0295 0296 QString KCompactDisc::trackArtist(unsigned track) 0297 { 0298 Q_D(KCompactDisc); 0299 if (!track) 0300 return QString(); 0301 return d->m_trackArtists[track]; 0302 } 0303 0304 QString KCompactDisc::trackTitle() 0305 { 0306 Q_D(KCompactDisc); 0307 return trackTitle(d->m_track); 0308 } 0309 0310 QString KCompactDisc::trackTitle(unsigned track) 0311 { 0312 Q_D(KCompactDisc); 0313 if (!track) 0314 return QString(); 0315 return d->m_trackTitles[track]; 0316 } 0317 0318 unsigned KCompactDisc::trackLength() 0319 { 0320 Q_D(KCompactDisc); 0321 return trackLength(d->m_track); 0322 } 0323 0324 unsigned KCompactDisc::trackLength(unsigned track) 0325 { 0326 Q_D(KCompactDisc); 0327 if (!track) 0328 return 0; 0329 return d->trackLength(track); 0330 } 0331 0332 unsigned KCompactDisc::track() 0333 { 0334 Q_D(KCompactDisc); 0335 return d->m_track; 0336 } 0337 0338 unsigned KCompactDisc::trackPosition() 0339 { 0340 Q_D(KCompactDisc); 0341 return d->m_trackPosition; 0342 } 0343 0344 unsigned KCompactDisc::tracks() 0345 { 0346 Q_D(KCompactDisc); 0347 return d->m_tracks; 0348 } 0349 0350 bool KCompactDisc::isPlaying() 0351 { 0352 Q_D(KCompactDisc); 0353 return (d->m_status == KCompactDisc::Playing); 0354 } 0355 0356 bool KCompactDisc::isPaused() 0357 { 0358 Q_D(KCompactDisc); 0359 return (d->m_status == KCompactDisc::Paused); 0360 } 0361 0362 bool KCompactDisc::isNoDisc() 0363 { 0364 Q_D(KCompactDisc); 0365 return (d->m_status == KCompactDisc::NoDisc); 0366 } 0367 0368 bool KCompactDisc::isAudio(unsigned track) 0369 { 0370 Q_D(KCompactDisc); 0371 if (!track) 0372 return 0; 0373 return d->isTrackAudio(track); 0374 } 0375 0376 void KCompactDisc::playTrack(unsigned track) 0377 { 0378 Q_D(KCompactDisc); 0379 0380 d->m_statusExpected = KCompactDisc::Playing; 0381 d->m_trackExpectedPosition = 0; 0382 d->m_seek = abs(int(d->m_trackExpectedPosition - trackPosition())); 0383 0384 d->playTrackPosition(track, 0); 0385 } 0386 0387 void KCompactDisc::playPosition(unsigned position) 0388 { 0389 Q_D(KCompactDisc); 0390 0391 d->m_statusExpected = Playing; 0392 d->m_trackExpectedPosition = position; 0393 d->m_seek = abs(int(d->m_trackExpectedPosition - trackPosition())); 0394 0395 d->playTrackPosition(d->m_track, position); 0396 } 0397 0398 void KCompactDisc::play() 0399 { 0400 doCommand(KCompactDisc::Play); 0401 } 0402 0403 void KCompactDisc::next() 0404 { 0405 doCommand(KCompactDisc::Next); 0406 } 0407 0408 void KCompactDisc::prev() 0409 { 0410 doCommand(KCompactDisc::Prev); 0411 } 0412 0413 void KCompactDisc::pause() 0414 { 0415 doCommand(KCompactDisc::Pause); 0416 } 0417 0418 void KCompactDisc::stop() 0419 { 0420 doCommand(KCompactDisc::Stop); 0421 } 0422 0423 void KCompactDisc::eject() 0424 { 0425 doCommand(KCompactDisc::Eject); 0426 } 0427 0428 void KCompactDisc::loop() 0429 { 0430 doCommand(KCompactDisc::Loop); 0431 } 0432 0433 void KCompactDisc::random() 0434 { 0435 doCommand(KCompactDisc::Random); 0436 } 0437 0438 void KCompactDisc::doCommand(KCompactDisc::DiscCommand cmd) 0439 { 0440 Q_D(KCompactDisc); 0441 unsigned track; 0442 0443 switch(cmd) { 0444 case Play: 0445 if(d->m_status == KCompactDisc::Playing) 0446 return; 0447 next(); 0448 break; 0449 0450 case Next: 0451 track = d->getNextTrackInPlaylist(); 0452 if(track) 0453 playTrack(track); 0454 break; 0455 0456 case Prev: 0457 track = d->getPrevTrackInPlaylist(); 0458 if(track) 0459 playTrack(track); 0460 break; 0461 0462 case Pause: 0463 if(d->m_status == KCompactDisc::Paused) 0464 d->m_statusExpected = KCompactDisc::Playing; 0465 else 0466 d->m_statusExpected = KCompactDisc::Paused; 0467 0468 d->pause(); 0469 break; 0470 0471 case Stop: 0472 d->m_statusExpected = KCompactDisc::Stopped; 0473 d->stop(); 0474 break; 0475 0476 case Eject: 0477 if(d->m_status != KCompactDisc::Ejected) { 0478 if(d->m_status != KCompactDisc::Stopped) { 0479 d->m_statusExpected = KCompactDisc::Ejected; 0480 d->stop(); 0481 } else { 0482 d->eject(); 0483 } 0484 } else { 0485 d->m_statusExpected = KCompactDisc::Stopped; 0486 d->closetray(); 0487 } 0488 break; 0489 0490 case Loop: 0491 setLoopPlaylist(!d->m_loopPlaylist); 0492 break; 0493 0494 case Random: 0495 setRandomPlaylist(!d->m_randomPlaylist); 0496 break; 0497 } 0498 } 0499 0500 void KCompactDisc::metadataLookup() 0501 { 0502 Q_D(KCompactDisc); 0503 d->queryMetadata(); 0504 } 0505 0506 void KCompactDisc::setRandomPlaylist(bool random) 0507 { 0508 Q_D(KCompactDisc); 0509 d->m_randomPlaylist = random; 0510 d->make_playlist(); 0511 Q_EMIT randomPlaylistChanged(d->m_randomPlaylist); 0512 } 0513 0514 void KCompactDisc::setLoopPlaylist(bool loop) 0515 { 0516 Q_D(KCompactDisc); 0517 d->m_loopPlaylist = loop; 0518 Q_EMIT loopPlaylistChanged(d->m_loopPlaylist); 0519 } 0520 0521 void KCompactDisc::setAutoMetadataLookup(bool autoMetadata) 0522 { 0523 Q_D(KCompactDisc); 0524 d->m_autoMetadata = autoMetadata; 0525 if(d->m_autoMetadata) 0526 metadataLookup(); 0527 } 0528 0529 bool KCompactDisc::setDevice(const QString &deviceName, unsigned volume, 0530 bool digitalPlayback, const QString &audioSystem, const QString &audioDevice) 0531 { 0532 const QString as = digitalPlayback ? audioSystem : QLatin1String("cdin"); 0533 const QString ad = digitalPlayback ? audioDevice : QString(); 0534 qDebug() << "Device init: " << deviceName << ", " << as << ", " << ad; 0535 0536 if(d_ptr->moveInterface(deviceName, as, ad)) { 0537 setVolume(volume); 0538 return 1; 0539 } else { 0540 // Severe (OS-level) error. 0541 return 0; 0542 } 0543 } 0544 0545 void KCompactDisc::setVolume(unsigned volume) 0546 { 0547 Q_D(KCompactDisc); 0548 qDebug() << "change volume: " << volume; 0549 d->setVolume(volume); 0550 } 0551 0552 void KCompactDisc::setBalance(unsigned balance) 0553 { 0554 Q_D(KCompactDisc); 0555 qDebug() << "change balance: " << balance; 0556 d->setBalance(balance); 0557 } 0558 0559 #include "moc_kcompactdisc.cpp"