Darrell Anderson 12 years ago
commit 35202ed0d8

3
configure vendored

@ -734,6 +734,9 @@ while [ "$#" -gt 0 ]; do
glibmainloop) glibmainloop)
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
CFG_GLIBMAINLOOP="$VAL" CFG_GLIBMAINLOOP="$VAL"
if [ "$VAL" = "yes" ]; then
echo "WARNING: glib main loop support is ***incomplete*** and will cause problems with threaded applications and/or those using non-standard event loops!"
fi
else else
UNKNOWN_OPT=yes UNKNOWN_OPT=yes
fi fi

@ -290,7 +290,6 @@ ftglue_face_goto_table( FT_Face face,
if ( face->num_faces > 1 ) if ( face->num_faces > 1 )
{ {
/* deal with TrueType collections */ /* deal with TrueType collections */
FT_ULong offset;
LOG(( ">> This is a TrueType Collection\n" )); LOG(( ">> This is a TrueType Collection\n" ));
@ -298,8 +297,6 @@ ftglue_face_goto_table( FT_Face face,
ACCESS_Frame( 4 ) ) ACCESS_Frame( 4 ) )
goto Exit; goto Exit;
offset = GET_ULong();
FORGET_Frame(); FORGET_Frame();
} }

@ -83,6 +83,9 @@
#endif #endif
class Q_EXPORT_CODECS_JP QJpUnicodeConv { class Q_EXPORT_CODECS_JP QJpUnicodeConv {
public:
virtual ~QJpUnicodeConv() {}
public: public:
enum Rules { enum Rules {
// "ASCII" is ANSI X.3.4-1986, a.k.a. US-ASCII here. // "ASCII" is ANSI X.3.4-1986, a.k.a. US-ASCII here.

@ -381,6 +381,7 @@ class QIconViewToolTip : public QToolTip
{ {
public: public:
QIconViewToolTip( QWidget *parent, QIconView *iv ); QIconViewToolTip( QWidget *parent, QIconView *iv );
virtual ~QIconViewToolTip();
void maybeTip( const QPoint &pos ); void maybeTip( const QPoint &pos );
@ -393,6 +394,10 @@ QIconViewToolTip::QIconViewToolTip( QWidget *parent, QIconView *iv )
{ {
} }
QIconViewToolTip::~QIconViewToolTip()
{
}
void QIconViewToolTip::maybeTip( const QPoint &pos ) void QIconViewToolTip::maybeTip( const QPoint &pos )
{ {
if ( !parentWidget() || !view || view->wordWrapIconText() || !view->showToolTips() ) if ( !parentWidget() || !view || view->wordWrapIconText() || !view->showToolTips() )

@ -68,6 +68,7 @@
#if defined(QT_THREAD_SUPPORT) #if defined(QT_THREAD_SUPPORT)
# include "qmutex.h" # include "qmutex.h"
# include "qthread.h" # include "qthread.h"
# include <private/qthreadinstance_p.h>
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT
#include <stdlib.h> #include <stdlib.h>
@ -383,7 +384,25 @@ Q_EXPORT Qt::HANDLE qt_get_application_thread_id()
} }
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT
#ifndef QT_THREAD_SUPPORT
QEventLoop *QApplication::eventloop = 0; // application event loop 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 #ifndef QT_NO_ACCEL
extern bool qt_dispatchAccelEvent( QWidget*, QKeyEvent* ); // def in qaccel.cpp extern bool qt_dispatchAccelEvent( QWidget*, QKeyEvent* ); // def in qaccel.cpp
@ -516,6 +535,41 @@ QClipboard *qt_clipboard = 0; // global clipboard object
#endif #endif
QWidgetList * qt_modal_stack=0; // stack of modal widgets 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 // Definitions for posted events
struct QPostEvent { struct QPostEvent {
QPostEvent( QObject *r, QEvent *e ): receiver( r ), event( e ) {} 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 ); initialize( argc, argv );
if ( qt_is_gui_used ) if ( qt_is_gui_used )
qt_maxWindowRect = desktop()->rect(); qt_maxWindowRect = desktop()->rect();
if ( eventloop ) if ( currentEventLoop() )
eventloop->appStartingUp(); currentEventLoop()->appStartingUp();
} }
/*! /*!
@ -874,8 +928,8 @@ QApplication::QApplication( Display* dpy, HANDLE visual, HANDLE colormap )
if ( qt_is_gui_used ) if ( qt_is_gui_used )
qt_maxWindowRect = desktop()->rect(); qt_maxWindowRect = desktop()->rect();
if ( eventloop ) if ( currentEventLoop() )
eventloop->appStartingUp(); currentEventLoop()->appStartingUp();
} }
/*! /*!
@ -916,13 +970,26 @@ QApplication::QApplication(Display *dpy, int argc, char **argv,
if ( qt_is_gui_used ) if ( qt_is_gui_used )
qt_maxWindowRect = desktop()->rect(); qt_maxWindowRect = desktop()->rect();
if ( eventloop ) if ( currentEventLoop() )
eventloop->appStartingUp(); currentEventLoop()->appStartingUp();
} }
#endif // Q_WS_X11 #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() void QApplication::init_precmdline()
{ {
@ -1030,8 +1097,8 @@ QApplication::~QApplication()
} }
#endif #endif
if ( eventloop ) if ( currentEventLoop() )
eventloop->appClosingDown(); currentEventLoop()->appClosingDown();
if ( postRList ) { if ( postRList ) {
QVFuncList::Iterator it = postRList->begin(); QVFuncList::Iterator it = postRList->begin();
while ( it != postRList->end() ) { // call post routines 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 ); 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; e->spont = FALSE;
return consumed; return consumed;
} }
@ -2793,9 +2880,10 @@ void QApplication::processOneEvent()
*/ */
QEventLoop *QApplication::eventLoop() QEventLoop *QApplication::eventLoop()
{ {
if ( !eventloop && !is_app_closing ) if ( !currentEventLoop() && !is_app_closing ) {
(void) new QEventLoop( qApp, "default event loop" ); (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 ); l->append( pe );
globalPostedEvents->append( pe ); globalPostedEvents->append( pe );
if (eventloop) #ifdef QT_THREAD_SUPPORT
eventloop->wakeUp(); 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 == 0 // we send to all receivers
|| receiver == pe->receiver ) // we send to THAT receiver || receiver == pe->receiver ) // we send to THAT receiver
&& ( event_type == 0 // we send all types && ( 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 // first, we diddle the event so that we can deliver
// it, and that noone will try to touch it later. // it, and that noone will try to touch it later.
pe->event->posted = FALSE; pe->event->posted = FALSE;

@ -63,6 +63,7 @@ class QWSDecoration;
#ifdef QT_THREAD_SUPPORT #ifdef QT_THREAD_SUPPORT
class QMutex; class QMutex;
class QThread;
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT
@ -369,7 +370,9 @@ private:
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
static QCursor *app_cursor; static QCursor *app_cursor;
#endif #endif
#ifndef QT_THREAD_SUPPORT
static QEventLoop* eventloop; static QEventLoop* eventloop;
#endif
static int app_tracking; static int app_tracking;
static bool is_app_running; static bool is_app_running;
static bool is_app_closing; static bool is_app_closing;
@ -425,6 +428,7 @@ private:
static void removePostedEvent( QEvent * ); static void removePostedEvent( QEvent * );
static void removePostedEvents( QObject *receiver, int event_type ); static void removePostedEvents( QObject *receiver, int event_type );
friend class QObject;
friend class QWidget; friend class QWidget;
friend class QETWidget; friend class QETWidget;
friend class QDialog; friend class QDialog;
@ -444,6 +448,15 @@ private: // Disabled copy constructor and operator=
QApplication( const QApplication & ); QApplication( const QApplication & );
QApplication &operator=( const QApplication & ); QApplication &operator=( const QApplication & );
#endif #endif
private:
static QEventLoop* currentEventLoop();
public:
#ifdef QT_THREAD_SUPPORT
static QThread* guiThread();
#endif
static bool isGuiThread();
}; };
inline int QApplication::argc() const inline int QApplication::argc() const

@ -430,7 +430,7 @@ static bool qt_x11EventFilter( XEvent* ev )
//XIM qt_xim = 0; //XIM qt_xim = 0;
Q_EXPORT XIMStyle qt_xim_style = 0; Q_EXPORT XIMStyle qt_xim_style = 0;
Q_EXPORT XIMStyle qt_xim_preferred_style = 0; Q_EXPORT XIMStyle qt_xim_preferred_style = 0;
Q_EXPORT static XIMStyle xim_default_style = XIMPreeditCallbacks | XIMStatusNothing; static XIMStyle xim_default_style = XIMPreeditCallbacks | XIMStatusNothing;
#endif #endif
Q_EXPORT int qt_ximComposingKeycode=0; Q_EXPORT int qt_ximComposingKeycode=0;
@ -5889,7 +5889,7 @@ static Bool qt_net_wm_sync_request_scanner(Display*, XEvent* event, XPointer arg
{ {
return (event->type == ClientMessage && event->xclient.window == *(Window*)arg return (event->type == ClientMessage && event->xclient.window == *(Window*)arg
&& event->xclient.message_type == qt_wm_protocols && event->xclient.message_type == qt_wm_protocols
&& event->xclient.data.l[ 0 ] == qt_net_wm_sync_request ); && ((unsigned int)event->xclient.data.l[ 0 ]) == qt_net_wm_sync_request );
} }
#endif #endif

@ -1749,9 +1749,9 @@ QColorDrag::QColorDrag( QWidget *dragsource, const char *name )
void QColorDrag::setColor( const QColor &col ) void QColorDrag::setColor( const QColor &col )
{ {
short r = (col.red() << 8) | col.red(); unsigned short r = (col.red() << 8) | col.red();
short g = (col.green() << 8) | col.green(); unsigned short g = (col.green() << 8) | col.green();
short b = (col.blue() << 8) | col.blue(); unsigned short b = (col.blue() << 8) | col.blue();
// make sure we transmit data in network order // make sure we transmit data in network order
r = htons(r); r = htons(r);

@ -137,6 +137,8 @@ public:
HelpRequest = 95, // CE (?) button pressed HelpRequest = 95, // CE (?) button pressed
WindowStateChange = 96, // window state has changed WindowStateChange = 96, // window state has changed
IconDrag = 97, // proxy icon dragged IconDrag = 97, // proxy icon dragged
MetaCall = 98, // meta method call (internal)
ThreadChange = 99, // thread changed
User = 1000, // first user event id User = 1000, // first user event id
MaxUser = 65535 // last user event id MaxUser = 65535 // last user event id
}; };

@ -41,6 +41,11 @@
#include "qapplication.h" #include "qapplication.h"
#include "qdatetime.h" #include "qdatetime.h"
#ifdef QT_THREAD_SUPPORT
# include "qthread.h"
# include "qthreadinstance_p.h"
#endif
/*! /*!
\class QEventLoop \class QEventLoop
\brief The QEventLoop class manages the event queue. \brief The QEventLoop class manages the event queue.
@ -100,15 +105,27 @@ QEventLoop::QEventLoop( QObject *parent, const char *name )
: QObject( parent, name ) : QObject( parent, name )
{ {
#if defined(QT_CHECK_STATE) #if defined(QT_CHECK_STATE)
if ( QApplication::eventloop ) if ( QApplication::currentEventLoop() )
qFatal( "QEventLoop: there must be only one event loop object. \nConstruct it before QApplication." ); qFatal( "QEventLoop: there must be only one event loop object per thread. \nIf this is supposed to be the main GUI event loop, construct it before QApplication." );
// for now ;) if (!QThread::currentThreadObject()) {
qFatal( "QEventLoop: this object can only be used in threads constructed via QThread." );
}
#endif // QT_CHECK_STATE #endif // QT_CHECK_STATE
d = new QEventLoopPrivate; d = new QEventLoopPrivate;
init(); init();
#ifdef QT_THREAD_SUPPORT
QThread* thread = QThread::currentThreadObject();
if (thread) {
if (thread->d) {
thread->d->eventLoop = this;
}
}
#else
QApplication::eventloop = this; QApplication::eventloop = this;
#endif
} }
/*! /*!
@ -118,7 +135,16 @@ QEventLoop::~QEventLoop()
{ {
cleanup(); cleanup();
delete d; delete d;
#ifdef QT_THREAD_SUPPORT
QThread* thread = QThread::currentThreadObject();
if (thread) {
if (thread->d) {
thread->d->eventLoop = 0;
}
}
#else
QApplication::eventloop = 0; QApplication::eventloop = 0;
#endif
} }
/*! /*!

@ -102,25 +102,6 @@ public:
virtual void wakeUp(); virtual void wakeUp();
#ifdef Q_QDOC
#else // Q_QDOC
#if defined(QT_USE_GLIBMAINLOOP)
// glib main loop support
/* internal: used to fit glib-main-loop gsource concept */
bool gsourcePrepare(GSource *gs, int * timeout);
bool gsourceCheck(GSource * gs);
bool gsourceDispatch(GSource * gs);
bool processX11Events();
// end glib main loop support
#endif //QT_USE_GLIBMAINLOOP
#endif // Q_QDOC
void setSingleToolkitEventHandling(bool enabled); void setSingleToolkitEventHandling(bool enabled);
signals: signals:
@ -145,6 +126,24 @@ private:
QEventLoopPrivate *d; QEventLoopPrivate *d;
friend class QApplication; friend class QApplication;
#ifdef Q_QDOC
#else // Q_QDOC
#if defined(QT_USE_GLIBMAINLOOP)
// glib main loop support
/* internal: used to fit glib-main-loop gsource concept */
public:
bool gsourcePrepare(GSource *gs, int * timeout);
bool gsourceCheck(GSource * gs);
bool gsourceDispatch(GSource * gs);
bool processX11Events();
// end glib main loop support
#endif //QT_USE_GLIBMAINLOOP
#endif // Q_QDOC
}; };
#endif // QEVENTLOOP_H #endif // QEVENTLOOP_H

@ -86,6 +86,10 @@ class QEventLoopPrivate
public: public:
QEventLoopPrivate() QEventLoopPrivate()
{ {
#if defined(Q_WS_X11)
xfd = -1;
x_gPollFD.fd = -1;
#endif // Q_WS_X11
reset(); reset();
} }
@ -106,16 +110,13 @@ public:
#if defined(Q_WS_X11) #if defined(Q_WS_X11)
int xfd; int xfd;
GPollFD x_gPollFD; GPollFD x_gPollFD;
#endif // Q_WS_X11 #endif // Q_WS_X11
int thread_pipe[2]; int thread_pipe[2];
GPollFD threadPipe_gPollFD; GPollFD threadPipe_gPollFD;
QPtrList<QSockNotGPollFD> sn_list; QPtrList<QSockNotGPollFD> sn_list;
// pending socket notifiers list // pending socket notifiers list
QPtrList<QSockNotGPollFD> sn_pending_list; QPtrList<QSockNotGPollFD> sn_pending_list;
@ -123,10 +124,11 @@ public:
uint pev_flags; uint pev_flags;
// My GSource // My GSource
GSource * gSource; GSource * gSource;
bool singletoolkit; bool singletoolkit;
// main context
GMainContext *ctx;
}; };
#endif // QEVENTLOOP_GLIB_P_H #endif // QEVENTLOOP_GLIB_P_H

@ -40,6 +40,7 @@
#include "qeventloop.h" #include "qeventloop.h"
#include "qapplication.h" #include "qapplication.h"
#include "qbitarray.h" #include "qbitarray.h"
#include "qmutex.h"
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
@ -561,6 +562,8 @@ int QEventLoop::activateTimers()
n_act++; n_act++;
QTimerEvent e( t->id ); QTimerEvent e( t->id );
QApplication::sendEvent( t->obj, &e ); // send event QApplication::sendEvent( t->obj, &e ); // send event
if ( !timerList ) // sendEvent allows other threads to execute, therefore we must check for list existence when it returns!
return 0;
if ( timerList->findRef( begin ) == -1 ) if ( timerList->findRef( begin ) == -1 )
begin = 0; begin = 0;
} }

@ -44,6 +44,7 @@
#include "qeventloop.h" #include "qeventloop.h"
#include "qapplication.h" #include "qapplication.h"
#include "qbitarray.h" #include "qbitarray.h"
#include "qmutex.h"
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
@ -369,9 +370,9 @@ void QEventLoop::registerSocketNotifier( QSocketNotifier *notifier )
return; return;
} }
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("register socket notifier %d\n", sockfd); printf("register socket notifier %d\n", sockfd);
#endif #endif
QPtrList<QSockNotGPollFD> *list = &d->sn_list; QPtrList<QSockNotGPollFD> *list = &d->sn_list;
QSockNotGPollFD *sn; QSockNotGPollFD *sn;
@ -424,9 +425,9 @@ void QEventLoop::unregisterSocketNotifier( QSocketNotifier *notifier )
return; return;
} }
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("unregister socket notifier %d\n", sockfd); printf("unregister socket notifier %d\n", sockfd);
#endif #endif
QPtrList<QSockNotGPollFD> *list = &d->sn_list; QPtrList<QSockNotGPollFD> *list = &d->sn_list;
QSockNotGPollFD *sn; QSockNotGPollFD *sn;
@ -457,9 +458,9 @@ void QEventLoop::setSocketNotifierPending( QSocketNotifier *notifier )
return; return;
} }
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("set socket notifier pending %d\n", sockfd); printf("set socket notifier pending %d\n", sockfd);
#endif #endif
QPtrList<QSockNotGPollFD> *list = &d->sn_list; QPtrList<QSockNotGPollFD> *list = &d->sn_list;
QSockNotGPollFD *sn; QSockNotGPollFD *sn;
@ -505,7 +506,9 @@ void QEventLoop::wakeUp()
size_t nbytes = 0; size_t nbytes = 0;
char c = 0; char c = 0;
if ( ::ioctl( d->thread_pipe[0], FIONREAD, (char*)&nbytes ) >= 0 && nbytes == 0 ) { if ( ::ioctl( d->thread_pipe[0], FIONREAD, (char*)&nbytes ) >= 0 && nbytes == 0 ) {
::write( d->thread_pipe[1], &c, 1 ); if (::write( d->thread_pipe[1], &c, 1 ) < 0) {
// Failed!
}
} }
} }
@ -577,12 +580,9 @@ int QEventLoop::activateSocketNotifiers()
++it; ++it;
d->sn_pending_list.removeRef( sn ); d->sn_pending_list.removeRef( sn );
if ( sn->pending ) { if ( sn->pending ) {
#ifdef DEBUG_QT_GLIBMAINLOOP
#ifdef DEBUG_QT_GLIBMAINLOOP
printf("activate sn : send event fd=%d\n", sn->gPollFD.fd ); printf("activate sn : send event fd=%d\n", sn->gPollFD.fd );
#endif #endif
sn->pending = FALSE; sn->pending = FALSE;
QApplication::sendEvent( sn->obj, &event ); QApplication::sendEvent( sn->obj, &event );
n_act++; n_act++;

@ -146,6 +146,7 @@ bool QEventLoop::processEvents( ProcessEventsFlags flags )
if ( qt_is_gui_used ) { if ( qt_is_gui_used ) {
QApplication::sendPostedEvents(); QApplication::sendPostedEvents();
if (QApplication::isGuiThread()) {
// Two loops so that posted events accumulate // Two loops so that posted events accumulate
while ( XPending( QPaintDevice::x11AppDisplay() ) ) { while ( XPending( QPaintDevice::x11AppDisplay() ) ) {
// also flushes output buffer // also flushes output buffer
@ -197,6 +198,7 @@ bool QEventLoop::processEvents( ProcessEventsFlags flags )
} }
} }
} }
}
if ( d->shortcut ) { if ( d->shortcut ) {
return FALSE; return FALSE;
@ -261,7 +263,7 @@ bool QEventLoop::processEvents( ProcessEventsFlags flags )
FD_ZERO( &d->sn_vec[2].select_fds ); FD_ZERO( &d->sn_vec[2].select_fds );
} }
if ( qt_is_gui_used ) { if ( qt_is_gui_used && QApplication::isGuiThread() ) {
// select for events on the event socket - only on X11 // select for events on the event socket - only on X11
FD_SET( d->xfd, &d->sn_vec[0].select_fds ); FD_SET( d->xfd, &d->sn_vec[0].select_fds );
highest = QMAX( highest, d->xfd ); highest = QMAX( highest, d->xfd );
@ -282,7 +284,8 @@ bool QEventLoop::processEvents( ProcessEventsFlags flags )
// unlock the GUI mutex and select. when we return from this function, there is // unlock the GUI mutex and select. when we return from this function, there is
// something for us to do // something for us to do
#if defined(QT_THREAD_SUPPORT) #if defined(QT_THREAD_SUPPORT)
locker.mutex()->unlock(); if ( locker.mutex() ) locker.mutex()->unlock();
else return false;
#endif #endif
int nsel; int nsel;
@ -296,7 +299,8 @@ bool QEventLoop::processEvents( ProcessEventsFlags flags )
// relock the GUI mutex before processing any pending events // relock the GUI mutex before processing any pending events
#if defined(QT_THREAD_SUPPORT) #if defined(QT_THREAD_SUPPORT)
locker.mutex()->lock(); if ( locker.mutex() ) locker.mutex()->lock();
else return false;
#endif #endif
// we are awake, broadcast it // we are awake, broadcast it

@ -39,7 +39,6 @@
** **
**********************************************************************/ **********************************************************************/
#include "qeventloop_glib_p.h" // includes qplatformdefs.h #include "qeventloop_glib_p.h" // includes qplatformdefs.h
#include "qeventloop.h" #include "qeventloop.h"
#include "qapplication.h" #include "qapplication.h"
@ -49,12 +48,15 @@
#if defined(QT_THREAD_SUPPORT) #if defined(QT_THREAD_SUPPORT)
# include "qmutex.h" # include "qmutex.h"
# include "qthread.h"
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT
#include <errno.h> #include <errno.h>
#include <glib.h> #include <glib.h>
// #define DEBUG_QT_GLIBMAINLOOP 1
// Qt-GSource Structure and Callbacks // Qt-GSource Structure and Callbacks
typedef struct { typedef struct {
@ -62,11 +64,9 @@ typedef struct {
QEventLoop * qeventLoop; QEventLoop * qeventLoop;
} QtGSource; } QtGSource;
static gboolean qt_gsource_prepare ( GSource *source, static gboolean qt_gsource_prepare ( GSource *source, gint *timeout );
gint *timeout );
static gboolean qt_gsource_check ( GSource *source ); static gboolean qt_gsource_check ( GSource *source );
static gboolean qt_gsource_dispatch ( GSource *source, static gboolean qt_gsource_dispatch ( GSource *source, GSourceFunc callback, gpointer user_data );
GSourceFunc callback, gpointer user_data );
static GSourceFuncs qt_gsource_funcs = { static GSourceFuncs qt_gsource_funcs = {
qt_gsource_prepare, qt_gsource_prepare,
@ -82,15 +82,32 @@ static GSourceFuncs qt_gsource_funcs = {
static gboolean qt_gsource_prepare ( GSource *source, static gboolean qt_gsource_prepare ( GSource *source,
gint *timeout ) gint *timeout )
{ {
QtGSource * qtGSource; QtGSource * qtGSource = (QtGSource*) source;
qtGSource = (QtGSource*) source; QEventLoop* candidateEventLoop = qtGSource->qeventLoop;
return qtGSource->qeventLoop->gsourcePrepare(source, timeout); QEventLoop* activeThreadEventLoop = QApplication::eventLoop();
if (candidateEventLoop == activeThreadEventLoop) {
return candidateEventLoop->gsourcePrepare(source, timeout);
}
else {
// Prepare failed
return FALSE;
}
} }
static gboolean qt_gsource_check ( GSource *source ) static gboolean qt_gsource_check ( GSource *source )
{ {
QtGSource * qtGSource = (QtGSource*) source; QtGSource * qtGSource = (QtGSource*) source;
return qtGSource->qeventLoop->gsourceCheck(source); QEventLoop* candidateEventLoop = qtGSource->qeventLoop;
QEventLoop* activeThreadEventLoop = QApplication::eventLoop();
if (candidateEventLoop == activeThreadEventLoop) {
return candidateEventLoop->gsourceCheck(source);
}
else {
// Check failed
return FALSE;
}
} }
static gboolean qt_gsource_dispatch ( GSource *source, static gboolean qt_gsource_dispatch ( GSource *source,
@ -100,7 +117,16 @@ static gboolean qt_gsource_dispatch ( GSource *source,
Q_UNUSED(user_data); Q_UNUSED(user_data);
QtGSource * qtGSource = (QtGSource*) source; QtGSource * qtGSource = (QtGSource*) source;
return qtGSource->qeventLoop->gsourceDispatch(source); QEventLoop* candidateEventLoop = qtGSource->qeventLoop;
QEventLoop* activeThreadEventLoop = QApplication::eventLoop();
if (candidateEventLoop == activeThreadEventLoop) {
return candidateEventLoop->gsourceDispatch(source);
}
else {
// Dispatch failed
return FALSE;
}
} }
@ -134,38 +160,43 @@ static QVFuncList *qt_postselect_handler = 0;
void qt_install_preselect_handler( VFPTR handler ) void qt_install_preselect_handler( VFPTR handler )
{ {
if ( !qt_preselect_handler ) if ( !qt_preselect_handler ) {
qt_preselect_handler = new QVFuncList; qt_preselect_handler = new QVFuncList;
}
qt_preselect_handler->append( handler ); qt_preselect_handler->append( handler );
} }
void qt_remove_preselect_handler( VFPTR handler ) void qt_remove_preselect_handler( VFPTR handler )
{ {
if ( qt_preselect_handler ) { if ( qt_preselect_handler ) {
QVFuncList::Iterator it = qt_preselect_handler->find( handler ); QVFuncList::Iterator it = qt_preselect_handler->find( handler );
if ( it != qt_preselect_handler->end() ) if ( it != qt_preselect_handler->end() ) {
qt_preselect_handler->remove( it ); qt_preselect_handler->remove( it );
} }
}
} }
void qt_install_postselect_handler( VFPTR handler ) void qt_install_postselect_handler( VFPTR handler )
{ {
if ( !qt_postselect_handler ) if ( !qt_postselect_handler ) {
qt_postselect_handler = new QVFuncList; qt_postselect_handler = new QVFuncList;
}
qt_postselect_handler->prepend( handler ); qt_postselect_handler->prepend( handler );
} }
void qt_remove_postselect_handler( VFPTR handler ) void qt_remove_postselect_handler( VFPTR handler )
{ {
if ( qt_postselect_handler ) { if ( qt_postselect_handler ) {
QVFuncList::Iterator it = qt_postselect_handler->find( handler ); QVFuncList::Iterator it = qt_postselect_handler->find( handler );
if ( it != qt_postselect_handler->end() ) if ( it != qt_postselect_handler->end() ) {
qt_postselect_handler->remove( it ); qt_postselect_handler->remove( it );
} }
}
} }
void QEventLoop::init() void QEventLoop::init()
{ {
// initialize ProcessEventFlags (all events & wait for more) // initialize ProcessEventFlags (all events & wait for more)
d->pev_flags = AllEvents | WaitForMore; d->pev_flags = AllEvents | WaitForMore;
// initialize the common parts of the event loop // initialize the common parts of the event loop
@ -177,50 +208,44 @@ void QEventLoop::init()
// intitialize the X11 parts of the event loop // intitialize the X11 parts of the event loop
d->xfd = -1; d->xfd = -1;
if ( qt_is_gui_used ) if ( qt_is_gui_used && QApplication::isGuiThread() ) {
d->xfd = XConnectionNumber( QPaintDevice::x11AppDisplay() ); d->xfd = XConnectionNumber( QPaintDevice::x11AppDisplay() );
}
// new GSource // new main context for thread
d->ctx = g_main_context_new();
QtGSource * qtGSource = (QtGSource*) g_source_new(&qt_gsource_funcs, g_main_context_push_thread_default(d->ctx);
sizeof(QtGSource));
// new GSource
QtGSource * qtGSource = (QtGSource*) g_source_new(&qt_gsource_funcs, sizeof(QtGSource));
g_source_set_can_recurse ((GSource*)qtGSource, TRUE); g_source_set_can_recurse ((GSource*)qtGSource, TRUE);
qtGSource->qeventLoop = this; qtGSource->qeventLoop = this;
// init main loop and attach gsource // init main loop and attach gsource
#ifdef DEBUG_QT_GLIBMAINLOOP
#ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside init(1)\n"); printf("inside init(1)\n");
#endif #endif
g_main_loop_new (NULL, 1);
g_source_attach( (GSource*)qtGSource, NULL );
d->gSource = (GSource*) qtGSource; g_main_loop_new (d->ctx, 1);
g_source_attach( (GSource*)qtGSource, d->ctx );
d->gSource = (GSource*)qtGSource;
// poll for X11 events // poll for X11 events
if ( qt_is_gui_used && QApplication::isGuiThread() ) {
if ( qt_is_gui_used ) {
d->x_gPollFD.fd = d->xfd; d->x_gPollFD.fd = d->xfd;
d->x_gPollFD.events = G_IO_IN | G_IO_HUP; d->x_gPollFD.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
g_source_add_poll(d->gSource, &d->x_gPollFD); g_source_add_poll(d->gSource, &d->x_gPollFD);
} }
// poll thread-pipe // poll thread-pipe
d->threadPipe_gPollFD.fd = d->thread_pipe[0]; d->threadPipe_gPollFD.fd = d->thread_pipe[0];
d->threadPipe_gPollFD.events = G_IO_IN | G_IO_HUP; d->threadPipe_gPollFD.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
g_source_add_poll(d->gSource, &d->threadPipe_gPollFD); g_source_add_poll(d->gSource, &d->threadPipe_gPollFD);
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside init(2)\n"); printf("inside init(2)\n");
#endif #endif
} }
@ -234,28 +259,32 @@ void QEventLoop::cleanup()
// cleanup the X11 parts of the event loop // cleanup the X11 parts of the event loop
d->xfd = -1; d->xfd = -1;
// unref the main context
g_main_context_unref(d->ctx);
// todo: destroy gsource // todo: destroy gsource
} }
bool QEventLoop::processEvents( ProcessEventsFlags flags ) bool QEventLoop::processEvents( ProcessEventsFlags flags )
{ {
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside processEvents(1) looplevel=%d\n", d->looplevel ); printf("inside processEvents(1) looplevel=%d\n", d->looplevel );
#endif #endif
ProcessEventsFlags save_flags; ProcessEventsFlags save_flags;
int rval; int rval;
save_flags = d->pev_flags; save_flags = d->pev_flags;
d->pev_flags = flags; d->pev_flags = flags;
rval = g_main_context_iteration(NULL, flags & WaitForMore ? TRUE : FALSE); rval = g_main_context_iteration(d->ctx, flags & WaitForMore ? TRUE : FALSE);
d->pev_flags = save_flags; d->pev_flags = save_flags;
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside processEvents(2) looplevel=%d rval=%d\n", d->looplevel, rval ); printf("inside processEvents(2) looplevel=%d rval=%d\n", d->looplevel, rval );
#endif #endif
return rval; // were events processed? return rval; // were events processed?
} }
@ -276,6 +305,7 @@ bool QEventLoop::processX11Events()
if ( qt_is_gui_used ) { if ( qt_is_gui_used ) {
QApplication::sendPostedEvents(); QApplication::sendPostedEvents();
if (QApplication::isGuiThread()) {
// Two loops so that posted events accumulate // Two loops so that posted events accumulate
while ( XPending( QPaintDevice::x11AppDisplay() ) ) { while ( XPending( QPaintDevice::x11AppDisplay() ) ) {
// also flushes output buffer // also flushes output buffer
@ -322,11 +352,13 @@ bool QEventLoop::processX11Events()
} }
nevents++; nevents++;
if ( qApp->x11ProcessEvent( &event ) == 1 ) if ( qApp->x11ProcessEvent( &event ) == 1 ) {
return TRUE; return TRUE;
} }
} }
} }
}
}
if ( d->shortcut ) { if ( d->shortcut ) {
return FALSE; return FALSE;
@ -336,8 +368,7 @@ bool QEventLoop::processX11Events()
const uint exclude_all = ExcludeSocketNotifiers | 0x08; const uint exclude_all = ExcludeSocketNotifiers | 0x08;
// 0x08 == ExcludeTimers for X11 only // 0x08 == ExcludeTimers for X11 only
if ( nevents > 0 && ( flags & exclude_all ) == exclude_all && if ( nevents > 0 && ( flags & exclude_all ) == exclude_all && ( flags & WaitForMore ) ) {
( flags & WaitForMore ) ) {
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@ -348,9 +379,9 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)
{ {
Q_UNUSED(gs); Q_UNUSED(gs);
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourcePrepare(1)\n"); printf("inside gsourcePrepare(1)\n");
#endif #endif
ProcessEventsFlags flags = d->pev_flags; ProcessEventsFlags flags = d->pev_flags;
@ -369,15 +400,15 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)
if ( ! ( flags & 0x08 ) ) { // 0x08 == ExcludeTimers for X11 only if ( ! ( flags & 0x08 ) ) { // 0x08 == ExcludeTimers for X11 only
tm = qt_wait_timer(); // wait for timer or X event tm = qt_wait_timer(); // wait for timer or X event
if ( !canWait ) { if ( !canWait ) {
if ( !tm ) if ( !tm ) {
tm = &zerotm; tm = &zerotm;
}
tm->tv_sec = 0; // no time to wait tm->tv_sec = 0; // no time to wait
tm->tv_usec = 0; tm->tv_usec = 0;
} }
} }
// include or exclude SocketNotifiers (by setting or cleaning poll events) // include or exclude SocketNotifiers (by setting or cleaning poll events)
if ( ! ( flags & ExcludeSocketNotifiers ) ) { if ( ! ( flags & ExcludeSocketNotifiers ) ) {
QPtrListIterator<QSockNotGPollFD> it( d->sn_list ); QPtrListIterator<QSockNotGPollFD> it( d->sn_list );
QSockNotGPollFD *sn; QSockNotGPollFD *sn;
@ -385,7 +416,8 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)
++it; ++it;
sn->gPollFD.events = sn->events; // restore poll events sn->gPollFD.events = sn->events; // restore poll events
} }
} else { }
else {
QPtrListIterator<QSockNotGPollFD> it( d->sn_list ); QPtrListIterator<QSockNotGPollFD> it( d->sn_list );
QSockNotGPollFD *sn; QSockNotGPollFD *sn;
while ( (sn=it.current()) ) { while ( (sn=it.current()) ) {
@ -394,13 +426,13 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)
} }
} }
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourcePrepare(2) canwait=%d\n", canWait); printf("inside gsourcePrepare(2) canwait=%d\n", canWait);
#endif #endif
if ( canWait ) if ( canWait ) {
emit aboutToBlock(); emit aboutToBlock();
}
if ( qt_preselect_handler ) { if ( qt_preselect_handler ) {
QVFuncList::Iterator it, end = qt_preselect_handler->end(); QVFuncList::Iterator it, end = qt_preselect_handler->end();
@ -408,45 +440,34 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)
(**it)(); (**it)();
} }
// unlock the GUI mutex and select. when we return from this function, there is #ifdef DEBUG_QT_GLIBMAINLOOP
// something for us to do
#if defined(QT_THREAD_SUPPORT)
locker.mutex()->unlock();
#endif
#ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourcePrepare(2.1) canwait=%d\n", canWait); printf("inside gsourcePrepare(2.1) canwait=%d\n", canWait);
#endif #endif
// do we have to dispatch events? // do we have to dispatch events?
if (hasPendingEvents()) { if (hasPendingEvents()) {
*timeout = 0; // no time to stay in poll *timeout = 0; // no time to stay in poll
#ifdef DEBUG_QT_GLIBMAINLOOP
#ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourcePrepare(3a)\n"); printf("inside gsourcePrepare(3a)\n");
#endif #endif
return FALSE; return FALSE;
} }
// stay in poll until something happens? // stay in poll until something happens?
if (!tm) { // fixme if (!tm) { // fixme
*timeout = -1; // wait forever *timeout = -1; // wait forever
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourcePrepare(3b) timeout=%d \n", *timeout); printf("inside gsourcePrepare(3b) timeout=%d \n", *timeout);
#endif #endif
return FALSE; return FALSE;
} }
// else timeout >=0 // else timeout >=0
*timeout = tm->tv_sec * 1000 + tm->tv_usec/1000; *timeout = tm->tv_sec * 1000 + tm->tv_usec/1000;
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourcePrepare(3c) timeout=%d \n", *timeout); printf("inside gsourcePrepare(3c) timeout=%d \n", *timeout);
#endif #endif
return FALSE; return FALSE;
} }
@ -455,18 +476,13 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)
bool QEventLoop::gsourceCheck(GSource *gs) { bool QEventLoop::gsourceCheck(GSource *gs) {
Q_UNUSED(gs); Q_UNUSED(gs);
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(1)\n"); printf("inside gsourceCheck(1)\n");
#endif #endif
// Socketnotifier events? // Socketnotifier events?
QPtrList<QSockNotGPollFD> *list = &d->sn_list; QPtrList<QSockNotGPollFD> *list = &d->sn_list;
//if ( list ) { //if ( list ) {
QSockNotGPollFD *sn = list->first(); QSockNotGPollFD *sn = list->first();
while ( sn ) { while ( sn ) {
if ( sn->gPollFD.revents ) if ( sn->gPollFD.revents )
@ -476,43 +492,41 @@ bool QEventLoop::gsourceCheck(GSource *gs) {
//} //}
if (d->x_gPollFD.revents) { if (d->x_gPollFD.revents) {
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(2) xfd!\n"); printf("inside gsourceCheck(2) xfd!\n");
#endif #endif
return TRUE; // we got events! return TRUE; // we got events!
} }
if (d->threadPipe_gPollFD.revents) { if (d->threadPipe_gPollFD.revents) {
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(2) threadpipe!!\n"); printf("inside gsourceCheck(2) threadpipe!!\n");
#endif #endif
return TRUE; // we got events! return TRUE; // we got events!
} }
if (hasPendingEvents()) { if (hasPendingEvents()) {
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(2) pendingEvents!\n"); printf("inside gsourceCheck(2) pendingEvents!\n");
#endif #endif
return TRUE; // we got more X11 events! return TRUE; // we got more X11 events!
} }
// check if we have timers to activate?
// check if we have timers to activate?
timeval * tm =qt_wait_timer(); timeval * tm =qt_wait_timer();
if (tm && (tm->tv_sec == 0 && tm->tv_usec == 0 )) { if (tm && (tm->tv_sec == 0 && tm->tv_usec == 0 )) {
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(2) qtwaittimer!\n"); printf("inside gsourceCheck(2) qtwaittimer!\n");
#endif #endif
return TRUE; return TRUE;
} }
// nothing to dispatch // nothing to dispatch
#ifdef DEBUG_QT_GLIBMAINLOOP
#ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(2) nothing to dispatch!\n"); printf("inside gsourceCheck(2) nothing to dispatch!\n");
#endif #endif
return FALSE; return FALSE;
} }
@ -526,16 +540,15 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {
QMutexLocker locker( QApplication::qt_mutex ); QMutexLocker locker( QApplication::qt_mutex );
#endif #endif
#if defined(QT_THREAD_SUPPORT) #if defined(QT_THREAD_SUPPORT)
locker.mutex()->lock(); if (locker.mutex()) locker.mutex()->lock();
#endif #endif
int nevents=0; int nevents=0;
ProcessEventsFlags flags = d->pev_flags; ProcessEventsFlags flags = d->pev_flags;
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceDispatch(1)\n"); printf("inside gsourceDispatch(1)\n");
#endif #endif
// we are awake, broadcast it // we are awake, broadcast it
emit awake(); emit awake();
@ -562,8 +575,6 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {
// if select says data is ready on any socket, then set the socket notifier // if select says data is ready on any socket, then set the socket notifier
// to pending // to pending
// if ( &d->sn_list ) { // if ( &d->sn_list ) {
QPtrList<QSockNotGPollFD> *list = &d->sn_list; QPtrList<QSockNotGPollFD> *list = &d->sn_list;
QSockNotGPollFD *sn = list->first(); QSockNotGPollFD *sn = list->first();
while ( sn ) { while ( sn ) {
@ -582,30 +593,28 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {
nevents += activateTimers(); nevents += activateTimers();
} }
// return true if we handled events, false otherwise // return true if we handled events, false otherwise
//return (nevents > 0); //return (nevents > 0);
// now process x11 events! // now process x11 events!
#ifdef DEBUG_QT_GLIBMAINLOOP
#ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceDispatch(2) hasPendingEvents=%d\n", hasPendingEvents()); printf("inside gsourceDispatch(2) hasPendingEvents=%d\n", hasPendingEvents());
#endif #endif
if (hasPendingEvents()) { if (hasPendingEvents()) {
// color approx. optimization - only on X11 // color approx. optimization - only on X11
qt_reset_color_avail(); qt_reset_color_avail();
#if defined(QT_THREAD_SUPPORT)
if (locker.mutex()) locker.mutex()->unlock();
#endif
processX11Events(); processX11Events();
} }
else {
#if defined(QT_THREAD_SUPPORT) #if defined(QT_THREAD_SUPPORT)
locker.mutex()->unlock(); if (locker.mutex()) locker.mutex()->unlock();
#endif #endif
}
if (d->singletoolkit) { if (d->singletoolkit) {
return TRUE; // Eat the event return TRUE; // Eat the event
@ -618,13 +627,19 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {
bool QEventLoop::hasPendingEvents() const bool QEventLoop::hasPendingEvents() const
{ {
extern uint qGlobalPostedEventsCount(); // from qapplication.cpp extern uint qGlobalPostedEventsCount(); // from qapplication.cpp
return ( qGlobalPostedEventsCount() || ( qt_is_gui_used ? XPending( QPaintDevice::x11AppDisplay() ) : 0)); return ( qGlobalPostedEventsCount() || ( (qt_is_gui_used && QApplication::isGuiThread()) ? XPending( QPaintDevice::x11AppDisplay() ) : 0));
} }
void QEventLoop::appStartingUp() void QEventLoop::appStartingUp()
{ {
if ( qt_is_gui_used ) if ( qt_is_gui_used ) {
d->xfd = XConnectionNumber( QPaintDevice::x11AppDisplay() ); d->xfd = XConnectionNumber( QPaintDevice::x11AppDisplay() );
if ( (d->x_gPollFD.fd == -1) && QApplication::isGuiThread() ) {
d->x_gPollFD.fd = d->xfd;
d->x_gPollFD.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
g_source_add_poll(d->gSource, &d->x_gPollFD);
}
}
} }
void QEventLoop::appClosingDown() void QEventLoop::appClosingDown()

@ -5424,6 +5424,7 @@ static void write_pbm_image( QImageIO *iio )
class QImageIOFrameGrabber : public QImageConsumer { class QImageIOFrameGrabber : public QImageConsumer {
public: public:
QImageIOFrameGrabber() : framecount(0) { } QImageIOFrameGrabber() : framecount(0) { }
virtual ~QImageIOFrameGrabber() { }
QImageDecoder *decoder; QImageDecoder *decoder;
int framecount; int framecount;

@ -477,6 +477,7 @@ bool QInputContext::isComposing() const
*/ */
bool QInputContext::filterEvent( const QEvent *event ) bool QInputContext::filterEvent( const QEvent *event )
{ {
Q_UNUSED(event);
return FALSE; return FALSE;
} }
@ -679,6 +680,11 @@ void QInputContext::unsetFocus()
*/ */
void QInputContext::setMicroFocus( int x, int y, int w, int h, QFont *f ) void QInputContext::setMicroFocus( int x, int y, int w, int h, QFont *f )
{ {
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(w);
Q_UNUSED(h);
Q_UNUSED(f);
} }
@ -705,6 +711,9 @@ void QInputContext::mouseHandler( int x, QEvent::Type type,
Qt::ButtonState button, Qt::ButtonState button,
Qt::ButtonState state ) Qt::ButtonState state )
{ {
Q_UNUSED(x);
Q_UNUSED(button);
Q_UNUSED(state);
// Default behavior for simple ephemeral input contexts. Some // Default behavior for simple ephemeral input contexts. Some
// complex input contexts should not be reset here. // complex input contexts should not be reset here.
if ( type == QEvent::MouseButtonPress || if ( type == QEvent::MouseButtonPress ||

@ -67,6 +67,8 @@
*/ */
bool QInputContext::x11FilterEvent( QWidget *keywidget, XEvent *event ) bool QInputContext::x11FilterEvent( QWidget *keywidget, XEvent *event )
{ {
Q_UNUSED(keywidget);
Q_UNUSED(event);
return FALSE; return FALSE;
} }

@ -80,7 +80,7 @@ void my_error_exit (j_common_ptr cinfo)
my_error_mgr* myerr = (my_error_mgr*) cinfo->err; my_error_mgr* myerr = (my_error_mgr*) cinfo->err;
char buffer[JMSG_LENGTH_MAX]; char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message)(cinfo, buffer); (*cinfo->err->format_message)(cinfo, buffer);
qWarning(buffer); qWarning("%s", buffer);
longjmp(myerr->setjmp_buffer, 1); longjmp(myerr->setjmp_buffer, 1);
} }

@ -381,6 +381,14 @@ public:
of these values. of these values.
*/ */
QNetworkProtocolFactoryBase::QNetworkProtocolFactoryBase() {
//
}
QNetworkProtocolFactoryBase::~QNetworkProtocolFactoryBase() {
//
}
/*! /*!
Constructor of the network protocol base class. Does some Constructor of the network protocol base class. Does some
initialization and connecting of signals and slots. initialization and connecting of signals and slots.

@ -63,6 +63,10 @@ template <class T> class QValueList;
class Q_EXPORT QNetworkProtocolFactoryBase class Q_EXPORT QNetworkProtocolFactoryBase
{ {
public:
QNetworkProtocolFactoryBase();
virtual ~QNetworkProtocolFactoryBase();
public: public:
virtual QNetworkProtocol *createObject() = 0; virtual QNetworkProtocol *createObject() = 0;

@ -50,22 +50,107 @@
#include "qptrvector.h" #include "qptrvector.h"
#ifdef QT_THREAD_SUPPORT #ifdef QT_THREAD_SUPPORT
#include <qmutex.h> #include "qmutex.h"
#include <private/qmutexpool_p.h> #include <private/qmutexpool_p.h>
#include "qthread.h"
#endif #endif
#include <ctype.h> #include <ctype.h>
#include <stdlib.h>
#ifndef QT_NO_USERDATA #ifndef QT_NO_USERDATA
class QObjectPrivate : public QPtrVector<QObjectUserData> class QObjectPrivate : public QPtrVector<QObjectUserData>
#else
class QObjectPrivate {
#endif
{ {
public: public:
#ifndef QT_NO_USERDATA
QObjectPrivate( uint s ) : QPtrVector<QObjectUserData>(s){ setAutoDelete( TRUE ); } QObjectPrivate( uint s ) : QPtrVector<QObjectUserData>(s){ setAutoDelete( TRUE ); }
#endif
QThread* ownThread;
}; };
#else
class QObjectPrivate { #if defined(QT_THREAD_SUPPORT)
void QObject::moveToThread_helper(QThread *targetThread)
{
QEvent e(QEvent::ThreadChange);
QApplication::sendEvent(this, &e);
if (childObjects) {
QObject *child;
QObjectListIt it(*childObjects);
while ( (child=it.current()) ) {
++it;
child->moveToThread_helper(targetThread);
}
}
}
void QObject::setThreadObject_helper(QThread *targetThread)
{
d->ownThread = targetThread;
if (childObjects) {
QObject *child;
QObjectListIt it(*childObjects);
while ( (child=it.current()) ) {
++it;
child->moveToThread_helper(targetThread);
}
}
}
/*!
Changes the thread affinity for this object and its children. The
object cannot be moved if it has a parent. Event processing will
continue in the \a targetThread. To move an object to the main
thread, pass QApplication::guiThread() as the \a targetThread.
Note that all active timers for the object will be reset. The
timers are first stopped in the current thread and restarted (with
the same interval) in the \a targetThread. As a result, constantly
moving an object between threads can postpone timer events
indefinitely.
\sa contextThreadObject()
*/
void QObject::moveToThread(QThread *targetThread)
{
QMutexLocker locker( QApplication::qt_mutex );
if (parentObj) {
#if defined(QT_DEBUG)
qWarning( "QObject::moveToThread: Cannot move objects with a parent" );
#endif
return;
}
if (isWidget) {
#if defined(QT_DEBUG)
qWarning( "QObject::moveToThread: Widgets cannot be moved to a new thread" );
#endif
return;
}
QThread *objectThread = contextThreadObject();
QThread *currentThread = QThread::currentThreadObject();
if (objectThread != currentThread) {
#if defined(QT_DEBUG)
qWarning( "QObject::moveToThread: Current thread is not the object's thread" );
#endif
return;
}
if (objectThread == targetThread) {
return;
}
moveToThread_helper(targetThread);
setThreadObject_helper(targetThread);
} }
#endif #endif
class QSenderObjectList : public QObjectList, public QShared class QSenderObjectList : public QObjectList, public QShared
@ -75,6 +160,41 @@ public:
QObject *currentSender; QObject *currentSender;
}; };
class Q_EXPORT QMetaCallEvent : public QEvent
{
public:
enum MetaCallType {
MetaCallEmit = 0,
MetaCallInvoke = 1
};
public:
QMetaCallEvent(int id, QObject *sender, QUObject *data, MetaCallType type);
~QMetaCallEvent();
inline int id() const { return id_; }
inline QObject *sender() const { return sender_; }
inline QUObject *data() const { return data_; }
inline MetaCallType type() const { return type_; }
private:
const int id_;
QObject *sender_;
QUObject *data_;
const MetaCallType type_;
};
/*! \internal
*/
QMetaCallEvent::QMetaCallEvent(int id, QObject *sender, QUObject *data, MetaCallType type)
:QEvent(MetaCall), id_(id), sender_(sender), data_(data), type_(type)
{ }
/*! \internal
*/
QMetaCallEvent::~QMetaCallEvent()
{ }
/*! /*!
\class Qt qnamespace.h \class Qt qnamespace.h
@ -269,7 +389,21 @@ void *qt_find_obj_child( QObject *parent, const char *type, const char *name )
return 0; return 0;
} }
#ifdef QT_THREAD_SUPPORT
/*!
Returns a pointer to the QThread* associated with
the current thread affinity of this object.
\sa moveToThread()
*/
QThread* QObject::contextThreadObject() const
{
return d->ownThread;
}
#endif
#ifndef QT_NO_PRELIMINARY_SIGNAL_SPY #ifndef QT_NO_PRELIMINARY_SIGNAL_SPY
/* /*
@ -436,6 +570,11 @@ QObject::QObject( QObject *parent, const char *name )
insert_tree( this ); insert_tree( this );
isTree = TRUE; isTree = TRUE;
} }
if ( !d )
d = new QObjectPrivate(0);
d->ownThread = QThread::currentThreadObject();
} }
@ -720,6 +859,36 @@ QObject* QObject::child( const char *objName, const char *inheritsClass,
return obj; return obj;
} }
/*! \internal */
QUObject* deepCopyQUObjectArray(QUObject* origArray)
{
QUObject* newArray;
int count = 0;
while (!((origArray+count)->isLastObject)) {
count++;
}
count++;
newArray = (QUObject*)malloc(sizeof(QUObject)*count);
for (int i=0; i<count; i++) {
(origArray+i)->deepCopy(newArray+i);
}
return newArray;
}
/*! \internal */
void destroyDeepCopiedQUObjectArray(QUObject* uArray)
{
int count = 0;
while (!((uArray+count)->isLastObject)) {
count++;
}
count++;
for (int i=0; i<count; i++) {
(uArray+i)->~QUObject();
}
free(uArray);
}
/*! /*!
\fn bool QObject::isWidgetType() const \fn bool QObject::isWidgetType() const
@ -777,6 +946,40 @@ bool QObject::event( QEvent *e )
delete this; delete this;
return TRUE; return TRUE;
case QEvent::MetaCall:
{
QMetaCallEvent* metaEvent = dynamic_cast<QMetaCallEvent*>(e);
if (metaEvent) {
if (d->ownThread == QThread::currentThreadObject()) {
QSenderObjectList* sol;
QObject* oldSender = 0;
sol = senderObjects;
if ( sol ) {
oldSender = sol->currentSender;
sol->ref();
sol->currentSender = metaEvent->sender();
}
QUObject *o = metaEvent->data();
if (metaEvent->type() == QMetaCallEvent::MetaCallEmit) {
qt_emit( metaEvent->id(), o );
}
if (metaEvent->type() == QMetaCallEvent::MetaCallInvoke) {
qt_invoke( metaEvent->id(), o );
}
if (sol ) {
sol->currentSender = oldSender;
if ( sol->deref() ) {
delete sol;
}
}
}
else {
qWarning("QObject: Ignoring metacall event from non-owning thread");
}
destroyDeepCopiedQUObjectArray(metaEvent->data());
}
}
default: default:
if ( e->type() >= QEvent::User ) { if ( e->type() >= QEvent::User ) {
customEvent( (QCustomEvent*) e ); customEvent( (QCustomEvent*) e );
@ -2337,6 +2540,7 @@ void QObject::activate_signal( int signal )
if ( !signalsBlocked() && signal >= 0 && if ( !signalsBlocked() && signal >= 0 &&
( !connections || !connections->at( signal ) ) ) { ( !connections || !connections->at( signal ) ) ) {
QUObject o[1]; QUObject o[1];
o[0].isLastObject = true;
qt_spy_signal( this, signal, o ); qt_spy_signal( this, signal, o );
return; return;
} }
@ -2349,6 +2553,7 @@ void QObject::activate_signal( int signal )
if ( !clist ) if ( !clist )
return; return;
QUObject o[1]; QUObject o[1];
o[0].isLastObject = true;
activate_signal( clist, o ); activate_signal( clist, o );
} }
@ -2364,6 +2569,8 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
qt_spy_signal( this, connections->findRef( clist), o ); qt_spy_signal( this, connections->findRef( clist), o );
#endif #endif
const QThread *currentThread = QThread::currentThreadObject();
QObject *object; QObject *object;
QSenderObjectList* sol; QSenderObjectList* sol;
QObject* oldSender = 0; QObject* oldSender = 0;
@ -2377,10 +2584,26 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
sol->ref(); sol->ref();
sol->currentSender = this; sol->currentSender = this;
} }
if ( c->memberType() == QSIGNAL_CODE ) if ( c->memberType() == QSIGNAL_CODE ) {
if (object->d->ownThread == currentThread) {
object->qt_emit( c->member(), o ); object->qt_emit( c->member(), o );
else }
else {
if (object->d->ownThread && !object->d->ownThread->finished()) {
QApplication::postEvent(object, new QMetaCallEvent(c->member(), this, deepCopyQUObjectArray(o), QMetaCallEvent::MetaCallEmit));
}
}
}
else {
if (object->d->ownThread == currentThread) {
object->qt_invoke( c->member(), o ); object->qt_invoke( c->member(), o );
}
else {
if (object->d->ownThread && !object->d->ownThread->finished()) {
QApplication::postEvent(object, new QMetaCallEvent(c->member(), this, deepCopyQUObjectArray(o), QMetaCallEvent::MetaCallInvoke));
}
}
}
if ( sol ) { if ( sol ) {
sol->currentSender = oldSender; sol->currentSender = oldSender;
if ( sol->deref() ) if ( sol->deref() )
@ -2401,10 +2624,26 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
sol->ref(); sol->ref();
sol->currentSender = this; sol->currentSender = this;
} }
if ( c->memberType() == QSIGNAL_CODE ) if ( c->memberType() == QSIGNAL_CODE ) {
if (object->d->ownThread == currentThread) {
object->qt_emit( c->member(), o ); object->qt_emit( c->member(), o );
else }
else {
if (object->d->ownThread && !object->d->ownThread->finished()) {
QApplication::postEvent(object, new QMetaCallEvent(c->member(), this, deepCopyQUObjectArray(o), QMetaCallEvent::MetaCallEmit));
}
}
}
else {
if (object->d->ownThread == currentThread) {
object->qt_invoke( c->member(), o ); object->qt_invoke( c->member(), o );
}
else {
if (object->d->ownThread && !object->d->ownThread->finished()) {
QApplication::postEvent(object, new QMetaCallEvent(c->member(), this, deepCopyQUObjectArray(o), QMetaCallEvent::MetaCallInvoke));
}
}
}
if (sol ) { if (sol ) {
sol->currentSender = oldSender; sol->currentSender = oldSender;
if ( sol->deref() ) if ( sol->deref() )
@ -2442,6 +2681,7 @@ void QObject::FNAME( int signal, TYPE param ) \
if ( !signalsBlocked() && signal >= 0 && \ if ( !signalsBlocked() && signal >= 0 && \
( !connections || !connections->at( signal ) ) ) { \ ( !connections || !connections->at( signal ) ) ) { \
QUObject o[2]; \ QUObject o[2]; \
o[1].isLastObject = true; \
static_QUType_##TYPE.set( o+1, param ); \ static_QUType_##TYPE.set( o+1, param ); \
qt_spy_signal( this, signal, o ); \ qt_spy_signal( this, signal, o ); \
return; \ return; \
@ -2453,6 +2693,7 @@ void QObject::FNAME( int signal, TYPE param ) \
if ( !clist ) \ if ( !clist ) \
return; \ return; \
QUObject o[2]; \ QUObject o[2]; \
o[1].isLastObject = true; \
static_QUType_##TYPE.set( o+1, param ); \ static_QUType_##TYPE.set( o+1, param ); \
activate_signal( clist, o ); \ activate_signal( clist, o ); \
} }
@ -2466,6 +2707,7 @@ void QObject::FNAME( int signal, TYPE param ) \
if ( !clist ) \ if ( !clist ) \
return; \ return; \
QUObject o[2]; \ QUObject o[2]; \
o[1].isLastObject = true; \
static_QUType_##TYPE.set( o+1, param ); \ static_QUType_##TYPE.set( o+1, param ); \
activate_signal( clist, o ); \ activate_signal( clist, o ); \
} }

@ -63,6 +63,10 @@ class QObjectUserData;
#endif #endif
struct QUObject; struct QUObject;
#ifdef QT_THREAD_SUPPORT
class QThread;
#endif
class Q_EXPORT QObject: public Qt class Q_EXPORT QObject: public Qt
{ {
Q_OBJECT Q_OBJECT
@ -217,6 +221,18 @@ private: // Disabled copy constructor and operator=
QObject( const QObject & ); QObject( const QObject & );
QObject &operator=( const QObject & ); QObject &operator=( const QObject & );
#endif #endif
public:
#ifdef QT_THREAD_SUPPORT
QThread* contextThreadObject() const;
void moveToThread(QThread *targetThread);
#endif
private:
#ifdef QT_THREAD_SUPPORT
void moveToThread_helper(QThread *targetThread);
void setThreadObject_helper(QThread *targetThread);
#endif
}; };

@ -529,9 +529,14 @@ static void create_dpis()
Q_CHECK_PTR( dpisX ); Q_CHECK_PTR( dpisX );
Q_CHECK_PTR( dpisY ); Q_CHECK_PTR( dpisY );
for ( i = 0; i < screens; i++ ) { for ( i = 0; i < screens; i++ ) {
if (DisplayWidthMM(dpy,i) < 1)
dpisX[ i ] = 75; // default the dpi to 75.
else
dpisX[ i ] = (DisplayWidth(dpy,i) * 254 + DisplayWidthMM(dpy,i)*5) dpisX[ i ] = (DisplayWidth(dpy,i) * 254 + DisplayWidthMM(dpy,i)*5)
/ (DisplayWidthMM(dpy,i)*10); / (DisplayWidthMM(dpy,i)*10);
if (DisplayHeightMM(dpy,i) < 1)
dpisY[ i ] = 75; // default the dpi to 75.
else
dpisY[ i ] = (DisplayHeight(dpy,i) * 254 + DisplayHeightMM(dpy,i)*5) dpisY[ i ] = (DisplayHeight(dpy,i) * 254 + DisplayHeightMM(dpy,i)*5)
/ (DisplayHeightMM(dpy,i)*10); / (DisplayHeightMM(dpy,i)*10);
} }

@ -379,7 +379,9 @@ void QProcessManager::sigchldHnd( int fd )
} }
char tmp; char tmp;
::read( fd, &tmp, sizeof(tmp) ); if (::read( fd, &tmp, sizeof(tmp) ) < 0) {
qWarning( "Could not read from file descriptor" );
}
#if defined(QT_QPROCESS_DEBUG) #if defined(QT_QPROCESS_DEBUG)
qDebug( "QProcessManager::sigchldHnd()" ); qDebug( "QProcessManager::sigchldHnd()" );
#endif #endif
@ -562,7 +564,9 @@ QT_SIGNAL_RETTYPE qt_C_sigchldHnd( QT_SIGNAL_ARGS )
return; return;
char a = 1; char a = 1;
::write( QProcessPrivate::procManager->sigchldFd[0], &a, sizeof(a) ); if (::write( QProcessPrivate::procManager->sigchldFd[0], &a, sizeof(a) ) < 0) {
qWarning( "Could not write to file descriptor" );
}
} }

@ -2725,10 +2725,6 @@ static bool khmer_shape_syllable(QOpenType *openType, QShaperItem *item)
#ifndef QT_NO_XFTFREETYPE #ifndef QT_NO_XFTFREETYPE
if (openType) { if (openType) {
unsigned short logClusters[16];
for (int i = 0; i < len; ++i)
logClusters[i] = i;
uint where[16]; uint where[16];
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
@ -3236,10 +3232,6 @@ static bool myanmar_shape_syllable(QOpenType *openType, QShaperItem *item, bool
#ifndef QT_NO_XFTFREETYPE #ifndef QT_NO_XFTFREETYPE
if (openType) { if (openType) {
unsigned short logClusters[32];
for (int i = 0; i < len; ++i)
logClusters[i] = i;
uint where[32]; uint where[32];
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {

@ -290,6 +290,7 @@ class Q_EXPORT QStyleControlElementData {
QString caption; QString caption;
QStyleControlElementGenericWidgetData topLevelWidgetData; QStyleControlElementGenericWidgetData topLevelWidgetData;
Q_UINT32 topLevelWidgetFlags; Q_UINT32 topLevelWidgetFlags;
QPixmap paletteBgPixmap;
}; };
class Q_EXPORT QStyleWidgetActionRequestData { class Q_EXPORT QStyleWidgetActionRequestData {
@ -1070,6 +1071,18 @@ public:
// bool - whether or not the upper two button drawing areas should be combined into one // bool - whether or not the upper two button drawing areas should be combined into one
SH_ScrollBar_CombineSubLineRegionDrawingAreas, SH_ScrollBar_CombineSubLineRegionDrawingAreas,
// Qt::QRgb - color of the popup menu arrow (active, menuitem enabled)
SH_PopupMenu_SubMenuArrowColorActiveEnabled,
// Qt::QRgb - color of the popup menu arrow (active, menuitem disabled)
SH_PopupMenu_SubMenuArrowColorActiveDisabled,
// Qt::QRgb - color of the popup menu arrow (inactive, menuitem enabled)
SH_PopupMenu_SubMenuArrowColorInactiveEnabled,
// Qt::QRgb - color of the popup menu arrow (active, menuitem disabled)
SH_PopupMenu_SubMenuArrowColorInactiveDisabled,
// do not add any values below/greater than this // do not add any values below/greater than this
SH_CustomBase = 0xf0000000 SH_CustomBase = 0xf0000000
}; };

@ -41,6 +41,7 @@
#include "qplatformdefs.h" #include "qplatformdefs.h"
#include "qthread.h" #include "qthread.h"
#include "qeventloop.h"
#include <private/qthreadinstance_p.h> #include <private/qthreadinstance_p.h>
#ifndef QT_H #ifndef QT_H
@ -238,4 +239,20 @@ void QThread::postEvent( QObject * receiver, QEvent * event )
} }
#endif #endif
QEventLoopThread::QEventLoopThread() : QThread()
{
//
}
QEventLoopThread::~QEventLoopThread()
{
//
}
void QEventLoopThread::run()
{
QEventLoop* eventLoop = QApplication::eventLoop();
if (eventLoop) eventLoop->exec();
}
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT

@ -118,11 +118,25 @@ protected:
private: private:
QThreadInstance * d; QThreadInstance * d;
friend class QThreadInstance; friend class QThreadInstance;
friend class QCoreApplicationThread;
friend class QApplication;
friend class QEventLoop;
#if defined(Q_DISABLE_COPY) #if defined(Q_DISABLE_COPY)
QThread( const QThread & ); QThread( const QThread & );
QThread &operator=( const QThread & ); QThread &operator=( const QThread & );
#endif // Q_DISABLE_COPY #endif // Q_DISABLE_COPY
public:
static QThread* currentThreadObject();
};
class Q_EXPORT QEventLoopThread : public QThread
{
public:
QEventLoopThread();
~QEventLoopThread();
virtual void run();
}; };
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT

@ -52,11 +52,6 @@ typedef pthread_mutex_t Q_MUTEX_T;
#include <sched.h> #include <sched.h>
static QThreadInstance main_instance = {
0, { 0, &main_instance }, 0, 0, 1, 0, PTHREAD_COND_INITIALIZER, 0
};
static QMutexPool *qt_thread_mutexpool = 0; static QMutexPool *qt_thread_mutexpool = 0;
@ -82,10 +77,20 @@ static void create_storage_key()
** QThreadInstance ** QThreadInstance
*************************************************************************/ *************************************************************************/
void QThreadInstance::setCurrentThread(QThread *thread)
{
pthread_once(&storage_key_once, create_storage_key);
pthread_setspecific(storage_key, thread);
}
QThreadInstance *QThreadInstance::current() QThreadInstance *QThreadInstance::current()
{ {
QThreadInstance *ret = NULL;
pthread_once( &storage_key_once, create_storage_key ); pthread_once( &storage_key_once, create_storage_key );
QThreadInstance *ret = (QThreadInstance *) pthread_getspecific( storage_key ); QThread *thread = (QThread *) pthread_getspecific( storage_key );
if (thread) {
ret = thread->d;
}
return ret; return ret;
} }
@ -101,6 +106,8 @@ void QThreadInstance::init(unsigned int stackSize)
pthread_cond_init(&thread_done, NULL); pthread_cond_init(&thread_done, NULL);
thread_id = 0; thread_id = 0;
eventLoop = 0;
// threads have not been initialized yet, do it now // threads have not been initialized yet, do it now
if (! qt_thread_mutexpool) QThread::initialize(); if (! qt_thread_mutexpool) QThread::initialize();
} }
@ -114,8 +121,8 @@ void *QThreadInstance::start( void *_arg )
{ {
void **arg = (void **) _arg; void **arg = (void **) _arg;
pthread_once( &storage_key_once, create_storage_key ); setCurrentThread( (QThread *) arg[0] );
pthread_setspecific( storage_key, arg[1] );
pthread_cleanup_push( QThreadInstance::finish, arg[1] ); pthread_cleanup_push( QThreadInstance::finish, arg[1] );
pthread_testcancel(); pthread_testcancel();
@ -192,9 +199,6 @@ void QThread::initialize()
qt_global_mutexpool = new QMutexPool( TRUE, 73 ); qt_global_mutexpool = new QMutexPool( TRUE, 73 );
if ( ! qt_thread_mutexpool ) if ( ! qt_thread_mutexpool )
qt_thread_mutexpool = new QMutexPool( FALSE, 127 ); qt_thread_mutexpool = new QMutexPool( FALSE, 127 );
pthread_once( &storage_key_once, create_storage_key );
pthread_setspecific( storage_key, &main_instance );
} }
/*! \internal /*! \internal
@ -206,11 +210,6 @@ void QThread::cleanup()
delete qt_thread_mutexpool; delete qt_thread_mutexpool;
qt_global_mutexpool = 0; qt_global_mutexpool = 0;
qt_thread_mutexpool = 0; qt_thread_mutexpool = 0;
QThreadInstance::finish(&main_instance);
pthread_once( &storage_key_once, create_storage_key );
pthread_setspecific( storage_key, 0 );
} }
/*! /*!
@ -470,5 +469,20 @@ bool QThread::wait( unsigned long time )
return (ret == 0); return (ret == 0);
} }
/*!
Returns a pointer to the currently executing QThread. If the
current thread was not started using the QThread API, this
function returns zero.
Note that QApplication creates a QThread object to represent the
main thread; calling this function from main() after creating
QApplication will return a valid pointer.
*/
QThread *QThread::currentThreadObject()
{
pthread_once(&storage_key_once, create_storage_key);
return reinterpret_cast<QThread *>(pthread_getspecific(storage_key));
}
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT

@ -56,6 +56,9 @@
#include "qstyle.h" #include "qstyle.h"
#include "qmetaobject.h" #include "qmetaobject.h"
#include "qguardedptr.h" #include "qguardedptr.h"
#if defined(QT_THREAD_SUPPORT)
#include "qthread.h"
#endif
#if defined(QT_ACCESSIBILITY_SUPPORT) #if defined(QT_ACCESSIBILITY_SUPPORT)
#include "qaccessible.h" #include "qaccessible.h"
#endif #endif
@ -887,6 +890,12 @@ QWidget::QWidget( QWidget *parent, const char *name, WFlags f, NFlags n )
} }
#endif #endif
#if defined(QT_THREAD_SUPPORT) && defined(QT_CHECK_STATE)
if (QThread::currentThreadObject() != QApplication::guiThread()) {
qFatal( "QWidget: Cannot create a QWidget outside of the main GUI thread" );
}
#endif
fstrut_dirty = 1; fstrut_dirty = 1;
isWidget = TRUE; // is a widget isWidget = TRUE; // is a widget

@ -3193,6 +3193,7 @@ void generateClass() // generate C++ source code for a class
offset++; offset++;
} }
} }
fprintf( out, " o[%d].isLastObject = true;\n", f->args->count() + 0 );
fprintf( out, " activate_signal( clist, o );\n" ); fprintf( out, " activate_signal( clist, o );\n" );
// get return values from inOut parameters // get return values from inOut parameters

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,58 +1,166 @@
#define CHAR_VAL 257
#define INT_VAL 258 /* A Bison parser, made by GNU Bison 2.4.1. */
#define DOUBLE_VAL 259
#define STRING 260 /* Skeleton interface for Bison's Yacc-like parsers in C
#define IDENTIFIER 261
#define FRIEND 262 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
#define TYPEDEF 263 Free Software Foundation, Inc.
#define AUTO 264
#define REGISTER 265 This program is free software: you can redistribute it and/or modify
#define STATIC 266 it under the terms of the GNU General Public License as published by
#define EXTERN 267 the Free Software Foundation, either version 3 of the License, or
#define INLINE 268 (at your option) any later version.
#define VIRTUAL 269
#define CONST 270 This program is distributed in the hope that it will be useful,
#define VOLATILE 271 but WITHOUT ANY WARRANTY; without even the implied warranty of
#define CHAR 272 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#define SHORT 273 GNU General Public License for more details.
#define INT 274
#define LONG 275 You should have received a copy of the GNU General Public License
#define SIGNED 276 along with this program. If not, see <http://www.gnu.org/licenses/>. */
#define UNSIGNED 277
#define FLOAT 278 /* As a special exception, you may create a larger work that contains
#define DOUBLE 279 part or all of the Bison parser skeleton and distribute that work
#define VOID 280 under terms of your choice, so long as that work isn't itself a
#define ENUM 281 parser generator using the skeleton or a modified version thereof
#define CLASS 282 as a parser skeleton. Alternatively, if you modify or redistribute
#define STRUCT 283 the parser skeleton itself, you may (at your option) remove this
#define UNION 284 special exception, which will cause the skeleton and the resulting
#define ASM 285 Bison output files to be licensed under the GNU General Public
#define PRIVATE 286 License without this special exception.
#define PROTECTED 287
#define PUBLIC 288 This special exception was added by the Free Software Foundation in
#define OPERATOR 289 version 2.2 of Bison. */
#define DBL_COLON 290
#define TRIPLE_DOT 291
#define TEMPLATE 292 /* Tokens. */
#define NAMESPACE 293 #ifndef YYTOKENTYPE
#define USING 294 # define YYTOKENTYPE
#define MUTABLE 295 /* Put the tokens into the symbol table, so that GDB and other debuggers
#define THROW 296 know about them. */
#define SIGNALS 297 enum yytokentype {
#define SLOTS 298 CHAR_VAL = 258,
#define Q_OBJECT 299 INT_VAL = 259,
#define Q_PROPERTY 300 DOUBLE_VAL = 260,
#define Q_OVERRIDE 301 STRING = 261,
#define Q_CLASSINFO 302 IDENTIFIER = 262,
#define Q_ENUMS 303 FRIEND = 263,
#define Q_SETS 304 TYPEDEF = 264,
#define READ 305 AUTO = 265,
#define WRITE 306 REGISTER = 266,
#define STORED 307 STATIC = 267,
#define DESIGNABLE 308 EXTERN = 268,
#define SCRIPTABLE 309 INLINE = 269,
#define RESET 310 VIRTUAL = 270,
typedef union { CONST = 271,
VOLATILE = 272,
CHAR = 273,
SHORT = 274,
INT = 275,
LONG = 276,
SIGNED = 277,
UNSIGNED = 278,
FLOAT = 279,
DOUBLE = 280,
VOID = 281,
ENUM = 282,
CLASS = 283,
STRUCT = 284,
UNION = 285,
ASM = 286,
PRIVATE = 287,
PROTECTED = 288,
PUBLIC = 289,
OPERATOR = 290,
DBL_COLON = 291,
TRIPLE_DOT = 292,
TEMPLATE = 293,
NAMESPACE = 294,
USING = 295,
MUTABLE = 296,
THROW = 297,
SIGNALS = 298,
SLOTS = 299,
Q_OBJECT = 300,
Q_PROPERTY = 301,
Q_OVERRIDE = 302,
Q_CLASSINFO = 303,
Q_ENUMS = 304,
Q_SETS = 305,
READ = 306,
WRITE = 307,
STORED = 308,
DESIGNABLE = 309,
SCRIPTABLE = 310,
RESET = 311
};
#endif
/* Tokens. */
#define CHAR_VAL 258
#define INT_VAL 259
#define DOUBLE_VAL 260
#define STRING 261
#define IDENTIFIER 262
#define FRIEND 263
#define TYPEDEF 264
#define AUTO 265
#define REGISTER 266
#define STATIC 267
#define EXTERN 268
#define INLINE 269
#define VIRTUAL 270
#define CONST 271
#define VOLATILE 272
#define CHAR 273
#define SHORT 274
#define INT 275
#define LONG 276
#define SIGNED 277
#define UNSIGNED 278
#define FLOAT 279
#define DOUBLE 280
#define VOID 281
#define ENUM 282
#define CLASS 283
#define STRUCT 284
#define UNION 285
#define ASM 286
#define PRIVATE 287
#define PROTECTED 288
#define PUBLIC 289
#define OPERATOR 290
#define DBL_COLON 291
#define TRIPLE_DOT 292
#define TEMPLATE 293
#define NAMESPACE 294
#define USING 295
#define MUTABLE 296
#define THROW 297
#define SIGNALS 298
#define SLOTS 299
#define Q_OBJECT 300
#define Q_PROPERTY 301
#define Q_OVERRIDE 302
#define Q_CLASSINFO 303
#define Q_ENUMS 304
#define Q_SETS 305
#define READ 306
#define WRITE 307
#define STORED 308
#define DESIGNABLE 309
#define SCRIPTABLE 310
#define RESET 311
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 1676 of yacc.c */
#line 692 "moc.y"
char char_val; char char_val;
int int_val; int int_val;
double double_val; double double_val;
@ -61,5 +169,17 @@ typedef union {
Function *function; Function *function;
ArgList *arg_list; ArgList *arg_list;
Argument *arg; Argument *arg;
/* Line 1676 of yacc.c */
#line 177 "moc_yacc.h"
} YYSTYPE; } YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval; extern YYSTYPE yylval;

