2#include "qgc_version.h"
4#include <QtCore/QCoreApplication>
5#include <QtCore/QProcessEnvironment>
13#if !defined(Q_OS_IOS) && !defined(Q_OS_ANDROID)
18#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
21 #include <sys/types.h>
25#ifdef QGC_HAS_LIBGCRYPT
29#if defined(Q_OS_MACOS)
30 #include <CoreFoundation/CoreFoundation.h>
31#elif defined(Q_OS_WIN)
32 #include <qt_windows.h>
45#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
46static void showLinuxErrorDialog(
const QByteArray& msg)
50 const pid_t pid = fork();
52 const QByteArray zenityText = QByteArrayLiteral(
"--text=") + msg;
53 execlp(
"zenity",
"zenity",
"--error",
"--title=Error", zenityText.constData(),
nullptr);
54 execlp(
"kdialog",
"kdialog",
"--error", msg.constData(),
nullptr);
55 execlp(
"xmessage",
"xmessage",
"-center", msg.constData(),
nullptr);
59 (void) waitpid(pid, &status, 0);
62 fprintf(stderr,
"Error: %s\n", msg.constData());
66#if defined(Q_OS_MACOS)
67void disableAppNapViaInfoDict()
69 CFBundleRef bundle = CFBundleGetMainBundle();
73 CFMutableDictionaryRef infoDict =
const_cast<CFMutableDictionaryRef
>(CFBundleGetInfoDictionary(bundle));
75 CFDictionarySetValue(infoDict, CFSTR(
"NSAppSleepDisabled"), kCFBooleanTrue);
83int __cdecl WindowsCrtReportHook(
int reportType,
char* message,
int* returnValue)
86 std::cerr << message << std::endl;
88 if (reportType == _CRT_ASSERT) {
97void __cdecl WindowsPurecallHandler()
99 (void) OutputDebugStringW(L
"QGC: _purecall\n");
102void WindowsInvalidParameterHandler([[maybe_unused]]
const wchar_t* expression,
103 [[maybe_unused]]
const wchar_t* function,
104 [[maybe_unused]]
const wchar_t* file,
105 [[maybe_unused]]
unsigned int line,
106 [[maybe_unused]] uintptr_t pReserved)
112LPTOP_LEVEL_EXCEPTION_FILTER g_prevUef =
nullptr;
114LONG WINAPI WindowsUnhandledExceptionFilter(EXCEPTION_POINTERS* ep)
116 const DWORD code = (ep && ep->ExceptionRecord) ? ep->ExceptionRecord->ExceptionCode : 0;
117 wchar_t buf[128] = {};
119 (void) _snwprintf_s(buf, _TRUNCATE, L
"QGC: unhandled SEH 0x%08lX\n",
static_cast<unsigned long>(code));
121 (void) swprintf(buf,
static_cast<int>(std::size(buf)), L
"QGC: unhandled SEH 0x%08lX\n",
static_cast<unsigned long>(code));
123 (void) OutputDebugStringW(buf);
125 const HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
126 if (h && (h != INVALID_HANDLE_VALUE)) {
128 const char narrow[] =
"QGC: unhandled SEH\n";
129 (void) WriteFile(h, narrow, (DWORD)
sizeof(narrow) - 1, &ignored,
nullptr);
132 return EXCEPTION_EXECUTE_HANDLER;
135void setWindowsErrorModes(
bool quietWindowsAsserts)
137 (void) SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
138 g_prevUef = SetUnhandledExceptionFilter(WindowsUnhandledExceptionFilter);
141 (void) _set_invalid_parameter_handler(WindowsInvalidParameterHandler);
142 (void) _set_purecall_handler(WindowsPurecallHandler);
144 if (quietWindowsAsserts) {
145 (void) _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
146 (void) _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
147 (void) _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
148 (void) _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, WindowsCrtReportHook);
149 (void) _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
150 (void) _set_error_mode(_OUT_TO_STDERR);
153 Q_UNUSED(quietWindowsAsserts);
163#ifdef QGC_HAS_LIBGCRYPT
166 if (gcry_check_version(
nullptr)) {
167 (void) gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
168 (void) gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
172#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
173 if (isRunningAsRoot()) {
174 return showRootError(argc, argv);
178#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
192 if (!qEnvironmentVariableIsSet(
"QT_ASSUME_STDERR_HAS_CONSOLE")) {
193 (void) qputenv(
"QT_ASSUME_STDERR_HAS_CONSOLE",
"1");
195 if (!qEnvironmentVariableIsSet(
"QT_FORCE_STDERR_LOGGING")) {
196 (void) qputenv(
"QT_FORCE_STDERR_LOGGING",
"1");
202 if (!qEnvironmentVariableIsSet(
"QT_WIN_DEBUG_CONSOLE")) {
203 (void) qputenv(
"QT_WIN_DEBUG_CONSOLE",
"attach");
209 disableAppNapViaInfoDict();
212#ifdef QGC_UNITTEST_BUILD
214 if (!qEnvironmentVariableIsSet(
"QT_QPA_PLATFORM")) {
215 (void) qputenv(
"QT_QPA_PLATFORM",
"offscreen");
222 QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
226 QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
229 QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
230 QCoreApplication::setAttribute(Qt::AA_CompressTabletEvents);
237#if !defined(Q_OS_IOS) && !defined(Q_OS_ANDROID)
247#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
248bool Platform::isRunningAsRoot()
250 return ::getuid() == 0;
253int Platform::showRootError([[maybe_unused]]
int argc, [[maybe_unused]]
char *argv[])
255 const QString message = QCoreApplication::translate(
"main",
256 "You are running %1 as root. "
257 "You should not do this since it will cause other issues with %1. "
258 "%1 will now exit.").arg(QLatin1String(QGC_APP_NAME));
259 showLinuxErrorDialog(message.toLocal8Bit());
264#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
267 const QString message = QCoreApplication::translate(
"main",
268 "A second instance of %1 is already running. "
269 "Please close the other instance and try again.").arg(QLatin1String(QGC_APP_NAME));
270#if defined(Q_OS_MACOS)
271 CFStringRef cfMessage = CFStringCreateWithCString(
nullptr, message.toUtf8().constData(), kCFStringEncodingUTF8);
272 CFUserNotificationDisplayAlert(0, kCFUserNotificationStopAlertLevel,
273 nullptr,
nullptr,
nullptr,
274 CFSTR(
"Error"), cfMessage,
275 nullptr,
nullptr,
nullptr,
nullptr);
276 CFRelease(cfMessage);
277#elif defined(Q_OS_WIN)
278 MessageBoxW(
nullptr, message.toStdWString().c_str(), L
"Error", MB_OK | MB_ICONERROR);
280 showLinuxErrorDialog(message.toLocal8Bit());
291 static const QString runguardString = QStringLiteral(
"%1 RunGuardKey").arg(QLatin1String(QGC_APP_NAME));
292 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.