Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/main.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           main.cpp  -  description
00003                              -------------------
00004     begin                : Mon Feb 18 09:48:17 CET 2002
00005     copyright            : (C) 2002 by Tue and Ken Haste Andersen
00006     email                :
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010 *                                                                         *
00011 *   This program is free software; you can redistribute it and/or modify  *
00012 *   it under the terms of the GNU General Public License as published by  *
00013 *   the Free Software Foundation; either version 2 of the License, or     *
00014 *   (at your option) any later version.                                   *
00015 *                                                                         *
00016 ***************************************************************************/
00017 
00018 #include <qapplication.h>
00019 #include <qfont.h>
00020 #include <qstring.h>
00021 #include <qtextcodec.h>
00022 #include <qtranslator.h>
00023 #include <qmessagebox.h>
00024 #include <qiodevice.h>
00025 #include <qfile.h>
00026 #include <qstringlist.h>
00027 #include <stdio.h>
00028 #include <math.h>
00029 #include "mixxx.h"
00030 #include "soundsourceproxy.h"
00031 #include "qpixmap.h"
00032 #include "qsplashscreen.h"
00033 #include "errordialoghandler.h"
00034 #include "defs_version.h"
00035 
00036 #ifdef __LADSPA__
00037 #include <ladspa/ladspaloader.h>
00038 #endif
00039 
00040 #ifdef __WINDOWS__
00041 #ifdef DEBUGCONSOLE
00042 #include <io.h> // Debug Console
00043 #include <windows.h>
00044 
00045 void InitDebugConsole() { // Open a Debug Console so we can printf
00046     int fd;
00047     FILE *fp;
00048 
00049     FreeConsole();
00050     if (AllocConsole()) {
00051         SetConsoleTitleA("Mixxx Debug Messages");
00052 
00053         fd = _open_osfhandle((long) GetStdHandle(STD_OUTPUT_HANDLE), 0);
00054         fp = _fdopen(fd, "w");
00055 
00056         *stdout = *fp;
00057         setvbuf(stdout, NULL, _IONBF, 0);
00058 
00059         fd = _open_osfhandle((long) GetStdHandle(STD_ERROR_HANDLE), 0);
00060         fp = _fdopen(fd, "w");
00061 
00062         *stderr = *fp;
00063         setvbuf(stderr, NULL, _IONBF, 0);
00064     }
00065 }
00066 #endif // DEBUGCONSOLE
00067 #endif // __WINDOWS__
00068 
00069 QApplication *a;
00070 
00071 QStringList plugin_paths; //yes this is global. sometimes global is good.
00072 
00073 //void qInitImages_mixxx();
00074 
00075 QFile Logfile; // global logfile variable
00076 
00077 /* Debug message handler which outputs to both a logfile and a
00078  * and prepends the thread the message came from too.
00079  */
00080 void MessageHandler(QtMsgType type, const char *input)
00081 {
00082     static QMutex mutex;
00083     QMutexLocker locker(&mutex);
00084     QByteArray ba;
00085     ba = "[" + QThread::currentThread()->objectName().toLocal8Bit() + "]: " + input + "\n";
00086 
00087     if(!Logfile.isOpen())
00088     {
00089         QString logFileName = QDir::homePath().append("/").append(SETTINGS_PATH).append("/mixxx.log");
00090 
00091         // XXX will there ever be a case that we can't write to our current
00092         // working directory?
00093         Logfile.setFileName(logFileName);
00094         Logfile.open(QIODevice::WriteOnly | QIODevice::Text);
00095     }
00096 
00097     ErrorDialogHandler* dialogHandler = ErrorDialogHandler::instance();
00098 
00099     switch (type) {
00100     case QtDebugMsg:
00101 #ifdef __WINDOWS__  //wtf? -kousu 2/2009
00102         if (strstr(input, "doneCurrent")) {
00103             break;
00104         }
00105 #endif
00106         fprintf(stderr, "Debug %s", ba.constData());
00107         Logfile.write("Debug ");
00108         Logfile.write(ba);
00109         break;
00110     case QtWarningMsg:
00111         fprintf(stderr, "Warning %s", ba.constData());
00112         Logfile.write("Warning ");
00113         Logfile.write(ba);
00114         // Don't use qWarning for reporting user-facing errors.
00115         //dialogHandler->requestErrorDialog(DLG_WARNING,input);
00116         break;
00117     case QtCriticalMsg:
00118         fprintf(stderr, "Critical %s", ba.constData());
00119         Logfile.write("Critical ");
00120         Logfile.write(ba);
00121         Logfile.flush();    // Ensure the error is written to the log before exiting
00122         dialogHandler->requestErrorDialog(DLG_CRITICAL,input);
00123 //         exit(-1);    // Done in ErrorDialogHandler
00124         break; //NOTREACHED
00125     case QtFatalMsg:
00126         fprintf(stderr, "Fatal %s", ba.constData());
00127         Logfile.write("Fatal ");
00128         Logfile.write(ba);
00129         Logfile.flush();    // Ensure the error is written to the log before aborting
00130         dialogHandler->requestErrorDialog(DLG_FATAL,input);
00131 //         abort();    // Done in ErrorDialogHandler
00132         break; //NOTREACHED
00133     }
00134     Logfile.flush();
00135 }
00136 
00137 int main(int argc, char * argv[])
00138 {
00139     // Check if an instance of Mixxx is already running
00140     // See http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Utilities/qtsingleapplication
00141 
00142     // These need to be set early on (not sure how early) in order to trigger
00143     // logic in the OS X appstore support patch from QTBUG-16549.
00144     QCoreApplication::setOrganizationDomain("mixxx.org");
00145     QCoreApplication::setOrganizationName("Mixxx");
00146 
00147 //it seems like this code should be inline in MessageHandler() but for some reason having it there corrupts the messages sometimes -kousu 2/2009
00148 
00149 
00150 #ifdef __WINDOWS__
00151   #ifdef DEBUGCONSOLE
00152     InitDebugConsole();
00153   #endif
00154 #endif
00155     qInstallMsgHandler(MessageHandler);
00156 
00157     // Other things depend on this name to enforce thread exclusivity,
00158     //  so if you change it here, change it also in:
00159     //      * ErrorDialogHandler::errorDialog()
00160     QThread::currentThread()->setObjectName("Main");
00161     QApplication a(argc, argv);
00162 
00163     //Enumerate and load SoundSource plugins
00164     SoundSourceProxy::loadPlugins();
00165 #ifdef __LADSPA__
00166     //LADSPALoader ladspaloader;
00167 #endif
00168 
00169     // Check if one of the command line arguments is "--no-visuals"
00170 //    bool bVisuals = true;
00171 //    for (int i=0; i<argc; ++i)
00172 //        if(QString("--no-visuals")==argv[i])
00173 //            bVisuals = false;
00174 
00175     // Construct a list of strings based on the command line arguments
00176     struct CmdlineArgs args;
00177     args.bStartInFullscreen = false; //Initialize vars
00178 
00179     // Only match supported file types since command line options are also parsed elsewhere
00180     QRegExp fileRx(SoundSourceProxy::supportedFileExtensionsRegex(), Qt::CaseInsensitive);
00181 
00182    for (int i = 0; i < argc; ++i) {
00183        if (   argv[i] == QString("-h")
00184             || argv[i] == QString("--h")
00185             || argv[i] == QString("--help")
00186     ) {
00187            fputs("Mixxx digital DJ software v",stdout);
00188            fputs(VERSION,stdout);
00189            fputs(" - Command line options",stdout);
00190            fputs(
00191                    "\n(These are case-sensitive.)\n\n\
00192     [FILE]                  Load the specified music file(s) at start-up.\n\
00193                             Each must be one of the following file types:\n\
00194                             ",stdout);
00195 
00196             QString fileExtensions = SoundSourceProxy::supportedFileExtensionsString();
00197             QByteArray fileExtensionsBA = QString(fileExtensions).toUtf8();
00198             fputs(fileExtensionsBA.constData(),stdout);
00199             fputs("\n\n",stdout);
00200             fputs("\
00201                             Each file you specify will be loaded into the\n\
00202                             next virtual deck.\n\
00203 \n\
00204     --resourcePath PATH     Top-level directory where Mixxx should look\n\
00205                             for its resource files such as MIDI mappings,\n\
00206                             overriding the default installation location.\n\
00207 \n\
00208     --pluginPath PATH       Top-level directory where Mixxx shoud look\n\
00209                             for sound source plugins in addition to default\n\
00210                             locations.\n\
00211 \n\
00212     --midiDebug             Causes Mixxx to display/log all of the MIDI\n\
00213                             messages it receives and script functions it loads\n\
00214 \n\
00215     --locale LOCALE         Use a custom locale for loading translations\n\
00216                             (e.g 'fr')\n\
00217 \n\
00218     -f, --fullScreen        Starts Mixxx in full-screen mode\n\
00219 \n\
00220     -h, --help              Display this help message and exit",stdout);
00221 
00222             fputs("\n\n(For more information, see http://mixxx.org/wiki/doku.php/command_line_options)\n",stdout);
00223             return(0);
00224         }
00225 
00226         if (argv[i]==QString("-f").toLower() || argv[i]==QString("--f") || argv[i]==QString("--fullScreen"))
00227         {
00228             args.bStartInFullscreen = true;
00229         } else if (argv[i] == QString("--locale") && i+1 < argc) {
00230             args.locale = argv[i+1];
00231         } else if (fileRx.indexIn(argv[i]) != -1) {
00232             args.qlMusicFiles += argv[i];
00233         }
00234     }
00235 
00236     // set up the plugin paths...
00237     /*
00238     qDebug() << "Setting up plugin paths...";
00239     plugin_paths = QStringList();
00240     QString ladspaPath = QString(getenv("LADSPA_PATH"));
00241 
00242     if (!ladspaPath.isEmpty())
00243     {
00244         // get the list of directories containing LADSPA plugins
00245 #ifdef __WINDOWS__
00246         //paths.ladspaPath.split(';');
00247 #else  //this doesn't work, I think we need to iterate over the splitting to do it properly
00248         //paths = ladspaPath.split(':');
00249 #endif
00250     }
00251     else
00252     {
00253         // add default path if LADSPA_PATH is not set
00254 #ifdef __LINUX__
00255         plugin_paths.push_back ("/usr/lib/ladspa/");
00256         plugin_paths.push_back ("/usr/lib64/ladspa/");
00257 #elif __APPLE__
00258       QDir dir(a.applicationDirPath());
00259      dir.cdUp();
00260      dir.cd("PlugIns");
00261          plugin_paths.push_back ("/Library/Audio/Plug-ins/LADSPA");
00262          plugin_paths.push_back (dir.absolutePath()); //ladspa_plugins directory in Mixxx.app bundle //XXX work in QApplication::appdir()
00263 #elif __WINDOWS__
00264         // not tested yet but should work:
00265         QString programFiles = QString(getenv("ProgramFiles"));
00266          plugin_paths.push_back (programFiles+"\\LADSPA Plugins");
00267          plugin_paths.push_back (programFiles+"\\Audacity\\Plug-Ins");
00268 #endif
00269     }
00270     qDebug() << "...done.";
00271     */
00272 
00273 
00274 #ifdef __APPLE__
00275      QDir dir(QApplication::applicationDirPath());
00276      // Set the search path for Qt plugins to be in the bundle's PlugIns
00277      // directory, but only if we think the mixxx binary is in a bundle.
00278      if (dir.path().contains(".app/")) {
00279          // If in a bundle, applicationDirPath() returns something formatted
00280          // like: .../Mixxx.app/Contents/MacOS
00281          dir.cdUp();
00282          dir.cd("PlugIns");
00283          qDebug() << "Setting Qt plugin search path to:" << dir.absolutePath();
00284          // asantoni: For some reason we need to do setLibraryPaths() and not
00285          // addLibraryPath(). The latter causes weird problems once the binary
00286          // is bundled (happened with 1.7.2 when Brian packaged it up).
00287          QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
00288      }
00289 #endif
00290 
00291     MixxxApp* mixxx = new MixxxApp(&a, args);
00292 
00293     //a.setMainWidget(mixxx);
00294     QObject::connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
00295 
00296     int result = -1;
00297 
00298     if (!(ErrorDialogHandler::instance()->checkError())) {
00299         qDebug() << "Displaying mixxx";
00300         mixxx->show();
00301 
00302         qDebug() << "Running Mixxx";
00303         result = a.exec();
00304     }
00305 
00306     delete mixxx;
00307 
00308     qDebug() << "Mixxx shutdown complete with code" << result;
00309 
00310     qInstallMsgHandler(0); //Reset to default.
00311 
00312     // Don't make any more output after this
00313     //    or mixxx.log will get clobbered!
00314     if(Logfile.isOpen()) {
00315         Logfile.close();
00316     }
00317 
00318     //delete plugin_paths;
00319     return result;
00320 }
00321 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines