Skip to content
Snippets Groups Projects
main.cc 7.35 KiB
Newer Older
  • Learn to ignore specific revisions
  • /****************************************************************************
     *
     *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
     *
     * QGroundControl is licensed according to the terms in the file
     * COPYING.md in the root of the source code directory.
     *
     ****************************************************************************/
    
    pixhawk's avatar
    pixhawk committed
    
    
    /**
     * @file
     *   @brief Main executable
     *   @author Lorenz Meier <mavteam@student.ethz.ch>
     *
     */
    
    
    #include <QtGlobal>
    
    #include <QApplication>
    
    #include <QIcon>
    
    Don Gagne's avatar
    Don Gagne committed
    #include <QSslSocket>
    
    #include <QProcessEnvironment>
    
    #include <QHostAddress>
    #include <QUdpSocket>
    
    Don Gagne's avatar
    Don Gagne committed
    #include <QtPlugin>
    
    Don Gagne's avatar
    Don Gagne committed
    #include "QGCApplication.h"
    
    #include "AppMessages.h"
    
    #ifndef __mobile__
        #include "QGCSerialPortInfo.h"
    
        #include "RunGuard.h"
    
    #ifdef UNITTEST_BUILD
        #include "UnitTest.h"
    #endif
    
    
    #ifdef QT_DEBUG
    
        #include "CmdLineOptParser.h"
        #ifdef Q_OS_WIN
            #include <crtdbg.h>
        #endif
    
    dogmaphobic's avatar
    dogmaphobic committed
    #ifdef QGC_ENABLE_BLUETOOTH
    
    dogmaphobic's avatar
    dogmaphobic committed
    #include <QtBluetooth/QBluetoothSocket>
    #endif
    
    
    Don Gagne's avatar
    Don Gagne committed
    #include <iostream>
    
    dogmaphobic's avatar
    dogmaphobic committed
    #include "QGCMapEngine.h"
    
    unknown's avatar
    unknown committed
    
    
    /* SDL does ugly things to main() */
    
    #undef main
    
    #ifndef __mobile__
    
        Q_DECLARE_METATYPE(QGCSerialPortInfo)
    
    /// @brief CRT Report Hook installed using _CrtSetReportHook. We install this hook when
    /// we don't want asserts to pop a dialog on windows.
    int WindowsCrtReportHook(int reportType, char* message, int* returnValue)
    {
        Q_UNUSED(reportType);
    
        std::cerr << message << std::endl;  // Output message to stderr
        *returnValue = 0;                   // Don't break into debugger
        return true;                        // We handled this fully ourselves
    }
    
    
    Gus Grubba's avatar
    Gus Grubba committed
    #if defined(__android__) && !defined(NO_SERIAL_LINK)
    
    Don Gagne's avatar
    Don Gagne committed
    #include <jni.h>
    #include "qserialport.h"
    
    jint JNI_OnLoad(JavaVM* vm, void* reserved)
    {
        Q_UNUSED(reserved);
    
        JNIEnv* env;
        if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
            return -1;
        }
    
        QSerialPort::setNativeMethods();
    
        return JNI_VERSION_1_6;
    }
    #endif
    
    
    pixhawk's avatar
    pixhawk committed
    /**
     * @brief Starts the application
     *
     * @param argc Number of commandline arguments
     * @param argv Commandline arguments
     * @return exit code, 0 for normal exit and !=0 for error cases
     */
    
    pixhawk's avatar
    pixhawk committed
    int main(int argc, char *argv[])
    {
    
    #ifndef __mobile__
        RunGuard guard("QGroundControlRunGuardKey");
        if (!guard.tryToRun()) {
            return 0;
        }
    #endif
    
    
    Daniel Agar's avatar
    Daniel Agar committed
        //Force writing to the console on UNIX/BSD devices
    
        if (!qEnvironmentVariableIsSet("QT_LOGGING_TO_CONSOLE"))
            qputenv("QT_LOGGING_TO_CONSOLE", "1");
    #endif
    
    
        // install the message handler
    
    Lorenz Meier's avatar
    Lorenz Meier committed
    #ifdef Q_OS_MAC
    
    #ifndef __ios__
    
        // Prevent Apple's app nap from screwing us over
        // tip: the domain can be cross-checked on the command line with <defaults domains>
        QProcess::execute("defaults write org.qgroundcontrol.qgroundcontrol NSAppSleepDisabled -bool YES");
    
    #endif
    
    Lorenz Meier's avatar
    Lorenz Meier committed
    #endif
    
        // Set our own OpenGL buglist
        qputenv("QT_OPENGL_BUGLIST", ":/opengl/resources/opengl/buglist.json");
    
    
        // Allow for command line override of renderer
        for (int i = 0; i < argc; i++) {
            const QString arg(argv[i]);
            if (arg == QStringLiteral("-angle")) {
                QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
                break;
            } else if (arg == QStringLiteral("-swrast")) {
                QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
                break;
            }
    
    
        // The following calls to qRegisterMetaType are done to silence debug output which warns
        // that we use these types in signals, and without calling qRegisterMetaType we can't queue
        // these signals. In general we don't queue these signals, but we do what the warning says
        // anyway to silence the debug output.
    
    Gus Grubba's avatar
    Gus Grubba committed
    #ifndef NO_SERIAL_LINK
    
        qRegisterMetaType<QSerialPort::SerialPortError>();
    
    dogmaphobic's avatar
    dogmaphobic committed
    #endif
    
    dogmaphobic's avatar
    dogmaphobic committed
    #ifdef QGC_ENABLE_BLUETOOTH
    
    dogmaphobic's avatar
    dogmaphobic committed
        qRegisterMetaType<QBluetoothSocket::SocketError>();
        qRegisterMetaType<QBluetoothServiceInfo>();
    
    dogmaphobic's avatar
    dogmaphobic committed
    #endif
    
        qRegisterMetaType<QAbstractSocket::SocketError>();
    
    #ifndef __mobile__
    
        qRegisterMetaType<QGCSerialPortInfo>();
    
    dogmaphobic's avatar
    dogmaphobic committed
    
        // We statically link our own QtLocation plugin
    
    
    #ifdef Q_OS_WIN
        // In Windows, the compiler doesn't see the use of the class created by Q_IMPORT_PLUGIN
    #pragma warning( disable : 4930 4101 )
    #endif
    
    
        Q_IMPORT_PLUGIN(QGeoServiceProviderFactoryQGC)
    
    Don Gagne's avatar
    Don Gagne committed
        bool runUnitTests = false;          // Run unit tests
    
    #ifdef QT_DEBUG
    
        // We parse a small set of command line options here prior to QGCApplication in order to handle the ones
    
        // which need to be handled before a QApplication object is started.
    
    Don Gagne's avatar
    Don Gagne committed
        bool stressUnitTests = false;       // Stress test unit tests
    
        bool quietWindowsAsserts = false;   // Don't let asserts pop dialog boxes
    
        QString unitTestOptions;
    
        CmdLineOpt_t rgCmdLineOptions[] = {
    
            { "--unittest",             &runUnitTests,          &unitTestOptions },
    
            { "--unittest-stress",      &stressUnitTests,       &unitTestOptions },
    
            { "--no-windows-assert-ui", &quietWindowsAsserts,   NULL },
    
            // Add additional command line option flags here
        };
    
        ParseCmdLineOptions(argc, argv, rgCmdLineOptions, sizeof(rgCmdLineOptions)/sizeof(rgCmdLineOptions[0]), false);
    
        if (stressUnitTests) {
            runUnitTests = true;
        }
    
        if (quietWindowsAsserts) {
    #ifdef Q_OS_WIN
            _CrtSetReportHook(WindowsCrtReportHook);
    #endif
        }
    
    
    #ifdef Q_OS_WIN
        if (runUnitTests) {
            // Don't pop up Windows Error Reporting dialog when app crashes. This prevents TeamCity from
            // hanging.
            DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
            SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
        }
    
    #endif // QT_DEBUG
    
    Don Gagne's avatar
    Don Gagne committed
        QGCApplication* app = new QGCApplication(argc, argv, runUnitTests);
    
        Q_CHECK_PTR(app);
    
    #ifdef Q_OS_LINUX
        QApplication::setWindowIcon(QIcon(":/res/resources/icons/qgroundcontrol.ico"));
    #endif /* Q_OS_LINUX */
    
    
        // There appears to be a threading issue in qRegisterMetaType which can cause it to throw a qWarning
        // about duplicate type converters. This is caused by a race condition in the Qt code. Still working
        // with them on tracking down the bug. For now we register the type which is giving us problems here
        // while we only have the main thread. That should prevent it from hitting the race condition later
        // on in the code.
        qRegisterMetaType<QList<QPair<QByteArray,QByteArray> > >();
    
        app->_initCommon();
    
    dogmaphobic's avatar
    dogmaphobic committed
        //-- Initialize Cache System
        getQGCMapEngine()->init();
    
        int exitCode = 0;
    
    #ifdef UNITTEST_BUILD
    
        if (runUnitTests) {
    
            for (int i=0; i < (stressUnitTests ? 20 : 1); i++) {
                if (!app->_initForUnitTests()) {
                    return -1;
                }
    
                // Run the test
                int failures = UnitTest::run(unitTestOptions);
                if (failures == 0) {
                    qDebug() << "ALL TESTS PASSED";
                    exitCode = 0;
                } else {
                    qDebug() << failures << " TESTS FAILED!";
                    exitCode = -failures;
                    break;
                }
    
        {
            if (!app->_initForNormalAppBoot()) {
                return -1;
            }
    
    Don Gagne's avatar
    Don Gagne committed
            exitCode = app->exec();
    
    Don Gagne's avatar
    Don Gagne committed
        delete app;
    
    dogmaphobic's avatar
    dogmaphobic committed
        //-- Shutdown Cache System
        destroyMapEngine();
    
    Don Gagne's avatar
    Don Gagne committed
        qDebug() << "After app delete";
    
    Don Gagne's avatar
    Don Gagne committed
        return exitCode;
    
    pixhawk's avatar
    pixhawk committed
    }