Darrell Anderson 12 years ago
commit 35202ed0d8

3
configure vendored

@ -734,6 +734,9 @@ while [ "$#" -gt 0 ]; do
glibmainloop)
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
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
UNKNOWN_OPT=yes
fi

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

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

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

@ -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;

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

@ -430,7 +430,7 @@ static bool qt_x11EventFilter( XEvent* ev )
//XIM qt_xim = 0;
Q_EXPORT XIMStyle qt_xim_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
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
&& 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

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

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

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

@ -102,25 +102,6 @@ public:
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);
signals:
@ -145,6 +126,24 @@ private:
QEventLoopPrivate *d;
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

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

@ -40,6 +40,7 @@
#include "qeventloop.h"
#include "qapplication.h"
#include "qbitarray.h"
#include "qmutex.h"
#include <stdlib.h>
#include <sys/types.h>
@ -561,6 +562,8 @@ int QEventLoop::activateTimers()
n_act++;
QTimerEvent e( t->id );
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 )
begin = 0;
}

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

@ -146,6 +146,7 @@ bool QEventLoop::processEvents( ProcessEventsFlags flags )
if ( qt_is_gui_used ) {
QApplication::sendPostedEvents();
if (QApplication::isGuiThread()) {
// Two loops so that posted events accumulate
while ( XPending( QPaintDevice::x11AppDisplay() ) ) {
// also flushes output buffer
@ -197,6 +198,7 @@ bool QEventLoop::processEvents( ProcessEventsFlags flags )
}
}
}
}
if ( d->shortcut ) {
return FALSE;
@ -261,7 +263,7 @@ bool QEventLoop::processEvents( ProcessEventsFlags flags )
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
FD_SET( d->xfd, &d->sn_vec[0].select_fds );
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
// something for us to do
#if defined(QT_THREAD_SUPPORT)
locker.mutex()->unlock();
if ( locker.mutex() ) locker.mutex()->unlock();
else return false;
#endif
int nsel;
@ -296,7 +299,8 @@ bool QEventLoop::processEvents( ProcessEventsFlags flags )
// relock the GUI mutex before processing any pending events
#if defined(QT_THREAD_SUPPORT)
locker.mutex()->lock();
if ( locker.mutex() ) locker.mutex()->lock();
else return false;
#endif
// we are awake, broadcast it

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

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

@ -477,6 +477,7 @@ bool QInputContext::isComposing() const
*/
bool QInputContext::filterEvent( const QEvent *event )
{
Q_UNUSED(event);
return FALSE;
}
@ -679,6 +680,11 @@ void QInputContext::unsetFocus()
*/
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 state )
{
Q_UNUSED(x);
Q_UNUSED(button);
Q_UNUSED(state);
// Default behavior for simple ephemeral input contexts. Some
// complex input contexts should not be reset here.
if ( type == QEvent::MouseButtonPress ||

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

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

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

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

@ -50,22 +50,107 @@
#include "qptrvector.h"
#ifdef QT_THREAD_SUPPORT
#include <qmutex.h>
#include "qmutex.h"
#include <private/qmutexpool_p.h>
#include "qthread.h"
#endif
#include <ctype.h>
#include <stdlib.h>
#ifndef QT_NO_USERDATA
class QObjectPrivate : public QPtrVector<QObjectUserData>
#else
class QObjectPrivate {
#endif
{
public:
#ifndef QT_NO_USERDATA
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
class QSenderObjectList : public QObjectList, public QShared
@ -75,6 +160,41 @@ public:
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
@ -269,7 +389,21 @@ void *qt_find_obj_child( QObject *parent, const char *type, const char *name )
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
/*
@ -436,6 +570,11 @@ QObject::QObject( QObject *parent, const char *name )
insert_tree( this );
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;
}
/*! \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
@ -777,6 +946,40 @@ bool QObject::event( QEvent *e )
delete this;
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:
if ( e->type() >= QEvent::User ) {
customEvent( (QCustomEvent*) e );
@ -2337,6 +2540,7 @@ void QObject::activate_signal( int signal )
if ( !signalsBlocked() && signal >= 0 &&
( !connections || !connections->at( signal ) ) ) {
QUObject o[1];
o[0].isLastObject = true;
qt_spy_signal( this, signal, o );
return;
}
@ -2349,6 +2553,7 @@ void QObject::activate_signal( int signal )
if ( !clist )
return;
QUObject o[1];
o[0].isLastObject = true;
activate_signal( clist, o );
}
@ -2364,6 +2569,8 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
qt_spy_signal( this, connections->findRef( clist), o );
#endif
const QThread *currentThread = QThread::currentThreadObject();
QObject *object;
QSenderObjectList* sol;
QObject* oldSender = 0;
@ -2377,10 +2584,26 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
sol->ref();
sol->currentSender = this;
}
if ( c->memberType() == QSIGNAL_CODE )
if ( c->memberType() == QSIGNAL_CODE ) {
if (object->d->ownThread == currentThread) {
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 );
}
else {
if (object->d->ownThread && !object->d->ownThread->finished()) {
QApplication::postEvent(object, new QMetaCallEvent(c->member(), this, deepCopyQUObjectArray(o), QMetaCallEvent::MetaCallInvoke));
}
}
}
if ( sol ) {
sol->currentSender = oldSender;
if ( sol->deref() )
@ -2401,10 +2624,26 @@ void QObject::activate_signal( QConnectionList *clist, QUObject *o )
sol->ref();
sol->currentSender = this;
}
if ( c->memberType() == QSIGNAL_CODE )
if ( c->memberType() == QSIGNAL_CODE ) {
if (object->d->ownThread == currentThread) {
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 );
}
else {
if (object->d->ownThread && !object->d->ownThread->finished()) {
QApplication::postEvent(object, new QMetaCallEvent(c->member(), this, deepCopyQUObjectArray(o), QMetaCallEvent::MetaCallInvoke));
}
}
}
if (sol ) {
sol->currentSender = oldSender;
if ( sol->deref() )
@ -2442,6 +2681,7 @@ void QObject::FNAME( int signal, TYPE param ) \
if ( !signalsBlocked() && signal >= 0 && \
( !connections || !connections->at( signal ) ) ) { \
QUObject o[2]; \
o[1].isLastObject = true; \
static_QUType_##TYPE.set( o+1, param ); \
qt_spy_signal( this, signal, o ); \
return; \
@ -2453,6 +2693,7 @@ void QObject::FNAME( int signal, TYPE param ) \
if ( !clist ) \
return; \
QUObject o[2]; \
o[1].isLastObject = true; \
static_QUType_##TYPE.set( o+1, param ); \
activate_signal( clist, o ); \
}
@ -2466,6 +2707,7 @@ void QObject::FNAME( int signal, TYPE param ) \
if ( !clist ) \
return; \
QUObject o[2]; \
o[1].isLastObject = true; \
static_QUType_##TYPE.set( o+1, param ); \
activate_signal( clist, o ); \
}

@ -63,6 +63,10 @@ class QObjectUserData;
#endif
struct QUObject;
#ifdef QT_THREAD_SUPPORT
class QThread;
#endif
class Q_EXPORT QObject: public Qt
{
Q_OBJECT
@ -217,6 +221,18 @@ private: // Disabled copy constructor and operator=
QObject( const QObject & );
QObject &operator=( const QObject & );
#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( dpisY );
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)
/ (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)
/ (DisplayHeightMM(dpy,i)*10);
}

@ -379,7 +379,9 @@ void QProcessManager::sigchldHnd( int fd )
}
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)
qDebug( "QProcessManager::sigchldHnd()" );
#endif
@ -562,7 +564,9 @@ QT_SIGNAL_RETTYPE qt_C_sigchldHnd( QT_SIGNAL_ARGS )
return;
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
if (openType) {
unsigned short logClusters[16];
for (int i = 0; i < len; ++i)
logClusters[i] = i;
uint where[16];
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
if (openType) {
unsigned short logClusters[32];
for (int i = 0; i < len; ++i)
logClusters[i] = i;
uint where[32];
for (int i = 0; i < len; ++i) {

@ -290,6 +290,7 @@ class Q_EXPORT QStyleControlElementData {
QString caption;
QStyleControlElementGenericWidgetData topLevelWidgetData;
Q_UINT32 topLevelWidgetFlags;
QPixmap paletteBgPixmap;
};
class Q_EXPORT QStyleWidgetActionRequestData {
@ -1070,6 +1071,18 @@ public:
// bool - whether or not the upper two button drawing areas should be combined into one
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
SH_CustomBase = 0xf0000000
};

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

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

@ -52,11 +52,6 @@ typedef pthread_mutex_t Q_MUTEX_T;
#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;
@ -82,10 +77,20 @@ static void create_storage_key()
** QThreadInstance
*************************************************************************/
void QThreadInstance::setCurrentThread(QThread *thread)
{
pthread_once(&storage_key_once, create_storage_key);
pthread_setspecific(storage_key, thread);
}
QThreadInstance *QThreadInstance::current()
{
QThreadInstance *ret = NULL;
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;
}
@ -101,6 +106,8 @@ void QThreadInstance::init(unsigned int stackSize)
pthread_cond_init(&thread_done, NULL);
thread_id = 0;
eventLoop = 0;
// threads have not been initialized yet, do it now
if (! qt_thread_mutexpool) QThread::initialize();
}
@ -114,8 +121,8 @@ void *QThreadInstance::start( void *_arg )
{
void **arg = (void **) _arg;
pthread_once( &storage_key_once, create_storage_key );
pthread_setspecific( storage_key, arg[1] );
setCurrentThread( (QThread *) arg[0] );
pthread_cleanup_push( QThreadInstance::finish, arg[1] );
pthread_testcancel();
@ -192,9 +199,6 @@ void QThread::initialize()
qt_global_mutexpool = new QMutexPool( TRUE, 73 );
if ( ! qt_thread_mutexpool )
qt_thread_mutexpool = new QMutexPool( FALSE, 127 );
pthread_once( &storage_key_once, create_storage_key );
pthread_setspecific( storage_key, &main_instance );
}
/*! \internal
@ -206,11 +210,6 @@ void QThread::cleanup()
delete qt_thread_mutexpool;
qt_global_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);
}
/*!
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

@ -56,6 +56,9 @@
#include "qstyle.h"
#include "qmetaobject.h"
#include "qguardedptr.h"
#if defined(QT_THREAD_SUPPORT)
#include "qthread.h"
#endif
#if defined(QT_ACCESSIBILITY_SUPPORT)
#include "qaccessible.h"
#endif
@ -887,6 +890,12 @@ QWidget::QWidget( QWidget *parent, const char *name, WFlags f, NFlags n )
}
#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;
isWidget = TRUE; // is a widget

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

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

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

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

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

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

@ -67,6 +67,7 @@ public:
virtual bool locked() = 0;
virtual bool trylock() = 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 <string.h>
// Private class declarations
class QRealMutexPrivate : public QMutexPrivate {
@ -86,6 +85,7 @@ public:
bool locked();
bool trylock();
int type() const;
int level();
bool recursive;
};
@ -102,6 +102,7 @@ public:
bool locked();
bool trylock();
int type() const;
int level();
int count;
unsigned long owner;
@ -197,6 +198,11 @@ int QRealMutexPrivate::type() const
return recursive ? Q_MUTEX_RECURSIVE : Q_MUTEX_NORMAL;
}
int QRealMutexPrivate::level()
{
return locked();
}
#ifndef Q_RECURSIVE_MUTEX_TYPE
QRecursiveMutexPrivate::QRecursiveMutexPrivate()
@ -330,6 +336,11 @@ int QRecursiveMutexPrivate::type() const
return Q_MUTEX_RECURSIVE;
}
int QRecursiveMutexPrivate::level()
{
return count;
}
#endif // !Q_RECURSIVE_MUTEX_TYPE
@ -511,6 +522,22 @@ bool QMutex::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
\brief The QMutexLocker class simplifies locking and unlocking QMutexes.

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

@ -39,6 +39,9 @@
**********************************************************************/
#include "qucom_p.h"
#include "qucomextra_p.h"
#include "qvariant.h"
// Standard types
@ -545,3 +548,24 @@ void QUType_QString::clear( QUObject *o )
delete (QString*)o->payload.ptr;
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
{
public: // scary MSVC bug makes this necessary
QUObject() : type( &static_QUType_Null ) {}
QUObject() : type( &static_QUType_Null ), isLastObject(false) {}
~QUObject() { type->clear( this ); }
QUType *type;
@ -184,6 +184,8 @@ public: // scary MSVC bug makes this necessary
} payload;
QUObject* deepCopy(QUObject*);
bool isLastObject;
};

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

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

@ -824,6 +824,10 @@ QToolTip::QToolTip( QWidget * widget, QToolTipGroup * group )
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

@ -92,6 +92,7 @@ class Q_EXPORT QToolTip: public Qt
{
public:
QToolTip( QWidget *, QToolTipGroup * = 0 );
virtual ~QToolTip();
//### add virtual d'tor for 4.0
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
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