drumstick  1.0.2
backendmanager.cpp
Go to the documentation of this file.
00001 /*
00002     Drumstick RT (realtime MIDI In/Out)
00003     Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl@users.sf.net>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License along
00016     with this program; if not, write to the Free Software Foundation, Inc.,
00017     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018 */
00019 
00020 #include <QtGlobal>
00021 #include <QDir>
00022 #include <QPluginLoader>
00023 #include <QCoreApplication>
00024 #include <QLibraryInfo>
00025 #include "backendmanager.h"
00026 
00027 #if defined(ALSA_BACKEND)
00028 Q_IMPORT_PLUGIN(ALSAMIDIInput)
00029 Q_IMPORT_PLUGIN(ALSAMIDIOutput)
00030 #endif
00031 
00032 #if defined(MAC_BACKEND)
00033 Q_IMPORT_PLUGIN(MacMIDIInput)
00034 Q_IMPORT_PLUGIN(MacMIDIOutput)
00035 #endif
00036 
00037 #if defined(WIN_BACKEND)
00038 Q_IMPORT_PLUGIN(WinMIDIInput)
00039 Q_IMPORT_PLUGIN(WinMIDIOutput)
00040 #endif
00041 
00042 #if defined(NET_BACKEND)
00043 Q_IMPORT_PLUGIN(NetMIDIInput)
00044 Q_IMPORT_PLUGIN(NetMIDIOutput)
00045 #endif
00046 
00047 #if defined(DUMMY_BACKEND)
00048 Q_IMPORT_PLUGIN(DummyInput)
00049 Q_IMPORT_PLUGIN(DummyOutput)
00050 #endif
00051 
00052 #if defined(SYNTH_BACKEND)
00053 Q_IMPORT_PLUGIN(SynthOutput)
00054 #endif
00055 
00056 #if defined(OSS_BACKEND)
00057 Q_IMPORT_PLUGIN(OSSInput)
00058 Q_IMPORT_PLUGIN(OSSOutput)
00059 #endif
00060 
00066 namespace drumstick {
00067 namespace rt {
00068 
00069 
00087     class BackendManager::BackendManagerPrivate {
00088     public:
00089         QList<MIDIInput*> m_inputsList;
00090         QList<MIDIOutput*> m_outputsList;
00091         ~BackendManagerPrivate()
00092         {
00093             clearLists();
00094         }
00095         void clearLists()
00096         {
00097             m_inputsList.clear();
00098             m_outputsList.clear();
00099         }
00100         void appendDir(const QString& candidate, QStringList& result)
00101         {
00102             //qDebug() << "testing " << candidate;
00103             QDir checked(candidate);
00104             if (checked.exists() && !result.contains(checked.absolutePath())) {
00105                 result << checked.absolutePath();
00106             }
00107         }
00108     };
00109 
00113     BackendManager::BackendManager(): d(new BackendManagerPrivate)
00114     {
00115         refresh();
00116     }
00117 
00121     BackendManager::~BackendManager()
00122     {
00123         delete d;
00124     }
00125 
00130     QStringList BackendManager::defaultPaths()
00131     {
00132         QStringList result;
00133         QString appPath = QCoreApplication::applicationDirPath() + QDir::separator();
00134     #if defined(Q_OS_WIN)
00135         d->appendDir( appPath + QSTR_DRUMSTICK, result );
00136     #elif defined(Q_OS_MAC)
00137         d->appendDir( appPath + QStringLiteral("../PlugIns/") + QSTR_DRUMSTICK, result );
00138     #else // Linux, Unix...
00139         QStringList libs;
00140         libs << "../lib/" << "../lib32/" << "../lib64/";
00141         foreach(const QString& lib, libs) {
00142             d->appendDir( appPath + lib + QSTR_DRUMSTICK, result );
00143         }
00144     #endif
00145         d->appendDir( appPath + ".." + QDir::separator() + QSTR_DRUMSTICK, result );
00146         QByteArray envdir = qgetenv(QSTR_DRUMSTICKRT.toLatin1());
00147         if(!envdir.isEmpty()) {
00148             d->appendDir(QString(envdir), result );
00149         }
00150         d->appendDir( QDir::homePath() + QDir::separator() + QSTR_DRUMSTICK, result );
00151         d->appendDir( QLibraryInfo::location(QLibraryInfo::PluginsPath) + QDir::separator() + QSTR_DRUMSTICK, result );
00152         foreach(const QString& path, QCoreApplication::libraryPaths()) {
00153             d->appendDir( path + QDir::separator() + QSTR_DRUMSTICK, result );
00154         }
00155         return result;
00156     }
00157 
00163     void BackendManager::refresh(QSettings *settings)
00164     {
00165         QString name_in;
00166         QString name_out;
00167         QStringList names;
00168         QStringList paths;
00169 
00170         if (settings != 0) {
00171             settings->beginGroup(QSTR_DRUMSTICKRT_GROUP);
00172             d->appendDir(settings->value(QSTR_DRUMSTICKRT_PATH).toString(), paths);
00173             name_in = settings->value(QSTR_DRUMSTICKRT_PUBLICNAMEIN).toString();
00174             name_out = settings->value(QSTR_DRUMSTICKRT_PUBLICNAMEOUT).toString();
00175             names << settings->value(QSTR_DRUMSTICKRT_EXCLUDED).toStringList();
00176             names << name_in;
00177             names << name_out;
00178             settings->endGroup();
00179         }
00180         paths << defaultPaths();
00181         d->clearLists();
00182 
00183         // Dynamic backends
00184         foreach(const QString& dir, paths) {
00185             QDir pluginsDir(dir);
00186             foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
00187                 if (QLibrary::isLibrary(fileName)) {
00188                     QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
00189                     QObject *obj = loader.instance();
00190                     if (obj != 0) {
00191                         MIDIInput *input = qobject_cast<MIDIInput*>(obj);
00192                         if (input != 0 && !d->m_inputsList.contains(input)) {
00193                             input->setPublicName(name_in);
00194                             input->setExcludedConnections(names);
00195                             d->m_inputsList << input;
00196                         } else {
00197                             MIDIOutput *output = qobject_cast<MIDIOutput*>(obj);
00198                             if (output != 0 && !d->m_outputsList.contains(output)) {
00199                                 output->setPublicName(name_out);
00200                                 output->setExcludedConnections(names);
00201                                 d->m_outputsList << output;
00202                             }
00203                         }
00204                     }
00205                 }
00206             }
00207         }
00208 
00209         // Static backends
00210         foreach(QObject* obj, QPluginLoader::staticInstances()) {
00211             if (obj != 0) {
00212                 MIDIInput *input = qobject_cast<MIDIInput*>(obj);
00213                 if (input != 0 && !d->m_inputsList.contains(input)) {
00214                     input->setPublicName(name_in);
00215                     input->setExcludedConnections(names);
00216                     d->m_inputsList << input;
00217                 } else {
00218                     MIDIOutput *output = qobject_cast<MIDIOutput*>(obj);
00219                     if (output != 0 && !d->m_outputsList.contains(output)) {
00220                         output->setPublicName(name_out);
00221                         output->setExcludedConnections(names);
00222                         d->m_outputsList << output;
00223                     }
00224                 }
00225             }
00226         }
00227     }
00228 
00229     QList<MIDIInput*> BackendManager::availableInputs()
00230     {
00231         return d->m_inputsList;
00232     }
00233 
00234     QList<MIDIOutput*> BackendManager::availableOutputs()
00235     {
00236         return d->m_outputsList;
00237     }
00238 
00239 }}