2017-01-27 15:55:38 +03:00
# include <QApplication>
2020-02-12 13:18:39 +03:00
# include <QDesktopWidget>
2017-01-27 15:55:38 +03:00
# include <QQmlApplicationEngine>
# include <QQmlContext>
# include <stdlib.h>
2019-11-26 16:02:37 +03:00
# include <signal.h>
2017-01-27 15:55:38 +03:00
# include <QtGlobal>
# include <QtWidgets>
2017-03-30 15:52:13 +03:00
# include <QQuickWindow>
2019-09-09 15:12:58 +03:00
# include <QQuickStyle>
2017-02-13 15:03:58 +03:00
# include "screenshot.h"
2017-01-27 15:55:38 +03:00
2019-11-26 16:02:37 +03:00
void handleExitSignal ( int sig ) {
printf ( " Exiting due to signal %d \n " , sig ) ;
QCoreApplication : : quit ( ) ;
}
2019-11-26 16:32:15 +03:00
void setupSignalHandlers ( ) {
# ifdef _WIN32
signal ( SIGINT , handleExitSignal ) ;
# else
2019-11-26 16:02:37 +03:00
struct sigaction sa ;
sa . sa_handler = handleExitSignal ;
sigset_t signal_mask ;
sigemptyset ( & signal_mask ) ;
sa . sa_mask = signal_mask ;
sa . sa_flags = 0 ;
sigaction ( SIGINT , & sa , nullptr ) ;
2019-11-26 16:32:15 +03:00
# endif
2019-11-26 16:02:37 +03:00
}
2017-01-27 15:55:38 +03:00
int main ( int argc , char * argv [ ] )
{
2019-11-26 16:32:15 +03:00
setupSignalHandlers ( ) ;
2019-11-26 16:02:37 +03:00
2017-03-16 15:42:20 +03:00
// Don't write .pyc files.
2017-03-16 14:42:32 +03:00
qputenv ( " PYTHONDONTWRITEBYTECODE " , " 1 " ) ;
2017-03-16 13:23:06 +03:00
2019-09-09 15:12:58 +03:00
// Use Material "Dense" variant, recommended for Desktop
qputenv ( " QT_QUICK_CONTROLS_MATERIAL_VARIANT " , " Dense " ) ;
QApplication : : setAttribute ( Qt : : AA_EnableHighDpiScaling ) ;
QApplication application ( argc , argv ) ;
application . setApplicationName ( " Yubico Authenticator " ) ;
2019-09-24 14:24:24 +03:00
application . setApplicationVersion ( APP_VERSION ) ;
2019-09-09 15:12:58 +03:00
application . setOrganizationName ( " Yubico " ) ;
application . setOrganizationDomain ( " com.yubico " ) ;
2020-02-12 13:18:39 +03:00
// Get x and y coordinates of all monitors
QVariantList monitorAreas ;
for ( QScreen * screen : QGuiApplication : : screens ( ) ) {
QRect monitorArea = screen - > geometry ( ) ;
QVariantMap coordinates ;
coordinates . insert ( " xMin " , monitorArea . x ( ) ) ;
coordinates . insert ( " xMax " , monitorArea . x ( ) + monitorArea . width ( ) ) ;
coordinates . insert ( " yMin " , monitorArea . y ( ) ) ;
coordinates . insert ( " yMax " , monitorArea . y ( ) + monitorArea . height ( ) ) ;
monitorAreas < < coordinates ;
}
2019-09-09 15:12:58 +03:00
QQuickStyle : : setStyle ( " Material " ) ;
2017-01-27 15:55:38 +03:00
2019-09-24 14:24:24 +03:00
QCommandLineParser cliParser ;
cliParser . setApplicationDescription ( " Yubico Authenticator for Desktop " ) ;
cliParser . addHelpOption ( ) ;
cliParser . addVersionOption ( ) ;
cliParser . addOptions ( {
{ " log-level " , QCoreApplication : : translate ( " main " , " Enable logging at verbosity <LEVEL>: DEBUG, INFO, WARNING, ERROR, CRITICAL " ) , QCoreApplication : : translate ( " main " , " LEVEL " ) } ,
{ " log-file " , QCoreApplication : : translate ( " main " , " Print logs to <FILE> instead of standard output; ignored without --log-level " ) , QCoreApplication : : translate ( " main " , " FILE " ) } ,
} ) ;
cliParser . process ( application ) ;
2018-02-22 11:26:12 +03:00
// A lock file is used, to ensure only one running instance at the time.
QString tmpDir = QDir : : tempPath ( ) ;
QLockFile lockFile ( tmpDir + " /yubioath-desktop.lock " ) ;
2018-02-21 18:21:41 +03:00
if ( ! lockFile . tryLock ( 100 ) ) {
QMessageBox msgBox ;
msgBox . setIcon ( QMessageBox : : Warning ) ;
2018-02-22 11:26:12 +03:00
msgBox . setText ( " Yubico Authenticator is already running. " ) ;
2018-02-21 18:21:41 +03:00
msgBox . exec ( ) ;
return 1 ;
}
2019-09-09 15:12:58 +03:00
QString app_dir = application . applicationDirPath ( ) ;
2017-03-19 00:24:38 +03:00
QString main_qml = " /qml/main.qml " ;
2017-01-27 15:55:38 +03:00
QString path_prefix ;
QString url_prefix ;
if ( QFileInfo : : exists ( " : " + main_qml ) ) {
// Embedded resources
path_prefix = " : " ;
url_prefix = " qrc:// " ;
} else if ( QFileInfo : : exists ( app_dir + main_qml ) ) {
// Try relative to executable
path_prefix = app_dir ;
url_prefix = app_dir ;
} else { //Assume qml/main.qml in cwd.
app_dir = " . " ;
path_prefix = " . " ;
url_prefix = " . " ;
}
2017-02-13 15:03:58 +03:00
ScreenShot screenshot ;
2017-01-27 15:55:38 +03:00
QQmlApplicationEngine engine ;
2017-03-30 14:14:24 +03:00
2017-01-27 15:55:38 +03:00
engine . rootContext ( ) - > setContextProperty ( " appDir " , app_dir ) ;
engine . rootContext ( ) - > setContextProperty ( " urlPrefix " , url_prefix ) ;
engine . rootContext ( ) - > setContextProperty ( " appVersion " , APP_VERSION ) ;
2017-02-13 15:03:58 +03:00
engine . rootContext ( ) - > setContextProperty ( " ScreenShot " , & screenshot ) ;
2019-09-09 15:12:58 +03:00
engine . rootContext ( ) - > setContextProperty ( " application " , & application ) ;
2020-02-12 13:18:39 +03:00
engine . rootContext ( ) - > setContextProperty ( " monitorAreas " , monitorAreas ) ;
2017-01-27 15:55:38 +03:00
engine . load ( QUrl ( url_prefix + main_qml ) ) ;
2018-02-21 15:29:45 +03:00
2017-03-30 15:52:13 +03:00
QObject * root = engine . rootObjects ( ) . first ( ) ;
2017-12-01 17:38:08 +03:00
2019-09-24 14:24:24 +03:00
if ( cliParser . isSet ( " log-level " ) ) {
if ( cliParser . isSet ( " log-file " ) ) {
2019-09-25 08:11:01 +03:00
QMetaObject : : invokeMethod ( root , " enableLoggingToFile " , Q_ARG ( QVariant , cliParser . value ( " log-level " ) ) , Q_ARG ( QVariant , cliParser . value ( " log-file " ) ) ) ;
2018-01-31 20:58:48 +03:00
} else {
2019-09-25 08:11:01 +03:00
QMetaObject : : invokeMethod ( root , " enableLogging " , Q_ARG ( QVariant , cliParser . value ( " log-level " ) ) ) ;
2018-01-31 20:58:48 +03:00
}
2018-01-31 15:53:50 +03:00
} else {
2019-09-25 08:11:01 +03:00
QMetaObject : : invokeMethod ( root , " disableLogging " ) ;
2017-12-01 17:38:08 +03:00
}
2019-09-24 14:24:24 +03:00
2017-03-30 15:52:13 +03:00
QQuickWindow * qmlWindow = qobject_cast < QQuickWindow * > ( root ) ;
2017-08-28 13:43:50 +03:00
// Set icon in the window, doesn't effect desktop icons.
qmlWindow - > setIcon ( QIcon ( path_prefix + " /images/windowicon.png " ) ) ;
2019-09-09 15:12:58 +03:00
const int status = application . exec ( ) ;
2017-11-22 17:04:42 +03:00
return status ;
2017-01-27 15:55:38 +03:00
}