2014-11-26 02:37:08 +01:00
///////////////////////////////////////////////////////////////////////////////
// MuldeR's Utilities for Qt
// Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
// http://www.gnu.org/licenses/lgpl-2.1.txt
//////////////////////////////////////////////////////////////////////////////////
//MUtils
# include <MUtils/Startup.h>
# include <MUtils/OSSupport.h>
# include <MUtils/Terminal.h>
# include <MUtils/ErrorHandler.h>
# include <MUtils/Exception.h>
//Qt
2014-11-29 01:22:46 +01:00
# include <QApplication>
# include <QMutex>
# include <QStringList>
# include <QLibraryInfo>
# include <QTextCodec>
# include <QImageReader>
# include <QFont>
# include <QMessageBox>
2014-11-26 02:37:08 +01:00
///////////////////////////////////////////////////////////////////////////////
// MESSAGE HANDLER
///////////////////////////////////////////////////////////////////////////////
static void qt_message_handler ( QtMsgType type , const char * msg )
{
if ( ( ! msg ) | | ( ! ( msg [ 0 ] ) ) )
{
return ;
}
MUtils : : Terminal : : write ( type , msg ) ;
if ( ( type = = QtCriticalMsg ) | | ( type = = QtFatalMsg ) )
{
MUtils : : OS : : fatal_exit ( MUTILS_WCHR ( QString : : fromUtf8 ( msg ) ) ) ;
}
}
2014-11-29 01:22:46 +01:00
static bool qt_event_filter ( void * message , long * result )
{
return MUtils : : OS : : handle_os_message ( message , result ) ;
}
2014-11-26 02:37:08 +01:00
///////////////////////////////////////////////////////////////////////////////
// STARTUP FUNCTION
///////////////////////////////////////////////////////////////////////////////
2014-12-21 17:19:04 +01:00
static int startup_main ( int & argc , char * * argv , MUtils : : Startup : : main_function_t * const entry_point , const char * const appName , const bool & debugConsole )
2014-11-26 02:37:08 +01:00
{
qInstallMsgHandler ( qt_message_handler ) ;
2014-12-21 17:19:04 +01:00
MUtils : : Terminal : : setup ( argc , argv , appName , MUTILS_DEBUG | | debugConsole ) ;
2014-11-26 02:37:08 +01:00
return entry_point ( argc , argv ) ;
}
2014-12-21 17:19:04 +01:00
static int startup_helper ( int & argc , char * * argv , MUtils : : Startup : : main_function_t * const entry_point , const char * const appName , const bool & debugConsole )
2014-11-26 02:37:08 +01:00
{
int iResult = - 1 ;
try
{
2014-12-21 17:19:04 +01:00
iResult = startup_main ( argc , argv , entry_point , appName , debugConsole ) ;
2014-11-26 02:37:08 +01:00
}
catch ( const std : : exception & error )
{
MUTILS_PRINT_ERROR ( " \n GURU MEDITATION !!! \n \n Exception error: \n %s \n " , error . what ( ) ) ;
MUtils : : OS : : fatal_exit ( L " Unhandeled C++ exception error, application will exit! " ) ;
}
catch ( . . . )
{
MUTILS_PRINT_ERROR ( " \n GURU MEDITATION !!! \n \n Unknown exception error! \n " ) ;
MUtils : : OS : : fatal_exit ( L " Unhandeled C++ exception error, application will exit! " ) ;
}
return iResult ;
}
2014-12-21 17:19:04 +01:00
int MUtils : : Startup : : startup ( int & argc , char * * argv , main_function_t * const entry_point , const char * const appName , const bool & debugConsole )
2014-11-26 02:37:08 +01:00
{
int iResult = - 1 ;
2014-11-30 20:29:41 +01:00
# if (MUTILS_DEBUG)
# ifdef _MSC_VER
_CrtSetDbgFlag ( _CRTDBG_CHECK_ALWAYS_DF | | _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ) ) ;
# endif //_MSCVER
2014-12-21 17:19:04 +01:00
iResult = startup_main ( argc , argv , entry_point , appName , debugConsole ) ;
2014-11-26 02:37:08 +01:00
# else //MUTILS_DEBUG
# ifdef _MSC_VER
__try
{
MUtils : : ErrorHandler : : initialize ( ) ;
2014-11-30 21:33:03 +01:00
MUtils : : OS : : check_debugger ( ) ;
2014-12-21 17:19:04 +01:00
iResult = startup_helper ( argc , argv , entry_point , appName , debugConsole ) ;
2014-11-26 02:37:08 +01:00
}
__except ( 1 )
{
MUTILS_PRINT_ERROR ( " \n GURU MEDITATION !!! \n \n Unhandeled structured exception error! \n " ) ;
MUtils : : OS : : fatal_exit ( L " Unhandeled structured exception error, application will exit! " ) ;
}
# else //_MSCVER
MUtils : : ErrorHandler : : initialize ( ) ;
2014-11-30 21:33:03 +01:00
MUtils : : OS : : check_debugger ( ) ;
2014-12-21 17:19:04 +01:00
iResult = startup_helper ( argc , argv , entry_point , appName , debugConsole ) ;
2014-11-26 02:37:08 +01:00
# endif //_MSCVER
# endif //MUTILS_DEBUG
return iResult ;
}
///////////////////////////////////////////////////////////////////////////////
2014-11-29 01:22:46 +01:00
// QT INITIALIZATION
///////////////////////////////////////////////////////////////////////////////
2014-12-20 23:47:06 +01:00
static QMutex g_init_lock ;
2014-11-29 01:22:46 +01:00
static const char * const g_imageformats [ ] = { " bmp " , " png " , " jpg " , " gif " , " ico " , " xpm " , " svg " , NULL } ;
2014-12-20 23:47:06 +01:00
QApplication * MUtils : : Startup : : create_qt ( int & argc , char * * argv , const QString & appName )
2014-11-29 01:22:46 +01:00
{
2014-12-20 23:47:06 +01:00
QMutexLocker lock ( & g_init_lock ) ;
2014-11-29 01:22:46 +01:00
const QStringList & arguments = MUtils : : OS : : arguments ( ) ;
//Don't initialized again, if done already
2014-12-20 23:47:06 +01:00
if ( QApplication : : instance ( ) ! = NULL )
2014-11-29 01:22:46 +01:00
{
2014-12-20 23:47:06 +01:00
qWarning ( " Qt is already initialized! " ) ;
return NULL ;
2014-11-29 01:22:46 +01:00
}
//Extract executable name from argv[] array
QString executableName = QLatin1String ( " LameXP.exe " ) ;
if ( arguments . count ( ) > 0 )
{
static const char * delimiters = " \\ /:? " ;
executableName = arguments [ 0 ] . trimmed ( ) ;
for ( int i = 0 ; delimiters [ i ] ; i + + )
{
int temp = executableName . lastIndexOf ( QChar ( delimiters [ i ] ) ) ;
if ( temp > = 0 ) executableName = executableName . mid ( temp + 1 ) ;
}
executableName = executableName . trimmed ( ) ;
if ( executableName . isEmpty ( ) )
{
executableName = QLatin1String ( " LameXP.exe " ) ;
}
}
//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 ) ;
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 ( ) ) ;
return false ;
}
if ( QLibraryInfo : : buildKey ( ) . compare ( QString : : fromLatin1 ( QT_BUILD_KEY ) , Qt : : CaseInsensitive ) )
{
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' was built for Qt '%2', but found Qt '%3'. " ) . arg ( executableName , QString : : fromLatin1 ( QT_BUILD_KEY ) , QLibraryInfo : : buildKey ( ) ) . toLatin1 ( ) . constData ( ) ) ;
return false ;
}
# 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 ) ;
# 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 ) )
{
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' requires Windows XP or later. " ) . arg ( executableName ) . toLatin1 ( ) . constData ( ) ) ;
}
//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 ) ;
}
else
{
const QString message = QString ( ) . sprintf ( " Running on an unknown WindowsNT-based system (v%u.%u). " , osVersion . versionMajor , osVersion . versionMinor ) ;
qWarning ( " %s \n " , MUTILS_UTF8 ( message ) ) ;
MUtils : : OS : : system_message_wrn ( MUTILS_WCHR ( message ) , L " LameXP " ) ;
}
//Check for compat mode
if ( osVersion . overrideFlag & & ( osVersion < = MUtils : : OS : : Version : : WINDOWS_WN100 ) )
{
qWarning ( " Windows compatibility mode detected! " ) ;
if ( ! arguments . contains ( " --ignore-compat-mode " , Qt : : CaseInsensitive ) )
{
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' doesn't support Windows compatibility mode. " ) . arg ( executableName ) . toLatin1 ( ) . constData ( ) ) ;
2014-12-20 23:47:06 +01:00
return NULL ;
2014-11-29 01:22:46 +01:00
}
}
//Check for Wine
if ( MUtils : : OS : : running_on_wine ( ) )
{
qWarning ( " It appears we are running under Wine, unexpected things might happen! \n " ) ;
}
//Set text Codec for locale
QTextCodec : : setCodecForLocale ( QTextCodec : : codecForName ( " UTF-8 " ) ) ;
//Create Qt application instance
2014-12-20 23:47:06 +01:00
QApplication * application = new QApplication ( argc , argv ) ;
2014-11-29 01:22:46 +01:00
//Load plugins from application directory
QCoreApplication : : setLibraryPaths ( QStringList ( ) < < QApplication : : applicationDirPath ( ) ) ;
qDebug ( " Library Path: \n %s \n " , MUTILS_UTF8 ( QApplication : : libraryPaths ( ) . first ( ) ) ) ;
//Set application properties
2014-12-20 23:47:06 +01:00
application - > setApplicationName ( appName ) ;
application - > setOrganizationName ( " LoRd_MuldeR " ) ;
application - > setOrganizationDomain ( " mulder.at.gg " ) ;
application - > setEventFilter ( qt_event_filter ) ;
2014-11-29 01:22:46 +01:00
//Check for supported image formats
QList < QByteArray > supportedFormats = QImageReader : : supportedImageFormats ( ) ;
for ( int i = 0 ; g_imageformats [ i ] ; i + + )
{
if ( ! supportedFormats . contains ( g_imageformats [ i ] ) )
{
qFatal ( " Qt initialization error: QImageIOHandler for '%s' missing! " , g_imageformats [ i ] ) ;
2014-12-20 23:47:06 +01:00
MUTILS_DELETE ( application ) ;
return NULL ;
2014-11-29 01:22:46 +01:00
}
}
2014-12-03 22:21:53 +01:00
//Setup console icon
MUtils : : Terminal : : set_icon ( QIcon ( " :/mutils/icons/bug.png " ) ) ;
2014-11-29 01:22:46 +01:00
//Enable larger/smaller font size
double fontScaleFactor = 1.0 ;
if ( arguments . contains ( " --huge-font " , Qt : : CaseInsensitive ) ) fontScaleFactor = 1.500 ;
if ( arguments . contains ( " --big-font " , Qt : : CaseInsensitive ) ) fontScaleFactor = 1.250 ;
if ( arguments . contains ( " --small-font " , Qt : : CaseInsensitive ) ) fontScaleFactor = 0.875 ;
if ( arguments . contains ( " --tiny-font " , Qt : : CaseInsensitive ) ) fontScaleFactor = 0.750 ;
if ( ! qFuzzyCompare ( fontScaleFactor , 1.0 ) )
{
qWarning ( " Application font scale factor set to: %.3f \n " , fontScaleFactor ) ;
2014-12-20 23:47:06 +01:00
QFont appFont = application - > font ( ) ;
2014-11-29 01:22:46 +01:00
appFont . setPointSizeF ( appFont . pointSizeF ( ) * fontScaleFactor ) ;
2014-12-20 23:47:06 +01:00
application - > setFont ( appFont ) ;
2014-11-29 01:22:46 +01:00
}
//Check for process elevation
if ( MUtils : : OS : : is_elevated ( ) & & ( ! MUtils : : OS : : running_on_wine ( ) ) )
{
QMessageBox messageBox ( QMessageBox : : Warning , " LameXP " , " <nobr>LameXP was started with 'elevated' rights, altough LameXP does not need these rights.<br>Running an applications with unnecessary rights is a potential security risk!</nobr> " , 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 )
{
2014-12-20 23:47:06 +01:00
MUTILS_DELETE ( application ) ;
2014-11-29 01:22:46 +01:00
return NULL ;
}
}
2014-12-20 23:47:06 +01:00
//Qt created successfully
return application ;
2014-11-29 01:22:46 +01:00
}
///////////////////////////////////////////////////////////////////////////////
2014-12-20 23:47:06 +01:00