@ -102,11 +102,17 @@ static Q_UINT32 now()
return 0; return 0;
} }
#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 3)))
#define Q_MODERN_RES_API
#else
#endif
static QPtrList<QHostAddress> * ns = 0; static QPtrList<QHostAddress> * ns = 0;
static QStrList * domains = 0; static QStrList * domains = 0;
static bool ipv6support = FALSE; static bool ipv6support = FALSE;
#if defined(Q_MODERN_RES_API)
#else
static int qdns_res_init() static int qdns_res_init()
{ {
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
@ -124,6 +130,7 @@ static int qdns_res_init()
return 0; // not called at all on Windows. return 0; // not called at all on Windows.
#endif #endif
} }
#endif
class QDnsPrivate { class QDnsPrivate {
@ -2539,11 +2546,6 @@ void QDns::doSynchronousLookup()
} }
#endif #endif
#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 3)))
#define Q_MODERN_RES_API
#else
#endif
void QDns::doResInit() void QDns::doResInit()
{ {
if ( ns ) if ( ns )

@ -144,6 +144,12 @@ public:
QSqlQuery createQuery() const { return QSqlQuery( new QNullResult(this) ); } QSqlQuery createQuery() const { return QSqlQuery( new QNullResult(this) ); }
}; };
QSqlDriverCreatorBase::QSqlDriverCreatorBase() {
}
QSqlDriverCreatorBase::~QSqlDriverCreatorBase() {
}
typedef QDict<QSqlDriverCreatorBase> QDriverDict; typedef QDict<QSqlDriverCreatorBase> QDriverDict;
class QSqlDatabaseManager : public QObject class QSqlDatabaseManager : public QObject

