diff options
Diffstat (limited to 'src/kernel/qapplication.cpp')
-rw-r--r-- | src/kernel/qapplication.cpp | 132 |
1 files changed, 118 insertions, 14 deletions
diff --git a/src/kernel/qapplication.cpp b/src/kernel/qapplication.cpp index 51aa247..5b43301 100644 --- a/src/kernel/qapplication.cpp +++ b/src/kernel/qapplication.cpp @@ -68,6 +68,7 @@ #if defined(QT_THREAD_SUPPORT) # include "qmutex.h" # include "qthread.h" +# include <private/qthreadinstance_p.h> #endif // QT_THREAD_SUPPORT #include <stdlib.h> @@ -383,7 +384,25 @@ Q_EXPORT Qt::HANDLE qt_get_application_thread_id() } #endif // QT_THREAD_SUPPORT +#ifndef QT_THREAD_SUPPORT QEventLoop *QApplication::eventloop = 0; // application event loop +#endif + +#ifdef QT_THREAD_SUPPORT +QEventLoop* QApplication::currentEventLoop() { + QThread* thread = QThread::currentThreadObject(); + if (thread) { + if (thread->d) { + return thread->d->eventLoop; + } + } + return NULL; +} +#else +QEventLoop* QApplication::currentEventLoop() { + return QApplication::eventloop; +} +#endif #ifndef QT_NO_ACCEL extern bool qt_dispatchAccelEvent( QWidget*, QKeyEvent* ); // def in qaccel.cpp @@ -516,6 +535,41 @@ QClipboard *qt_clipboard = 0; // global clipboard object #endif QWidgetList * qt_modal_stack=0; // stack of modal widgets +#ifdef QT_THREAD_SUPPORT +// thread wrapper for the main() thread +class QCoreApplicationThread : public QThread +{ +public: + inline QCoreApplicationThread() + { + QThreadInstance::setCurrentThread(this); + + // thread should be running and not finished for the lifetime + // of the application (even if QCoreApplication goes away) + d->running = true; + d->finished = false; + d->eventLoop = NULL; + } + inline ~QCoreApplicationThread() + { + // avoid warning from QThread + d->running = false; + } +private: + inline void run() + { + // this function should never be called, it is implemented + // only so that we can instantiate the object + qFatal("QCoreApplicationThread: internal error"); + } +}; + +static QCoreApplicationThread qt_main_thread; +static QThread *mainThread() { return &qt_main_thread; } +#else +static QThread* mainThread() { return QThread::currentThread(); } +#endif + // Definitions for posted events struct QPostEvent { QPostEvent( QObject *r, QEvent *e ): receiver( r ), event( e ) {} @@ -818,8 +872,8 @@ void QApplication::construct( int &argc, char **argv, Type type ) initialize( argc, argv ); if ( qt_is_gui_used ) qt_maxWindowRect = desktop()->rect(); - if ( eventloop ) - eventloop->appStartingUp(); + if ( currentEventLoop() ) + currentEventLoop()->appStartingUp(); } /*! @@ -874,8 +928,8 @@ QApplication::QApplication( Display* dpy, HANDLE visual, HANDLE colormap ) if ( qt_is_gui_used ) qt_maxWindowRect = desktop()->rect(); - if ( eventloop ) - eventloop->appStartingUp(); + if ( currentEventLoop() ) + currentEventLoop()->appStartingUp(); } /*! @@ -916,13 +970,26 @@ QApplication::QApplication(Display *dpy, int argc, char **argv, if ( qt_is_gui_used ) qt_maxWindowRect = desktop()->rect(); - if ( eventloop ) - eventloop->appStartingUp(); + if ( currentEventLoop() ) + currentEventLoop()->appStartingUp(); } #endif // Q_WS_X11 +#ifdef QT_THREAD_SUPPORT +QThread* QApplication::guiThread() { + return mainThread(); +} + +bool QApplication::isGuiThread() { + return (QThread::currentThreadObject() == guiThread()); +} +#else +bool QApplication::isGuiThread() { + return true; +} +#endif void QApplication::init_precmdline() { @@ -1030,8 +1097,8 @@ QApplication::~QApplication() } #endif - if ( eventloop ) - eventloop->appClosingDown(); + if ( currentEventLoop() ) + currentEventLoop()->appClosingDown(); if ( postRList ) { QVFuncList::Iterator it = postRList->begin(); while ( it != postRList->end() ) { // call post routines @@ -2698,8 +2765,28 @@ bool QApplication::internalNotify( QObject *receiver, QEvent * e) } - if (!handled) + if (!handled) { +#if defined(QT_THREAD_SUPPORT) + int locklevel = 0; + int llcount; + if (QApplication::qt_mutex) { + QApplication::qt_mutex->lock(); // 1 of 2 + locklevel = qt_mutex->level() - 1; + for (llcount=0; llcount<locklevel; llcount++) { + QApplication::qt_mutex->unlock(); + } + QApplication::qt_mutex->unlock(); // 2 of 2 + } +#endif consumed = receiver->event( e ); +#if defined(QT_THREAD_SUPPORT) + if (QApplication::qt_mutex) { + for (llcount=0; llcount<locklevel; llcount++) { + QApplication::qt_mutex->lock(); + } + } +#endif + } e->spont = FALSE; return consumed; } @@ -2793,9 +2880,10 @@ void QApplication::processOneEvent() */ QEventLoop *QApplication::eventLoop() { - if ( !eventloop && !is_app_closing ) + if ( !currentEventLoop() && !is_app_closing ) { (void) new QEventLoop( qApp, "default event loop" ); - return eventloop; + } + return currentEventLoop(); } @@ -3263,8 +3351,23 @@ void QApplication::postEvent( QObject *receiver, QEvent *event ) l->append( pe ); globalPostedEvents->append( pe ); - if (eventloop) - eventloop->wakeUp(); +#ifdef QT_THREAD_SUPPORT + if ( event->type() == QEvent::MetaCall ) { + // Wake up the receiver thread event loop + QThread* thread = receiver->contextThreadObject(); + if (thread) { + if (thread->d) { + if (thread->d->eventLoop) { + thread->d->eventLoop->wakeUp(); + } + } + } + return; + } +#endif + + if (currentEventLoop()) + currentEventLoop()->wakeUp(); } @@ -3326,7 +3429,8 @@ void QApplication::sendPostedEvents( QObject *receiver, int event_type ) && ( receiver == 0 // we send to all receivers || receiver == pe->receiver ) // we send to THAT receiver && ( event_type == 0 // we send all types - || event_type == pe->event->type() ) ) { // we send THAT type + || event_type == pe->event->type() ) // we send THAT type + && ( (!pe->receiver) || (pe->receiver->contextThreadObject() == QThread::currentThreadObject()) ) ) { // only send if active thread is receiver object owning thread // first, we diddle the event so that we can deliver // it, and that noone will try to touch it later. pe->event->posted = FALSE; |