X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2FStartup.cpp;h=4795a2b76292e5934afe3b91d3db7ccd600f3a26;hb=96eaf7ddccfd1928dd1a00b8aa0858b6bb27d744;hp=d1bea2734d5addd8fe19fbda14868734bed065a5;hpb=c3a7afa5093f3611d1f019aeaebc996b45421f8a;p=mutilities%2FMUtilities.git diff --git a/src/Startup.cpp b/src/Startup.cpp index d1bea27..4795a2b 100644 --- a/src/Startup.cpp +++ b/src/Startup.cpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // MuldeR's Utilities for Qt -// Copyright (C) 2004-2014 LoRd_MuldeR +// Copyright (C) 2004-2017 LoRd_MuldeR // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -24,6 +24,7 @@ #include #include #include +#include #include //Qt @@ -36,6 +37,22 @@ #include #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +#include +#else +#define QAbstractNativeEventFilter QObject +#define Q_DECL_OVERRIDE +#endif + +//CRT +#include + +//MSVC +#if defined(_MSC_VER) +#define FORCE_INLINE __forceinline +#else +#define FORCE_INLINE inline +#endif /////////////////////////////////////////////////////////////////////////////// // Qt Static Initialization @@ -92,38 +109,85 @@ namespace MUtils // MESSAGE HANDLER /////////////////////////////////////////////////////////////////////////////// -static void qt_message_handler(QtMsgType type, const char *msg) +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) +static void qt_message_handler(QtMsgType type, const char *const msg) { - if((!msg) || (!(msg[0]))) + if (msg && msg[0]) { - return; + MUtils::Terminal::write(type, msg); + if ((type == QtCriticalMsg) || (type == QtFatalMsg)) + { + MUtils::OS::fatal_exit(MUTILS_WCHR(QString::fromUtf8(msg))); + } } - - MUtils::Terminal::write(type, msg); - - if((type == QtCriticalMsg) || (type == QtFatalMsg)) +} +#else +#define qInstallMsgHandler(X) qInstallMessageHandler((X)) +static void qt_message_handler(QtMsgType type, const QMessageLogContext&, const QString &msg) +{ + if (!msg.isEmpty()) { - MUtils::OS::fatal_exit(MUTILS_WCHR(QString::fromUtf8(msg))); + MUtils::Terminal::write(type, msg.toUtf8().constData()); + if ((type == QtCriticalMsg) || (type == QtFatalMsg)) + { + MUtils::OS::fatal_exit(MUTILS_WCHR(msg)); + } } } +#endif + +/////////////////////////////////////////////////////////////////////////////// +// EVENT FILTER +/////////////////////////////////////////////////////////////////////////////// -static bool qt_event_filter(void *message, long *result) +namespace MUtils { - return MUtils::OS::handle_os_message(message, result); + namespace Startup + { + namespace Internal + { + class NativeEventFilter : public QAbstractNativeEventFilter + { + public: + bool nativeEventFilter(const QByteArray&, void *message, long *result) Q_DECL_OVERRIDE + { + return filterEvent(message, result); + }; + + static FORCE_INLINE bool filterEvent(void *message, long *result) + { + return MUtils::OS::handle_os_message(message, result); + } + + static NativeEventFilter *instance(void) + { + while (m_instance.isNull()) + { + m_instance.reset(new NativeEventFilter()); + } + return m_instance.data(); + } + + private: + NativeEventFilter(void) {} + static QScopedPointer m_instance; + }; + } + } } /////////////////////////////////////////////////////////////////////////////// // STARTUP FUNCTION /////////////////////////////////////////////////////////////////////////////// -static int startup_main(int &argc, char **argv, MUtils::Startup::main_function_t *const entry_point, const char* const appName, const bool &debugConsole) +static FORCE_INLINE int startup_main(int &argc, char **argv, MUtils::Startup::main_function_t *const entry_point, const char* const appName, const bool &debugConsole) { qInstallMsgHandler(qt_message_handler); MUtils::Terminal::setup(argc, argv, appName, MUTILS_DEBUG || debugConsole); return entry_point(argc, argv); } -static int startup_helper(int &argc, char **argv, MUtils::Startup::main_function_t *const entry_point, const char* const appName, const bool &debugConsole) +static FORCE_INLINE int startup_helper(int &argc, char **argv, MUtils::Startup::main_function_t *const entry_point, const char* const appName, const bool &debugConsole) { int iResult = -1; try @@ -180,37 +244,44 @@ int MUtils::Startup::startup(int &argc, char **argv, main_function_t *const entr static QMutex g_init_lock; static const char *const g_imageformats[] = {"bmp", "png", "jpg", "gif", "ico", "xpm", "svg", NULL}; -static QString getExecutableName(int &argc, char **argv) +static FORCE_INLINE QString getExecutableName(int &argc, char **argv) { if(argc >= 1) { const char *argv0 = argv[0]; - if(const char *const ptr = strrchr(argv0, '/')) - { - argv0 = ptr + 1; - } - if(const char *const ptr = strrchr(argv0, '\\')) + for (int i = 0; i < 2; i++) { - argv0 = ptr + 1; + static const char SEP[2] = { '/', '\\' }; + if (const char *const ptr = strrchr(argv0, SEP[i])) + { + argv0 = ptr + 1; + } } if(strlen(argv0) > 1) { - QString::fromLatin1(argv0); + return QString::fromLatin1(argv0); } } return QLatin1String("Program.exe"); } -QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString &appName) +static FORCE_INLINE void qt_registry_cleanup(void) +{ + static const wchar_t *const QT_JUNK_KEY = L"Software\\Trolltech\\OrganizationDefaults"; + MUtils::Registry::reg_key_delete(MUtils::Registry::root_user, MUTILS_QSTR(QT_JUNK_KEY), true, true); +} + +QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString &appName, const QString &appAuthor, const QString &appDomain) { QMutexLocker lock(&g_init_lock); const OS::ArgumentMap &arguments = MUtils::OS::arguments(); //Don't initialized again, if done already - if(QApplication::instance() != NULL) + QScopedPointer application(dynamic_cast(QApplication::instance())); + if(!application.isNull()) { qWarning("Qt is already initialized!"); - return NULL; + return application.take(); } //Extract executable name from argv[] array @@ -219,7 +290,7 @@ QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString & //Check Qt version #ifdef QT_BUILD_KEY qDebug("Using Qt v%s [%s], %s, %s", qVersion(), QLibraryInfo::buildDate().toString(Qt::ISODate).toLatin1().constData(), (qSharedBuild() ? "DLL" : "Static"), QLibraryInfo::buildKey().toLatin1().constData()); - qDebug("Compiled with Qt v%s [%s], %s\n", QT_VERSION_STR, QT_PACKAGEDATE_STR, QT_BUILD_KEY); + qDebug("Compiled with Qt v%s, %s\n", QT_VERSION_STR, QT_BUILD_KEY); if(_stricmp(qVersion(), QT_VERSION_STR)) { qFatal("%s", QApplication::tr("Executable '%1' requires Qt v%2, but found Qt v%3.").arg(executableName, QString::fromLatin1(QT_VERSION_STR), QString::fromLatin1(qVersion())).toLatin1().constData()); @@ -232,11 +303,10 @@ QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString & } #else qDebug("Using Qt v%s [%s], %s", qVersion(), QLibraryInfo::buildDate().toString(Qt::ISODate).toLatin1().constData(), (qSharedBuild() ? "DLL" : "Static")); - qDebug("Compiled with Qt v%s [%s]\n", QT_VERSION_STR, QT_PACKAGEDATE_STR); + qDebug("Compiled with Qt v%s\n", QT_VERSION_STR); #endif //Check the Windows version - const MUtils::OS::Version::os_version_t &osVersion = MUtils::OS::os_version(); if((osVersion.type != MUtils::OS::Version::OS_WINDOWS) || (osVersion < MUtils::OS::Version::WINDOWS_WINXP)) { @@ -246,13 +316,13 @@ QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString & //Check whether we are running on a supported Windows version if(const char *const friendlyName = MUtils::OS::os_friendly_name(osVersion)) { - qDebug("Running on %s (NT v%u.%u).\n", friendlyName, osVersion.versionMajor, osVersion.versionMinor); + qDebug("Running on %s (NT v%u.%u.%u).\n", friendlyName, osVersion.versionMajor, osVersion.versionMinor, osVersion.versionBuild); } else { - const QString message = QString().sprintf("Running on an unknown WindowsNT-based system (v%u.%u).", osVersion.versionMajor, osVersion.versionMinor); + const QString message = QString().sprintf("Running on an unknown WindowsNT-based system (v%u.%u.%u).", osVersion.versionMajor, osVersion.versionMinor, osVersion.versionBuild); qWarning("%s\n", MUTILS_UTF8(message)); - MUtils::OS::system_message_wrn(MUTILS_WCHR(message), L"LameXP"); + MUtils::OS::system_message_wrn(MUTILS_WCHR(executableName), MUTILS_WCHR(message)); } //Check for compat mode @@ -276,7 +346,10 @@ QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString & QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); //Create Qt application instance - QApplication *application = new QApplication(argc, argv); + application.reset(new QApplication(argc, argv)); + + //Register the Qt clean-up function + atexit(qt_registry_cleanup); //Load plugins from application directory QCoreApplication::setLibraryPaths(QStringList() << QApplication::applicationDirPath()); @@ -284,9 +357,13 @@ QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString & //Set application properties application->setApplicationName(appName); - application->setOrganizationName("LoRd_MuldeR"); - application->setOrganizationDomain("mulder.at.gg"); - application->setEventFilter(qt_event_filter); + application->setOrganizationDomain(appDomain); + application->setOrganizationName(appAuthor); +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + application->setEventFilter(&Internal::NativeEventFilter::filterEvent); +#else + application->installNativeEventFilter(Internal::NativeEventFilter::instance()); +#endif //Check for supported image formats QList supportedFormats = QImageReader::supportedImageFormats(); @@ -295,7 +372,6 @@ QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString & if(!supportedFormats.contains(g_imageformats[i])) { qFatal("Qt initialization error: QImageIOHandler for '%s' missing!", g_imageformats[i]); - MUTILS_DELETE(application); return NULL; } } @@ -320,18 +396,17 @@ QApplication *MUtils::Startup::create_qt(int &argc, char **argv, const QString & //Check for process elevation if(MUtils::OS::is_elevated() && (!MUtils::OS::running_on_wine())) { - QMessageBox messageBox(QMessageBox::Warning, "LameXP", "LameXP was started with 'elevated' rights, altough LameXP does not need these rights.
Running an applications with unnecessary rights is a potential security risk!
", QMessageBox::NoButton, NULL, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint); + QMessageBox messageBox(QMessageBox::Warning, executableName, "This program was started with 'elevated' rights, altough it does not need these rights.
Running an applications with unnecessary rights is a potential security risk!
", QMessageBox::NoButton, NULL, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint); messageBox.addButton("Quit Program (Recommended)", QMessageBox::NoRole); messageBox.addButton("Ignore", QMessageBox::NoRole); if(messageBox.exec() == 0) { - MUTILS_DELETE(application); return NULL; } } - //Qt created successfully - return application; + //QApplication created successfully + return application.take(); } ///////////////////////////////////////////////////////////////////////////////