2#include "qgc_version.h"
4#include <QtCore/QCoreApplication>
5#include <QtCore/QProcessEnvironment>
13#if !defined(Q_OS_IOS) && !defined(Q_OS_ANDROID)
14 #include <QtWidgets/QApplication>
15 #include <QtWidgets/QMessageBox>
20#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
22 #include <sys/types.h>
25#if defined(Q_OS_MACOS)
26 #include <CoreFoundation/CoreFoundation.h>
27#elif defined(Q_OS_WIN)
28 #include <qt_windows.h>
41#if defined(Q_OS_MACOS)
42void disableAppNapViaInfoDict()
44 CFBundleRef bundle = CFBundleGetMainBundle();
48 CFMutableDictionaryRef infoDict =
const_cast<CFMutableDictionaryRef
>(CFBundleGetInfoDictionary(bundle));
50 CFDictionarySetValue(infoDict, CFSTR(
"NSAppSleepDisabled"), kCFBooleanTrue);
58int __cdecl WindowsCrtReportHook(
int reportType,
char* message,
int* returnValue)
61 std::cerr << message << std::endl;
63 if (reportType == _CRT_ASSERT) {
72void __cdecl WindowsPurecallHandler()
74 (void) OutputDebugStringW(L
"QGC: _purecall\n");
77void WindowsInvalidParameterHandler([[maybe_unused]]
const wchar_t* expression,
78 [[maybe_unused]]
const wchar_t* function,
79 [[maybe_unused]]
const wchar_t* file,
80 [[maybe_unused]]
unsigned int line,
81 [[maybe_unused]] uintptr_t pReserved)
87LPTOP_LEVEL_EXCEPTION_FILTER g_prevUef =
nullptr;
89LONG WINAPI WindowsUnhandledExceptionFilter(EXCEPTION_POINTERS* ep)
91 const DWORD code = (ep && ep->ExceptionRecord) ? ep->ExceptionRecord->ExceptionCode : 0;
92 wchar_t buf[128] = {};
94 (void) _snwprintf_s(buf, _TRUNCATE, L
"QGC: unhandled SEH 0x%08lX\n",
static_cast<unsigned long>(code));
96 (void) swprintf(buf,
static_cast<int>(std::size(buf)), L
"QGC: unhandled SEH 0x%08lX\n",
static_cast<unsigned long>(code));
98 (void) OutputDebugStringW(buf);
100 const HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
101 if (h && (h != INVALID_HANDLE_VALUE)) {
103 const char narrow[] =
"QGC: unhandled SEH\n";
104 (void) WriteFile(h, narrow, (DWORD)
sizeof(narrow) - 1, &ignored,
nullptr);
107 return EXCEPTION_EXECUTE_HANDLER;
110void setWindowsErrorModes(
bool quietWindowsAsserts)
112 (void) SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
113 g_prevUef = SetUnhandledExceptionFilter(WindowsUnhandledExceptionFilter);
116 (void) _set_invalid_parameter_handler(WindowsInvalidParameterHandler);
117 (void) _set_purecall_handler(WindowsPurecallHandler);
119 if (quietWindowsAsserts) {
120 (void) _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
121 (void) _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
122 (void) _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
123 (void) _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, WindowsCrtReportHook);
124 (void) _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
125 (void) _set_error_mode(_OUT_TO_STDERR);
128 Q_UNUSED(quietWindowsAsserts);
139#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
140 if (isRunningAsRoot()) {
141 return showRootError(argc, argv);
145#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
157 if (!qEnvironmentVariableIsSet(
"QT_ASSUME_STDERR_HAS_CONSOLE")) {
158 (void) qputenv(
"QT_ASSUME_STDERR_HAS_CONSOLE",
"1");
160 if (!qEnvironmentVariableIsSet(
"QT_FORCE_STDERR_LOGGING")) {
161 (void) qputenv(
"QT_FORCE_STDERR_LOGGING",
"1");
166 if (!qEnvironmentVariableIsSet(
"QT_WIN_DEBUG_CONSOLE")) {
167 (void) qputenv(
"QT_WIN_DEBUG_CONSOLE",
"attach");
173 disableAppNapViaInfoDict();
177#ifdef QGC_UNITTEST_BUILD
179 if (!qEnvironmentVariableIsSet(
"QT_QPA_PLATFORM")) {
180 (void) qputenv(
"QT_QPA_PLATFORM",
"offscreen");
187 QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
191 QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
194 QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
195 QCoreApplication::setAttribute(Qt::AA_CompressTabletEvents);
202#if !defined(Q_OS_IOS) && !defined(Q_OS_ANDROID)
212#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
213bool Platform::isRunningAsRoot()
215 return ::getuid() == 0;
218int Platform::showRootError(
int argc,
char *argv[])
220 const QApplication errorApp(argc, argv);
221 (void) QMessageBox::critical(
nullptr,
222 QCoreApplication::translate(
"main",
"Error"),
223 QCoreApplication::translate(
"main",
224 "You are running %1 as root. "
225 "You should not do this since it will cause other issues with %1. "
226 "%1 will now exit.<br/><br/>").arg(QLatin1String(QGC_APP_NAME)));
231#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
234 const QApplication errorApp(argc, argv);
235 (void) QMessageBox::critical(
nullptr,
236 QCoreApplication::translate(
"main",
"Error"),
237 QCoreApplication::translate(
"main",
238 "A second instance of %1 is already running. "
239 "Please close the other instance and try again.").arg(QLatin1String(QGC_APP_NAME)));
249 static const QString runguardString = QStringLiteral(
"%1 RunGuardKey").arg(QLatin1String(QGC_APP_NAME));
250 static RunGuard guard(runguardString);
int setupSignalHandlers()
bool checkStoragePermissions()
Result of parsing command-line arguments.
bool quietWindowsAsserts
Windows only: Disable assert dialogs.
bool listTests
List available tests and exit.
bool useDesktopGL
Windows only: Force Desktop OpenGL.
bool useSwRast
Windows/macOS: Force software OpenGL.