1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #include "qcoreapplication.h"
42 #include "qcoreapplication_p.h"
43 
44 #ifndef QT_NO_QOBJECT
45 #include "qabstracteventdispatcher.h"
46 #include "qcoreevent.h"
47 #include "qeventloop.h"
48 #endif
49 #include "qmetaobject.h"
50 #include "qcorecmdlineargs_p.h"
51 #include <qdatastream.h>
52 #include <qdebug.h>
53 #include <qdir.h>
54 #include <qfile.h>
55 #include <qfileinfo.h>
56 #include <qmutex.h>
57 #include <private/qloggingregistry_p.h>
58 #include <qscopeguard.h>
59 #include <qstandardpaths.h>
60 #ifndef QT_NO_QOBJECT
61 #include <qthread.h>
62 #include <qthreadstorage.h>
63 #include <private/qthread_p.h>
64 #if QT_CONFIG(thread)
65 #include <qthreadpool.h>
66 #endif
67 #endif
68 #include <qelapsedtimer.h>
69 #include <qlibraryinfo.h>
70 #include <qvarlengtharray.h>
71 #include <private/qfactoryloader_p.h>
72 #include <private/qfunctions_p.h>
73 #include <private/qlocale_p.h>
74 #include <private/qlocking_p.h>
75 #include <private/qhooks_p.h>
76 
77 #ifndef QT_NO_QOBJECT
78 #if defined(Q_OS_UNIX)
79 # if defined(Q_OS_DARWIN)
80 #  include "qeventdispatcher_cf_p.h"
81 # else
82 #  if !defined(QT_NO_GLIB)
83 #   include "qeventdispatcher_glib_p.h"
84 #  endif
85 # endif
86 # include "qeventdispatcher_unix_p.h"
87 #endif
88 #ifdef Q_OS_WIN
89 # ifdef Q_OS_WINRT
90 #  include "qeventdispatcher_winrt_p.h"
91 #  include "qfunctions_winrt.h"
92 #  include <wrl.h>
93 #  include <Windows.ApplicationModel.core.h>
94    using namespace ABI::Windows::ApplicationModel::Core;
95    using namespace Microsoft::WRL;
96 # else
97 #  include "qeventdispatcher_win_p.h"
98 # endif
99 #endif
100 #endif // QT_NO_QOBJECT
101 
102 #if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
103 #  include <private/qjni_p.h>
104 #  include <private/qjnihelpers_p.h>
105 #endif
106 
107 #ifdef Q_OS_MAC
108 #  include "qcore_mac_p.h"
109 #endif
110 
111 #include <stdlib.h>
112 
113 #ifdef Q_OS_UNIX
114 #  include <locale.h>
115 #  include <unistd.h>
116 #  include <sys/types.h>
117 #endif
118 
119 #ifdef Q_OS_VXWORKS
120 #  include <taskLib.h>
121 #endif
122 
123 #ifdef Q_OS_WASM
124 #include <emscripten/val.h>
125 #endif
126 
127 #ifdef QT_BOOTSTRAPPED
128 #include <private/qtrace_p.h>
129 #else
130 #include <qtcore_tracepoints_p.h>
131 #endif
132 
133 #include <algorithm>
134 
135 QT_BEGIN_NAMESPACE
136 
137 #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
138 extern QString qAppFileName();
139 #endif
140 
141 #if QT_VERSION >= 0x060000
142 # error "Bump QCoreApplicatoinPrivate::app_compile_version to 0x060000"
143 #endif
144 int QCoreApplicationPrivate::app_compile_version = 0x050000; //we don't know exactly, but it's at least 5.0.0
145 
146 bool QCoreApplicationPrivate::setuidAllowed = false;
147 
148 #if !defined(Q_OS_WIN)
149 #ifdef Q_OS_DARWIN
infoDictionaryStringProperty(const QString & propertyName)150 QString QCoreApplicationPrivate::infoDictionaryStringProperty(const QString &propertyName)
151 {
152     QString bundleName;
153     QCFString cfPropertyName = propertyName.toCFString();
154     CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
155                                                             cfPropertyName);
156     if (string)
157         bundleName = QString::fromCFString(static_cast<CFStringRef>(string));
158     return bundleName;
159 }
160 #endif
appName() const161 QString QCoreApplicationPrivate::appName() const
162 {
163     QString applicationName;
164 #ifdef Q_OS_DARWIN
165     applicationName = infoDictionaryStringProperty(QStringLiteral("CFBundleName"));
166 #endif
167     if (applicationName.isEmpty() && argv[0]) {
168         char *p = strrchr(argv[0], '/');
169         applicationName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
170     }
171 
172     return applicationName;
173 }
appVersion() const174 QString QCoreApplicationPrivate::appVersion() const
175 {
176     QString applicationVersion;
177 #ifndef QT_BOOTSTRAPPED
178 #  ifdef Q_OS_DARWIN
179     applicationVersion = infoDictionaryStringProperty(QStringLiteral("CFBundleVersion"));
180 #  elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
181     QJNIObjectPrivate context(QtAndroidPrivate::context());
182     if (context.isValid()) {
183         QJNIObjectPrivate pm = context.callObjectMethod(
184             "getPackageManager", "()Landroid/content/pm/PackageManager;");
185         QJNIObjectPrivate pn = context.callObjectMethod<jstring>("getPackageName");
186         if (pm.isValid() && pn.isValid()) {
187             QJNIObjectPrivate packageInfo = pm.callObjectMethod(
188                 "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;",
189                 pn.object(), 0);
190             if (packageInfo.isValid()) {
191                 QJNIObjectPrivate versionName = packageInfo.getObjectField(
192                     "versionName", "Ljava/lang/String;");
193                 if (versionName.isValid())
194                     return versionName.toString();
195             }
196         }
197     }
198 #  endif
199 #endif
200     return applicationVersion;
201 }
202 #endif
203 
204 QString *QCoreApplicationPrivate::cachedApplicationFilePath = nullptr;
205 
checkInstance(const char * function)206 bool QCoreApplicationPrivate::checkInstance(const char *function)
207 {
208     bool b = (QCoreApplication::self != nullptr);
209     if (!b)
210         qWarning("QApplication::%s: Please instantiate the QApplication object first", function);
211     return b;
212 }
213 
214 #if QT_CONFIG(commandlineparser)
addQtOptions(QList<QCommandLineOption> * options)215 void QCoreApplicationPrivate::addQtOptions(QList<QCommandLineOption> *options)
216 {
217     options->append(QCommandLineOption(QStringLiteral("qmljsdebugger"),
218                 QStringLiteral("Activates the QML/JS debugger with a specified port. The value must be of format port:1234[,block]. \"block\" makes the application wait for a connection."),
219                 QStringLiteral("value")));
220 }
221 #endif
222 
processCommandLineArguments()223 void QCoreApplicationPrivate::processCommandLineArguments()
224 {
225     int j = argc ? 1 : 0;
226     for (int i = 1; i < argc; ++i) {
227         if (!argv[i])
228             continue;
229         if (*argv[i] != '-') {
230             argv[j++] = argv[i];
231             continue;
232         }
233         const char *arg = argv[i];
234         if (arg[1] == '-') // startsWith("--")
235             ++arg;
236         if (strncmp(arg, "-qmljsdebugger=", 15) == 0) {
237             qmljs_debug_arguments = QString::fromLocal8Bit(arg + 15);
238         } else if (strcmp(arg, "-qmljsdebugger") == 0 && i < argc - 1) {
239             ++i;
240             qmljs_debug_arguments = QString::fromLocal8Bit(argv[i]);
241         } else {
242             argv[j++] = argv[i];
243         }
244     }
245 
246     if (j < argc) {
247         argv[j] = nullptr;
248         argc = j;
249     }
250 }
251 
252 // Support for introspection
253 
qt_startup_hook()254 extern "C" void Q_CORE_EXPORT qt_startup_hook()
255 {
256 }
257 
258 typedef QList<QtStartUpFunction> QStartUpFuncList;
259 Q_GLOBAL_STATIC(QStartUpFuncList, preRList)
260 typedef QList<QtCleanUpFunction> QVFuncList;
261 Q_GLOBAL_STATIC(QVFuncList, postRList)
262 static QBasicMutex globalRoutinesMutex;
263 
264 /*!
265     \internal
266 
267     Adds a global routine that will be called from the QCoreApplication
268     constructor. The public API is Q_COREAPP_STARTUP_FUNCTION.
269 */
qAddPreRoutine(QtStartUpFunction p)270 void qAddPreRoutine(QtStartUpFunction p)
271 {
272     QStartUpFuncList *list = preRList();
273     if (!list)
274         return;
275 
276     if (QCoreApplication::instance())
277         p();
278 
279     // Due to C++11 parallel dynamic initialization, this can be called
280     // from multiple threads.
281     const auto locker = qt_scoped_lock(globalRoutinesMutex);
282     list->prepend(p); // in case QCoreApplication is re-created, see qt_call_pre_routines
283 }
284 
qAddPostRoutine(QtCleanUpFunction p)285 void qAddPostRoutine(QtCleanUpFunction p)
286 {
287     QVFuncList *list = postRList();
288     if (!list)
289         return;
290     const auto locker = qt_scoped_lock(globalRoutinesMutex);
291     list->prepend(p);
292 }
293 
qRemovePostRoutine(QtCleanUpFunction p)294 void qRemovePostRoutine(QtCleanUpFunction p)
295 {
296     QVFuncList *list = postRList();
297     if (!list)
298         return;
299     const auto locker = qt_scoped_lock(globalRoutinesMutex);
300     list->removeAll(p);
301 }
302 
qt_call_pre_routines()303 static void qt_call_pre_routines()
304 {
305     if (!preRList.exists())
306         return;
307 
308     QVFuncList list;
309     {
310         const auto locker = qt_scoped_lock(globalRoutinesMutex);
311         // Unlike qt_call_post_routines, we don't empty the list, because
312         // Q_COREAPP_STARTUP_FUNCTION is a macro, so the user expects
313         // the function to be executed every time QCoreApplication is created.
314         list = *preRList;
315     }
316     for (int i = 0; i < list.count(); ++i)
317         list.at(i)();
318 }
319 
qt_call_post_routines()320 void Q_CORE_EXPORT qt_call_post_routines()
321 {
322     if (!postRList.exists())
323         return;
324 
325     forever {
326         QVFuncList list;
327         {
328             // extract the current list and make the stored list empty
329             const auto locker = qt_scoped_lock(globalRoutinesMutex);
330             qSwap(*postRList, list);
331         }
332 
333         if (list.isEmpty())
334             break;
335         for (QtCleanUpFunction f : qAsConst(list))
336             f();
337     }
338 }
339 
340 
341 // initialized in qcoreapplication and in qtextstream autotest when setlocale is called.
342 static bool qt_locale_initialized = false;
343 
344 #ifndef QT_NO_QOBJECT
345 
346 // app starting up if false
347 bool QCoreApplicationPrivate::is_app_running = false;
348  // app closing down if true
349 bool QCoreApplicationPrivate::is_app_closing = false;
350 
qGlobalPostedEventsCount()351 Q_CORE_EXPORT uint qGlobalPostedEventsCount()
352 {
353     QThreadData *currentThreadData = QThreadData::current();
354     return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset;
355 }
356 
357 QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = nullptr;
358 
359 #endif // QT_NO_QOBJECT
360 
361 QCoreApplication *QCoreApplication::self = nullptr;
362 uint QCoreApplicationPrivate::attribs =
363     (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents) |
364     (1 << Qt::AA_SynthesizeMouseForUnhandledTabletEvents);
365 
366 struct QCoreApplicationData {
QCoreApplicationDataQCoreApplicationData367     QCoreApplicationData() noexcept {
368         applicationNameSet = false;
369         applicationVersionSet = false;
370     }
~QCoreApplicationDataQCoreApplicationData371     ~QCoreApplicationData() {
372 #ifndef QT_NO_QOBJECT
373         // cleanup the QAdoptedThread created for the main() thread
374         if (auto *t = QCoreApplicationPrivate::theMainThread.loadAcquire()) {
375             QThreadData *data = QThreadData::get2(t);
376             data->deref(); // deletes the data and the adopted thread
377         }
378 #endif
379     }
380 
381     QString orgName, orgDomain;
382     QString application; // application name, initially from argv[0], can then be modified.
383     QString applicationVersion;
384     bool applicationNameSet; // true if setApplicationName was called
385     bool applicationVersionSet; // true if setApplicationVersion was called
386 
387 #if QT_CONFIG(library)
388     QScopedPointer<QStringList> app_libpaths;
389     QScopedPointer<QStringList> manual_libpaths;
390 #endif
391 
392 };
393 
394 Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
395 
396 #ifndef QT_NO_QOBJECT
397 static bool quitLockRefEnabled = true;
398 #endif
399 
400 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
401 // Check whether the command line arguments passed to QCoreApplication
402 // match those passed into main(), to see if the user has modified them
403 // before passing them on to us. We do this by comparing to the global
404 // __argv/__argc (MS extension). Deep comparison is required since
405 // argv/argc is rebuilt by our WinMain entrypoint.
isArgvModified(int argc,char ** argv)406 static inline bool isArgvModified(int argc, char **argv)
407 {
408     if (__argc != argc || !__argv /* wmain() */)
409         return true;
410     if (__argv == argv)
411         return false;
412     for (int a = 0; a < argc; ++a) {
413         if (argv[a] != __argv[a] && strcmp(argv[a], __argv[a]))
414             return true;
415     }
416     return false;
417 }
418 
contains(int argc,char ** argv,const char * needle)419 static inline bool contains(int argc, char **argv, const char *needle)
420 {
421     for (int a = 0; a < argc; ++a) {
422         if (!strcmp(argv[a], needle))
423             return true;
424     }
425     return false;
426 }
427 #endif // Q_OS_WIN && !Q_OS_WINRT
428 
QCoreApplicationPrivate(int & aargc,char ** aargv,uint flags)429 QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
430     :
431 #ifndef QT_NO_QOBJECT
432       QObjectPrivate(),
433 #endif
434       argc(aargc)
435     , argv(aargv)
436 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
437     , origArgc(0)
438     , origArgv(nullptr)
439 #endif
440     , application_type(QCoreApplicationPrivate::Tty)
441 #ifndef QT_NO_QOBJECT
442     , in_exec(false)
443     , aboutToQuitEmitted(false)
444     , threadData_clean(false)
445 #else
446     , q_ptr(nullptr)
447 #endif
448 {
449     app_compile_version = flags & 0xffffff;
450     static const char *const empty = "";
451     if (argc == 0 || argv == nullptr) {
452         argc = 0;
453         argv = const_cast<char **>(&empty);
454     }
455 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
456     if (!isArgvModified(argc, argv)) {
457         origArgc = argc;
458         origArgv = new char *[argc];
459         std::copy(argv, argv + argc, QT_MAKE_CHECKED_ARRAY_ITERATOR(origArgv, argc));
460     }
461 #endif // Q_OS_WIN && !Q_OS_WINRT
462 
463 #ifndef QT_NO_QOBJECT
464     QCoreApplicationPrivate::is_app_closing = false;
465 
466 #  if defined(Q_OS_UNIX)
467     if (Q_UNLIKELY(!setuidAllowed && (geteuid() != getuid())))
468         qFatal("FATAL: The application binary appears to be running setuid, this is a security hole.");
469 #  endif // Q_OS_UNIX
470 
471 #ifdef Q_OS_WINRT
472     QThreadData::setMainThread();
473 #endif
474 
475     QThread *cur = QThread::currentThread(); // note: this may end up setting theMainThread!
476     if (cur != theMainThread.loadAcquire())
477         qWarning("WARNING: QApplication was not created in the main() thread.");
478 #endif
479 }
480 
~QCoreApplicationPrivate()481 QCoreApplicationPrivate::~QCoreApplicationPrivate()
482 {
483 #ifndef QT_NO_QOBJECT
484     cleanupThreadData();
485 #endif
486 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
487     delete [] origArgv;
488 #endif
489     QCoreApplicationPrivate::clearApplicationFilePath();
490 }
491 
492 #ifndef QT_NO_QOBJECT
493 
cleanupThreadData()494 void QCoreApplicationPrivate::cleanupThreadData()
495 {
496     auto thisThreadData = threadData.loadRelaxed();
497 
498     if (thisThreadData && !threadData_clean) {
499 #if QT_CONFIG(thread)
500         void *data = &thisThreadData->tls;
501         QThreadStorageData::finish((void **)data);
502 #endif
503 
504         // need to clear the state of the mainData, just in case a new QCoreApplication comes along.
505         const auto locker = qt_scoped_lock(thisThreadData->postEventList.mutex);
506         for (int i = 0; i < thisThreadData->postEventList.size(); ++i) {
507             const QPostEvent &pe = thisThreadData->postEventList.at(i);
508             if (pe.event) {
509                 --pe.receiver->d_func()->postedEvents;
510                 pe.event->posted = false;
511                 delete pe.event;
512             }
513         }
514         thisThreadData->postEventList.clear();
515         thisThreadData->postEventList.recursion = 0;
516         thisThreadData->quitNow = false;
517         threadData_clean = true;
518     }
519 }
520 
createEventDispatcher()521 void QCoreApplicationPrivate::createEventDispatcher()
522 {
523     Q_Q(QCoreApplication);
524     QThreadData *data = QThreadData::current();
525     Q_ASSERT(!data->hasEventDispatcher());
526     eventDispatcher = data->createEventDispatcher();
527     eventDispatcher->setParent(q);
528 }
529 
eventDispatcherReady()530 void QCoreApplicationPrivate::eventDispatcherReady()
531 {
532 }
533 
534 QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
mainThread()535 QThread *QCoreApplicationPrivate::mainThread()
536 {
537     Q_ASSERT(theMainThread.loadRelaxed() != nullptr);
538     return theMainThread.loadRelaxed();
539 }
540 
threadRequiresCoreApplication()541 bool QCoreApplicationPrivate::threadRequiresCoreApplication()
542 {
543     QThreadData *data = QThreadData::current(false);
544     if (!data)
545         return true;    // default setting
546     return data->requiresCoreApplication;
547 }
548 
checkReceiverThread(QObject * receiver)549 void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
550 {
551     QThread *currentThread = QThread::currentThread();
552     QThread *thr = receiver->thread();
553     Q_ASSERT_X(currentThread == thr || !thr,
554                "QCoreApplication::sendEvent",
555                QString::asprintf("Cannot send events to objects owned by a different thread. "
556                                  "Current thread 0x%p. Receiver '%ls' (of type '%s') was created in thread 0x%p",
557                                  currentThread, qUtf16Printable(receiver->objectName()),
558                                  receiver->metaObject()->className(), thr)
559                .toLocal8Bit().data());
560     Q_UNUSED(currentThread);
561     Q_UNUSED(thr);
562 }
563 
564 #endif // QT_NO_QOBJECT
565 
appendApplicationPathToLibraryPaths()566 void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
567 {
568 #if QT_CONFIG(library)
569     QStringList *app_libpaths = coreappdata()->app_libpaths.data();
570     if (!app_libpaths)
571         coreappdata()->app_libpaths.reset(app_libpaths = new QStringList);
572     QString app_location = QCoreApplication::applicationFilePath();
573     app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
574 #ifdef Q_OS_WINRT
575     if (app_location.isEmpty())
576         app_location.append(QLatin1Char('/'));
577 #endif
578     app_location = QDir(app_location).canonicalPath();
579     if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
580         app_libpaths->append(app_location);
581 #endif
582 }
583 
qAppName()584 QString qAppName()
585 {
586     if (!QCoreApplicationPrivate::checkInstance("qAppName"))
587         return QString();
588     return QCoreApplication::instance()->d_func()->appName();
589 }
590 
initLocale()591 void QCoreApplicationPrivate::initLocale()
592 {
593     if (qt_locale_initialized)
594         return;
595     qt_locale_initialized = true;
596 #if defined(Q_OS_UNIX) && !defined(QT_BOOTSTRAPPED)
597     setlocale(LC_ALL, "");
598 #endif
599 }
600 
601 
602 /*!
603     \class QCoreApplication
604     \inmodule QtCore
605     \brief The QCoreApplication class provides an event loop for Qt
606     applications without UI.
607 
608     This class is used by non-GUI applications to provide their event
609     loop. For non-GUI application that uses Qt, there should be exactly
610     one QCoreApplication object. For GUI applications, see
611     QGuiApplication. For applications that use the Qt Widgets module,
612     see QApplication.
613 
614     QCoreApplication contains the main event loop, where all events
615     from the operating system (e.g., timer and network events) and
616     other sources are processed and dispatched. It also handles the
617     application's initialization and finalization, as well as
618     system-wide and application-wide settings.
619 
620     \section1 The Event Loop and Event Handling
621 
622     The event loop is started with a call to exec(). Long-running
623     operations can call processEvents() to keep the application
624     responsive.
625 
626     In general, we recommend that you create a QCoreApplication,
627     QGuiApplication or a QApplication object in your \c main()
628     function as early as possible. exec() will not return until
629     the event loop exits; e.g., when quit() is called.
630 
631     Several static convenience functions are also provided. The
632     QCoreApplication object is available from instance(). Events can
633     be sent with sendEvent() or posted to an event queue with postEvent().
634     Pending events can be removed with removePostedEvents() or dispatched
635     with sendPostedEvents().
636 
637     The class provides a quit() slot and an aboutToQuit() signal.
638 
639     \section1 Application and Library Paths
640 
641     An application has an applicationDirPath() and an
642     applicationFilePath(). Library paths (see QLibrary) can be retrieved
643     with libraryPaths() and manipulated by setLibraryPaths(), addLibraryPath(),
644     and removeLibraryPath().
645 
646     \section1 Internationalization and Translations
647 
648     Translation files can be added or removed
649     using installTranslator() and removeTranslator(). Application
650     strings can be translated using translate(). The QObject::tr()
651     and QObject::trUtf8() functions are implemented in terms of
652     translate().
653 
654     \section1 Accessing Command Line Arguments
655 
656     The command line arguments which are passed to QCoreApplication's
657     constructor should be accessed using the arguments() function.
658 
659     \note QCoreApplication removes option \c -qmljsdebugger="...". It parses the
660     argument of \c qmljsdebugger, and then removes this option plus its argument.
661 
662     For more advanced command line option handling, create a QCommandLineParser.
663 
664     \section1 Locale Settings
665 
666     On Unix/Linux Qt is configured to use the system locale settings by
667     default. This can cause a conflict when using POSIX functions, for
668     instance, when converting between data types such as floats and
669     strings, since the notation may differ between locales. To get
670     around this problem, call the POSIX function \c{setlocale(LC_NUMERIC,"C")}
671     right after initializing QApplication, QGuiApplication or QCoreApplication
672     to reset the locale that is used for number formatting to "C"-locale.
673 
674     \sa QGuiApplication, QAbstractEventDispatcher, QEventLoop,
675     {Semaphores Example}, {Wait Conditions Example}
676 */
677 
678 /*!
679     \fn static QCoreApplication *QCoreApplication::instance()
680 
681     Returns a pointer to the application's QCoreApplication (or
682     QGuiApplication/QApplication) instance.
683 
684     If no instance has been allocated, \nullptr is returned.
685 */
686 
687 /*!
688     \internal
689  */
QCoreApplication(QCoreApplicationPrivate & p)690 QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
691 #ifdef QT_NO_QOBJECT
692     : d_ptr(&p)
693 #else
694     : QObject(p, nullptr)
695 #endif
696 {
697     d_func()->q_ptr = this;
698     // note: it is the subclasses' job to call
699     // QCoreApplicationPrivate::eventDispatcher->startingUp();
700 }
701 
702 #ifndef QT_NO_QOBJECT
703 /*!
704     \deprecated
705     This function is equivalent to calling \c {QCoreApplication::eventDispatcher()->flush()},
706     which also is deprecated, see QAbstractEventDispatcher::flush(). Use sendPostedEvents()
707     and processEvents() for more fine-grained control of the event loop instead.
708 
709     Historically this functions was used to flush the platform-specific native event queues.
710 
711     \sa sendPostedEvents(), processEvents(), QAbstractEventDispatcher::flush()
712 */
713 #if QT_DEPRECATED_SINCE(5, 9)
flush()714 void QCoreApplication::flush()
715 {
716     if (self && self->d_func()->eventDispatcher)
717         self->d_func()->eventDispatcher->flush();
718 }
719 #endif
720 #endif
721 
722 /*!
723     Constructs a Qt core application. Core applications are applications without
724     a graphical user interface. Such applications are used at the console or as
725     server processes.
726 
727     The \a argc and \a argv arguments are processed by the application,
728     and made available in a more convenient form by the arguments()
729     function.
730 
731     \warning The data referred to by \a argc and \a argv must stay valid
732     for the entire lifetime of the QCoreApplication object. In addition,
733     \a argc must be greater than zero and \a argv must contain at least
734     one valid character string.
735 */
QCoreApplication(int & argc,char ** argv,int _internal)736 QCoreApplication::QCoreApplication(int &argc, char **argv
737 #ifndef Q_QDOC
738                                    , int _internal
739 #endif
740                                    )
741 #ifdef QT_NO_QOBJECT
742     : d_ptr(new QCoreApplicationPrivate(argc, argv, _internal))
743 #else
744     : QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
745 #endif
746 {
747     d_func()->q_ptr = this;
748     d_func()->init();
749 #ifndef QT_NO_QOBJECT
750     QCoreApplicationPrivate::eventDispatcher->startingUp();
751 #endif
752 }
753 
754 /*!
755   \enum QCoreApplication::anonymous
756   \internal
757 
758   \value ApplicationFlags QT_VERSION
759 */
760 
init()761 void QCoreApplicationPrivate::init()
762 {
763     Q_TRACE_SCOPE(QCoreApplicationPrivate_init);
764 
765 #if defined(Q_OS_MACOS)
766     QMacAutoReleasePool pool;
767 #endif
768 
769     Q_Q(QCoreApplication);
770 
771     initLocale();
772 
773     Q_ASSERT_X(!QCoreApplication::self, "QCoreApplication", "there should be only one application object");
774     QCoreApplication::self = q;
775 
776 #if QT_CONFIG(thread)
777 #ifdef Q_OS_WASM
778     QThreadPrivate::idealThreadCount = emscripten::val::global("navigator")["hardwareConcurrency"].as<int>();
779 #endif
780 #endif
781 
782     // Store app name/version (so they're still available after QCoreApplication is destroyed)
783     if (!coreappdata()->applicationNameSet)
784         coreappdata()->application = appName();
785 
786     if (!coreappdata()->applicationVersionSet)
787         coreappdata()->applicationVersion = appVersion();
788 
789 #if defined(Q_OS_ANDROID)
790     // We've deferred initializing the logging registry due to not being
791     // able to guarantee that logging happened on the same thread as the
792     // Qt main thread, but now that the Qt main thread is set up, we can
793     // enable categorized logging.
794     QLoggingRegistry::instance()->initializeRules();
795 #endif
796 
797 #if QT_CONFIG(library)
798     // Reset the lib paths, so that they will be recomputed, taking the availability of argv[0]
799     // into account. If necessary, recompute right away and replay the manual changes on top of the
800     // new lib paths.
801     QStringList *appPaths = coreappdata()->app_libpaths.take();
802     QStringList *manualPaths = coreappdata()->manual_libpaths.take();
803     if (appPaths) {
804         if (manualPaths) {
805             // Replay the delta. As paths can only be prepended to the front or removed from
806             // anywhere in the list, we can just linearly scan the lists and find the items that
807             // have been removed. Once the original list is exhausted we know all the remaining
808             // items have been added.
809             QStringList newPaths(q->libraryPaths());
810             for (int i = manualPaths->length(), j = appPaths->length(); i > 0 || j > 0; qt_noop()) {
811                 if (--j < 0) {
812                     newPaths.prepend((*manualPaths)[--i]);
813                 } else if (--i < 0) {
814                     newPaths.removeAll((*appPaths)[j]);
815                 } else if ((*manualPaths)[i] != (*appPaths)[j]) {
816                     newPaths.removeAll((*appPaths)[j]);
817                     ++i; // try again with next item.
818                 }
819             }
820             delete manualPaths;
821             coreappdata()->manual_libpaths.reset(new QStringList(newPaths));
822         }
823         delete appPaths;
824     }
825 #endif
826 
827 #ifndef QT_NO_QOBJECT
828     // use the event dispatcher created by the app programmer (if any)
829     Q_ASSERT(!eventDispatcher);
830     auto thisThreadData = threadData.loadRelaxed();
831     eventDispatcher = thisThreadData->eventDispatcher.loadRelaxed();
832 
833     // otherwise we create one
834     if (!eventDispatcher)
835         createEventDispatcher();
836     Q_ASSERT(eventDispatcher);
837 
838     if (!eventDispatcher->parent()) {
839         eventDispatcher->moveToThread(thisThreadData->thread.loadAcquire());
840         eventDispatcher->setParent(q);
841     }
842 
843     thisThreadData->eventDispatcher = eventDispatcher;
844     eventDispatcherReady();
845 #endif
846 
847     processCommandLineArguments();
848 
849     qt_call_pre_routines();
850     qt_startup_hook();
851 #ifndef QT_BOOTSTRAPPED
852     if (Q_UNLIKELY(qtHookData[QHooks::Startup]))
853         reinterpret_cast<QHooks::StartupCallback>(qtHookData[QHooks::Startup])();
854 #endif
855 
856 #ifndef QT_NO_QOBJECT
857     is_app_running = true; // No longer starting up.
858 #endif
859 }
860 
861 /*!
862     Destroys the QCoreApplication object.
863 */
~QCoreApplication()864 QCoreApplication::~QCoreApplication()
865 {
866     qt_call_post_routines();
867 
868     self = nullptr;
869 #ifndef QT_NO_QOBJECT
870     QCoreApplicationPrivate::is_app_closing = true;
871     QCoreApplicationPrivate::is_app_running = false;
872 #endif
873 
874 #if QT_CONFIG(thread)
875     // Synchronize and stop the global thread pool threads.
876     QThreadPool *globalThreadPool = nullptr;
877     QT_TRY {
878         globalThreadPool = QThreadPool::globalInstance();
879     } QT_CATCH (...) {
880         // swallow the exception, since destructors shouldn't throw
881     }
882     if (globalThreadPool) {
883         globalThreadPool->waitForDone();
884         delete globalThreadPool;
885     }
886 #endif
887 
888 #ifndef QT_NO_QOBJECT
889     d_func()->threadData.loadRelaxed()->eventDispatcher = nullptr;
890     if (QCoreApplicationPrivate::eventDispatcher)
891         QCoreApplicationPrivate::eventDispatcher->closingDown();
892     QCoreApplicationPrivate::eventDispatcher = nullptr;
893 #endif
894 
895 #if QT_CONFIG(library)
896     coreappdata()->app_libpaths.reset();
897     coreappdata()->manual_libpaths.reset();
898 #endif
899 }
900 
901 /*!
902     \since 5.3
903 
904     Allows the application to run setuid on UNIX platforms if \a allow
905     is true.
906 
907     If \a allow is false (the default) and Qt detects the application is
908     running with an effective user id different than the real user id,
909     the application will be aborted when a QCoreApplication instance is
910     created.
911 
912     Qt is not an appropriate solution for setuid programs due to its
913     large attack surface. However some applications may be required
914     to run in this manner for historical reasons. This flag will
915     prevent Qt from aborting the application when this is detected,
916     and must be set before a QCoreApplication instance is created.
917 
918     \note It is strongly recommended not to enable this option since
919     it introduces security risks.
920 */
setSetuidAllowed(bool allow)921 void QCoreApplication::setSetuidAllowed(bool allow)
922 {
923     QCoreApplicationPrivate::setuidAllowed = allow;
924 }
925 
926 /*!
927     \since 5.3
928 
929     Returns true if the application is allowed to run setuid on UNIX
930     platforms.
931 
932     \sa QCoreApplication::setSetuidAllowed()
933 */
isSetuidAllowed()934 bool QCoreApplication::isSetuidAllowed()
935 {
936     return QCoreApplicationPrivate::setuidAllowed;
937 }
938 
939 
940 /*!
941     Sets the attribute \a attribute if \a on is true;
942     otherwise clears the attribute.
943 
944     \note Some application attributes must be set \b before creating a
945     QCoreApplication instance. Refer to the Qt::ApplicationAttribute
946     documentation for more information.
947 
948     \sa testAttribute()
949 */
setAttribute(Qt::ApplicationAttribute attribute,bool on)950 void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
951 {
952     if (on)
953         QCoreApplicationPrivate::attribs |= 1 << attribute;
954     else
955         QCoreApplicationPrivate::attribs &= ~(1 << attribute);
956 #if defined(QT_NO_QOBJECT)
957     if (Q_UNLIKELY(qApp)) {
958 #else
959     if (Q_UNLIKELY(QCoreApplicationPrivate::is_app_running)) {
960 #endif
961         switch (attribute) {
962             case Qt::AA_EnableHighDpiScaling:
963             case Qt::AA_DisableHighDpiScaling:
964             case Qt::AA_PluginApplication:
965             case Qt::AA_UseDesktopOpenGL:
966             case Qt::AA_UseOpenGLES:
967             case Qt::AA_UseSoftwareOpenGL:
968             case Qt::AA_ShareOpenGLContexts:
969 #ifdef QT_BOOTSTRAPPED
970                 qWarning("Attribute %d must be set before QCoreApplication is created.",
971                          attribute);
972 #else
973                 qWarning("Attribute Qt::%s must be set before QCoreApplication is created.",
974                          QMetaEnum::fromType<Qt::ApplicationAttribute>().valueToKey(attribute));
975 #endif
976                 break;
977             default:
978                 break;
979         }
980     }
981 }
982 
983 /*!
984   Returns \c true if attribute \a attribute is set;
985   otherwise returns \c false.
986 
987   \sa setAttribute()
988  */
989 bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
990 {
991     return QCoreApplicationPrivate::testAttribute(attribute);
992 }
993 
994 
995 #ifndef QT_NO_QOBJECT
996 
997 /*!
998     \property QCoreApplication::quitLockEnabled
999 
1000     \brief Whether the use of the QEventLoopLocker feature can cause the
1001     application to quit.
1002 
1003     The default is \c true.
1004 
1005     \sa QEventLoopLocker
1006 */
1007 
1008 bool QCoreApplication::isQuitLockEnabled()
1009 {
1010     return quitLockRefEnabled;
1011 }
1012 
1013 static bool doNotify(QObject *, QEvent *);
1014 
1015 void QCoreApplication::setQuitLockEnabled(bool enabled)
1016 {
1017     quitLockRefEnabled = enabled;
1018 }
1019 
1020 #if QT_DEPRECATED_SINCE(5, 6)
1021 /*!
1022   \internal
1023   \deprecated
1024 
1025   This function is here to make it possible for Qt extensions to
1026   hook into event notification without subclassing QApplication
1027 */
1028 bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
1029 {
1030     return notifyInternal2(receiver, event);
1031 }
1032 #endif
1033 
1034 /*!
1035   \internal
1036   \since 5.6
1037 
1038   This function is here to make it possible for Qt extensions to
1039   hook into event notification without subclassing QApplication.
1040 */
1041 bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event)
1042 {
1043     bool selfRequired = QCoreApplicationPrivate::threadRequiresCoreApplication();
1044     if (!self && selfRequired)
1045         return false;
1046 
1047     // Make it possible for Qt Script to hook into events even
1048     // though QApplication is subclassed...
1049     bool result = false;
1050     void *cbdata[] = { receiver, event, &result };
1051     if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
1052         return result;
1053     }
1054 
1055     // Qt enforces the rule that events can only be sent to objects in
1056     // the current thread, so receiver->d_func()->threadData is
1057     // equivalent to QThreadData::current(), just without the function
1058     // call overhead.
1059     QObjectPrivate *d = receiver->d_func();
1060     QThreadData *threadData = d->threadData;
1061     QScopedScopeLevelCounter scopeLevelCounter(threadData);
1062     if (!selfRequired)
1063         return doNotify(receiver, event);
1064     return self->notify(receiver, event);
1065 }
1066 
1067 /*!
1068     \internal
1069     \since 5.10
1070 
1071     Forwards the \a event to the \a receiver, using the spontaneous
1072     state of the \a originatingEvent if specified.
1073 */
1074 bool QCoreApplication::forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent)
1075 {
1076     if (event && originatingEvent)
1077         event->spont = originatingEvent->spont;
1078 
1079     return notifyInternal2(receiver, event);
1080 }
1081 
1082 /*!
1083   Sends \a event to \a receiver: \a {receiver}->event(\a event).
1084   Returns the value that is returned from the receiver's event
1085   handler. Note that this function is called for all events sent to
1086   any object in any thread.
1087 
1088   For certain types of events (e.g. mouse and key events),
1089   the event will be propagated to the receiver's parent and so on up to
1090   the top-level object if the receiver is not interested in the event
1091   (i.e., it returns \c false).
1092 
1093   There are five different ways that events can be processed;
1094   reimplementing this virtual function is just one of them. All five
1095   approaches are listed below:
1096   \list 1
1097   \li Reimplementing \l {QWidget::}{paintEvent()}, \l {QWidget::}{mousePressEvent()} and so
1098   on. This is the most common, easiest, and least powerful way.
1099 
1100   \li Reimplementing this function. This is very powerful, providing
1101   complete control; but only one subclass can be active at a time.
1102 
1103   \li Installing an event filter on QCoreApplication::instance(). Such
1104   an event filter is able to process all events for all widgets, so
1105   it's just as powerful as reimplementing notify(); furthermore, it's
1106   possible to have more than one application-global event filter.
1107   Global event filters even see mouse events for
1108   \l{QWidget::isEnabled()}{disabled widgets}. Note that application
1109   event filters are only called for objects that live in the main
1110   thread.
1111 
1112   \li Reimplementing QObject::event() (as QWidget does). If you do
1113   this you get Tab key presses, and you get to see the events before
1114   any widget-specific event filters.
1115 
1116   \li Installing an event filter on the object. Such an event filter gets all
1117   the events, including Tab and Shift+Tab key press events, as long as they
1118   do not change the focus widget.
1119   \endlist
1120 
1121   \b{Future direction:} This function will not be called for objects that live
1122   outside the main thread in Qt 6. Applications that need that functionality
1123   should find other solutions for their event inspection needs in the meantime.
1124   The change may be extended to the main thread, causing this function to be
1125   deprecated.
1126 
1127   \warning If you override this function, you must ensure all threads that
1128   process events stop doing so before your application object begins
1129   destruction. This includes threads started by other libraries that you may be
1130   using, but does not apply to Qt's own threads.
1131 
1132   \sa QObject::event(), installNativeEventFilter()
1133 */
1134 
1135 bool QCoreApplication::notify(QObject *receiver, QEvent *event)
1136 {
1137     // no events are delivered after ~QCoreApplication() has started
1138     if (QCoreApplicationPrivate::is_app_closing)
1139         return true;
1140     return doNotify(receiver, event);
1141 }
1142 
1143 static bool doNotify(QObject *receiver, QEvent *event)
1144 {
1145     if (receiver == nullptr) {                        // serious error
1146         qWarning("QCoreApplication::notify: Unexpected null receiver");
1147         return true;
1148     }
1149 
1150 #ifndef QT_NO_DEBUG
1151     QCoreApplicationPrivate::checkReceiverThread(receiver);
1152 #endif
1153 
1154     return receiver->isWidgetType() ? false : QCoreApplicationPrivate::notify_helper(receiver, event);
1155 }
1156 
1157 bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
1158 {
1159     // We can't access the application event filters outside of the main thread (race conditions)
1160     Q_ASSERT(receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread());
1161 
1162     if (extraData) {
1163         // application event filters are only called for objects in the GUI thread
1164         for (int i = 0; i < extraData->eventFilters.size(); ++i) {
1165             QObject *obj = extraData->eventFilters.at(i);
1166             if (!obj)
1167                 continue;
1168             if (obj->d_func()->threadData != threadData) {
1169                 qWarning("QCoreApplication: Application event filter cannot be in a different thread.");
1170                 continue;
1171             }
1172             if (obj->eventFilter(receiver, event))
1173                 return true;
1174         }
1175     }
1176     return false;
1177 }
1178 
1179 bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
1180 {
1181     if (receiver != QCoreApplication::instance() && receiver->d_func()->extraData) {
1182         for (int i = 0; i < receiver->d_func()->extraData->eventFilters.size(); ++i) {
1183             QObject *obj = receiver->d_func()->extraData->eventFilters.at(i);
1184             if (!obj)
1185                 continue;
1186             if (obj->d_func()->threadData != receiver->d_func()->threadData) {
1187                 qWarning("QCoreApplication: Object event filter cannot be in a different thread.");
1188                 continue;
1189             }
1190             if (obj->eventFilter(receiver, event))
1191                 return true;
1192         }
1193     }
1194     return false;
1195 }
1196 
1197 /*!
1198   \internal
1199 
1200   Helper function called by QCoreApplicationPrivate::notify() and qapplication.cpp
1201  */
1202 bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
1203 {
1204     // Note: when adjusting the tracepoints in here
1205     // consider adjusting QApplicationPrivate::notify_helper too.
1206     Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type());
1207     bool consumed = false;
1208     bool filtered = false;
1209     Q_TRACE_EXIT(QCoreApplication_notify_exit, consumed, filtered);
1210 
1211     // send to all application event filters (only does anything in the main thread)
1212     if (QCoreApplication::self
1213             && receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread()
1214             && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) {
1215         filtered = true;
1216         return filtered;
1217     }
1218     // send to all receiver event filters
1219     if (sendThroughObjectEventFilters(receiver, event)) {
1220         filtered = true;
1221         return filtered;
1222     }
1223 
1224     // deliver the event
1225     consumed = receiver->event(event);
1226     return consumed;
1227 }
1228 
1229 /*!
1230   Returns \c true if an application object has not been created yet;
1231   otherwise returns \c false.
1232 
1233   \sa closingDown()
1234 */
1235 
1236 bool QCoreApplication::startingUp()
1237 {
1238     return !QCoreApplicationPrivate::is_app_running;
1239 }
1240 
1241 /*!
1242   Returns \c true if the application objects are being destroyed;
1243   otherwise returns \c false.
1244 
1245   \sa startingUp()
1246 */
1247 
1248 bool QCoreApplication::closingDown()
1249 {
1250     return QCoreApplicationPrivate::is_app_closing;
1251 }
1252 
1253 
1254 /*!
1255     Processes some pending events for the calling thread according to
1256     the specified \a flags.
1257 
1258     You can call this function occasionally when your program is busy
1259     performing a long operation (e.g. copying a file).
1260 
1261     In the event that you are running a local loop which calls this function
1262     continuously, without an event loop, the
1263     \l{QEvent::DeferredDelete}{DeferredDelete} events will
1264     not be processed. This can affect the behaviour of widgets,
1265     e.g. QToolTip, that rely on \l{QEvent::DeferredDelete}{DeferredDelete}
1266     events to function properly. An alternative would be to call
1267     \l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from
1268     within that local loop.
1269 
1270     Calling this function processes events only for the calling thread,
1271     and returns after all available events have been processed. Available
1272     events are events queued before the function call. This means that
1273     events that are posted while the function runs will be queued until
1274     a later round of event processing.
1275 
1276     \threadsafe
1277 
1278     \sa exec(), QTimer, QEventLoop::processEvents(), flush(), sendPostedEvents()
1279 */
1280 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
1281 {
1282     QThreadData *data = QThreadData::current();
1283     if (!data->hasEventDispatcher())
1284         return;
1285     data->eventDispatcher.loadRelaxed()->processEvents(flags);
1286 }
1287 
1288 /*!
1289     \overload processEvents()
1290 
1291     Processes pending events for the calling thread for \a ms
1292     milliseconds or until there are no more events to process,
1293     whichever is shorter.
1294 
1295     You can call this function occasionally when your program is busy
1296     doing a long operation (e.g. copying a file).
1297 
1298     Calling this function processes events only for the calling thread.
1299 
1300     \note Unlike the \l{QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)}{processEvents()}
1301     overload, this function also processes events that are posted while the function runs.
1302 
1303     \note All events that were queued before the timeout will be processed,
1304     however long it takes.
1305 
1306     \threadsafe
1307 
1308     \sa exec(), QTimer, QEventLoop::processEvents()
1309 */
1310 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int ms)
1311 {
1312     // ### Qt 6: consider splitting this method into a public and a private
1313     //           one, so that a user-invoked processEvents can be detected
1314     //           and handled properly.
1315     QThreadData *data = QThreadData::current();
1316     if (!data->hasEventDispatcher())
1317         return;
1318     QElapsedTimer start;
1319     start.start();
1320     while (data->eventDispatcher.loadRelaxed()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
1321         if (start.elapsed() > ms)
1322             break;
1323     }
1324 }
1325 
1326 /*****************************************************************************
1327   Main event loop wrappers
1328  *****************************************************************************/
1329 
1330 /*!
1331     Enters the main event loop and waits until exit() is called.  Returns
1332     the value that was passed to exit() (which is 0 if exit() is called via
1333     quit()).
1334 
1335     It is necessary to call this function to start event handling. The
1336     main event loop receives events from the window system and
1337     dispatches these to the application widgets.
1338 
1339     To make your application perform idle processing (by executing a
1340     special function whenever there are no pending events), use a
1341     QTimer with 0 timeout. More advanced idle processing schemes can
1342     be achieved using processEvents().
1343 
1344     We recommend that you connect clean-up code to the
1345     \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in
1346     your application's \c{main()} function because on some platforms the
1347     exec() call may not return. For example, on Windows
1348     when the user logs off, the system terminates the process after Qt
1349     closes all top-level windows. Hence, there is no guarantee that the
1350     application will have time to exit its event loop and execute code at
1351     the end of the \c{main()} function after the exec()
1352     call.
1353 
1354     \sa quit(), exit(), processEvents(), QApplication::exec()
1355 */
1356 int QCoreApplication::exec()
1357 {
1358     if (!QCoreApplicationPrivate::checkInstance("exec"))
1359         return -1;
1360 
1361     QThreadData *threadData = self->d_func()->threadData;
1362     if (threadData != QThreadData::current()) {
1363         qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
1364         return -1;
1365     }
1366     if (!threadData->eventLoops.isEmpty()) {
1367         qWarning("QCoreApplication::exec: The event loop is already running");
1368         return -1;
1369     }
1370 
1371     threadData->quitNow = false;
1372     QEventLoop eventLoop;
1373     self->d_func()->in_exec = true;
1374     self->d_func()->aboutToQuitEmitted = false;
1375     int returnCode = eventLoop.exec();
1376     threadData->quitNow = false;
1377 
1378     if (self)
1379         self->d_func()->execCleanup();
1380 
1381     return returnCode;
1382 }
1383 
1384 
1385 // Cleanup after eventLoop is done executing in QCoreApplication::exec().
1386 // This is for use cases in which QCoreApplication is instantiated by a
1387 // library and not by an application executable, for example, Active X
1388 // servers.
1389 
1390 void QCoreApplicationPrivate::execCleanup()
1391 {
1392     threadData.loadRelaxed()->quitNow = false;
1393     in_exec = false;
1394     if (!aboutToQuitEmitted)
1395         emit q_func()->aboutToQuit(QCoreApplication::QPrivateSignal());
1396     aboutToQuitEmitted = true;
1397     QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
1398 }
1399 
1400 
1401 /*!
1402   Tells the application to exit with a return code.
1403 
1404     After this function has been called, the application leaves the
1405     main event loop and returns from the call to exec(). The exec()
1406     function returns \a returnCode. If the event loop is not running,
1407     this function does nothing.
1408 
1409   By convention, a \a returnCode of 0 means success, and any non-zero
1410   value indicates an error.
1411 
1412   It's good practice to always connect signals to this slot using a
1413   \l{Qt::}{QueuedConnection}. If a signal connected (non-queued) to this slot
1414   is emitted before control enters the main event loop (such as before
1415   "int main" calls \l{QCoreApplication::}{exec()}), the slot has no effect
1416   and the application never exits. Using a queued connection ensures that the
1417   slot will not be invoked until after control enters the main event loop.
1418 
1419   Note that unlike the C library function of the same name, this
1420   function \e does return to the caller -- it is event processing that
1421   stops.
1422 
1423   \sa quit(), exec()
1424 */
1425 void QCoreApplication::exit(int returnCode)
1426 {
1427     if (!self)
1428         return;
1429     QThreadData *data = self->d_func()->threadData.loadRelaxed();
1430     data->quitNow = true;
1431     for (int i = 0; i < data->eventLoops.size(); ++i) {
1432         QEventLoop *eventLoop = data->eventLoops.at(i);
1433         eventLoop->exit(returnCode);
1434     }
1435 }
1436 
1437 /*****************************************************************************
1438   QCoreApplication management of posted events
1439  *****************************************************************************/
1440 
1441 #ifndef QT_NO_QOBJECT
1442 /*!
1443     \fn bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1444 
1445     Sends event \a event directly to receiver \a receiver, using the
1446     notify() function. Returns the value that was returned from the
1447     event handler.
1448 
1449     The event is \e not deleted when the event has been sent. The normal
1450     approach is to create the event on the stack, for example:
1451 
1452     \snippet code/src_corelib_kernel_qcoreapplication.cpp 0
1453 
1454     \sa postEvent(), notify()
1455 */
1456 bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1457 {
1458     Q_TRACE(QCoreApplication_sendEvent, receiver, event, event->type());
1459 
1460     if (event)
1461         event->spont = false;
1462     return notifyInternal2(receiver, event);
1463 }
1464 
1465 /*!
1466     \internal
1467 */
1468 bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)
1469 {
1470     Q_TRACE(QCoreApplication_sendSpontaneousEvent, receiver, event, event->type());
1471 
1472     if (event)
1473         event->spont = true;
1474     return notifyInternal2(receiver, event);
1475 }
1476 
1477 #endif // QT_NO_QOBJECT
1478 
1479 QCoreApplicationPrivate::QPostEventListLocker QCoreApplicationPrivate::lockThreadPostEventList(QObject *object)
1480 {
1481     QPostEventListLocker locker;
1482 
1483     if (!object) {
1484         locker.threadData = QThreadData::current();
1485         locker.locker = qt_unique_lock(locker.threadData->postEventList.mutex);
1486         return locker;
1487     }
1488 
1489     auto &threadData = QObjectPrivate::get(object)->threadData;
1490 
1491     // if object has moved to another thread, follow it
1492     for (;;) {
1493         // synchronizes with the storeRelease in QObject::moveToThread
1494         locker.threadData = threadData.loadAcquire();
1495         if (!locker.threadData) {
1496             // destruction in progress
1497             return locker;
1498         }
1499 
1500         auto temporaryLocker = qt_unique_lock(locker.threadData->postEventList.mutex);
1501         if (locker.threadData == threadData.loadAcquire()) {
1502             locker.locker = std::move(temporaryLocker);
1503             break;
1504         }
1505     }
1506 
1507     Q_ASSERT(locker.threadData);
1508     return locker;
1509 }
1510 
1511 /*!
1512     \since 4.3
1513 
1514     Adds the event \a event, with the object \a receiver as the
1515     receiver of the event, to an event queue and returns immediately.
1516 
1517     The event must be allocated on the heap since the post event queue
1518     will take ownership of the event and delete it once it has been
1519     posted.  It is \e {not safe} to access the event after
1520     it has been posted.
1521 
1522     When control returns to the main event loop, all events that are
1523     stored in the queue will be sent using the notify() function.
1524 
1525     Events are sorted in descending \a priority order, i.e. events
1526     with a high \a priority are queued before events with a lower \a
1527     priority. The \a priority can be any integer value, i.e. between
1528     INT_MAX and INT_MIN, inclusive; see Qt::EventPriority for more
1529     details. Events with equal \a priority will be processed in the
1530     order posted.
1531 
1532     \threadsafe
1533 
1534     \sa sendEvent(), notify(), sendPostedEvents(), Qt::EventPriority
1535 */
1536 void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
1537 {
1538     Q_TRACE_SCOPE(QCoreApplication_postEvent, receiver, event, event->type());
1539 
1540     if (receiver == nullptr) {
1541         qWarning("QCoreApplication::postEvent: Unexpected null receiver");
1542         delete event;
1543         return;
1544     }
1545 
1546     auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
1547     if (!locker.threadData) {
1548         // posting during destruction? just delete the event to prevent a leak
1549         delete event;
1550         return;
1551     }
1552 
1553     QThreadData *data = locker.threadData;
1554 
1555     // if this is one of the compressible events, do compression
1556     if (receiver->d_func()->postedEvents
1557         && self && self->compressEvent(event, receiver, &data->postEventList)) {
1558         Q_TRACE(QCoreApplication_postEvent_event_compressed, receiver, event);
1559         return;
1560     }
1561 
1562     if (event->type() == QEvent::DeferredDelete)
1563         receiver->d_ptr->deleteLaterCalled = true;
1564 
1565     if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) {
1566         // remember the current running eventloop for DeferredDelete
1567         // events posted in the receiver's thread.
1568 
1569         // Events sent by non-Qt event handlers (such as glib) may not
1570         // have the scopeLevel set correctly. The scope level makes sure that
1571         // code like this:
1572         //     foo->deleteLater();
1573         //     qApp->processEvents(); // without passing QEvent::DeferredDelete
1574         // will not cause "foo" to be deleted before returning to the event loop.
1575 
1576         // If the scope level is 0 while loopLevel != 0, we are called from a
1577         // non-conformant code path, and our best guess is that the scope level
1578         // should be 1. (Loop level 0 is special: it means that no event loops
1579         // are running.)
1580         int loopLevel = data->loopLevel;
1581         int scopeLevel = data->scopeLevel;
1582         if (scopeLevel == 0 && loopLevel != 0)
1583             scopeLevel = 1;
1584         static_cast<QDeferredDeleteEvent *>(event)->level = loopLevel + scopeLevel;
1585     }
1586 
1587     // delete the event on exceptions to protect against memory leaks till the event is
1588     // properly owned in the postEventList
1589     QScopedPointer<QEvent> eventDeleter(event);
1590     Q_TRACE(QCoreApplication_postEvent_event_posted, receiver, event, event->type());
1591     data->postEventList.addEvent(QPostEvent(receiver, event, priority));
1592     eventDeleter.take();
1593     event->posted = true;
1594     ++receiver->d_func()->postedEvents;
1595     data->canWait = false;
1596     locker.unlock();
1597 
1598     QAbstractEventDispatcher* dispatcher = data->eventDispatcher.loadAcquire();
1599     if (dispatcher)
1600         dispatcher->wakeUp();
1601 }
1602 
1603 /*!
1604   \internal
1605   Returns \c true if \a event was compressed away (possibly deleted) and should not be added to the list.
1606 */
1607 bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1608 {
1609 #ifdef Q_OS_WIN
1610     Q_ASSERT(event);
1611     Q_ASSERT(receiver);
1612     Q_ASSERT(postedEvents);
1613 
1614     // compress posted timers to this object.
1615     if (event->type() == QEvent::Timer && receiver->d_func()->postedEvents > 0) {
1616         int timerId = ((QTimerEvent *) event)->timerId();
1617         for (int i=0; i<postedEvents->size(); ++i) {
1618             const QPostEvent &e = postedEvents->at(i);
1619             if (e.receiver == receiver && e.event && e.event->type() == QEvent::Timer
1620                 && ((QTimerEvent *) e.event)->timerId() == timerId) {
1621                 delete event;
1622                 return true;
1623             }
1624         }
1625         return false;
1626     }
1627 #endif
1628 
1629     if (event->type() == QEvent::DeferredDelete) {
1630         if (receiver->d_ptr->deleteLaterCalled) {
1631             // there was a previous DeferredDelete event, so we can drop the new one
1632             delete event;
1633             return true;
1634         }
1635         // deleteLaterCalled is set to true in postedEvents when queueing the very first
1636         // deferred deletion event.
1637         return false;
1638     }
1639 
1640     if (event->type() == QEvent::Quit && receiver->d_func()->postedEvents > 0) {
1641         for (int i = 0; i < postedEvents->size(); ++i) {
1642             const QPostEvent &cur = postedEvents->at(i);
1643             if (cur.receiver != receiver
1644                     || cur.event == nullptr
1645                     || cur.event->type() != event->type())
1646                 continue;
1647             // found an event for this receiver
1648             delete event;
1649             return true;
1650         }
1651     }
1652 
1653     return false;
1654 }
1655 
1656 /*!
1657   Immediately dispatches all events which have been previously queued
1658   with QCoreApplication::postEvent() and which are for the object \a
1659   receiver and have the event type \a event_type.
1660 
1661   Events from the window system are \e not dispatched by this
1662   function, but by processEvents().
1663 
1664   If \a receiver is \nullptr, the events of \a event_type are sent for
1665   all objects. If \a event_type is 0, all the events are sent for
1666   \a receiver.
1667 
1668   \note This method must be called from the thread in which its QObject
1669   parameter, \a receiver, lives.
1670 
1671   \sa flush(), postEvent()
1672 */
1673 void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type)
1674 {
1675     // ### Qt 6: consider splitting this method into a public and a private
1676     //           one, so that a user-invoked sendPostedEvents can be detected
1677     //           and handled properly.
1678     QThreadData *data = QThreadData::current();
1679 
1680     QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1681 }
1682 
1683 void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
1684                                                QThreadData *data)
1685 {
1686     if (event_type == -1) {
1687         // we were called by an obsolete event dispatcher.
1688         event_type = 0;
1689     }
1690 
1691     if (receiver && receiver->d_func()->threadData != data) {
1692         qWarning("QCoreApplication::sendPostedEvents: Cannot send "
1693                  "posted events for objects in another thread");
1694         return;
1695     }
1696 
1697     ++data->postEventList.recursion;
1698 
1699     auto locker = qt_unique_lock(data->postEventList.mutex);
1700 
1701     // by default, we assume that the event dispatcher can go to sleep after
1702     // processing all events. if any new events are posted while we send
1703     // events, canWait will be set to false.
1704     data->canWait = (data->postEventList.size() == 0);
1705 
1706     if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) {
1707         --data->postEventList.recursion;
1708         return;
1709     }
1710 
1711     data->canWait = true;
1712 
1713     // okay. here is the tricky loop. be careful about optimizing
1714     // this, it looks the way it does for good reasons.
1715     int startOffset = data->postEventList.startOffset;
1716     int &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1717     data->postEventList.insertionOffset = data->postEventList.size();
1718 
1719     // Exception-safe cleaning up without the need for a try/catch block
1720     struct CleanUp {
1721         QObject *receiver;
1722         int event_type;
1723         QThreadData *data;
1724         bool exceptionCaught;
1725 
1726         inline CleanUp(QObject *receiver, int event_type, QThreadData *data) :
1727             receiver(receiver), event_type(event_type), data(data), exceptionCaught(true)
1728         {}
1729         inline ~CleanUp()
1730         {
1731             if (exceptionCaught) {
1732                 // since we were interrupted, we need another pass to make sure we clean everything up
1733                 data->canWait = false;
1734             }
1735 
1736             --data->postEventList.recursion;
1737             if (!data->postEventList.recursion && !data->canWait && data->hasEventDispatcher())
1738                 data->eventDispatcher.loadRelaxed()->wakeUp();
1739 
1740             // clear the global list, i.e. remove everything that was
1741             // delivered.
1742             if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1743                 const QPostEventList::iterator it = data->postEventList.begin();
1744                 data->postEventList.erase(it, it + data->postEventList.startOffset);
1745                 data->postEventList.insertionOffset -= data->postEventList.startOffset;
1746                 Q_ASSERT(data->postEventList.insertionOffset >= 0);
1747                 data->postEventList.startOffset = 0;
1748             }
1749         }
1750     };
1751     CleanUp cleanup(receiver, event_type, data);
1752 
1753     while (i < data->postEventList.size()) {
1754         // avoid live-lock
1755         if (i >= data->postEventList.insertionOffset)
1756             break;
1757 
1758         const QPostEvent &pe = data->postEventList.at(i);
1759         ++i;
1760 
1761         if (!pe.event)
1762             continue;
1763         if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1764             data->canWait = false;
1765             continue;
1766         }
1767 
1768         if (pe.event->type() == QEvent::DeferredDelete) {
1769             // DeferredDelete events are sent either
1770             // 1) when the event loop that posted the event has returned; or
1771             // 2) if explicitly requested (with QEvent::DeferredDelete) for
1772             //    events posted by the current event loop; or
1773             // 3) if the event was posted before the outermost event loop.
1774 
1775             int eventLevel = static_cast<QDeferredDeleteEvent *>(pe.event)->loopLevel();
1776             int loopLevel = data->loopLevel + data->scopeLevel;
1777             const bool allowDeferredDelete =
1778                 (eventLevel > loopLevel
1779                  || (!eventLevel && loopLevel > 0)
1780                  || (event_type == QEvent::DeferredDelete
1781                      && eventLevel == loopLevel));
1782             if (!allowDeferredDelete) {
1783                 // cannot send deferred delete
1784                 if (!event_type && !receiver) {
1785                     // we must copy it first; we want to re-post the event
1786                     // with the event pointer intact, but we can't delay
1787                     // nulling the event ptr until after re-posting, as
1788                     // addEvent may invalidate pe.
1789                     QPostEvent pe_copy = pe;
1790 
1791                     // null out the event so if sendPostedEvents recurses, it
1792                     // will ignore this one, as it's been re-posted.
1793                     const_cast<QPostEvent &>(pe).event = nullptr;
1794 
1795                     // re-post the copied event so it isn't lost
1796                     data->postEventList.addEvent(pe_copy);
1797                 }
1798                 continue;
1799             }
1800         }
1801 
1802         // first, we diddle the event so that we can deliver
1803         // it, and that no one will try to touch it later.
1804         pe.event->posted = false;
1805         QEvent *e = pe.event;
1806         QObject * r = pe.receiver;
1807 
1808         --r->d_func()->postedEvents;
1809         Q_ASSERT(r->d_func()->postedEvents >= 0);
1810 
1811         // next, update the data structure so that we're ready
1812         // for the next event.
1813         const_cast<QPostEvent &>(pe).event = nullptr;
1814 
1815         locker.unlock();
1816         const auto relocker = qScopeGuard([&locker] { locker.lock(); });
1817 
1818         QScopedPointer<QEvent> event_deleter(e); // will delete the event (with the mutex unlocked)
1819 
1820         // after all that work, it's time to deliver the event.
1821         QCoreApplication::sendEvent(r, e);
1822 
1823         // careful when adding anything below this point - the
1824         // sendEvent() call might invalidate any invariants this
1825         // function depends on.
1826     }
1827 
1828     cleanup.exceptionCaught = false;
1829 }
1830 
1831 /*!
1832     \since 4.3
1833 
1834     Removes all events of the given \a eventType that were posted
1835     using postEvent() for \a receiver.
1836 
1837     The events are \e not dispatched, instead they are removed from
1838     the queue. You should never need to call this function. If you do
1839     call it, be aware that killing events may cause \a receiver to
1840     break one or more invariants.
1841 
1842     If \a receiver is \nullptr, the events of \a eventType are removed
1843     for all objects. If \a eventType is 0, all the events are removed
1844     for \a receiver. You should never call this function with \a
1845     eventType of 0.
1846 
1847     \threadsafe
1848 */
1849 
1850 void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
1851 {
1852     auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
1853     QThreadData *data = locker.threadData;
1854 
1855     // the QObject destructor calls this function directly.  this can
1856     // happen while the event loop is in the middle of posting events,
1857     // and when we get here, we may not have any more posted events
1858     // for this object.
1859     if (receiver && !receiver->d_func()->postedEvents)
1860         return;
1861 
1862     //we will collect all the posted events for the QObject
1863     //and we'll delete after the mutex was unlocked
1864     QVarLengthArray<QEvent*> events;
1865     int n = data->postEventList.size();
1866     int j = 0;
1867 
1868     for (int i = 0; i < n; ++i) {
1869         const QPostEvent &pe = data->postEventList.at(i);
1870 
1871         if ((!receiver || pe.receiver == receiver)
1872             && (pe.event && (eventType == 0 || pe.event->type() == eventType))) {
1873             --pe.receiver->d_func()->postedEvents;
1874             pe.event->posted = false;
1875             events.append(pe.event);
1876             const_cast<QPostEvent &>(pe).event = nullptr;
1877         } else if (!data->postEventList.recursion) {
1878             if (i != j)
1879                 qSwap(data->postEventList[i], data->postEventList[j]);
1880             ++j;
1881         }
1882     }
1883 
1884 #ifdef QT_DEBUG
1885     if (receiver && eventType == 0) {
1886         Q_ASSERT(!receiver->d_func()->postedEvents);
1887     }
1888 #endif
1889 
1890     if (!data->postEventList.recursion) {
1891         // truncate list
1892         data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
1893     }
1894 
1895     locker.unlock();
1896     qDeleteAll(events);
1897 }
1898 
1899 /*!
1900   Removes \a event from the queue of posted events, and emits a
1901   warning message if appropriate.
1902 
1903   \warning This function can be \e really slow. Avoid using it, if
1904   possible.
1905 
1906   \threadsafe
1907 */
1908 
1909 void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
1910 {
1911     if (!event || !event->posted)
1912         return;
1913 
1914     QThreadData *data = QThreadData::current();
1915 
1916     const auto locker = qt_scoped_lock(data->postEventList.mutex);
1917 
1918     if (data->postEventList.size() == 0) {
1919 #if defined(QT_DEBUG)
1920         qDebug("QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
1921                 (void*)event, event->type());
1922         return;
1923 #endif
1924     }
1925 
1926     for (int i = 0; i < data->postEventList.size(); ++i) {
1927         const QPostEvent & pe = data->postEventList.at(i);
1928         if (pe.event == event) {
1929 #ifndef QT_NO_DEBUG
1930             qWarning("QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
1931                      event->type(),
1932                      pe.receiver->metaObject()->className(),
1933                      pe.receiver->objectName().toLocal8Bit().data());
1934 #endif
1935             --pe.receiver->d_func()->postedEvents;
1936             pe.event->posted = false;
1937             delete pe.event;
1938             const_cast<QPostEvent &>(pe).event = nullptr;
1939             return;
1940         }
1941     }
1942 }
1943 
1944 /*!\reimp
1945 
1946 */
1947 bool QCoreApplication::event(QEvent *e)
1948 {
1949     if (e->type() == QEvent::Quit) {
1950         quit();
1951         return true;
1952     }
1953     return QObject::event(e);
1954 }
1955 
1956 /*! \enum QCoreApplication::Encoding
1957     \obsolete
1958 
1959     This enum type used to define the 8-bit encoding of character string
1960     arguments to translate(). This enum is now obsolete and UTF-8 will be
1961     used in all cases.
1962 
1963     \value UnicodeUTF8   UTF-8.
1964     \omitvalue Latin1
1965     \omitvalue DefaultCodec \omit UTF-8. \endomit
1966     \omitvalue CodecForTr
1967 
1968     \sa QObject::tr(), QString::fromUtf8()
1969 */
1970 
1971 void QCoreApplicationPrivate::ref()
1972 {
1973     quitLockRef.ref();
1974 }
1975 
1976 void QCoreApplicationPrivate::deref()
1977 {
1978     if (!quitLockRef.deref())
1979         maybeQuit();
1980 }
1981 
1982 void QCoreApplicationPrivate::maybeQuit()
1983 {
1984     if (quitLockRef.loadRelaxed() == 0 && in_exec && quitLockRefEnabled && shouldQuit())
1985         QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::Quit));
1986 }
1987 
1988 /*!
1989     Tells the application to exit with return code 0 (success).
1990     Equivalent to calling QCoreApplication::exit(0).
1991 
1992     It's common to connect the QGuiApplication::lastWindowClosed() signal
1993     to quit(), and you also often connect e.g. QAbstractButton::clicked() or
1994     signals in QAction, QMenu, or QMenuBar to it.
1995 
1996     It's good practice to always connect signals to this slot using a
1997     \l{Qt::}{QueuedConnection}. If a signal connected (non-queued) to this slot
1998     is emitted before control enters the main event loop (such as before
1999     "int main" calls \l{QCoreApplication::}{exec()}), the slot has no effect
2000     and the application never exits. Using a queued connection ensures that the
2001     slot will not be invoked until after control enters the main event loop.
2002 
2003     Example:
2004 
2005     \snippet code/src_corelib_kernel_qcoreapplication.cpp 1
2006 
2007     \sa exit(), aboutToQuit(), QGuiApplication::lastWindowClosed()
2008 */
2009 
2010 void QCoreApplication::quit()
2011 {
2012     exit(0);
2013 }
2014 
2015 /*!
2016   \fn void QCoreApplication::aboutToQuit()
2017 
2018   This signal is emitted when the application is about to quit the
2019   main event loop, e.g. when the event loop level drops to zero.
2020   This may happen either after a call to quit() from inside the
2021   application or when the user shuts down the entire desktop session.
2022 
2023   The signal is particularly useful if your application has to do some
2024   last-second cleanup. Note that no user interaction is possible in
2025   this state.
2026 
2027   \sa quit()
2028 */
2029 
2030 #endif // QT_NO_QOBJECT
2031 
2032 #ifndef QT_NO_TRANSLATION
2033 /*!
2034     Adds the translation file \a translationFile to the list of
2035     translation files to be used for translations.
2036 
2037     Multiple translation files can be installed. Translations are
2038     searched for in the reverse order in which they were installed,
2039     so the most recently installed translation file is searched first
2040     and the first translation file installed is searched last.
2041     The search stops as soon as a translation containing a matching
2042     string is found.
2043 
2044     Installing or removing a QTranslator, or changing an installed QTranslator
2045     generates a \l{QEvent::LanguageChange}{LanguageChange} event for the
2046     QCoreApplication instance. A QApplication instance will propagate the event
2047     to all toplevel widgets, where a reimplementation of changeEvent can
2048     re-translate the user interface by passing user-visible strings via the
2049     tr() function to the respective property setters. User-interface classes
2050     generated by Qt Designer provide a \c retranslateUi() function that can be
2051     called.
2052 
2053     The function returns \c true on success and false on failure.
2054 
2055     \sa removeTranslator(), translate(), QTranslator::load(), {Dynamic Translation}
2056 */
2057 
2058 bool QCoreApplication::installTranslator(QTranslator *translationFile)
2059 {
2060     if (!translationFile)
2061         return false;
2062 
2063     if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
2064         return false;
2065     QCoreApplicationPrivate *d = self->d_func();
2066     {
2067         QWriteLocker locker(&d->translateMutex);
2068         d->translators.prepend(translationFile);
2069     }
2070 
2071 #ifndef QT_NO_TRANSLATION_BUILDER
2072     if (translationFile->isEmpty())
2073         return false;
2074 #endif
2075 
2076 #ifndef QT_NO_QOBJECT
2077     QEvent ev(QEvent::LanguageChange);
2078     QCoreApplication::sendEvent(self, &ev);
2079 #endif
2080 
2081     return true;
2082 }
2083 
2084 /*!
2085     Removes the translation file \a translationFile from the list of
2086     translation files used by this application. (It does not delete the
2087     translation file from the file system.)
2088 
2089     The function returns \c true on success and false on failure.
2090 
2091     \sa installTranslator(), translate(), QObject::tr()
2092 */
2093 
2094 bool QCoreApplication::removeTranslator(QTranslator *translationFile)
2095 {
2096     if (!translationFile)
2097         return false;
2098     if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
2099         return false;
2100     QCoreApplicationPrivate *d = self->d_func();
2101     QWriteLocker locker(&d->translateMutex);
2102     if (d->translators.removeAll(translationFile)) {
2103 #ifndef QT_NO_QOBJECT
2104         locker.unlock();
2105         if (!self->closingDown()) {
2106             QEvent ev(QEvent::LanguageChange);
2107             QCoreApplication::sendEvent(self, &ev);
2108         }
2109 #endif
2110         return true;
2111     }
2112     return false;
2113 }
2114 
2115 static void replacePercentN(QString *result, int n)
2116 {
2117     if (n >= 0) {
2118         int percentPos = 0;
2119         int len = 0;
2120         while ((percentPos = result->indexOf(QLatin1Char('%'), percentPos + len)) != -1) {
2121             len = 1;
2122             if (percentPos + len == result->length())
2123                 break;
2124             QString fmt;
2125             if (result->at(percentPos + len) == QLatin1Char('L')) {
2126                 ++len;
2127                 if (percentPos + len == result->length())
2128                     break;
2129                 fmt = QLatin1String("%L1");
2130             } else {
2131                 fmt = QLatin1String("%1");
2132             }
2133             if (result->at(percentPos + len) == QLatin1Char('n')) {
2134                 fmt = fmt.arg(n);
2135                 ++len;
2136                 result->replace(percentPos, len, fmt);
2137                 len = fmt.length();
2138             }
2139         }
2140     }
2141 }
2142 
2143 /*!
2144     \threadsafe
2145 
2146     Returns the translation text for \a sourceText, by querying the
2147     installed translation files. The translation files are searched
2148     from the most recently installed file back to the first
2149     installed file.
2150 
2151     QObject::tr() provides this functionality more conveniently.
2152 
2153     \a context is typically a class name (e.g., "MyDialog") and \a
2154     sourceText is either English text or a short identifying text.
2155 
2156     \a disambiguation is an identifying string, for when the same \a
2157     sourceText is used in different roles within the same context. By
2158     default, it is \nullptr.
2159 
2160     See the \l QTranslator and \l QObject::tr() documentation for
2161     more information about contexts, disambiguations and comments.
2162 
2163     \a n is used in conjunction with \c %n to support plural forms.
2164     See QObject::tr() for details.
2165 
2166     If none of the translation files contain a translation for \a
2167     sourceText in \a context, this function returns a QString
2168     equivalent of \a sourceText.
2169 
2170     This function is not virtual. You can use alternative translation
2171     techniques by subclassing \l QTranslator.
2172 
2173     \sa QObject::tr(), installTranslator(), removeTranslator(), translate()
2174 */
2175 QString QCoreApplication::translate(const char *context, const char *sourceText,
2176                                     const char *disambiguation, int n)
2177 {
2178     QString result;
2179 
2180     if (!sourceText)
2181         return result;
2182 
2183     if (self) {
2184         QCoreApplicationPrivate *d = self->d_func();
2185         QReadLocker locker(&d->translateMutex);
2186         if (!d->translators.isEmpty()) {
2187             QList<QTranslator*>::ConstIterator it;
2188             QTranslator *translationFile;
2189             for (it = d->translators.constBegin(); it != d->translators.constEnd(); ++it) {
2190                 translationFile = *it;
2191                 result = translationFile->translate(context, sourceText, disambiguation, n);
2192                 if (!result.isNull())
2193                     break;
2194             }
2195         }
2196     }
2197 
2198     if (result.isNull())
2199         result = QString::fromUtf8(sourceText);
2200 
2201     replacePercentN(&result, n);
2202     return result;
2203 }
2204 
2205 /*! \fn static QString QCoreApplication::translate(const char *context, const char *key, const char *disambiguation, Encoding encoding, int n = -1)
2206 
2207   \obsolete
2208 */
2209 
2210 // Declared in qglobal.h
2211 QString qtTrId(const char *id, int n)
2212 {
2213     return QCoreApplication::translate(nullptr, id, nullptr, n);
2214 }
2215 
2216 bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
2217 {
2218     if (!QCoreApplication::self)
2219         return false;
2220     QCoreApplicationPrivate *d = QCoreApplication::self->d_func();
2221     QReadLocker locker(&d->translateMutex);
2222     return d->translators.contains(translator);
2223 }
2224 
2225 #else
2226 
2227 QString QCoreApplication::translate(const char *context, const char *sourceText,
2228                                     const char *disambiguation, int n)
2229 {
2230     Q_UNUSED(context)
2231     Q_UNUSED(disambiguation)
2232     QString ret = QString::fromUtf8(sourceText);
2233     if (n >= 0)
2234         ret.replace(QLatin1String("%n"), QString::number(n));
2235     return ret;
2236 }
2237 
2238 #endif //QT_NO_TRANSLATION
2239 
2240 // Makes it possible to point QCoreApplication to a custom location to ensure
2241 // the directory is added to the patch, and qt.conf and deployed plugins are
2242 // found from there. This is for use cases in which QGuiApplication is
2243 // instantiated by a library and not by an application executable, for example,
2244 // Active X servers.
2245 
2246 void QCoreApplicationPrivate::setApplicationFilePath(const QString &path)
2247 {
2248     if (QCoreApplicationPrivate::cachedApplicationFilePath)
2249         *QCoreApplicationPrivate::cachedApplicationFilePath = path;
2250     else
2251         QCoreApplicationPrivate::cachedApplicationFilePath = new QString(path);
2252 }
2253 
2254 /*!
2255     Returns the directory that contains the application executable.
2256 
2257     For example, if you have installed Qt in the \c{C:\Qt}
2258     directory, and you run the \c{regexp} example, this function will
2259     return "C:/Qt/examples/tools/regexp".
2260 
2261     On \macos and iOS this will point to the directory actually containing
2262     the executable, which may be inside an application bundle (if the
2263     application is bundled).
2264 
2265     \warning On Linux, this function will try to get the path from the
2266     \c {/proc} file system. If that fails, it assumes that \c
2267     {argv[0]} contains the absolute file name of the executable. The
2268     function also assumes that the current directory has not been
2269     changed by the application.
2270 
2271     \sa applicationFilePath()
2272 */
2273 QString QCoreApplication::applicationDirPath()
2274 {
2275     if (!self) {
2276         qWarning("QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
2277         return QString();
2278     }
2279 
2280     QCoreApplicationPrivate *d = self->d_func();
2281     if (d->cachedApplicationDirPath.isNull())
2282         d->cachedApplicationDirPath = QFileInfo(applicationFilePath()).path();
2283     return d->cachedApplicationDirPath;
2284 }
2285 
2286 /*!
2287     Returns the file path of the application executable.
2288 
2289     For example, if you have installed Qt in the \c{/usr/local/qt}
2290     directory, and you run the \c{regexp} example, this function will
2291     return "/usr/local/qt/examples/tools/regexp/regexp".
2292 
2293     \warning On Linux, this function will try to get the path from the
2294     \c {/proc} file system. If that fails, it assumes that \c
2295     {argv[0]} contains the absolute file name of the executable. The
2296     function also assumes that the current directory has not been
2297     changed by the application.
2298 
2299     \sa applicationDirPath()
2300 */
2301 QString QCoreApplication::applicationFilePath()
2302 {
2303     if (!self) {
2304         qWarning("QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
2305         return QString();
2306     }
2307 
2308     QCoreApplicationPrivate *d = self->d_func();
2309 
2310     if (d->argc) {
2311         static QByteArray procName = QByteArray(d->argv[0]);
2312         if (procName != d->argv[0]) {
2313             // clear the cache if the procname changes, so we reprocess it.
2314             QCoreApplicationPrivate::clearApplicationFilePath();
2315             procName = QByteArray(d->argv[0]);
2316         }
2317     }
2318 
2319     if (QCoreApplicationPrivate::cachedApplicationFilePath)
2320         return *QCoreApplicationPrivate::cachedApplicationFilePath;
2321 
2322 #if defined(Q_OS_WIN)
2323     QCoreApplicationPrivate::setApplicationFilePath(QFileInfo(qAppFileName()).filePath());
2324     return *QCoreApplicationPrivate::cachedApplicationFilePath;
2325 #elif defined(Q_OS_MAC)
2326     QString qAppFileName_str = qAppFileName();
2327     if(!qAppFileName_str.isEmpty()) {
2328         QFileInfo fi(qAppFileName_str);
2329         if (fi.exists()) {
2330             QCoreApplicationPrivate::setApplicationFilePath(fi.canonicalFilePath());
2331             return *QCoreApplicationPrivate::cachedApplicationFilePath;
2332         }
2333     }
2334 #endif
2335 #if defined( Q_OS_UNIX )
2336 #  if defined(Q_OS_LINUX) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_EMBEDDED))
2337     // Try looking for a /proc/<pid>/exe symlink first which points to
2338     // the absolute path of the executable
2339     QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
2340     if (pfi.exists() && pfi.isSymLink()) {
2341         QCoreApplicationPrivate::setApplicationFilePath(pfi.canonicalFilePath());
2342         return *QCoreApplicationPrivate::cachedApplicationFilePath;
2343     }
2344 #  endif
2345     if (!arguments().isEmpty()) {
2346         QString argv0 = QFile::decodeName(arguments().at(0).toLocal8Bit());
2347         QString absPath;
2348 
2349         if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
2350             /*
2351               If argv0 starts with a slash, it is already an absolute
2352               file path.
2353             */
2354             absPath = argv0;
2355         } else if (argv0.contains(QLatin1Char('/'))) {
2356             /*
2357               If argv0 contains one or more slashes, it is a file path
2358               relative to the current directory.
2359             */
2360             absPath = QDir::current().absoluteFilePath(argv0);
2361         } else {
2362             /*
2363               Otherwise, the file path has to be determined using the
2364               PATH environment variable.
2365             */
2366             absPath = QStandardPaths::findExecutable(argv0);
2367         }
2368 
2369         absPath = QDir::cleanPath(absPath);
2370 
2371         QFileInfo fi(absPath);
2372         if (fi.exists()) {
2373             QCoreApplicationPrivate::setApplicationFilePath(fi.canonicalFilePath());
2374             return *QCoreApplicationPrivate::cachedApplicationFilePath;
2375         }
2376     }
2377 
2378 #endif
2379     return QString();
2380 }
2381 
2382 /*!
2383     \since 4.4
2384 
2385     Returns the current process ID for the application.
2386 */
2387 qint64 QCoreApplication::applicationPid()
2388 {
2389 #if defined(Q_OS_WIN)
2390     return GetCurrentProcessId();
2391 #elif defined(Q_OS_VXWORKS)
2392     return (pid_t) taskIdCurrent;
2393 #else
2394     return getpid();
2395 #endif
2396 }
2397 
2398 /*!
2399     \since 4.1
2400 
2401     Returns the list of command-line arguments.
2402 
2403     Usually arguments().at(0) is the program name, arguments().at(1)
2404     is the first argument, and arguments().last() is the last
2405     argument. See the note below about Windows.
2406 
2407     Calling this function is slow - you should store the result in a variable
2408     when parsing the command line.
2409 
2410     \warning On Unix, this list is built from the argc and argv parameters passed
2411     to the constructor in the main() function. The string-data in argv is
2412     interpreted using QString::fromLocal8Bit(); hence it is not possible to
2413     pass, for example, Japanese command line arguments on a system that runs in a
2414     Latin1 locale. Most modern Unix systems do not have this limitation, as they are
2415     Unicode-based.
2416 
2417     On Windows, the list is built from the argc and argv parameters only if
2418     modified argv/argc parameters are passed to the constructor. In that case,
2419     encoding problems might occur.
2420 
2421     Otherwise, the arguments() are constructed from the return value of
2422     \l{http://msdn2.microsoft.com/en-us/library/ms683156(VS.85).aspx}{GetCommandLine()}.
2423     As a result of this, the string given by arguments().at(0) might not be
2424     the program name on Windows, depending on how the application was started.
2425 
2426     \sa applicationFilePath(), QCommandLineParser
2427 */
2428 
2429 QStringList QCoreApplication::arguments()
2430 {
2431     QStringList list;
2432 
2433     if (!self) {
2434         qWarning("QCoreApplication::arguments: Please instantiate the QApplication object first");
2435         return list;
2436     }
2437 
2438     const QCoreApplicationPrivate *d = self->d_func();
2439 
2440     const int argc = d->argc;
2441     char ** const argv = d->argv;
2442     list.reserve(argc);
2443 
2444 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
2445     const bool argsModifiedByUser = d->origArgv == nullptr;
2446     if (!argsModifiedByUser) {
2447         // On Windows, it is possible to pass Unicode arguments on
2448         // the command line, but we don't implement any of the wide
2449         // entry-points (wmain/wWinMain), so get the arguments from
2450         // the Windows API instead of using argv. Note that we only
2451         // do this when argv were not modified by the user in main().
2452         QString cmdline = QString::fromWCharArray(GetCommandLine());
2453         QStringList commandLineArguments = qWinCmdArgs(cmdline);
2454 
2455         // Even if the user didn't modify argv before passing them
2456         // on to QCoreApplication, derived QApplications might have.
2457         // If that's the case argc will differ from origArgc.
2458         if (argc != d->origArgc) {
2459             // Note: On MingGW the arguments from GetCommandLine are
2460             // not wildcard expanded (if wildcard expansion is enabled),
2461             // as opposed to the arguments in argv. This means we can't
2462             // compare commandLineArguments to argv/origArgc, but
2463             // must remove elements by value, based on whether they
2464             // were filtered out from argc.
2465             for (int i = 0; i < d->origArgc; ++i) {
2466                 if (!contains(argc, argv, d->origArgv[i]))
2467                     commandLineArguments.removeAll(QString::fromLocal8Bit(d->origArgv[i]));
2468             }
2469         }
2470 
2471         return commandLineArguments;
2472     } // Fall back to rebuilding from argv/argc when a modified argv was passed.
2473 #endif // defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
2474 
2475     for (int a = 0; a < argc; ++a)
2476         list << QString::fromLocal8Bit(argv[a]);
2477 
2478     return list;
2479 }
2480 
2481 /*!
2482     \property QCoreApplication::organizationName
2483     \brief the name of the organization that wrote this application
2484 
2485     The value is used by the QSettings class when it is constructed
2486     using the empty constructor. This saves having to repeat this
2487     information each time a QSettings object is created.
2488 
2489     On Mac, QSettings uses \l {QCoreApplication::}{organizationDomain()} as the organization
2490     if it's not an empty string; otherwise it uses
2491     organizationName(). On all other platforms, QSettings uses
2492     organizationName() as the organization.
2493 
2494     \sa organizationDomain, applicationName
2495 */
2496 
2497 /*!
2498   \fn void QCoreApplication::organizationNameChanged()
2499   \internal
2500 
2501   While not useful from C++ due to how organizationName is normally set once on
2502   startup, this is still needed for QML so that bindings are reevaluated after
2503   that initial change.
2504 */
2505 void QCoreApplication::setOrganizationName(const QString &orgName)
2506 {
2507     if (coreappdata()->orgName == orgName)
2508         return;
2509     coreappdata()->orgName = orgName;
2510 #ifndef QT_NO_QOBJECT
2511     if (QCoreApplication::self)
2512         emit QCoreApplication::self->organizationNameChanged();
2513 #endif
2514 }
2515 
2516 QString QCoreApplication::organizationName()
2517 {
2518     return coreappdata()->orgName;
2519 }
2520 
2521 /*!
2522     \property QCoreApplication::organizationDomain
2523     \brief the Internet domain of the organization that wrote this application
2524 
2525     The value is used by the QSettings class when it is constructed
2526     using the empty constructor. This saves having to repeat this
2527     information each time a QSettings object is created.
2528 
2529     On Mac, QSettings uses organizationDomain() as the organization
2530     if it's not an empty string; otherwise it uses organizationName().
2531     On all other platforms, QSettings uses organizationName() as the
2532     organization.
2533 
2534     \sa organizationName, applicationName, applicationVersion
2535 */
2536 /*!
2537   \fn void QCoreApplication::organizationDomainChanged()
2538   \internal
2539 
2540   Primarily for QML, see organizationNameChanged.
2541 */
2542 void QCoreApplication::setOrganizationDomain(const QString &orgDomain)
2543 {
2544     if (coreappdata()->orgDomain == orgDomain)
2545         return;
2546     coreappdata()->orgDomain = orgDomain;
2547 #ifndef QT_NO_QOBJECT
2548     if (QCoreApplication::self)
2549         emit QCoreApplication::self->organizationDomainChanged();
2550 #endif
2551 }
2552 
2553 QString QCoreApplication::organizationDomain()
2554 {
2555     return coreappdata()->orgDomain;
2556 }
2557 
2558 /*!
2559     \property QCoreApplication::applicationName
2560     \brief the name of this application
2561 
2562     The value is used by the QSettings class when it is constructed
2563     using the empty constructor. This saves having to repeat this
2564     information each time a QSettings object is created.
2565 
2566     If not set, the application name defaults to the executable name (since 5.0).
2567 
2568     \sa organizationName, organizationDomain, applicationVersion, applicationFilePath()
2569 */
2570 /*!
2571   \fn void QCoreApplication::applicationNameChanged()
2572   \internal
2573 
2574   Primarily for QML, see organizationNameChanged.
2575 */
2576 void QCoreApplication::setApplicationName(const QString &application)
2577 {
2578     coreappdata()->applicationNameSet = !application.isEmpty();
2579     QString newAppName = application;
2580     if (newAppName.isEmpty() && QCoreApplication::self)
2581         newAppName = QCoreApplication::self->d_func()->appName();
2582     if (coreappdata()->application == newAppName)
2583         return;
2584     coreappdata()->application = newAppName;
2585 #ifndef QT_NO_QOBJECT
2586     if (QCoreApplication::self)
2587         emit QCoreApplication::self->applicationNameChanged();
2588 #endif
2589 }
2590 
2591 QString QCoreApplication::applicationName()
2592 {
2593     return coreappdata() ? coreappdata()->application : QString();
2594 }
2595 
2596 // Exported for QDesktopServices (Qt4 behavior compatibility)
2597 Q_CORE_EXPORT QString qt_applicationName_noFallback()
2598 {
2599     return coreappdata()->applicationNameSet ? coreappdata()->application : QString();
2600 }
2601 
2602 /*!
2603     \property QCoreApplication::applicationVersion
2604     \since 4.4
2605     \brief the version of this application
2606 
2607     If not set, the application version defaults to a platform-specific value
2608     determined from the main application executable or package (since Qt 5.9):
2609 
2610     \table
2611     \header
2612         \li Platform
2613         \li Source
2614     \row
2615         \li Windows (classic desktop)
2616         \li PRODUCTVERSION parameter of the VERSIONINFO resource
2617     \row
2618         \li Universal Windows Platform
2619         \li version attribute of the application package manifest
2620     \row
2621         \li macOS, iOS, tvOS, watchOS
2622         \li CFBundleVersion property of the information property list
2623     \row
2624         \li Android
2625         \li android:versionName property of the AndroidManifest.xml manifest element
2626     \endtable
2627 
2628     On other platforms, the default is the empty string.
2629 
2630     \sa applicationName, organizationName, organizationDomain
2631 */
2632 /*!
2633   \fn void QCoreApplication::applicationVersionChanged()
2634   \internal
2635 
2636   Primarily for QML, see organizationNameChanged.
2637 */
2638 void QCoreApplication::setApplicationVersion(const QString &version)
2639 {
2640     coreappdata()->applicationVersionSet = !version.isEmpty();
2641     QString newVersion = version;
2642     if (newVersion.isEmpty() && QCoreApplication::self)
2643         newVersion = QCoreApplication::self->d_func()->appVersion();
2644     if (coreappdata()->applicationVersion == newVersion)
2645         return;
2646     coreappdata()->applicationVersion = newVersion;
2647 #ifndef QT_NO_QOBJECT
2648     if (QCoreApplication::self)
2649         emit QCoreApplication::self->applicationVersionChanged();
2650 #endif
2651 }
2652 
2653 QString QCoreApplication::applicationVersion()
2654 {
2655     return coreappdata() ? coreappdata()->applicationVersion : QString();
2656 }
2657 
2658 #if QT_CONFIG(library)
2659 
2660 Q_GLOBAL_STATIC(QRecursiveMutex, libraryPathMutex)
2661 
2662 /*!
2663     Returns a list of paths that the application will search when
2664     dynamically loading libraries.
2665 
2666     The return value of this function may change when a QCoreApplication
2667     is created. It is not recommended to call it before creating a
2668     QCoreApplication. The directory of the application executable (\b not
2669     the working directory) is part of the list if it is known. In order
2670     to make it known a QCoreApplication has to be constructed as it will
2671     use \c {argv[0]} to find it.
2672 
2673     Qt provides default library paths, but they can also be set using
2674     a \l{Using qt.conf}{qt.conf} file. Paths specified in this file
2675     will override default values. Note that if the qt.conf file is in
2676     the directory of the application executable, it may not be found
2677     until a QCoreApplication is created. If it is not found when calling
2678     this function, the default library paths will be used.
2679 
2680     The list will include the installation directory for plugins if
2681     it exists (the default installation directory for plugins is \c
2682     INSTALL/plugins, where \c INSTALL is the directory where Qt was
2683     installed). The colon separated entries of the \c QT_PLUGIN_PATH
2684     environment variable are always added. The plugin installation
2685     directory (and its existence) may change when the directory of
2686     the application executable becomes known.
2687 
2688     If you want to iterate over the list, you can use the \l foreach
2689     pseudo-keyword:
2690 
2691     \snippet code/src_corelib_kernel_qcoreapplication.cpp 2
2692 
2693     \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary,
2694         {How to Create Qt Plugins}
2695 */
2696 QStringList QCoreApplication::libraryPaths()
2697 {
2698     QMutexLocker locker(libraryPathMutex());
2699     return libraryPathsLocked();
2700 }
2701 
2702 /*!
2703     \internal
2704 */
2705 QStringList QCoreApplication::libraryPathsLocked()
2706 {
2707     if (coreappdata()->manual_libpaths)
2708         return *(coreappdata()->manual_libpaths);
2709 
2710     if (!coreappdata()->app_libpaths) {
2711         QStringList *app_libpaths = new QStringList;
2712         coreappdata()->app_libpaths.reset(app_libpaths);
2713 
2714         auto setPathsFromEnv = [&](QString libPathEnv) {
2715             if (!libPathEnv.isEmpty()) {
2716                 QStringList paths = libPathEnv.split(QDir::listSeparator(), Qt::SkipEmptyParts);
2717                 for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
2718                     QString canonicalPath = QDir(*it).canonicalPath();
2719                     if (!canonicalPath.isEmpty()
2720                         && !app_libpaths->contains(canonicalPath)) {
2721                         app_libpaths->append(canonicalPath);
2722                     }
2723                 }
2724             }
2725         };
2726         setPathsFromEnv(qEnvironmentVariable("QT_PLUGIN_PATH"));
2727 #ifdef Q_OS_ANDROID
2728         setPathsFromEnv(qEnvironmentVariable("QT_BUNDLED_LIBS_PATH"));
2729 #endif
2730 #ifdef Q_OS_DARWIN
2731         // Check the main bundle's PlugIns directory as this is a standard location for Apple OSes.
2732         // Note that the QLibraryInfo::PluginsPath below will coincidentally be the same as this value
2733         // but with a different casing, so it can't be relied upon when the underlying filesystem
2734         // is case sensitive (and this is always the case on newer OSes like iOS).
2735         if (CFBundleRef bundleRef = CFBundleGetMainBundle()) {
2736             if (QCFType<CFURLRef> urlRef = CFBundleCopyBuiltInPlugInsURL(bundleRef)) {
2737                 if (QCFType<CFURLRef> absoluteUrlRef = CFURLCopyAbsoluteURL(urlRef)) {
2738                     if (QCFString path = CFURLCopyFileSystemPath(absoluteUrlRef, kCFURLPOSIXPathStyle)) {
2739                         if (QFile::exists(path)) {
2740                             path = QDir(path).canonicalPath();
2741                             if (!app_libpaths->contains(path))
2742                                 app_libpaths->append(path);
2743                         }
2744                     }
2745                 }
2746             }
2747         }
2748 #endif // Q_OS_DARWIN
2749 
2750         QString installPathPlugins =  QLibraryInfo::location(QLibraryInfo::PluginsPath);
2751         if (QFile::exists(installPathPlugins)) {
2752             // Make sure we convert from backslashes to slashes.
2753             installPathPlugins = QDir(installPathPlugins).canonicalPath();
2754             if (!app_libpaths->contains(installPathPlugins))
2755                 app_libpaths->append(installPathPlugins);
2756         }
2757 
2758         // If QCoreApplication is not yet instantiated,
2759         // make sure we add the application path when we construct the QCoreApplication
2760         if (self) self->d_func()->appendApplicationPathToLibraryPaths();
2761     }
2762     return *(coreappdata()->app_libpaths);
2763 }
2764 
2765 
2766 
2767 /*!
2768 
2769     Sets the list of directories to search when loading libraries to
2770     \a paths. All existing paths will be deleted and the path list
2771     will consist of the paths given in \a paths.
2772 
2773     The library paths are reset to the default when an instance of
2774     QCoreApplication is destructed.
2775 
2776     \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
2777  */
2778 void QCoreApplication::setLibraryPaths(const QStringList &paths)
2779 {
2780     QMutexLocker locker(libraryPathMutex());
2781 
2782     // setLibraryPaths() is considered a "remove everything and then add some new ones" operation.
2783     // When the application is constructed it should still amend the paths. So we keep the originals
2784     // around, and even create them if they don't exist, yet.
2785     if (!coreappdata()->app_libpaths)
2786         libraryPathsLocked();
2787 
2788     if (coreappdata()->manual_libpaths)
2789         *(coreappdata()->manual_libpaths) = paths;
2790     else
2791         coreappdata()->manual_libpaths.reset(new QStringList(paths));
2792 
2793     locker.unlock();
2794     QFactoryLoader::refreshAll();
2795 }
2796 
2797 /*!
2798   Prepends \a path to the beginning of the library path list, ensuring that
2799   it is searched for libraries first. If \a path is empty or already in the
2800   path list, the path list is not changed.
2801 
2802   The default path list consists of a single entry, the installation
2803   directory for plugins.  The default installation directory for plugins
2804   is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
2805   installed.
2806 
2807   The library paths are reset to the default when an instance of
2808   QCoreApplication is destructed.
2809 
2810   \sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
2811  */
2812 void QCoreApplication::addLibraryPath(const QString &path)
2813 {
2814     if (path.isEmpty())
2815         return;
2816 
2817     QString canonicalPath = QDir(path).canonicalPath();
2818     if (canonicalPath.isEmpty())
2819         return;
2820 
2821     QMutexLocker locker(libraryPathMutex());
2822 
2823     QStringList *libpaths = coreappdata()->manual_libpaths.data();
2824     if (libpaths) {
2825         if (libpaths->contains(canonicalPath))
2826             return;
2827     } else {
2828         // make sure that library paths are initialized
2829         libraryPathsLocked();
2830         QStringList *app_libpaths = coreappdata()->app_libpaths.data();
2831         if (app_libpaths->contains(canonicalPath))
2832             return;
2833 
2834         coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
2835     }
2836 
2837     libpaths->prepend(canonicalPath);
2838     locker.unlock();
2839     QFactoryLoader::refreshAll();
2840 }
2841 
2842 /*!
2843     Removes \a path from the library path list. If \a path is empty or not
2844     in the path list, the list is not changed.
2845 
2846     The library paths are reset to the default when an instance of
2847     QCoreApplication is destructed.
2848 
2849     \sa addLibraryPath(), libraryPaths(), setLibraryPaths()
2850 */
2851 void QCoreApplication::removeLibraryPath(const QString &path)
2852 {
2853     if (path.isEmpty())
2854         return;
2855 
2856     QString canonicalPath = QDir(path).canonicalPath();
2857     if (canonicalPath.isEmpty())
2858         return;
2859 
2860     QMutexLocker locker(libraryPathMutex());
2861 
2862     QStringList *libpaths = coreappdata()->manual_libpaths.data();
2863     if (libpaths) {
2864         if (libpaths->removeAll(canonicalPath) == 0)
2865             return;
2866     } else {
2867         // make sure that library paths is initialized
2868         libraryPathsLocked();
2869         QStringList *app_libpaths = coreappdata()->app_libpaths.data();
2870         if (!app_libpaths->contains(canonicalPath))
2871             return;
2872 
2873         coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
2874         libpaths->removeAll(canonicalPath);
2875     }
2876 
2877     locker.unlock();
2878     QFactoryLoader::refreshAll();
2879 }
2880 
2881 #endif // QT_CONFIG(library)
2882 
2883 #ifndef QT_NO_QOBJECT
2884 
2885 /*!
2886     Installs an event filter \a filterObj for all native events
2887     received by the application in the main thread.
2888 
2889     The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()}
2890     function, which is called for all native events received in the main thread.
2891 
2892     The QAbstractNativeEventFilter::nativeEventFilter() function should
2893     return true if the event should be filtered, i.e. stopped. It should
2894     return false to allow normal Qt processing to continue: the native
2895     event can then be translated into a QEvent and handled by the standard
2896     Qt \l{QEvent} {event} filtering, e.g. QObject::installEventFilter().
2897 
2898     If multiple event filters are installed, the filter that was
2899     installed last is activated first.
2900 
2901     \note The filter function set here receives native messages,
2902     i.e. MSG or XCB event structs.
2903 
2904     \note Native event filters will be disabled in the application when the
2905     Qt::AA_PluginApplication attribute is set.
2906 
2907     For maximum portability, you should always try to use QEvent
2908     and QObject::installEventFilter() whenever possible.
2909 
2910     \sa QObject::installEventFilter()
2911 
2912     \since 5.0
2913 */
2914 void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
2915 {
2916     if (QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
2917         qWarning("Native event filters are not applied when the Qt::AA_PluginApplication attribute is set");
2918         return;
2919     }
2920 
2921     QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire());
2922     if (!filterObj || !eventDispatcher)
2923         return;
2924     eventDispatcher->installNativeEventFilter(filterObj);
2925 }
2926 
2927 /*!
2928     Removes an event \a filterObject from this object. The
2929     request is ignored if such an event filter has not been installed.
2930 
2931     All event filters for this object are automatically removed when
2932     this object is destroyed.
2933 
2934     It is always safe to remove an event filter, even during event
2935     filter activation (i.e. from the nativeEventFilter() function).
2936 
2937     \sa installNativeEventFilter()
2938     \since 5.0
2939 */
2940 void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filterObject)
2941 {
2942     QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2943     if (!filterObject || !eventDispatcher)
2944         return;
2945     eventDispatcher->removeNativeEventFilter(filterObject);
2946 }
2947 
2948 /*!
2949     \deprecated
2950 
2951     This function returns \c true if there are pending events; otherwise
2952     returns \c false. Pending events can be either from the window
2953     system or posted events using postEvent().
2954 
2955     \note this function is not thread-safe. It may only be called in the main
2956     thread and only if there are no other threads running in the application
2957     (including threads Qt starts for its own purposes).
2958 
2959     \sa QAbstractEventDispatcher::hasPendingEvents()
2960 */
2961 #if QT_DEPRECATED_SINCE(5, 3)
2962 bool QCoreApplication::hasPendingEvents()
2963 {
2964     QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2965     if (eventDispatcher)
2966         return eventDispatcher->hasPendingEvents();
2967     return false;
2968 }
2969 #endif
2970 
2971 /*!
2972     Returns a pointer to the event dispatcher object for the main thread. If no
2973     event dispatcher exists for the thread, this function returns \nullptr.
2974 */
2975 QAbstractEventDispatcher *QCoreApplication::eventDispatcher()
2976 {
2977     if (QCoreApplicationPrivate::theMainThread.loadAcquire())
2978         return QCoreApplicationPrivate::theMainThread.loadRelaxed()->eventDispatcher();
2979     return nullptr;
2980 }
2981 
2982 /*!
2983     Sets the event dispatcher for the main thread to \a eventDispatcher. This
2984     is only possible as long as there is no event dispatcher installed yet. That
2985     is, before QCoreApplication has been instantiated. This method takes
2986     ownership of the object.
2987 */
2988 void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
2989 {
2990     QThread *mainThread = QCoreApplicationPrivate::theMainThread.loadAcquire();
2991     if (!mainThread)
2992         mainThread = QThread::currentThread(); // will also setup theMainThread
2993     mainThread->setEventDispatcher(eventDispatcher);
2994 }
2995 
2996 #endif // QT_NO_QOBJECT
2997 
2998 /*!
2999     \macro Q_COREAPP_STARTUP_FUNCTION(QtStartUpFunction ptr)
3000     \since 5.1
3001     \relates QCoreApplication
3002     \reentrant
3003 
3004     Adds a global function that will be called from the QCoreApplication
3005     constructor. This macro is normally used to initialize libraries
3006     for program-wide functionality, without requiring the application to
3007     call into the library for initialization.
3008 
3009     The function specified by \a ptr should take no arguments and should
3010     return nothing. For example:
3011 
3012     \snippet code/src_corelib_kernel_qcoreapplication.cpp 3
3013 
3014     Note that the startup function will run at the end of the QCoreApplication constructor,
3015     before any GUI initialization. If GUI code is required in the function,
3016     use a timer (or a queued invocation) to perform the initialization later on,
3017     from the event loop.
3018 
3019     If QCoreApplication is deleted and another QCoreApplication is created,
3020     the startup function will be invoked again.
3021 
3022     \note This macro is not suitable for use in library code that is then
3023     statically linked into an application since the function may not be called
3024     at all due to being eliminated by the linker.
3025 */
3026 
3027 /*!
3028     \fn void qAddPostRoutine(QtCleanUpFunction ptr)
3029     \threadsafe
3030     \relates QCoreApplication
3031 
3032     Adds a global routine that will be called from the QCoreApplication
3033     destructor. This function is normally used to add cleanup routines
3034     for program-wide functionality.
3035 
3036     The cleanup routines are called in the reverse order of their addition.
3037 
3038     The function specified by \a ptr should take no arguments and should
3039     return nothing. For example:
3040 
3041     \snippet code/src_corelib_kernel_qcoreapplication.cpp 4
3042 
3043     Note that for an application- or module-wide cleanup, qAddPostRoutine()
3044     is often not suitable. For example, if the program is split into dynamically
3045     loaded modules, the relevant module may be unloaded long before the
3046     QCoreApplication destructor is called. In such cases, if using qAddPostRoutine()
3047     is still desirable, qRemovePostRoutine() can be used to prevent a routine
3048     from being called by the QCoreApplication destructor. For example, if that
3049     routine was called before the module was unloaded.
3050 
3051     For modules and libraries, using a reference-counted
3052     initialization manager or Qt's parent-child deletion mechanism may
3053     be better. Here is an example of a private class that uses the
3054     parent-child mechanism to call a cleanup function at the right
3055     time:
3056 
3057     \snippet code/src_corelib_kernel_qcoreapplication.cpp 5
3058 
3059     By selecting the right parent object, this can often be made to
3060     clean up the module's data at the right moment.
3061 
3062     \note This function has been thread-safe since Qt 5.10.
3063 
3064     \sa qRemovePostRoutine()
3065 */
3066 
3067 /*!
3068     \fn void qRemovePostRoutine(QtCleanUpFunction ptr)
3069     \threadsafe
3070     \relates QCoreApplication
3071     \since 5.3
3072 
3073     Removes the cleanup routine specified by \a ptr from the list of
3074     routines called by the QCoreApplication destructor. The routine
3075     must have been previously added to the list by a call to
3076     qAddPostRoutine(), otherwise this function has no effect.
3077 
3078     \note This function has been thread-safe since Qt 5.10.
3079 
3080     \sa qAddPostRoutine()
3081 */
3082 
3083 /*!
3084     \macro Q_DECLARE_TR_FUNCTIONS(context)
3085     \relates QCoreApplication
3086 
3087     The Q_DECLARE_TR_FUNCTIONS() macro declares and implements two
3088     translation functions, \c tr() and \c trUtf8(), with these
3089     signatures:
3090 
3091     \snippet code/src_corelib_kernel_qcoreapplication.cpp 6
3092 
3093     This macro is useful if you want to use QObject::tr() or
3094     QObject::trUtf8() in classes that don't inherit from QObject.
3095 
3096     Q_DECLARE_TR_FUNCTIONS() must appear at the very top of the
3097     class definition (before the first \c{public:} or \c{protected:}).
3098     For example:
3099 
3100     \snippet code/src_corelib_kernel_qcoreapplication.cpp 7
3101 
3102     The \a context parameter is normally the class name, but it can
3103     be any text.
3104 
3105     \sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
3106 */
3107 
3108 QT_END_NAMESPACE
3109 
3110 #ifndef QT_NO_QOBJECT
3111 #include "moc_qcoreapplication.cpp"
3112 #endif
3113