@ -65,6 +65,9 @@ class QSqlDatabasePrivate;
class QM_EXPORT_SQL QSqlDriverCreatorBase class QM_EXPORT_SQL QSqlDriverCreatorBase
{ {
public:
QSqlDriverCreatorBase();
virtual ~QSqlDriverCreatorBase();
public: public:
virtual QSqlDriver* createObject() = 0; virtual QSqlDriver* createObject() = 0;
}; };

@ -347,6 +347,11 @@ QStyleControlElementData populateControlElementDataFromWidget(const QWidget* wid
const QButton *button = dynamic_cast<const QButton*>(widget); const QButton *button = dynamic_cast<const QButton*>(widget);
if (button) { if (button) {
ceData.text = button->text(); ceData.text = button->text();
const QPixmap* paletteBgPixmap = 0;
paletteBgPixmap = button->paletteBackgroundPixmap();
if (paletteBgPixmap) {
ceData.paletteBgPixmap = *paletteBgPixmap;
}
} }
} }
if (ceData.widgetObjectTypes.contains("QTabBar")) { if (ceData.widgetObjectTypes.contains("QTabBar")) {
@ -3215,6 +3220,13 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleControlElementData &ceData
ret = 0; ret = 0;
break; break;
case SH_PopupMenu_SubMenuArrowColorActiveEnabled:
case SH_PopupMenu_SubMenuArrowColorActiveDisabled:
case SH_PopupMenu_SubMenuArrowColorInactiveEnabled:
case SH_PopupMenu_SubMenuArrowColorInactiveDisabled:
ret = -1;
break;
default: default:
ret = 0; ret = 0;
break; break;

@ -74,6 +74,9 @@ private:
QMutex( const QMutex & ); QMutex( const QMutex & );
QMutex &operator=( const QMutex & ); QMutex &operator=( const QMutex & );
#endif #endif
public:
int level();
}; };
class Q_EXPORT QMutexLocker class Q_EXPORT QMutexLocker

