/* * KMix -- KDE's full featured mini mixer * * Copyright 1996-2000 Christian Esken * Copyright 2000-2003 Christian Esken , Stefan Schimanski <1Stein@gmx.de> * Copyright 2002-2007 Christian Esken , Helio Chissini de Castro * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kmixd.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KMix #include "core/GlobalConfig.h" #include "core/mixertoolbox.h" #include "core/kmixdevicemanager.h" #include "core/version.h" K_PLUGIN_FACTORY(KMixDFactory, registerPlugin();) K_EXPORT_PLUGIN(KMixDFactory("kmixd")) /* KMixD * Constructs a mixer window (KMix main window) */ KMixD::KMixD(QObject* parent, const QList&) : KDEDModule(parent), m_multiDriverMode (false), // -<- I never-ever want the multi-drivermode to be activated by accident m_dontSetDefaultCardOnStart (false) { setObjectName( QLatin1String("KMixD" )); // disable delete-on-close because KMix might just sit in the background waiting for cards to be plugged in //setAttribute(Qt::WA_DeleteOnClose, false); GlobalConfig::init(); //initActions(); // init actions first, so we can use them in the loadConfig() already loadConfig(); // Load config before initMixer(), e.g. due to "MultiDriver" keyword //initActionsLate(); // init actions that require a loaded config //KGlobal::locale()->insertCatalog( QLatin1String( "kmix-controls" )); //initWidgets(); //initPrefDlg(); MixerToolBox::instance()->initMixer(m_multiDriverMode, m_backendFilter, m_hwInfoString); KMixDeviceManager *theKMixDeviceManager = KMixDeviceManager::instance(); theKMixDeviceManager->initHotplug(); connect(theKMixDeviceManager, SIGNAL(plugged(const char*,QString,QString&)), SLOT (plugged(const char*,QString,QString&)) ); connect(theKMixDeviceManager, SIGNAL(unplugged(QString)), SLOT (unplugged(QString)) ); } KMixD::~KMixD() { MixerToolBox::instance()->deinitMixer(); } /* void KMixD::initActionsLate() { if ( m_autouseMultimediaKeys ) { KAction* globalAction = actionCollection()->addAction("increase_volume"); globalAction->setText(i18n("Increase Volume")); globalAction->setGlobalShortcut(KShortcut(Qt::Key_VolumeUp), ( KAction::ShortcutTypes)( KAction::ActiveShortcut | KAction::DefaultShortcut), KAction::NoAutoloading); connect(globalAction, SIGNAL(triggered(bool)), SLOT(slotIncreaseVolume())); globalAction = actionCollection()->addAction("decrease_volume"); globalAction->setText(i18n("Decrease Volume")); globalAction->setGlobalShortcut(KShortcut(Qt::Key_VolumeDown)); connect(globalAction, SIGNAL(triggered(bool)), SLOT(slotDecreaseVolume())); globalAction = actionCollection()->addAction("mute"); globalAction->setText(i18n("Mute")); globalAction->setGlobalShortcut(KShortcut(Qt::Key_VolumeMute)); connect(globalAction, SIGNAL(triggered(bool)), SLOT(slotMute())); } } */ void KMixD::saveConfig() { kDebug() << "About to save config"; saveBaseConfig(); saveVolumes(); #warning We must Sync here, or we will lose configuration data. The reson for that is unknown. kDebug() << "Saved config ... now syncing explicitly"; KGlobal::config()->sync(); kDebug() << "Saved config ... sync finished"; } void KMixD::saveBaseConfig() { kDebug() << "About to save config (Base)"; KConfigGroup config(KGlobal::config(), "Global"); config.writeEntry( "DefaultCardOnStart", m_defaultCardOnStart ); config.writeEntry( "ConfigVersion", KMIX_CONFIG_VERSION ); config.writeEntry( "AutoUseMultimediaKeys", m_autouseMultimediaKeys ); Mixer* mixerMasterCard = Mixer::getGlobalMasterMixer(); if ( mixerMasterCard != 0 ) { config.writeEntry( "MasterMixer", mixerMasterCard->id() ); } std::shared_ptr mdMaster = Mixer::getGlobalMasterMD(); if ( mdMaster ) { config.writeEntry( "MasterMixerDevice", mdMaster->id() ); } QString mixerIgnoreExpression = MixerToolBox::instance()->mixerIgnoreExpression(); config.writeEntry( "MixerIgnoreExpression", mixerIgnoreExpression ); kDebug() << "Config (Base) saving done"; } /** * Stores the volumes of all mixers Can be restored via loadVolumes() or * the kmixctrl application. */ void KMixD::saveVolumes() { kDebug() << "About to save config (Volume)"; KConfig *cfg = new KConfig( QLatin1String( "kmixctrlrc" ) ); for ( int i=0; iisOpen() ) { // protect from unplugged devices (better do *not* save them) mixer->volumeSave( cfg ); } } cfg->sync(); delete cfg; kDebug() << "Config (Volume) saving done"; } void KMixD::loadConfig() { loadBaseConfig(); //loadViewConfig(); // mw->loadConfig() explicitly called always after creating mw. //loadVolumes(); // not in use } void KMixD::loadBaseConfig() { KConfigGroup config(KGlobal::config(), "Global"); m_multiDriverMode = config.readEntry("MultiDriver", false); m_defaultCardOnStart = config.readEntry( "DefaultCardOnStart", "" ); m_autouseMultimediaKeys = config.readEntry( "AutoUseMultimediaKeys", true ); // currently not in use in kmixd QString mixerMasterCard = config.readEntry( "MasterMixer", "" ); QString masterDev = config.readEntry( "MasterMixerDevice", "" ); //if ( ! mixerMasterCard.isEmpty() && ! masterDev.isEmpty() ) { Mixer::setGlobalMaster(mixerMasterCard, masterDev, true); //} QString mixerIgnoreExpression = config.readEntry( "MixerIgnoreExpression", "Modem" ); m_backendFilter = config.readEntry<>( "Backends", QList() ); MixerToolBox::instance()->setMixerIgnoreExpression(mixerIgnoreExpression); } /** * Loads the volumes of all mixers from kmixctrlrc. * In other words: * Restores the default voumes as stored via saveVolumes() or the * execution of "kmixctrl --save" */ /* Currently this is not in use void KMixD::loadVolumes() { KConfig *cfg = new KConfig( QLatin1String( "kmixctrlrc" ), true ); for ( int i=0; ivolumeLoad( cfg ); } delete cfg; } */ void KMixD::plugged( const char* driverName, const QString& /*udi*/, QString& dev) { // kDebug(67100) << "Plugged: dev=" << dev << "(" << driverName << ") udi=" << udi << "\n"; QString driverNameString; driverNameString = driverName; int devNum = dev.toInt(); Mixer *mixer = new Mixer( driverNameString, devNum ); if ( mixer != 0 ) { kDebug(67100) << "Plugged: dev=" << dev << "\n"; MixerToolBox::instance()->possiblyAddMixer(mixer); } } void KMixD::unplugged( const QString& udi) { // kDebug(67100) << "Unplugged: udi=" <udi() << "\n"; if (mixer->udi() == udi ) { kDebug(67100) << "Unplugged Match: Removing udi=" <removeMixer(mixer); // Check whether the Global Master disappeared, and select a new one if necessary std::shared_ptr md = Mixer::getGlobalMasterMD(); if ( globalMasterMixerDestroyed || md.get() == 0 ) { // We don't know what the global master should be now. // So lets play stupid, and just select the recommended master of the first device if ( Mixer::mixers().count() > 0 ) { std::shared_ptr master = ((Mixer::mixers())[0])->getLocalMasterMD(); if ( master.get() != 0 ) { QString localMaster = master->id(); Mixer::setGlobalMaster( ((Mixer::mixers())[0])->id(), localMaster, false); QString text; text = i18n("The soundcard containing the master device was unplugged. Changing to control %1 on card %2.", master->readableName(), ((Mixer::mixers())[0])->readableName() ); // KMixToolBox::notification("MasterFallback", text); } } } if ( Mixer::mixers().count() == 0 ) { QString text; text = i18n("The last soundcard was unplugged."); // KMixToolBox::notification("MasterFallback", text); } break; } } } #include "moc_kmixd.cpp"