Move handling of -qmljsdebugger argument to QCoreApplication
[profile/ivi/qtbase.git] / src / corelib / kernel / qcoreapplication.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qcoreapplication.h"
43 #include "qcoreapplication_p.h"
44
45 #include "qabstracteventdispatcher.h"
46 #include "qcoreevent.h"
47 #include "qeventloop.h"
48 #include "qcorecmdlineargs_p.h"
49 #include <qdatastream.h>
50 #include <qdebug.h>
51 #include <qdir.h>
52 #include <qfile.h>
53 #include <qfileinfo.h>
54 #include <qhash.h>
55 #include <private/qprocess_p.h>
56 #include <qtextcodec.h>
57 #include <qthread.h>
58 #include <qthreadpool.h>
59 #include <qthreadstorage.h>
60 #include <private/qthread_p.h>
61 #include <qelapsedtimer.h>
62 #include <qlibraryinfo.h>
63 #include <qvarlengtharray.h>
64 #include <private/qfactoryloader_p.h>
65 #include <private/qfunctions_p.h>
66 #include <private/qlocale_p.h>
67
68 #ifdef Q_OS_SYMBIAN
69 #  include <exception>
70 #  include <f32file.h>
71 #  include <e32ldr.h>
72 #  include "qeventdispatcher_symbian_p.h"
73 #  include "private/qcore_symbian_p.h"
74 #  include "private/qfilesystemengine_p.h"
75 #  include <apacmdln.h>
76 #elif defined(Q_OS_UNIX)
77 #  if !defined(QT_NO_GLIB)
78 #    include "qeventdispatcher_glib_p.h"
79 #  endif
80 #  include "qeventdispatcher_unix_p.h"
81 #endif
82
83 #ifdef Q_OS_WIN
84 #  include "qeventdispatcher_win_p.h"
85 #endif
86
87 #ifdef Q_OS_MAC
88 #  include "qcore_mac_p.h"
89 #endif
90
91 #include <stdlib.h>
92
93 #ifdef Q_OS_UNIX
94 #  include <locale.h>
95 #endif
96
97 #ifdef Q_OS_VXWORKS
98 #  include <taskLib.h>
99 #endif
100
101 QT_BEGIN_NAMESPACE
102
103 class QMutexUnlocker
104 {
105 public:
106     inline explicit QMutexUnlocker(QMutex *m)
107         : mtx(m)
108     { }
109     inline ~QMutexUnlocker() { unlock(); }
110     inline void unlock() { if (mtx) mtx->unlock(); mtx = 0; }
111
112 private:
113     Q_DISABLE_COPY(QMutexUnlocker)
114
115     QMutex *mtx;
116 };
117
118 #ifdef Q_OS_SYMBIAN
119 typedef TDriveNumber (*SystemDriveFunc)(RFs&);
120 static SystemDriveFunc PtrGetSystemDrive = 0;
121 static CApaCommandLine* apaCommandLine = 0;
122 static char *apaTail = 0;
123 static QVector<char *> *apaArgv = 0;
124
125 static void qt_cleanup_apa_cmd_line()
126 {
127     delete apaCommandLine;
128     apaCommandLine = 0;
129     delete apaArgv;
130     apaArgv = 0;
131     delete apaTail;
132     apaTail = 0;
133 }
134
135 static inline void qt_init_symbian_apa_arguments(int &argc, char **&argv)
136 {
137     // If app is launched via CApaCommandLine::StartApp(), normal arguments only contain
138     // application name.
139     if (argc == 1) {
140         CApaCommandLine* commandLine = QCoreApplicationPrivate::symbianCommandLine();
141         if(commandLine) {
142             TPtrC8 apaCmdLine = commandLine->TailEnd();
143             int tailLen = apaCmdLine.Length();
144             if (tailLen) {
145                 apaTail = reinterpret_cast<char *>(qMalloc(tailLen + 1));
146                 qMemCopy(apaTail, reinterpret_cast<const char *>(apaCmdLine.Ptr()), tailLen);
147                 apaTail[tailLen] = '\0';
148                 apaArgv = new QVector<char *>(8);
149                 // Reuse windows command line parsing
150                 *apaArgv = qWinCmdLine<char>(apaTail, tailLen, argc);
151                 apaArgv->insert(0, argv[0]);
152                 argc++;
153                 argv = apaArgv->data();
154             }
155         }
156     }
157 }
158
159 CApaCommandLine* QCoreApplicationPrivate::symbianCommandLine()
160 {
161     // Getting of Apa command line needs to be static as it can only be called successfully
162         // once per process.
163     if (!apaCommandLine) {
164         TInt err = CApaCommandLine::GetCommandLineFromProcessEnvironment(apaCommandLine);
165         if (err == KErrNone) {
166             qAddPostRoutine(qt_cleanup_apa_cmd_line);
167         }
168     }
169     return apaCommandLine;
170 }
171
172 #endif
173
174 #if defined(Q_OS_WIN) || defined(Q_WS_MAC)
175 extern QString qAppFileName();
176 #endif
177
178 int QCoreApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly, but it's at least 4.0.0
179
180 #if !defined(Q_OS_WIN)
181 #ifdef Q_OS_MAC
182 QString QCoreApplicationPrivate::macMenuBarName()
183 {
184     QString bundleName;
185     CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("CFBundleName"));
186     if (string)
187         bundleName = QCFString::toQString(static_cast<CFStringRef>(string));
188     return bundleName;
189 }
190 #endif
191 QString QCoreApplicationPrivate::appName() const
192 {
193     static QString applName;
194 #ifdef Q_OS_MAC
195     applName = macMenuBarName();
196 #endif
197     if (applName.isEmpty() && argv[0]) {
198         char *p = strrchr(argv[0], '/');
199         applName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
200     }
201     return applName;
202 }
203 #endif
204
205 bool QCoreApplicationPrivate::checkInstance(const char *function)
206 {
207     bool b = (QCoreApplication::self != 0);
208     if (!b)
209         qWarning("QApplication::%s: Please instantiate the QApplication object first", function);
210     return b;
211 }
212
213 void QCoreApplicationPrivate::processCommandLineArguments()
214 {
215     int j = argc ? 1 : 0;
216     for (int i = 1; i < argc; ++i) {
217         if (argv[i] && *argv[i] != '-') {
218             argv[j++] = argv[i];
219             continue;
220         }
221         QByteArray arg = argv[i];
222         if (arg.startsWith("-qmljsdebugger=")) {
223             qmljs_debug_arguments = QString::fromLocal8Bit(arg.right(arg.length() - 15));
224         } else {
225             argv[j++] = argv[i];
226         }
227     }
228
229     if (j < argc) {
230         argv[j] = 0;
231         argc = j;
232     }
233 }
234
235 // Support for introspection
236
237 QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 };
238
239 void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set)
240 {
241     qt_signal_spy_callback_set = callback_set;
242 }
243
244 extern "C" void Q_CORE_EXPORT qt_startup_hook()
245 {
246 }
247
248 typedef QList<QtCleanUpFunction> QVFuncList;
249 Q_GLOBAL_STATIC(QVFuncList, postRList)
250
251 void qAddPostRoutine(QtCleanUpFunction p)
252 {
253     QVFuncList *list = postRList();
254     if (!list)
255         return;
256     list->prepend(p);
257 }
258
259 void qRemovePostRoutine(QtCleanUpFunction p)
260 {
261     QVFuncList *list = postRList();
262     if (!list)
263         return;
264     list->removeAll(p);
265 }
266
267 void Q_CORE_EXPORT qt_call_post_routines()
268 {
269     QVFuncList *list = 0;
270     QT_TRY {
271         list = postRList();
272     } QT_CATCH(const std::bad_alloc &) {
273         // ignore - if we can't allocate a post routine list,
274         // there's a high probability that there's no post
275         // routine to be executed :)
276     }
277     if (!list)
278         return;
279     while (!list->isEmpty())
280         (list->takeFirst())();
281 }
282
283
284 // app starting up if false
285 bool QCoreApplicationPrivate::is_app_running = false;
286  // app closing down if true
287 bool QCoreApplicationPrivate::is_app_closing = false;
288 // initialized in qcoreapplication and in qtextstream autotest when setlocale is called.
289 Q_CORE_EXPORT bool qt_locale_initialized = false;
290
291 Q_CORE_EXPORT uint qGlobalPostedEventsCount()
292 {
293     QThreadData *currentThreadData = QThreadData::current();
294     return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset;
295 }
296
297
298 void qt_set_current_thread_to_main_thread()
299 {
300     QCoreApplicationPrivate::theMainThread = QThread::currentThread();
301 }
302
303
304
305 QCoreApplication *QCoreApplication::self = 0;
306 QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0;
307 uint QCoreApplicationPrivate::attribs;
308
309 #ifdef Q_OS_UNIX
310 Qt::HANDLE qt_application_thread_id = 0;
311 #endif
312
313 struct QCoreApplicationData {
314     QCoreApplicationData() {
315 #ifndef QT_NO_LIBRARY
316         app_libpaths = 0;
317 #endif
318     }
319     ~QCoreApplicationData() {
320 #ifndef QT_NO_LIBRARY
321         delete app_libpaths;
322 #endif
323
324         // cleanup the QAdoptedThread created for the main() thread
325        if (QCoreApplicationPrivate::theMainThread) {
326            QThreadData *data = QThreadData::get2(QCoreApplicationPrivate::theMainThread);
327            QCoreApplicationPrivate::theMainThread = 0;
328            data->deref(); // deletes the data and the adopted thread
329        }
330     }
331     QString orgName, orgDomain, application;
332     QString applicationVersion;
333
334 #ifndef QT_NO_LIBRARY
335     QStringList *app_libpaths;
336 #endif
337
338 };
339
340 Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
341
342 QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
343     : QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0),
344       in_exec(false), aboutToQuitEmitted(false), threadData_clean(false)
345 {
346     app_compile_version = flags & 0xffffff;
347     static const char *const empty = "";
348     if (argc == 0 || argv == 0) {
349         argc = 0;
350         argv = (char **)&empty; // ouch! careful with QCoreApplication::argv()!
351     }
352     QCoreApplicationPrivate::is_app_closing = false;
353
354 #ifdef Q_OS_SYMBIAN
355     qt_init_symbian_apa_arguments(argc, argv);
356 #endif
357
358 #ifdef Q_OS_UNIX
359     qt_application_thread_id = QThread::currentThreadId();
360 #endif
361
362     // note: this call to QThread::currentThread() may end up setting theMainThread!
363     if (QThread::currentThread() != theMainThread)
364         qWarning("WARNING: QApplication was not created in the main() thread.");
365 }
366
367 QCoreApplicationPrivate::~QCoreApplicationPrivate()
368 {
369     cleanupThreadData();
370 }
371
372 void QCoreApplicationPrivate::cleanupThreadData()
373 {
374     if (threadData && !threadData_clean) {
375 #ifndef QT_NO_THREAD
376         void *data = &threadData->tls;
377         QThreadStorageData::finish((void **)data);
378 #endif
379
380         // need to clear the state of the mainData, just in case a new QCoreApplication comes along.
381         QMutexLocker locker(&threadData->postEventList.mutex);
382         for (int i = 0; i < threadData->postEventList.size(); ++i) {
383             const QPostEvent &pe = threadData->postEventList.at(i);
384             if (pe.event) {
385                 --pe.receiver->d_func()->postedEvents;
386                 pe.event->posted = false;
387                 delete pe.event;
388             }
389         }
390         threadData->postEventList.clear();
391         threadData->postEventList.recursion = 0;
392         threadData->quitNow = false;
393         threadData_clean = true;
394     }
395 }
396
397 void QCoreApplicationPrivate::createEventDispatcher()
398 {
399     Q_Q(QCoreApplication);
400 #if defined(Q_OS_SYMBIAN)
401     eventDispatcher = new QEventDispatcherSymbian(q);
402 #elif defined(Q_OS_UNIX)
403 #  if !defined(QT_NO_GLIB)
404     if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
405         eventDispatcher = new QEventDispatcherGlib(q);
406     else
407 #  endif
408         eventDispatcher = new QEventDispatcherUNIX(q);
409 #elif defined(Q_OS_WIN)
410     eventDispatcher = new QEventDispatcherWin32(q);
411 #else
412 #  error "QEventDispatcher not yet ported to this platform"
413 #endif
414 }
415
416 void QCoreApplicationPrivate::_q_initializeProcessManager()
417 {
418 #ifndef QT_NO_PROCESS
419 #  ifdef Q_OS_UNIX
420     QProcessPrivate::initializeProcessManager();
421 #  endif
422 #endif
423 }
424
425
426 QThread *QCoreApplicationPrivate::theMainThread = 0;
427 QThread *QCoreApplicationPrivate::mainThread()
428 {
429     Q_ASSERT(theMainThread != 0);
430     return theMainThread;
431 }
432
433 #if !defined (QT_NO_DEBUG) || defined (QT_MAC_FRAMEWORK_BUILD)
434 void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
435 {
436     QThread *currentThread = QThread::currentThread();
437     QThread *thr = receiver->thread();
438     Q_ASSERT_X(currentThread == thr || !thr,
439                "QCoreApplication::sendEvent",
440                QString::fromLatin1("Cannot send events to objects owned by a different thread. "
441                                    "Current thread %1. Receiver '%2' (of type '%3') was created in thread %4")
442                .arg(QString::number((quintptr) currentThread, 16))
443                .arg(receiver->objectName())
444                .arg(QLatin1String(receiver->metaObject()->className()))
445                .arg(QString::number((quintptr) thr, 16))
446                .toLocal8Bit().data());
447     Q_UNUSED(currentThread);
448     Q_UNUSED(thr);
449 }
450 #elif defined(Q_OS_SYMBIAN) && defined (QT_NO_DEBUG)
451 // no implementation in release builds, but keep the symbol present
452 void QCoreApplicationPrivate::checkReceiverThread(QObject * /* receiver */)
453 {
454 }
455 #endif
456
457 void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
458 {
459 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
460     QStringList *app_libpaths = coreappdata()->app_libpaths;
461     Q_ASSERT(app_libpaths);
462 # if defined(Q_OS_SYMBIAN)
463     QString app_location( QCoreApplication::applicationDirPath() );
464     // File existence check for application's private dir requires additional '\' or
465     // platform security will not allow it.
466     if (app_location !=  QLibraryInfo::location(QLibraryInfo::PluginsPath) && QFile::exists(app_location + QLatin1Char('\\')) && !app_libpaths->contains(app_location))
467 # else
468     QString app_location( QCoreApplication::applicationFilePath() );
469     app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
470     app_location = QDir(app_location).canonicalPath();
471     if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
472 # endif
473         app_libpaths->append(app_location);
474 #endif
475 }
476
477 QString qAppName()
478 {
479     if (!QCoreApplicationPrivate::checkInstance("qAppName"))
480         return QString();
481     return QCoreApplication::instance()->d_func()->appName();
482 }
483
484 /*!
485     \class QCoreApplication
486     \brief The QCoreApplication class provides an event loop for console Qt
487     applications.
488
489     This class is used by non-GUI applications to provide their event
490     loop. For non-GUI application that uses Qt, there should be exactly
491     one QCoreApplication object. For GUI applications, see
492     QApplication.
493
494     QCoreApplication contains the main event loop, where all events
495     from the operating system (e.g., timer and network events) and
496     other sources are processed and dispatched. It also handles the
497     application's initialization and finalization, as well as
498     system-wide and application-wide settings.
499
500     \section1 The Event Loop and Event Handling
501
502     The event loop is started with a call to exec(). Long running
503     operations can call processEvents() to keep the application
504     responsive.
505
506     In general, we recommend that you create a QCoreApplication or a
507     QApplication object in your \c main() function as early as
508     possible. exec() will not return until the event loop exits; e.g.,
509     when quit() is called.
510
511     Several static convenience functions are also provided. The
512     QCoreApplication object is available from instance(). Events can
513     be sent or posted using sendEvent(), postEvent(), and
514     sendPostedEvents(). Pending events can be removed with
515     removePostedEvents() or flushed with flush().
516
517     The class provides a quit() slot and an aboutToQuit() signal.
518
519     \section1 Application and Library Paths
520
521     An application has an applicationDirPath() and an
522     applicationFilePath(). Library paths (see QLibrary) can be retrieved
523     with libraryPaths() and manipulated by setLibraryPaths(), addLibraryPath(),
524     and removeLibraryPath().
525
526     \section1 Internationalization and Translations
527
528     Translation files can be added or removed
529     using installTranslator() and removeTranslator(). Application
530     strings can be translated using translate(). The QObject::tr()
531     and QObject::trUtf8() functions are implemented in terms of
532     translate().
533
534     \section1 Accessing Command Line Arguments
535
536     The command line arguments which are passed to QCoreApplication's
537     constructor should be accessed using the arguments() function.
538     Note that some arguments supplied by the user may have been
539     processed and removed by QCoreApplication.
540
541     In cases where command line arguments need to be obtained using the
542     argv() function, you must convert them from the local string encoding
543     using QString::fromLocal8Bit().
544
545     \section1 Locale Settings
546
547     On Unix/Linux Qt is configured to use the system locale settings by
548     default. This can cause a conflict when using POSIX functions, for
549     instance, when converting between data types such as floats and
550     strings, since the notation may differ between locales. To get
551     around this problem, call the POSIX function \c{setlocale(LC_NUMERIC,"C")}
552     right after initializing QApplication or QCoreApplication to reset
553     the locale that is used for number formatting to "C"-locale.
554
555     \sa QApplication, QAbstractEventDispatcher, QEventLoop,
556     {Semaphores Example}, {Wait Conditions Example}
557 */
558
559 /*!
560     \fn static QCoreApplication *QCoreApplication::instance()
561
562     Returns a pointer to the application's QCoreApplication (or
563     QApplication) instance.
564
565     If no instance has been allocated, \c null is returned.
566 */
567
568 /*!\internal
569  */
570 QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
571     : QObject(p, 0)
572 {
573     init();
574     // note: it is the subclasses' job to call
575     // QCoreApplicationPrivate::eventDispatcher->startingUp();
576 }
577
578 /*!
579     Flushes the platform specific event queues.
580
581     If you are doing graphical changes inside a loop that does not
582     return to the event loop on asynchronous window systems like X11
583     or double buffered window systems like Mac OS X, and you want to
584     visualize these changes immediately (e.g. Splash Screens), call
585     this function.
586
587     \sa sendPostedEvents()
588 */
589 void QCoreApplication::flush()
590 {
591     if (self && self->d_func()->eventDispatcher)
592         self->d_func()->eventDispatcher->flush();
593 }
594
595 /*!
596     Constructs a Qt kernel application. Kernel applications are
597     applications without a graphical user interface. These type of
598     applications are used at the console or as server processes.
599
600     The \a argc and \a argv arguments are processed by the application,
601     and made available in a more convenient form by the arguments()
602     function.
603
604     \warning The data referred to by \a argc and \a argv must stay valid
605     for the entire lifetime of the QCoreApplication object. In addition,
606     \a argc must be greater than zero and \a argv must contain at least
607     one valid character string.
608 */
609 QCoreApplication::QCoreApplication(int &argc, char **argv, int _internal)
610 : QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
611 {
612     init();
613     QCoreApplicationPrivate::eventDispatcher->startingUp();
614 #if defined(Q_OS_SYMBIAN)
615 #ifndef QT_NO_LIBRARY
616     // Refresh factoryloader, as text codecs are requested during lib path
617     // resolving process and won't be therefore properly loaded.
618     // Unknown if this is symbian specific issue.
619     QFactoryLoader::refreshAll();
620 #endif
621 #ifndef QT_NO_SYSTEMLOCALE
622     d_func()->symbianInit();
623 #endif
624 #endif //Q_OS_SYMBIAN
625 }
626
627
628 // ### move to QCoreApplicationPrivate constructor?
629 void QCoreApplication::init()
630 {
631     Q_D(QCoreApplication);
632
633 #ifdef Q_OS_UNIX
634     setlocale(LC_ALL, "");                // use correct char set mapping
635     qt_locale_initialized = true;
636 #endif
637
638     Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
639     QCoreApplication::self = this;
640
641 #ifdef Q_OS_SYMBIAN
642     //ensure temp and working directories exist
643     QFileSystemEngine::createDirectory(QFileSystemEntry(QFileSystemEngine::tempPath()), true);
644     QFileSystemEngine::createDirectory(QFileSystemEntry(QFileSystemEngine::currentPath()), true);
645 #endif
646
647 #ifndef QT_NO_THREAD
648     QThread::initialize();
649 #endif
650
651     // use the event dispatcher created by the app programmer (if any)
652     if (!QCoreApplicationPrivate::eventDispatcher)
653         QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;
654     // otherwise we create one
655     if (!QCoreApplicationPrivate::eventDispatcher)
656         d->createEventDispatcher();
657     Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0);
658
659     if (!QCoreApplicationPrivate::eventDispatcher->parent())
660         QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread);
661
662     d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;
663
664 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
665     if (!coreappdata()->app_libpaths) {
666         // make sure that library paths is initialized
667         libraryPaths();
668     } else {
669         d->appendApplicationPathToLibraryPaths();
670     }
671 #endif
672
673 #ifdef QT_EVAL
674     extern void qt_core_eval_init(uint);
675     qt_core_eval_init(d->application_type);
676 #endif
677
678 #if    defined(Q_OS_SYMBIAN)  \
679     && defined(Q_CC_NOKIAX86) \
680     && defined(QT_DEBUG)
681     /**
682      * Prevent the executable from being locked in the Symbian emulator. The
683      * code dramatically simplifies debugging on Symbian, but beyond that has
684      * no impact.
685      *
686      * Force the ZLazyUnloadTimer to fire and therefore unload code segments
687      * immediately. The code affects Symbian's file server and on the other
688      * hand needs only to be run once in each emulator run.
689      */
690     {
691         RLoader loader;
692         CleanupClosePushL(loader);
693         User::LeaveIfError(loader.Connect());
694         User::LeaveIfError(loader.CancelLazyDllUnload());
695         CleanupStack::PopAndDestroy(&loader);
696     }
697 #endif
698
699     d->processCommandLineArguments();
700
701     qt_startup_hook();
702 }
703
704 #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
705 void QCoreApplicationPrivate::symbianInit()
706 {
707     if (!environmentChangeNotifier)
708         environmentChangeNotifier.reset(new QEnvironmentChangeNotifier);
709 }
710 #endif
711
712
713 /*!
714     Destroys the QCoreApplication object.
715 */
716 QCoreApplication::~QCoreApplication()
717 {
718     qt_call_post_routines();
719
720     self = 0;
721     QCoreApplicationPrivate::is_app_closing = true;
722     QCoreApplicationPrivate::is_app_running = false;
723
724 #if !defined(QT_NO_THREAD)
725 #if !defined(QT_NO_CONCURRENT)
726     // Synchronize and stop the global thread pool threads.
727     QThreadPool *globalThreadPool = 0;
728     QT_TRY {
729         globalThreadPool = QThreadPool::globalInstance();
730     } QT_CATCH (...) {
731         // swallow the exception, since destructors shouldn't throw
732     }
733     if (globalThreadPool)
734         globalThreadPool->waitForDone();
735 #endif
736     QThread::cleanup();
737 #endif
738
739     d_func()->threadData->eventDispatcher = 0;
740     if (QCoreApplicationPrivate::eventDispatcher)
741         QCoreApplicationPrivate::eventDispatcher->closingDown();
742     QCoreApplicationPrivate::eventDispatcher = 0;
743
744 #ifndef QT_NO_LIBRARY
745     delete coreappdata()->app_libpaths;
746     coreappdata()->app_libpaths = 0;
747 #endif
748 }
749
750
751 /*!
752     Sets the attribute \a attribute if \a on is true;
753     otherwise clears the attribute.
754
755     One of the attributes that can be set with this method is
756     Qt::AA_ImmediateWidgetCreation. It tells Qt to create toplevel
757     windows immediately. Normally, resources for widgets are allocated
758     on demand to improve efficiency and minimize resource usage.
759     Therefore, if it is important to minimize resource consumption, do
760     not set this attribute.
761
762     \sa testAttribute()
763 */
764 void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
765 {
766     if (on)
767         QCoreApplicationPrivate::attribs |= 1 << attribute;
768     else
769         QCoreApplicationPrivate::attribs &= ~(1 << attribute);
770 }
771
772 /*!
773   Returns true if attribute \a attribute is set;
774   otherwise returns false.
775
776   \sa setAttribute()
777  */
778 bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
779 {
780     return QCoreApplicationPrivate::testAttribute(attribute);
781 }
782
783
784 /*!
785   \internal
786
787   This function is here to make it possible for Qt extensions to
788   hook into event notification without subclassing QApplication
789 */
790 bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
791 {
792     // Make it possible for Qt Jambi and QSA to hook into events even
793     // though QApplication is subclassed...
794     bool result = false;
795     void *cbdata[] = { receiver, event, &result };
796     if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
797         return result;
798     }
799
800     // Qt enforces the rule that events can only be sent to objects in
801     // the current thread, so receiver->d_func()->threadData is
802     // equivalent to QThreadData::current(), just without the function
803     // call overhead.
804     QObjectPrivate *d = receiver->d_func();
805     QThreadData *threadData = d->threadData;
806
807     // Exception-safety without try/catch
808     struct Incrementer {
809         int &variable;
810         inline Incrementer(int &variable) : variable(variable)
811         { ++variable; }
812         inline ~Incrementer()
813         { --variable; }
814     };
815     Incrementer inc(threadData->loopLevel);
816
817 #ifdef QT_JAMBI_BUILD
818     int deleteWatch = 0;
819     int *oldDeleteWatch = QObjectPrivate::setDeleteWatch(d, &deleteWatch);
820
821     bool inEvent = d->inEventHandler;
822     d->inEventHandler = true;
823 #endif
824
825     bool returnValue;
826     returnValue = notify(receiver, event);
827
828 #ifdef QT_JAMBI_BUILD
829     // Restore the previous state if the object was not deleted..
830     if (!deleteWatch) {
831         d->inEventHandler = inEvent;
832     }
833     QObjectPrivate::resetDeleteWatch(d, oldDeleteWatch, deleteWatch);
834 #endif
835     return returnValue;
836 }
837
838
839 /*!
840   Sends \a event to \a receiver: \a {receiver}->event(\a event).
841   Returns the value that is returned from the receiver's event
842   handler. Note that this function is called for all events sent to
843   any object in any thread.
844
845   For certain types of events (e.g. mouse and key events),
846   the event will be propagated to the receiver's parent and so on up to
847   the top-level object if the receiver is not interested in the event
848   (i.e., it returns false).
849
850   There are five different ways that events can be processed;
851   reimplementing this virtual function is just one of them. All five
852   approaches are listed below:
853   \list 1
854   \i Reimplementing paintEvent(), mousePressEvent() and so
855   on. This is the commonest, easiest and least powerful way.
856
857   \i Reimplementing this function. This is very powerful, providing
858   complete control; but only one subclass can be active at a time.
859
860   \i Installing an event filter on QCoreApplication::instance(). Such
861   an event filter is able to process all events for all widgets, so
862   it's just as powerful as reimplementing notify(); furthermore, it's
863   possible to have more than one application-global event filter.
864   Global event filters even see mouse events for
865   \l{QWidget::isEnabled()}{disabled widgets}. Note that application
866   event filters are only called for objects that live in the main
867   thread.
868
869   \i Reimplementing QObject::event() (as QWidget does). If you do
870   this you get Tab key presses, and you get to see the events before
871   any widget-specific event filters.
872
873   \i Installing an event filter on the object. Such an event filter gets all
874   the events, including Tab and Shift+Tab key press events, as long as they
875   do not change the focus widget.
876   \endlist
877
878   \sa QObject::event(), installEventFilter()
879 */
880
881 bool QCoreApplication::notify(QObject *receiver, QEvent *event)
882 {
883     Q_D(QCoreApplication);
884     // no events are delivered after ~QCoreApplication() has started
885     if (QCoreApplicationPrivate::is_app_closing)
886         return true;
887
888     if (receiver == 0) {                        // serious error
889         qWarning("QCoreApplication::notify: Unexpected null receiver");
890         return true;
891     }
892
893 #ifndef QT_NO_DEBUG
894     d->checkReceiverThread(receiver);
895 #endif
896
897     return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);
898 }
899
900 bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
901 {
902     if (receiver->d_func()->threadData == this->threadData) {
903         // application event filters are only called for objects in the GUI thread
904         for (int i = 0; i < eventFilters.size(); ++i) {
905             register QObject *obj = eventFilters.at(i);
906             if (!obj)
907                 continue;
908             if (obj->d_func()->threadData != threadData) {
909                 qWarning("QCoreApplication: Application event filter cannot be in a different thread.");
910                 continue;
911             }
912             if (obj->eventFilter(receiver, event))
913                 return true;
914         }
915     }
916     return false;
917 }
918
919 bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
920 {
921     Q_Q(QCoreApplication);
922     if (receiver != q) {
923         for (int i = 0; i < receiver->d_func()->eventFilters.size(); ++i) {
924             register QObject *obj = receiver->d_func()->eventFilters.at(i);
925             if (!obj)
926                 continue;
927             if (obj->d_func()->threadData != receiver->d_func()->threadData) {
928                 qWarning("QCoreApplication: Object event filter cannot be in a different thread.");
929                 continue;
930             }
931             if (obj->eventFilter(receiver, event))
932                 return true;
933         }
934     }
935     return false;
936 }
937
938 /*!\internal
939
940   Helper function called by notify()
941  */
942 bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
943 {
944     // send to all application event filters
945     if (sendThroughApplicationEventFilters(receiver, event))
946         return true;
947     // send to all receiver event filters
948     if (sendThroughObjectEventFilters(receiver, event))
949         return true;
950     // deliver the event
951     return receiver->event(event);
952 }
953
954 /*!
955   Returns true if an application object has not been created yet;
956   otherwise returns false.
957
958   \sa closingDown()
959 */
960
961 bool QCoreApplication::startingUp()
962 {
963     return !QCoreApplicationPrivate::is_app_running;
964 }
965
966 /*!
967   Returns true if the application objects are being destroyed;
968   otherwise returns false.
969
970   \sa startingUp()
971 */
972
973 bool QCoreApplication::closingDown()
974 {
975     return QCoreApplicationPrivate::is_app_closing;
976 }
977
978
979 /*!
980     Processes all pending events for the calling thread according to
981     the specified \a flags until there are no more events to process.
982
983     You can call this function occasionally when your program is busy
984     performing a long operation (e.g. copying a file).
985
986     In event you are running a local loop which calls this function
987     continuously, without an event loop, the
988     \l{QEvent::DeferredDelete}{DeferredDelete} events will
989     not be processed. This can affect the behaviour of widgets,
990     e.g. QToolTip, that rely on \l{QEvent::DeferredDelete}{DeferredDelete}
991     events to function properly. An alternative would be to call
992     \l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from
993     within that local loop.
994
995     Calling this function processes events only for the calling thread.
996
997     \threadsafe
998
999     \sa exec(), QTimer, QEventLoop::processEvents(), flush(), sendPostedEvents()
1000 */
1001 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
1002 {
1003     QThreadData *data = QThreadData::current();
1004     if (!data->eventDispatcher)
1005         return;
1006     if (flags & QEventLoop::DeferredDeletion)
1007         QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1008     data->eventDispatcher->processEvents(flags);
1009 }
1010
1011 /*!
1012     \overload processEvents()
1013
1014     Processes pending events for the calling thread for \a maxtime
1015     milliseconds or until there are no more events to process,
1016     whichever is shorter.
1017
1018     You can call this function occasionally when you program is busy
1019     doing a long operation (e.g. copying a file).
1020
1021     Calling this function processes events only for the calling thread.
1022
1023     \threadsafe
1024
1025     \sa exec(), QTimer, QEventLoop::processEvents()
1026 */
1027 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime)
1028 {
1029     QThreadData *data = QThreadData::current();
1030     if (!data->eventDispatcher)
1031         return;
1032     QElapsedTimer start;
1033     start.start();
1034     if (flags & QEventLoop::DeferredDeletion)
1035         QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1036     while (data->eventDispatcher->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
1037         if (start.elapsed() > maxtime)
1038             break;
1039         if (flags & QEventLoop::DeferredDeletion)
1040             QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1041     }
1042 }
1043
1044 /*****************************************************************************
1045   Main event loop wrappers
1046  *****************************************************************************/
1047
1048 /*!
1049     Enters the main event loop and waits until exit() is called.
1050     Returns the value that was set to exit() (which is 0 if exit() is
1051     called via quit()).
1052
1053     It is necessary to call this function to start event handling. The
1054     main event loop receives events from the window system and
1055     dispatches these to the application widgets.
1056
1057     To make your application perform idle processing (i.e. executing a
1058     special function whenever there are no pending events), use a
1059     QTimer with 0 timeout. More advanced idle processing schemes can
1060     be achieved using processEvents().
1061
1062     We recommend that you connect clean-up code to the
1063     \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in
1064     your application's \c{main()} function because on some platforms the
1065     QCoreApplication::exec() call may not return. For example, on Windows
1066     when the user logs off, the system terminates the process after Qt
1067     closes all top-level windows. Hence, there is no guarantee that the
1068     application will have time to exit its event loop and execute code at
1069     the end of the \c{main()} function after the QCoreApplication::exec()
1070     call.
1071
1072     \sa quit(), exit(), processEvents(), QApplication::exec()
1073 */
1074 int QCoreApplication::exec()
1075 {
1076     if (!QCoreApplicationPrivate::checkInstance("exec"))
1077         return -1;
1078
1079     QThreadData *threadData = self->d_func()->threadData;
1080     if (threadData != QThreadData::current()) {
1081         qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
1082         return -1;
1083     }
1084     if (!threadData->eventLoops.isEmpty()) {
1085         qWarning("QCoreApplication::exec: The event loop is already running");
1086         return -1;
1087     }
1088
1089     threadData->quitNow = false;
1090     QEventLoop eventLoop;
1091     self->d_func()->in_exec = true;
1092     self->d_func()->aboutToQuitEmitted = false;
1093     int returnCode = eventLoop.exec();
1094     threadData->quitNow = false;
1095     if (self) {
1096         self->d_func()->in_exec = false;
1097         if (!self->d_func()->aboutToQuitEmitted)
1098             emit self->aboutToQuit();
1099         self->d_func()->aboutToQuitEmitted = true;
1100         sendPostedEvents(0, QEvent::DeferredDelete);
1101     }
1102
1103     return returnCode;
1104 }
1105
1106
1107 /*!
1108   Tells the application to exit with a return code.
1109
1110     After this function has been called, the application leaves the
1111     main event loop and returns from the call to exec(). The exec()
1112     function returns \a returnCode. If the event loop is not running,
1113     this function does nothing.
1114
1115   By convention, a \a returnCode of 0 means success, and any non-zero
1116   value indicates an error.
1117
1118   Note that unlike the C library function of the same name, this
1119   function \e does return to the caller -- it is event processing that
1120   stops.
1121
1122   \sa quit(), exec()
1123 */
1124 void QCoreApplication::exit(int returnCode)
1125 {
1126     if (!self)
1127         return;
1128     QThreadData *data = self->d_func()->threadData;
1129     data->quitNow = true;
1130     for (int i = 0; i < data->eventLoops.size(); ++i) {
1131         QEventLoop *eventLoop = data->eventLoops.at(i);
1132         eventLoop->exit(returnCode);
1133     }
1134 }
1135
1136 /*****************************************************************************
1137   QCoreApplication management of posted events
1138  *****************************************************************************/
1139
1140 /*!
1141     \fn bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1142
1143     Sends event \a event directly to receiver \a receiver, using the
1144     notify() function. Returns the value that was returned from the
1145     event handler.
1146
1147     The event is \e not deleted when the event has been sent. The normal
1148     approach is to create the event on the stack, for example:
1149
1150     \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 0
1151
1152     \sa postEvent(), notify()
1153 */
1154
1155 /*!
1156     Adds the event \a event, with the object \a receiver as the
1157     receiver of the event, to an event queue and returns immediately.
1158
1159     The event must be allocated on the heap since the post event queue
1160     will take ownership of the event and delete it once it has been
1161     posted.  It is \e {not safe} to access the event after
1162     it has been posted.
1163
1164     When control returns to the main event loop, all events that are
1165     stored in the queue will be sent using the notify() function.
1166
1167     Events are processed in the order posted. For more control over
1168     the processing order, use the postEvent() overload below, which
1169     takes a priority argument. This function posts all event with a
1170     Qt::NormalEventPriority.
1171
1172     \threadsafe
1173
1174     \sa sendEvent(), notify(), sendPostedEvents()
1175 */
1176
1177 void QCoreApplication::postEvent(QObject *receiver, QEvent *event)
1178 {
1179     postEvent(receiver, event, Qt::NormalEventPriority);
1180 }
1181
1182
1183 /*!
1184     \overload postEvent()
1185     \since 4.3
1186
1187     Adds the event \a event, with the object \a receiver as the
1188     receiver of the event, to an event queue and returns immediately.
1189
1190     The event must be allocated on the heap since the post event queue
1191     will take ownership of the event and delete it once it has been
1192     posted.  It is \e {not safe} to access the event after
1193     it has been posted.
1194
1195     When control returns to the main event loop, all events that are
1196     stored in the queue will be sent using the notify() function.
1197
1198     Events are sorted in descending \a priority order, i.e. events
1199     with a high \a priority are queued before events with a lower \a
1200     priority. The \a priority can be any integer value, i.e. between
1201     INT_MAX and INT_MIN, inclusive; see Qt::EventPriority for more
1202     details. Events with equal \a priority will be processed in the
1203     order posted.
1204
1205     \threadsafe
1206
1207     \sa sendEvent(), notify(), sendPostedEvents(), Qt::EventPriority
1208 */
1209 void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
1210 {
1211     if (receiver == 0) {
1212         qWarning("QCoreApplication::postEvent: Unexpected null receiver");
1213         delete event;
1214         return;
1215     }
1216
1217     QThreadData * volatile * pdata = &receiver->d_func()->threadData;
1218     QThreadData *data = *pdata;
1219     if (!data) {
1220         // posting during destruction? just delete the event to prevent a leak
1221         delete event;
1222         return;
1223     }
1224
1225     // lock the post event mutex
1226     data->postEventList.mutex.lock();
1227
1228     // if object has moved to another thread, follow it
1229     while (data != *pdata) {
1230         data->postEventList.mutex.unlock();
1231
1232         data = *pdata;
1233         if (!data) {
1234             // posting during destruction? just delete the event to prevent a leak
1235             delete event;
1236             return;
1237         }
1238
1239         data->postEventList.mutex.lock();
1240     }
1241
1242     QMutexUnlocker locker(&data->postEventList.mutex);
1243
1244     // if this is one of the compressible events, do compression
1245     if (receiver->d_func()->postedEvents
1246         && self && self->compressEvent(event, receiver, &data->postEventList)) {
1247         return;
1248     }
1249
1250     if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) {
1251         // remember the current running eventloop for DeferredDelete
1252         // events posted in the receiver's thread
1253         event->d = reinterpret_cast<QEventPrivate *>(quintptr(data->loopLevel));
1254     }
1255
1256     // delete the event on exceptions to protect against memory leaks till the event is
1257     // properly owned in the postEventList
1258     QScopedPointer<QEvent> eventDeleter(event);
1259     data->postEventList.addEvent(QPostEvent(receiver, event, priority));
1260     eventDeleter.take();
1261     event->posted = true;
1262     ++receiver->d_func()->postedEvents;
1263     data->canWait = false;
1264     locker.unlock();
1265
1266     if (data->eventDispatcher)
1267         data->eventDispatcher->wakeUp();
1268 }
1269
1270 /*!
1271   \internal
1272   Returns true if \a event was compressed away (possibly deleted) and should not be added to the list.
1273 */
1274 bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1275 {
1276 #ifdef Q_OS_WIN
1277     Q_ASSERT(event);
1278     Q_ASSERT(receiver);
1279     Q_ASSERT(postedEvents);
1280
1281     // compress posted timers to this object.
1282     if (event->type() == QEvent::Timer && receiver->d_func()->postedEvents > 0) {
1283         int timerId = ((QTimerEvent *) event)->timerId();
1284         for (int i=0; i<postedEvents->size(); ++i) {
1285             const QPostEvent &e = postedEvents->at(i);
1286             if (e.receiver == receiver && e.event && e.event->type() == QEvent::Timer
1287                 && ((QTimerEvent *) e.event)->timerId() == timerId) {
1288                 delete event;
1289                 return true;
1290             }
1291         }
1292     } else
1293 #endif
1294         if ((event->type() == QEvent::DeferredDelete
1295              || event->type() == QEvent::Quit)
1296             && receiver->d_func()->postedEvents > 0) {
1297             for (int i = 0; i < postedEvents->size(); ++i) {
1298                 const QPostEvent &cur = postedEvents->at(i);
1299                 if (cur.receiver != receiver
1300                     || cur.event == 0
1301                     || cur.event->type() != event->type())
1302                     continue;
1303                 // found an event for this receiver
1304                 delete event;
1305                 return true;
1306             }
1307         }
1308     return false;
1309 }
1310
1311 /*!
1312   \fn void QCoreApplication::sendPostedEvents()
1313   \overload sendPostedEvents()
1314
1315     Dispatches all posted events, i.e. empties the event queue.
1316 */
1317
1318 /*!
1319   Immediately dispatches all events which have been previously queued
1320   with QCoreApplication::postEvent() and which are for the object \a receiver
1321   and have the event type \a event_type.
1322
1323   Events from the window system are \e not dispatched by this
1324   function, but by processEvents().
1325
1326   If \a receiver is null, the events of \a event_type are sent for all
1327   objects. If \a event_type is 0, all the events are sent for \a receiver.
1328
1329   \note This method must be called from the same thread as its QObject parameter, \a receiver.
1330
1331   \sa flush(), postEvent()
1332 */
1333
1334 void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type)
1335 {
1336     QThreadData *data = QThreadData::current();
1337
1338     QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1339 }
1340
1341 void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
1342                                                QThreadData *data)
1343 {
1344     if (event_type == -1) {
1345         // we were called by an obsolete event dispatcher.
1346         event_type = 0;
1347     }
1348
1349     if (receiver && receiver->d_func()->threadData != data) {
1350         qWarning("QCoreApplication::sendPostedEvents: Cannot send "
1351                  "posted events for objects in another thread");
1352         return;
1353     }
1354
1355     ++data->postEventList.recursion;
1356
1357     QMutexLocker locker(&data->postEventList.mutex);
1358
1359     // by default, we assume that the event dispatcher can go to sleep after
1360     // processing all events. if any new events are posted while we send
1361     // events, canWait will be set to false.
1362     data->canWait = (data->postEventList.size() == 0);
1363
1364     if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) {
1365         --data->postEventList.recursion;
1366         return;
1367     }
1368
1369     data->canWait = true;
1370
1371     // okay. here is the tricky loop. be careful about optimizing
1372     // this, it looks the way it does for good reasons.
1373     int startOffset = data->postEventList.startOffset;
1374     int &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1375     data->postEventList.insertionOffset = data->postEventList.size();
1376
1377     // Exception-safe cleaning up without the need for a try/catch block
1378     struct CleanUp {
1379         QObject *receiver;
1380         int event_type;
1381         QThreadData *data;
1382         bool exceptionCaught;
1383
1384         inline CleanUp(QObject *receiver, int event_type, QThreadData *data) :
1385             receiver(receiver), event_type(event_type), data(data), exceptionCaught(true)
1386         {}
1387         inline ~CleanUp()
1388         {
1389             if (exceptionCaught) {
1390                 // since we were interrupted, we need another pass to make sure we clean everything up
1391                 data->canWait = false;
1392             }
1393
1394             --data->postEventList.recursion;
1395             if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
1396                 data->eventDispatcher->wakeUp();
1397
1398             // clear the global list, i.e. remove everything that was
1399             // delivered.
1400             if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1401                 const QPostEventList::iterator it = data->postEventList.begin();
1402                 data->postEventList.erase(it, it + data->postEventList.startOffset);
1403                 data->postEventList.insertionOffset -= data->postEventList.startOffset;
1404                 Q_ASSERT(data->postEventList.insertionOffset >= 0);
1405                 data->postEventList.startOffset = 0;
1406             }
1407         }
1408     };
1409     CleanUp cleanup(receiver, event_type, data);
1410
1411     while (i < data->postEventList.size()) {
1412         // avoid live-lock
1413         if (i >= data->postEventList.insertionOffset)
1414             break;
1415
1416         const QPostEvent &pe = data->postEventList.at(i);
1417         ++i;
1418
1419         if (!pe.event)
1420             continue;
1421         if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1422             data->canWait = false;
1423             continue;
1424         }
1425
1426         if (pe.event->type() == QEvent::DeferredDelete) {
1427             // DeferredDelete events are only sent when we are explicitly asked to
1428             // (s.a. QEvent::DeferredDelete), and then only if the event loop that
1429             // posted the event has returned.
1430             const bool allowDeferredDelete =
1431                 (quintptr(pe.event->d) > unsigned(data->loopLevel)
1432                  || (!quintptr(pe.event->d) && data->loopLevel > 0)
1433                  || (event_type == QEvent::DeferredDelete
1434                      && quintptr(pe.event->d) == unsigned(data->loopLevel)));
1435             if (!allowDeferredDelete) {
1436                 // cannot send deferred delete
1437                 if (!event_type && !receiver) {
1438                     // don't lose the event
1439                     data->postEventList.addEvent(pe);
1440                     const_cast<QPostEvent &>(pe).event = 0;
1441                 }
1442                 continue;
1443             }
1444         }
1445
1446         // first, we diddle the event so that we can deliver
1447         // it, and that no one will try to touch it later.
1448         pe.event->posted = false;
1449         QScopedPointer<QEvent> e(pe.event);
1450         QObject * r = pe.receiver;
1451
1452         --r->d_func()->postedEvents;
1453         Q_ASSERT(r->d_func()->postedEvents >= 0);
1454
1455         // next, update the data structure so that we're ready
1456         // for the next event.
1457         const_cast<QPostEvent &>(pe).event = 0;
1458
1459         struct MutexUnlocker
1460         {
1461             QMutexLocker &m;
1462             MutexUnlocker(QMutexLocker &m) : m(m) { m.unlock(); }
1463             ~MutexUnlocker() { m.relock(); }
1464         };
1465         MutexUnlocker unlocker(locker);
1466
1467         // after all that work, it's time to deliver the event.
1468         QCoreApplication::sendEvent(r, e.data());
1469
1470         // careful when adding anything below this point - the
1471         // sendEvent() call might invalidate any invariants this
1472         // function depends on.
1473     }
1474
1475     cleanup.exceptionCaught = false;
1476 }
1477
1478 /*!
1479   Removes all events posted using postEvent() for \a receiver.
1480
1481   The events are \e not dispatched, instead they are removed from the
1482   queue. You should never need to call this function. If you do call it,
1483   be aware that killing events may cause \a receiver to break one or
1484   more invariants.
1485
1486   \threadsafe
1487 */
1488
1489 void QCoreApplication::removePostedEvents(QObject *receiver)
1490 {
1491     removePostedEvents(receiver, 0);
1492 }
1493
1494 /*!
1495     \overload removePostedEvents()
1496     \since 4.3
1497
1498     Removes all events of the given \a eventType that were posted
1499     using postEvent() for \a receiver.
1500
1501     The events are \e not dispatched, instead they are removed from
1502     the queue. You should never need to call this function. If you do
1503     call it, be aware that killing events may cause \a receiver to
1504     break one or more invariants.
1505
1506     If \a receiver is null, the events of \a eventType are removed for
1507     all objects. If \a eventType is 0, all the events are removed for
1508     \a receiver.
1509
1510     \threadsafe
1511 */
1512
1513 void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
1514 {
1515     QThreadData *data = receiver ? receiver->d_func()->threadData : QThreadData::current();
1516     QMutexLocker locker(&data->postEventList.mutex);
1517
1518     // the QObject destructor calls this function directly.  this can
1519     // happen while the event loop is in the middle of posting events,
1520     // and when we get here, we may not have any more posted events
1521     // for this object.
1522     if (receiver && !receiver->d_func()->postedEvents)
1523         return;
1524
1525     //we will collect all the posted events for the QObject
1526     //and we'll delete after the mutex was unlocked
1527     QVarLengthArray<QEvent*> events;
1528     int n = data->postEventList.size();
1529     int j = 0;
1530
1531     for (int i = 0; i < n; ++i) {
1532         const QPostEvent &pe = data->postEventList.at(i);
1533
1534         if ((!receiver || pe.receiver == receiver)
1535             && (pe.event && (eventType == 0 || pe.event->type() == eventType))) {
1536             --pe.receiver->d_func()->postedEvents;
1537             pe.event->posted = false;
1538             events.append(pe.event);
1539             const_cast<QPostEvent &>(pe).event = 0;
1540         } else if (!data->postEventList.recursion) {
1541             if (i != j)
1542                 data->postEventList.swap(i, j);
1543             ++j;
1544         }
1545     }
1546
1547 #ifdef QT_DEBUG
1548     if (receiver && eventType == 0) {
1549         Q_ASSERT(!receiver->d_func()->postedEvents);
1550     }
1551 #endif
1552
1553     if (!data->postEventList.recursion) {
1554         // truncate list
1555         data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
1556     }
1557
1558     locker.unlock();
1559     for (int i = 0; i < events.count(); ++i) {
1560         delete events[i];
1561     }
1562 }
1563
1564 /*!
1565   Removes \a event from the queue of posted events, and emits a
1566   warning message if appropriate.
1567
1568   \warning This function can be \e really slow. Avoid using it, if
1569   possible.
1570
1571   \threadsafe
1572 */
1573
1574 void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
1575 {
1576     if (!event || !event->posted)
1577         return;
1578
1579     QThreadData *data = QThreadData::current();
1580
1581     QMutexLocker locker(&data->postEventList.mutex);
1582
1583     if (data->postEventList.size() == 0) {
1584 #if defined(QT_DEBUG)
1585         qDebug("QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
1586                 (void*)event, event->type());
1587         return;
1588 #endif
1589     }
1590
1591     for (int i = 0; i < data->postEventList.size(); ++i) {
1592         const QPostEvent & pe = data->postEventList.at(i);
1593         if (pe.event == event) {
1594 #ifndef QT_NO_DEBUG
1595             qWarning("QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
1596                      event->type(),
1597                      pe.receiver->metaObject()->className(),
1598                      pe.receiver->objectName().toLocal8Bit().data());
1599 #endif
1600             --pe.receiver->d_func()->postedEvents;
1601             pe.event->posted = false;
1602             delete pe.event;
1603             const_cast<QPostEvent &>(pe).event = 0;
1604             return;
1605         }
1606     }
1607 }
1608
1609 /*!\reimp
1610
1611 */
1612 bool QCoreApplication::event(QEvent *e)
1613 {
1614     if (e->type() == QEvent::Quit) {
1615         quit();
1616         return true;
1617     }
1618     return QObject::event(e);
1619 }
1620
1621 /*! \enum QCoreApplication::Encoding
1622
1623     This enum type defines the 8-bit encoding of character string
1624     arguments to translate():
1625
1626     \value CodecForTr  The encoding specified by
1627                        QTextCodec::codecForTr() (Latin-1 if none has
1628                        been set).
1629     \value UnicodeUTF8  UTF-8.
1630     \value DefaultCodec  (Obsolete) Use CodecForTr instead.
1631
1632     \sa QObject::tr(), QObject::trUtf8(), QString::fromUtf8()
1633 */
1634
1635 /*!
1636     Tells the application to exit with return code 0 (success).
1637     Equivalent to calling QCoreApplication::exit(0).
1638
1639     It's common to connect the QApplication::lastWindowClosed() signal
1640     to quit(), and you also often connect e.g. QAbstractButton::clicked() or
1641     signals in QAction, QMenu, or QMenuBar to it.
1642
1643     Example:
1644
1645     \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 1
1646
1647     \sa exit(), aboutToQuit(), QApplication::lastWindowClosed()
1648 */
1649
1650 void QCoreApplication::quit()
1651 {
1652     exit(0);
1653 }
1654
1655 /*!
1656   \fn void QCoreApplication::aboutToQuit()
1657
1658   This signal is emitted when the application is about to quit the
1659   main event loop, e.g. when the event loop level drops to zero.
1660   This may happen either after a call to quit() from inside the
1661   application or when the users shuts down the entire desktop session.
1662
1663   The signal is particularly useful if your application has to do some
1664   last-second cleanup. Note that no user interaction is possible in
1665   this state.
1666
1667   \sa quit()
1668 */
1669
1670 #ifndef QT_NO_TRANSLATION
1671 /*!
1672     Adds the translation file \a translationFile to the list of
1673     translation files to be used for translations.
1674
1675     Multiple translation files can be installed. Translations are
1676     searched for in the reverse order in which they were installed,
1677     so the most recently installed translation file is searched first
1678     and the first translation file installed is searched last.
1679     The search stops as soon as a translation containing a matching
1680     string is found.
1681
1682     Installing or removing a QTranslator, or changing an installed QTranslator
1683     generates a \l{QEvent::LanguageChange}{LanguageChange} event for the
1684     QCoreApplication instance. A QApplication instance will propagate the event
1685     to all toplevel windows, where a reimplementation of changeEvent can
1686     re-translate the user interface by passing user-visible strings via the
1687     tr() function to the respective property setters. User-interface classes
1688     generated by \l{Qt Designer} provide a \c retranslateUi() function that can be
1689     called.
1690
1691     \sa removeTranslator() translate() QTranslator::load() {Dynamic Translation}
1692 */
1693
1694 void QCoreApplication::installTranslator(QTranslator *translationFile)
1695 {
1696     if (!translationFile)
1697         return;
1698
1699     if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
1700         return;
1701     QCoreApplicationPrivate *d = self->d_func();
1702     d->translators.prepend(translationFile);
1703
1704 #ifndef QT_NO_TRANSLATION_BUILDER
1705     if (translationFile->isEmpty())
1706         return;
1707 #endif
1708
1709     QEvent ev(QEvent::LanguageChange);
1710     QCoreApplication::sendEvent(self, &ev);
1711 }
1712
1713 /*!
1714     Removes the translation file \a translationFile from the list of
1715     translation files used by this application. (It does not delete the
1716     translation file from the file system.)
1717
1718     \sa installTranslator() translate(), QObject::tr()
1719 */
1720
1721 void QCoreApplication::removeTranslator(QTranslator *translationFile)
1722 {
1723     if (!translationFile)
1724         return;
1725     if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
1726         return;
1727     QCoreApplicationPrivate *d = self->d_func();
1728     if (d->translators.removeAll(translationFile) && !self->closingDown()) {
1729         QEvent ev(QEvent::LanguageChange);
1730         QCoreApplication::sendEvent(self, &ev);
1731     }
1732 }
1733
1734 /*!
1735     \overload translate()
1736 */
1737 QString QCoreApplication::translate(const char *context, const char *sourceText,
1738                                     const char *disambiguation, Encoding encoding)
1739 {
1740     return translate(context, sourceText, disambiguation, encoding, -1);
1741 }
1742
1743 static void replacePercentN(QString *result, int n)
1744 {
1745     if (n >= 0) {
1746         int percentPos = 0;
1747         int len = 0;
1748         while ((percentPos = result->indexOf(QLatin1Char('%'), percentPos + len)) != -1) {
1749             len = 1;
1750             QString fmt;
1751             if (result->at(percentPos + len) == QLatin1Char('L')) {
1752                 ++len;
1753                 fmt = QLatin1String("%L1");
1754             } else {
1755                 fmt = QLatin1String("%1");
1756             }
1757             if (result->at(percentPos + len) == QLatin1Char('n')) {
1758                 fmt = fmt.arg(n);
1759                 ++len;
1760                 result->replace(percentPos, len, fmt);
1761                 len = fmt.length();
1762             }
1763         }
1764     }
1765 }
1766
1767 /*!
1768     \reentrant
1769     \since 4.5
1770
1771     Returns the translation text for \a sourceText, by querying the
1772     installed translation files. The translation files are searched
1773     from the most recently installed file back to the first
1774     installed file.
1775
1776     QObject::tr() and QObject::trUtf8() provide this functionality
1777     more conveniently.
1778
1779     \a context is typically a class name (e.g., "MyDialog") and \a
1780     sourceText is either English text or a short identifying text.
1781
1782     \a disambiguation is an identifying string, for when the same \a
1783     sourceText is used in different roles within the same context. By
1784     default, it is null.
1785
1786     See the \l QTranslator and \l QObject::tr() documentation for
1787     more information about contexts, disambiguations and comments.
1788
1789     \a encoding indicates the 8-bit encoding of character strings.
1790
1791     \a n is used in conjunction with \c %n to support plural forms.
1792     See QObject::tr() for details.
1793
1794     If none of the translation files contain a translation for \a
1795     sourceText in \a context, this function returns a QString
1796     equivalent of \a sourceText. The encoding of \a sourceText is
1797     specified by \e encoding; it defaults to CodecForTr.
1798
1799     This function is not virtual. You can use alternative translation
1800     techniques by subclassing \l QTranslator.
1801
1802     \warning This method is reentrant only if all translators are
1803     installed \e before calling this method. Installing or removing
1804     translators while performing translations is not supported. Doing
1805     so will most likely result in crashes or other undesirable
1806     behavior.
1807
1808     \sa QObject::tr() installTranslator() QTextCodec::codecForTr()
1809 */
1810
1811
1812 QString QCoreApplication::translate(const char *context, const char *sourceText,
1813                                     const char *disambiguation, Encoding encoding, int n)
1814 {
1815     QString result;
1816
1817     if (!sourceText)
1818         return result;
1819
1820     if (self && !self->d_func()->translators.isEmpty()) {
1821         QList<QTranslator*>::ConstIterator it;
1822         QTranslator *translationFile;
1823         for (it = self->d_func()->translators.constBegin(); it != self->d_func()->translators.constEnd(); ++it) {
1824             translationFile = *it;
1825             result = translationFile->translate(context, sourceText, disambiguation, n);
1826             if (!result.isEmpty())
1827                 break;
1828         }
1829     }
1830
1831     if (result.isEmpty()) {
1832 #ifdef QT_NO_TEXTCODEC
1833         Q_UNUSED(encoding)
1834 #else
1835         if (encoding == UnicodeUTF8)
1836             result = QString::fromUtf8(sourceText);
1837         else if (QTextCodec::codecForTr() != 0)
1838             result = QTextCodec::codecForTr()->toUnicode(sourceText);
1839         else
1840 #endif
1841             result = QString::fromLatin1(sourceText);
1842     }
1843
1844     replacePercentN(&result, n);
1845     return result;
1846 }
1847
1848 // Declared in qglobal.h
1849 QString qtTrId(const char *id, int n)
1850 {
1851     return QCoreApplication::translate(0, id, 0, QCoreApplication::UnicodeUTF8, n);
1852 }
1853
1854 bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
1855 {
1856     return QCoreApplication::self
1857            && QCoreApplication::self->d_func()->translators.contains(translator);
1858 }
1859
1860 #endif //QT_NO_TRANSLATE
1861
1862 /*!
1863     Returns the directory that contains the application executable.
1864
1865     For example, if you have installed Qt in the \c{C:\Trolltech\Qt}
1866     directory, and you run the \c{regexp} example, this function will
1867     return "C:/Trolltech/Qt/examples/tools/regexp".
1868
1869     On Mac OS X this will point to the directory actually containing the
1870     executable, which may be inside of an application bundle (if the
1871     application is bundled).
1872
1873     \warning On Linux, this function will try to get the path from the
1874     \c {/proc} file system. If that fails, it assumes that \c
1875     {argv[0]} contains the absolute file name of the executable. The
1876     function also assumes that the current directory has not been
1877     changed by the application.
1878
1879     In Symbian this function will return the application private directory,
1880     not the path to executable itself, as those are always in \c {/sys/bin}.
1881     If the application is in a read only drive, i.e. ROM, then the private path
1882     on the system drive will be returned.
1883
1884     \sa applicationFilePath()
1885 */
1886 QString QCoreApplication::applicationDirPath()
1887 {
1888     if (!self) {
1889         qWarning("QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
1890         return QString();
1891     }
1892
1893     QCoreApplicationPrivate *d = self->d_func();
1894     if (d->cachedApplicationDirPath.isNull())
1895 #if defined(Q_OS_SYMBIAN)
1896     {
1897         QString appPath;
1898         RFs& fs = qt_s60GetRFs();
1899         TChar driveChar;
1900         QChar qDriveChar;
1901         driveChar = (RProcess().FileName())[0];
1902
1903         //Check if the process is installed in a read only drive (typically ROM),
1904         //and use the system drive (typically C:) if so.
1905         TInt drive;
1906         TDriveInfo driveInfo;
1907         TInt err = fs.CharToDrive(driveChar, drive);
1908         if (err == KErrNone) {
1909             err = fs.Drive(driveInfo, drive);
1910         }
1911         if (err != KErrNone || (driveInfo.iDriveAtt & KDriveAttRom) || (driveInfo.iMediaAtt
1912             & KMediaAttWriteProtected)) {
1913             if(!PtrGetSystemDrive)
1914                 PtrGetSystemDrive = reinterpret_cast<SystemDriveFunc>(qt_resolveS60PluginFunc(S60Plugin_GetSystemDrive));
1915             Q_ASSERT(PtrGetSystemDrive);
1916             drive = PtrGetSystemDrive(fs);
1917             fs.DriveToChar(drive, driveChar);
1918         }
1919
1920         qDriveChar = QChar(QLatin1Char(driveChar)).toUpper();
1921
1922         TFileName privatePath;
1923         fs.PrivatePath(privatePath);
1924         appPath = qt_TDesC2QString(privatePath);
1925         appPath.prepend(QLatin1Char(':')).prepend(qDriveChar);
1926
1927         // Create the appPath if it doesn't exist. Non-existing appPath will cause
1928         // Platform Security violations later on if the app doesn't have AllFiles capability.
1929         err = fs.CreatePrivatePath(drive);
1930         if (err != KErrNone)
1931             qWarning("QCoreApplication::applicationDirPath: Failed to create private path.");
1932
1933         d->cachedApplicationDirPath = QFileInfo(appPath).path();
1934     }
1935 #else
1936         d->cachedApplicationDirPath = QFileInfo(applicationFilePath()).path();
1937 #endif
1938     return d->cachedApplicationDirPath;
1939 }
1940
1941 /*!
1942     Returns the file path of the application executable.
1943
1944     For example, if you have installed Qt in the \c{/usr/local/qt}
1945     directory, and you run the \c{regexp} example, this function will
1946     return "/usr/local/qt/examples/tools/regexp/regexp".
1947
1948     \warning On Linux, this function will try to get the path from the
1949     \c {/proc} file system. If that fails, it assumes that \c
1950     {argv[0]} contains the absolute file name of the executable. The
1951     function also assumes that the current directory has not been
1952     changed by the application.
1953
1954     \sa applicationDirPath()
1955 */
1956 QString QCoreApplication::applicationFilePath()
1957 {
1958     if (!self) {
1959         qWarning("QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
1960         return QString();
1961     }
1962
1963     QCoreApplicationPrivate *d = self->d_func();
1964     if (!d->cachedApplicationFilePath.isNull())
1965         return d->cachedApplicationFilePath;
1966
1967 #if defined(Q_OS_WIN)
1968     d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
1969     return d->cachedApplicationFilePath;
1970 #elif defined(Q_WS_MAC)
1971     QString qAppFileName_str = qAppFileName();
1972     if(!qAppFileName_str.isEmpty()) {
1973         QFileInfo fi(qAppFileName_str);
1974         d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
1975         return d->cachedApplicationFilePath;
1976     }
1977 #endif
1978 #if defined(Q_OS_SYMBIAN)
1979     QString appPath;
1980     RProcess proc;
1981     TInt err = proc.Open(proc.Id());
1982     if (err == KErrNone) {
1983         TFileName procName = proc.FileName();
1984         appPath.append(QString(reinterpret_cast<const QChar*>(procName.Ptr()), procName.Length()));
1985         proc.Close();
1986     }
1987
1988     d->cachedApplicationFilePath = appPath;
1989     return d->cachedApplicationFilePath;
1990
1991 #elif defined( Q_OS_UNIX )
1992 #  ifdef Q_OS_LINUX
1993     // Try looking for a /proc/<pid>/exe symlink first which points to
1994     // the absolute path of the executable
1995     QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
1996     if (pfi.exists() && pfi.isSymLink()) {
1997         d->cachedApplicationFilePath = pfi.canonicalFilePath();
1998         return d->cachedApplicationFilePath;
1999     }
2000 #  endif
2001
2002     QString argv0 = QFile::decodeName(QByteArray(argv()[0]));
2003     QString absPath;
2004
2005     if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
2006         /*
2007           If argv0 starts with a slash, it is already an absolute
2008           file path.
2009         */
2010         absPath = argv0;
2011     } else if (argv0.contains(QLatin1Char('/'))) {
2012         /*
2013           If argv0 contains one or more slashes, it is a file path
2014           relative to the current directory.
2015         */
2016         absPath = QDir::current().absoluteFilePath(argv0);
2017     } else {
2018         /*
2019           Otherwise, the file path has to be determined using the
2020           PATH environment variable.
2021         */
2022         QByteArray pEnv = qgetenv("PATH");
2023         QDir currentDir = QDir::current();
2024         QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1Char(':'));
2025         for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
2026             if ((*p).isEmpty())
2027                 continue;
2028             QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
2029             QFileInfo candidate_fi(candidate);
2030             if (candidate_fi.exists() && !candidate_fi.isDir()) {
2031                 absPath = candidate;
2032                 break;
2033             }
2034         }
2035     }
2036
2037     absPath = QDir::cleanPath(absPath);
2038
2039     QFileInfo fi(absPath);
2040     d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
2041     return d->cachedApplicationFilePath;
2042 #endif
2043 }
2044
2045 /*!
2046     \since 4.4
2047
2048     Returns the current process ID for the application.
2049 */
2050 qint64 QCoreApplication::applicationPid()
2051 {
2052 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
2053     return GetCurrentProcessId();
2054 #elif defined(Q_OS_VXWORKS)
2055     return (pid_t) taskIdCurrent;
2056 #else
2057     return getpid();
2058 #endif
2059 }
2060
2061 /*!
2062     \obsolete
2063
2064     Use arguments().size() instead.
2065 */
2066 int QCoreApplication::argc()
2067 {
2068     if (!self) {
2069         qWarning("QCoreApplication::argc: Please instantiate the QApplication object first");
2070         return 0;
2071     }
2072     return self->d_func()->argc;
2073 }
2074
2075
2076 /*!
2077     \obsolete
2078
2079     Use arguments() instead.
2080 */
2081 char **QCoreApplication::argv()
2082 {
2083     if (!self) {
2084         qWarning("QCoreApplication::argv: Please instantiate the QApplication object first");
2085         return 0;
2086     }
2087     return self->d_func()->argv;
2088 }
2089
2090 /*!
2091     \since 4.1
2092
2093     Returns the list of command-line arguments.
2094
2095     Usually arguments().at(0) is the program name, arguments().at(1)
2096     is the first argument, and arguments().last() is the last
2097     argument. See the note below about Windows.
2098
2099     Calling this function is slow - you should store the result in a variable
2100     when parsing the command line.
2101
2102     \warning On Unix, this list is built from the argc and argv parameters passed
2103     to the constructor in the main() function. The string-data in argv is
2104     interpreted using QString::fromLocal8Bit(); hence it is not possible to
2105     pass, for example, Japanese command line arguments on a system that runs in a
2106     Latin1 locale. Most modern Unix systems do not have this limitation, as they are
2107     Unicode-based.
2108
2109     On NT-based Windows, this limitation does not apply either.
2110     On Windows, the arguments() are not built from the contents of argv/argc, as
2111     the content does not support Unicode. Instead, the arguments() are constructed
2112     from the return value of
2113     \l{http://msdn2.microsoft.com/en-us/library/ms683156(VS.85).aspx}{GetCommandLine()}.
2114     As a result of this, the string given by arguments().at(0) might not be
2115     the program name on Windows, depending on how the application was started.
2116
2117     For Symbian applications started with \c RApaLsSession::StartApp one can specify
2118     arguments using \c CApaCommandLine::SetTailEndL function. Such arguments are only
2119     available via this method; they will not be passed to \c main function. Also note
2120     that only 8-bit string data set with \c CApaCommandLine::SetTailEndL is supported
2121     by this function.
2122
2123     \sa applicationFilePath()
2124 */
2125
2126 QStringList QCoreApplication::arguments()
2127 {
2128     QStringList list;
2129
2130     if (!self) {
2131         qWarning("QCoreApplication::arguments: Please instantiate the QApplication object first");
2132         return list;
2133     }
2134 #ifdef Q_OS_WIN
2135     QString cmdline = QString::fromWCharArray(GetCommandLine());
2136
2137 #if defined(Q_OS_WINCE)
2138     wchar_t tempFilename[MAX_PATH+1];
2139     if (GetModuleFileName(0, tempFilename, MAX_PATH)) {
2140         tempFilename[MAX_PATH] = 0;
2141         cmdline.prepend(QLatin1Char('\"') + QString::fromWCharArray(tempFilename) + QLatin1String("\" "));
2142     }
2143 #endif // Q_OS_WINCE
2144
2145     list = qWinCmdArgs(cmdline);
2146     if (self->d_func()->application_type) { // GUI app? Skip known - see qapplication.cpp
2147         QStringList stripped;
2148         for (int a = 0; a < list.count(); ++a) {
2149             QString arg = list.at(a);
2150             QByteArray l1arg = arg.toLatin1();
2151             if (l1arg == "-qdevel" ||
2152                 l1arg == "-qdebug" ||
2153                 l1arg == "-reverse" ||
2154                 l1arg == "-stylesheet" ||
2155                 l1arg == "-widgetcount")
2156                 ;
2157             else if (l1arg.startsWith("-style=") ||
2158                      l1arg.startsWith("-qmljsdebugger="))
2159                 ;
2160             else if (l1arg == "-style" ||
2161                      l1arg == "-session" ||
2162                      l1arg == "-testability")
2163                 ++a;
2164             else
2165                 stripped += arg;
2166         }
2167         list = stripped;
2168     }
2169 #else
2170     const int ac = self->d_func()->argc;
2171     char ** const av = self->d_func()->argv;
2172     for (int a = 0; a < ac; ++a) {
2173         list << QString::fromLocal8Bit(av[a]);
2174     }
2175 #endif
2176
2177     return list;
2178 }
2179
2180 /*!
2181     \property QCoreApplication::organizationName
2182     \brief the name of the organization that wrote this application
2183
2184     The value is used by the QSettings class when it is constructed
2185     using the empty constructor. This saves having to repeat this
2186     information each time a QSettings object is created.
2187
2188     On Mac, QSettings uses organizationDomain() as the organization
2189     if it's not an empty string; otherwise it uses
2190     organizationName(). On all other platforms, QSettings uses
2191     organizationName() as the organization.
2192
2193     \sa organizationDomain applicationName
2194 */
2195
2196 void QCoreApplication::setOrganizationName(const QString &orgName)
2197 {
2198     coreappdata()->orgName = orgName;
2199 }
2200
2201 QString QCoreApplication::organizationName()
2202 {
2203     return coreappdata()->orgName;
2204 }
2205
2206 /*!
2207     \property QCoreApplication::organizationDomain
2208     \brief the Internet domain of the organization that wrote this application
2209
2210     The value is used by the QSettings class when it is constructed
2211     using the empty constructor. This saves having to repeat this
2212     information each time a QSettings object is created.
2213
2214     On Mac, QSettings uses organizationDomain() as the organization
2215     if it's not an empty string; otherwise it uses organizationName().
2216     On all other platforms, QSettings uses organizationName() as the
2217     organization.
2218
2219     \sa organizationName applicationName applicationVersion
2220 */
2221 void QCoreApplication::setOrganizationDomain(const QString &orgDomain)
2222 {
2223     coreappdata()->orgDomain = orgDomain;
2224 }
2225
2226 QString QCoreApplication::organizationDomain()
2227 {
2228     return coreappdata()->orgDomain;
2229 }
2230
2231 /*!
2232     \property QCoreApplication::applicationName
2233     \brief the name of this application
2234
2235     The value is used by the QSettings class when it is constructed
2236     using the empty constructor. This saves having to repeat this
2237     information each time a QSettings object is created.
2238
2239     \sa organizationName organizationDomain applicationVersion
2240 */
2241 void QCoreApplication::setApplicationName(const QString &application)
2242 {
2243     coreappdata()->application = application;
2244 }
2245
2246 QString QCoreApplication::applicationName()
2247 {
2248     return coreappdata()->application;
2249 }
2250
2251 /*!
2252     \property QCoreApplication::applicationVersion
2253     \since 4.4
2254     \brief the version of this application
2255
2256     \sa applicationName organizationName organizationDomain
2257 */
2258 void QCoreApplication::setApplicationVersion(const QString &version)
2259 {
2260     coreappdata()->applicationVersion = version;
2261 }
2262
2263 QString QCoreApplication::applicationVersion()
2264 {
2265     return coreappdata()->applicationVersion;
2266 }
2267
2268 #ifndef QT_NO_LIBRARY
2269
2270 Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
2271
2272 /*!
2273     Returns a list of paths that the application will search when
2274     dynamically loading libraries.
2275
2276     Qt provides default library paths, but they can also be set using
2277     a \l{Using qt.conf}{qt.conf} file. Paths specified in this file
2278     will override default values.
2279
2280     This list will include the installation directory for plugins if
2281     it exists (the default installation directory for plugins is \c
2282     INSTALL/plugins, where \c INSTALL is the directory where Qt was
2283     installed).  The directory of the application executable (NOT the
2284     working directory) is always added, as well as the colon separated
2285     entries of the QT_PLUGIN_PATH environment variable.
2286
2287     If you want to iterate over the list, you can use the \l foreach
2288     pseudo-keyword:
2289
2290     \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 2
2291
2292     \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary,
2293         {How to Create Qt Plugins}
2294 */
2295 QStringList QCoreApplication::libraryPaths()
2296 {
2297     QMutexLocker locker(libraryPathMutex());
2298     if (!coreappdata()->app_libpaths) {
2299         QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList;
2300         QString installPathPlugins =  QLibraryInfo::location(QLibraryInfo::PluginsPath);
2301 #if defined(Q_OS_SYMBIAN)
2302         // Add existing path on all drives for relative PluginsPath in Symbian
2303         if (installPathPlugins.at(1) != QChar(QLatin1Char(':'))) {
2304             QString tempPath = installPathPlugins;
2305             if (tempPath.at(tempPath.length() - 1) != QDir::separator()) {
2306                 tempPath += QDir::separator();
2307             }
2308             RFs& fs = qt_s60GetRFs();
2309             TPtrC tempPathPtr(reinterpret_cast<const TText*> (tempPath.constData()));
2310             TFindFile finder(fs);
2311             TInt err = finder.FindByDir(tempPathPtr, tempPathPtr);
2312             while (err == KErrNone) {
2313                 QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()),
2314                                  finder.File().Length());
2315                 foundDir = QDir(foundDir).canonicalPath();
2316                 if (!app_libpaths->contains(foundDir))
2317                     app_libpaths->append(foundDir);
2318                 err = finder.Find();
2319             }
2320         }
2321 #else
2322         if (QFile::exists(installPathPlugins)) {
2323             // Make sure we convert from backslashes to slashes.
2324             installPathPlugins = QDir(installPathPlugins).canonicalPath();
2325             if (!app_libpaths->contains(installPathPlugins))
2326                 app_libpaths->append(installPathPlugins);
2327         }
2328 #endif
2329
2330         // If QCoreApplication is not yet instantiated,
2331         // make sure we add the application path when we construct the QCoreApplication
2332         if (self) self->d_func()->appendApplicationPathToLibraryPaths();
2333
2334         const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH");
2335         if (!libPathEnv.isEmpty()) {
2336 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
2337             QLatin1Char pathSep(';');
2338 #else
2339             QLatin1Char pathSep(':');
2340 #endif
2341             QStringList paths = QString::fromLatin1(libPathEnv).split(pathSep, QString::SkipEmptyParts);
2342             for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
2343                 QString canonicalPath = QDir(*it).canonicalPath();
2344                 if (!canonicalPath.isEmpty()
2345                     && !app_libpaths->contains(canonicalPath)) {
2346                     app_libpaths->append(canonicalPath);
2347                 }
2348             }
2349         }
2350     }
2351     return *(coreappdata()->app_libpaths);
2352 }
2353
2354
2355
2356 /*!
2357
2358     Sets the list of directories to search when loading libraries to
2359     \a paths. All existing paths will be deleted and the path list
2360     will consist of the paths given in \a paths.
2361
2362     In Symbian this function is only useful for setting paths for
2363     finding Qt extension plugin stubs, since the OS can only
2364     load libraries from the \c{/sys/bin} directory.
2365
2366     \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
2367  */
2368 void QCoreApplication::setLibraryPaths(const QStringList &paths)
2369 {
2370     QMutexLocker locker(libraryPathMutex());
2371     if (!coreappdata()->app_libpaths)
2372         coreappdata()->app_libpaths = new QStringList;
2373     *(coreappdata()->app_libpaths) = paths;
2374     locker.unlock();
2375     QFactoryLoader::refreshAll();
2376 }
2377
2378 /*!
2379   Prepends \a path to the beginning of the library path list, ensuring that
2380   it is searched for libraries first. If \a path is empty or already in the
2381   path list, the path list is not changed.
2382
2383   The default path list consists of a single entry, the installation
2384   directory for plugins.  The default installation directory for plugins
2385   is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
2386   installed.
2387
2388   In Symbian this function is only useful for adding paths for
2389   finding Qt extension plugin stubs, since the OS can only
2390   load libraries from the \c{/sys/bin} directory.
2391
2392   \sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
2393  */
2394 void QCoreApplication::addLibraryPath(const QString &path)
2395 {
2396     if (path.isEmpty())
2397         return;
2398
2399     QMutexLocker locker(libraryPathMutex());
2400
2401     // make sure that library paths is initialized
2402     libraryPaths();
2403
2404     QString canonicalPath = QDir(path).canonicalPath();
2405     if (!canonicalPath.isEmpty()
2406         && !coreappdata()->app_libpaths->contains(canonicalPath)) {
2407         coreappdata()->app_libpaths->prepend(canonicalPath);
2408         locker.unlock();
2409         QFactoryLoader::refreshAll();
2410     }
2411 }
2412
2413 /*!
2414     Removes \a path from the library path list. If \a path is empty or not
2415     in the path list, the list is not changed.
2416
2417     \sa addLibraryPath(), libraryPaths(), setLibraryPaths()
2418 */
2419 void QCoreApplication::removeLibraryPath(const QString &path)
2420 {
2421     if (path.isEmpty())
2422         return;
2423
2424     QMutexLocker locker(libraryPathMutex());
2425
2426     // make sure that library paths is initialized
2427     libraryPaths();
2428
2429     QString canonicalPath = QDir(path).canonicalPath();
2430     coreappdata()->app_libpaths->removeAll(canonicalPath);
2431     QFactoryLoader::refreshAll();
2432 }
2433
2434 #endif //QT_NO_LIBRARY
2435
2436 /*!
2437     \typedef QCoreApplication::EventFilter
2438
2439     A function with the following signature that can be used as an
2440     event filter:
2441
2442     \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 3
2443
2444     \sa setEventFilter()
2445 */
2446
2447 /*!
2448     \fn EventFilter QCoreApplication::setEventFilter(EventFilter filter)
2449
2450     Replaces the event filter function for the QCoreApplication with
2451     \a filter and returns the pointer to the replaced event filter
2452     function. Only the current event filter function is called. If you
2453     want to use both filter functions, save the replaced EventFilter
2454     in a place where yours can call it.
2455
2456     The event filter function set here is called for all messages
2457     received by all threads meant for all Qt objects. It is \e not
2458     called for messages that are not meant for Qt objects.
2459
2460     The event filter function should return true if the message should
2461     be filtered, (i.e. stopped). It should return false to allow
2462     processing the message to continue.
2463
2464     By default, no event filter function is set (i.e., this function
2465     returns a null EventFilter the first time it is called).
2466
2467     \note The filter function set here receives native messages,
2468     i.e. MSG or XEvent structs, that are going to Qt objects. It is
2469     called by QCoreApplication::filterEvent(). If the filter function
2470     returns false to indicate the message should be processed further,
2471     the native message can then be translated into a QEvent and
2472     handled by the standard Qt \l{QEvent} {event} filering, e.g.
2473     QObject::installEventFilter().
2474
2475     \note The filter function set here is different form the filter
2476     function set via QAbstractEventDispatcher::setEventFilter(), which
2477     gets all messages received by its thread, even messages meant for
2478     objects that are not handled by Qt.
2479
2480     \sa QObject::installEventFilter(), QAbstractEventDispatcher::setEventFilter()
2481 */
2482 QCoreApplication::EventFilter
2483 QCoreApplication::setEventFilter(QCoreApplication::EventFilter filter)
2484 {
2485     Q_D(QCoreApplication);
2486     EventFilter old = d->eventFilter;
2487     d->eventFilter = filter;
2488     return old;
2489 }
2490
2491 /*!
2492     Sends \a message through the event filter that was set by
2493     setEventFilter(). If no event filter has been set, this function
2494     returns false; otherwise, this function returns the result of the
2495     event filter function in the \a result parameter.
2496
2497     \sa setEventFilter()
2498 */
2499 bool QCoreApplication::filterEvent(void *message, long *result)
2500 {
2501     Q_D(QCoreApplication);
2502     if (result)
2503         *result = 0;
2504     if (d->eventFilter)
2505         return d->eventFilter(message, result);
2506 #ifdef Q_OS_WIN
2507     return winEventFilter(reinterpret_cast<MSG *>(message), result);
2508 #else
2509     return false;
2510 #endif
2511 }
2512
2513 /*!
2514     This function returns true if there are pending events; otherwise
2515     returns false. Pending events can be either from the window
2516     system or posted events using postEvent().
2517
2518     \sa QAbstractEventDispatcher::hasPendingEvents()
2519 */
2520 bool QCoreApplication::hasPendingEvents()
2521 {
2522     QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2523     if (eventDispatcher)
2524         return eventDispatcher->hasPendingEvents();
2525     return false;
2526 }
2527
2528 /*
2529     \fn void QCoreApplication::watchUnixSignal(int signal, bool watch)
2530     \internal
2531 */
2532
2533 /*!
2534     \fn void QCoreApplication::unixSignal(int number)
2535     \internal
2536
2537     This signal is emitted whenever a Unix signal is received by the
2538     application. The Unix signal received is specified by its \a number.
2539 */
2540
2541 /*!
2542     \fn void qAddPostRoutine(QtCleanUpFunction ptr)
2543     \relates QCoreApplication
2544
2545     Adds a global routine that will be called from the QApplication
2546     destructor. This function is normally used to add cleanup routines
2547     for program-wide functionality.
2548
2549     The function specified by \a ptr should take no arguments and should
2550     return nothing. For example:
2551
2552     \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 4
2553
2554     Note that for an application- or module-wide cleanup,
2555     qAddPostRoutine() is often not suitable. For example, if the
2556     program is split into dynamically loaded modules, the relevant
2557     module may be unloaded long before the QApplication destructor is
2558     called.
2559
2560     For modules and libraries, using a reference-counted
2561     initialization manager or Qt's parent-child deletion mechanism may
2562     be better. Here is an example of a private class that uses the
2563     parent-child mechanism to call a cleanup function at the right
2564     time:
2565
2566     \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 5
2567
2568     By selecting the right parent object, this can often be made to
2569     clean up the module's data at the right moment.
2570 */
2571
2572 /*!
2573     \macro Q_DECLARE_TR_FUNCTIONS(context)
2574     \relates QCoreApplication
2575
2576     The Q_DECLARE_TR_FUNCTIONS() macro declares and implements two
2577     translation functions, \c tr() and \c trUtf8(), with these
2578     signatures:
2579
2580     \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 6
2581
2582     This macro is useful if you want to use QObject::tr() or
2583     QObject::trUtf8() in classes that don't inherit from QObject.
2584
2585     Q_DECLARE_TR_FUNCTIONS() must appear at the very top of the
2586     class definition (before the first \c{public:} or \c{protected:}).
2587     For example:
2588
2589     \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 7
2590
2591     The \a context parameter is normally the class name, but it can
2592     be any string.
2593
2594     \sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
2595 */
2596
2597 QT_END_NAMESPACE
2598
2599 #include "moc_qcoreapplication.cpp"