@ -67,6 +67,7 @@ public:
virtual bool locked() = 0; virtual bool locked() = 0;
virtual bool trylock() = 0; virtual bool trylock() = 0;
virtual int type() const = 0; virtual int type() const = 0;
virtual int level() = 0;
}; };

@ -74,7 +74,6 @@ typedef pthread_mutex_t Q_MUTEX_T;
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
// Private class declarations // Private class declarations
class QRealMutexPrivate : public QMutexPrivate { class QRealMutexPrivate : public QMutexPrivate {
@ -86,6 +85,7 @@ public:
bool locked(); bool locked();
bool trylock(); bool trylock();
int type() const; int type() const;
int level();
bool recursive; bool recursive;
}; };
@ -102,6 +102,7 @@ public:
bool locked(); bool locked();
bool trylock(); bool trylock();
int type() const; int type() const;
int level();
int count; int count;
unsigned long owner; unsigned long owner;
@ -197,6 +198,11 @@ int QRealMutexPrivate::type() const
return recursive ? Q_MUTEX_RECURSIVE : Q_MUTEX_NORMAL; return recursive ? Q_MUTEX_RECURSIVE : Q_MUTEX_NORMAL;
} }
int QRealMutexPrivate::level()
{
return locked();
}
#ifndef Q_RECURSIVE_MUTEX_TYPE #ifndef Q_RECURSIVE_MUTEX_TYPE
QRecursiveMutexPrivate::QRecursiveMutexPrivate() QRecursiveMutexPrivate::QRecursiveMutexPrivate()
@ -330,6 +336,11 @@ int QRecursiveMutexPrivate::type() const
return Q_MUTEX_RECURSIVE; return Q_MUTEX_RECURSIVE;
} }
int QRecursiveMutexPrivate::level()
{
return count;
}
#endif // !Q_RECURSIVE_MUTEX_TYPE #endif // !Q_RECURSIVE_MUTEX_TYPE
@ -511,6 +522,22 @@ bool QMutex::tryLock()
return d->trylock(); return d->trylock();
} }
/*!
Returns the current lock level of the mutex.
0 means the mutex is unlocked
This method should only be called when the mutex has already been locked
by lock(), otherwise the lock level could change before the next line
of code is executed.
WARNING: Non-recursive mutexes will never exceed a lock level of 1!
\sa lock(), unlock(), locked()
*/
int QMutex::level()
{
return d->level();
}
/*! /*!
\class QMutexLocker qmutex.h \class QMutexLocker qmutex.h
\brief The QMutexLocker class simplifies locking and unlocking QMutexes. \brief The QMutexLocker class simplifies locking and unlocking QMutexes.

@ -62,8 +62,12 @@
#include <pthread.h> #include <pthread.h>
#endif #endif
class QThread;
class QEventLoop;
class QThreadInstance { class QThreadInstance {
public: public:
static void setCurrentThread(QThread *thread);
static QThreadInstance *current(); static QThreadInstance *current();
void init(unsigned int stackSize); void init(unsigned int stackSize);
@ -95,6 +99,8 @@ public:
static unsigned int __stdcall start( void * ); static unsigned int __stdcall start( void * );
static void finish( QThreadInstance * ); static void finish( QThreadInstance * );
#endif // Q_OS_WIN32 #endif // Q_OS_WIN32
QEventLoop* eventLoop;
}; };
#endif // QT_THREAD_SUPPORT #endif // QT_THREAD_SUPPORT

@ -39,6 +39,9 @@
**********************************************************************/ **********************************************************************/
#include "qucom_p.h" #include "qucom_p.h"
#include "qucomextra_p.h"
#include "qvariant.h"
// Standard types // Standard types
@ -545,3 +548,24 @@ void QUType_QString::clear( QUObject *o )
delete (QString*)o->payload.ptr; delete (QString*)o->payload.ptr;
o->payload.ptr = 0; o->payload.ptr = 0;
} }
QUObject* QUObject::deepCopy(QUObject* newLocation) {
QUObject* ret;
if (newLocation) {
ret = new(newLocation) QUObject(*this);
}
else {
ret = new QUObject(*this);
}
// Any type that has a clear() method must be copied here!
if (*(type->uuid()) == TID_QUType_charstar) {
static_QUType_charstar.set( ret, (const char *)static_QUType_charstar.get(this), true );
}
if (*(type->uuid()) == TID_QUType_QString) {
static_QUType_QString.set( ret, (QString)static_QUType_QString.get(this) );
}
if (*(type->uuid()) == TID_QUType_QVariant) {
static_QUType_QVariant.set( ret, (QVariant)static_QUType_QVariant.get(this) );
}
return ret;
}

@ -127,7 +127,7 @@ extern Q_EXPORT QUType_Null static_QUType_Null;
struct Q_EXPORT QUObject struct Q_EXPORT QUObject
{ {
public: // scary MSVC bug makes this necessary public: // scary MSVC bug makes this necessary
QUObject() : type( &static_QUType_Null ) {} QUObject() : type( &static_QUType_Null ), isLastObject(false) {}
~QUObject() { type->clear( this ); } ~QUObject() { type->clear( this ); }
QUType *type; QUType *type;
@ -184,6 +184,8 @@ public: // scary MSVC bug makes this necessary
} payload; } payload;
QUObject* deepCopy(QUObject*);
bool isLastObject;
}; };

@ -265,6 +265,7 @@ class QListViewToolTip : public QToolTip
{ {
public: public:
QListViewToolTip( QWidget *parent, QListView *lv ); QListViewToolTip( QWidget *parent, QListView *lv );
virtual ~QListViewToolTip();
void maybeTip( const QPoint &pos ); void maybeTip( const QPoint &pos );
@ -278,6 +279,10 @@ QListViewToolTip::QListViewToolTip( QWidget *parent, QListView *lv )
{ {
} }
QListViewToolTip::~QListViewToolTip()
{
}
void QListViewToolTip::maybeTip( const QPoint &pos ) void QListViewToolTip::maybeTip( const QPoint &pos )
{ {
if ( !parentWidget() || !view || !view->showToolTips() ) if ( !parentWidget() || !view || !view->showToolTips() )

@ -1391,6 +1391,7 @@ void QPopupMenu::show()
performDelayedChanges(); performDelayedChanges();
updateSize(TRUE); updateSize(TRUE);
QWidget::show(); QWidget::show();
updateSize();
popupActive = -1; popupActive = -1;
if(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this)) if(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this))
d->mouseMoveBuffer = QRegion(); d->mouseMoveBuffer = QRegion();

@ -824,6 +824,10 @@ QToolTip::QToolTip( QWidget * widget, QToolTipGroup * group )
QString::null, g, QString::null, this, FALSE ); QString::null, g, QString::null, this, FALSE );
} }
QToolTip::~QToolTip()
{
}
/*! /*!
Adds a tool tip to \a widget. \a text is the text to be shown in Adds a tool tip to \a widget. \a text is the text to be shown in

@ -92,6 +92,7 @@ class Q_EXPORT QToolTip: public Qt
{ {
public: public:
QToolTip( QWidget *, QToolTipGroup * = 0 ); QToolTip( QWidget *, QToolTipGroup * = 0 );
virtual ~QToolTip();
//### add virtual d'tor for 4.0 //### add virtual d'tor for 4.0
static void add( QWidget *, const QString &); static void add( QWidget *, const QString &);

@ -0,0 +1,173 @@
/****************************************************************
**
** Qt threading tutorial
** (c) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net>
**
** This tutorial is released into the Public Domain and
** can therefore be modified and/or used for any purpose
**
****************************************************************/
#include "main.h"
#include <unistd.h>
#include <qtimer.h>
#include <qeventloop.h>
void WorkerObject::run()
{
qDebug( "[%s] thread: %p event loop: %p", threadFriendlyName.ascii(), QThread::currentThreadObject(), QApplication::eventLoop() );
QEventLoop* eventLoop = QApplication::eventLoop();
if (!eventLoop) return;
QTimer *t = new QTimer(this);
connect( t, SIGNAL(timeout()), SLOT(timerHandler()) );
t->start( 1000, FALSE );
for( int count = 0; count < 5; count++ ) {
sleep( 1 );
qDebug( "[%s] Ping!", threadFriendlyName.ascii() );
displayMessage("Hi", "There!");
eventLoop->processEvents(QEventLoop::AllEvents);
}
eventLoop->exit(0);
}
void WorkerObject::timerHandler()
{
qDebug( "[%s] Timer fired!", threadFriendlyName.ascii() );
}
void MainObject::emitMessage(QString str1, QString str2)
{
qDebug( "%s", ("[MainObject] emitMessage: " + str1 + " " + str2).ascii() );
}
void MainObject::buttonClicked()
{
qDebug( "[MainObject] Button clicked!" );
QEventLoop* eventLoop = QApplication::eventLoop();
if (!eventLoop) return;
eventLoop->exit(0);
}
#define SET_UP_WORKER(x, y, z) \
WorkerObject x; \
x.threadFriendlyName = y; \
x.moveToThread(&z); \
QObject::connect(&x, SIGNAL(displayMessage(QString,QString)), &mainobject, SLOT(emitMessage(QString,QString))); \
QTimer::singleShot(0, &x, SLOT(run()));
int main( int argc, char **argv )
{
QApplication a( argc, argv );
qDebug( "[MainObject] thread: %p event loop: %p", QThread::currentThreadObject(), QApplication::eventLoop() );
QPushButton hello( "Exit", 0 );
hello.resize( 100, 30 );
MainObject mainobject;
QEventLoopThread workerthread0;
QEventLoopThread workerthread1;
QEventLoopThread workerthread2;
QEventLoopThread workerthread3;
QEventLoopThread workerthread4;
QEventLoopThread workerthread5;
QEventLoopThread workerthread6;
QEventLoopThread workerthread7;
QEventLoopThread workerthread8;
QEventLoopThread workerthread9;
QEventLoopThread workerthread10;
QEventLoopThread workerthread11;
QEventLoopThread workerthread12;
QEventLoopThread workerthread13;
QEventLoopThread workerthread14;
QEventLoopThread workerthread15;
QEventLoopThread workerthread16;
QEventLoopThread workerthread17;
QEventLoopThread workerthread18;
QEventLoopThread workerthread19;
SET_UP_WORKER(workerobject0, "WorkerObject0", workerthread0)
SET_UP_WORKER(workerobject1, "WorkerObject1", workerthread1)
SET_UP_WORKER(workerobject2, "WorkerObject2", workerthread2)
SET_UP_WORKER(workerobject3, "WorkerObject3", workerthread3)
SET_UP_WORKER(workerobject4, "WorkerObject4", workerthread4)
SET_UP_WORKER(workerobject5, "WorkerObject5", workerthread5)
SET_UP_WORKER(workerobject6, "WorkerObject6", workerthread6)
SET_UP_WORKER(workerobject7, "WorkerObject7", workerthread7)
SET_UP_WORKER(workerobject8, "WorkerObject8", workerthread8)
SET_UP_WORKER(workerobject9, "WorkerObject9", workerthread9)
SET_UP_WORKER(workerobject10, "WorkerObjec10", workerthread10)
SET_UP_WORKER(workerobject11, "WorkerObjec11", workerthread11)
SET_UP_WORKER(workerobject12, "WorkerObjec12", workerthread12)
SET_UP_WORKER(workerobject13, "WorkerObjec13", workerthread13)
SET_UP_WORKER(workerobject14, "WorkerObjec14", workerthread14)
SET_UP_WORKER(workerobject15, "WorkerObjec15", workerthread15)
SET_UP_WORKER(workerobject16, "WorkerObjec16", workerthread16)
SET_UP_WORKER(workerobject17, "WorkerObjec17", workerthread17)
SET_UP_WORKER(workerobject18, "WorkerObjec18", workerthread18)
SET_UP_WORKER(workerobject19, "WorkerObjec19", workerthread19)
workerthread0.start();
workerthread1.start();
workerthread2.start();
workerthread3.start();
workerthread4.start();
workerthread5.start();
workerthread6.start();
workerthread7.start();
workerthread8.start();
workerthread9.start();
workerthread10.start();
workerthread11.start();
workerthread12.start();
workerthread13.start();
workerthread14.start();
workerthread15.start();
workerthread16.start();
workerthread17.start();
workerthread18.start();
workerthread19.start();
a.setMainWidget( &hello );
QObject::connect(&hello, SIGNAL(clicked()), &mainobject, SLOT(buttonClicked()));
hello.show();
a.exec();
hello.hide();
qDebug( "[MainObject] Waiting for thread completion..." );
workerthread0.wait();
workerthread1.wait();
workerthread2.wait();
workerthread3.wait();
workerthread4.wait();
workerthread5.wait();
workerthread6.wait();
workerthread7.wait();
workerthread8.wait();
workerthread9.wait();
workerthread10.wait();
workerthread11.wait();
workerthread12.wait();
workerthread13.wait();
workerthread14.wait();
workerthread15.wait();
workerthread16.wait();
workerthread17.wait();
workerthread18.wait();
workerthread19.wait();
qDebug( "[MainObject] Finished!" );
}

@ -0,0 +1,45 @@
/****************************************************************
**
** Qt threading tutorial
** (c) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net>
**
** This tutorial is released into the Public Domain and
** can therefore be modified and/or used for any purpose
**
****************************************************************/
#ifndef _MAIN_H_
#define _MAIN_H_
#include <qapplication.h>
#include <qobject.h>
#include <qpushbutton.h>
#include <qthread.h>
class MainObject;
class WorkerObject : public QObject
{
Q_OBJECT
public slots:
void run();
void timerHandler();
signals:
void displayMessage(QString, QString);
public:
QString threadFriendlyName;
};
class MainObject : public QObject
{
Q_OBJECT
public slots:
void emitMessage(QString, QString);
void buttonClicked();
};
#endif // _MAIN_H_

@ -0,0 +1,5 @@
TEMPLATE = app
CONFIG += qt warn_on release
HEADERS = main.h
SOURCES = main.cpp
TARGET = t15

@ -1,2 +1,2 @@
TEMPLATE = subdirs TEMPLATE = subdirs
SUBDIRS = t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 SUBDIRS = t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15

Loading…
Cancel
Save