|
|
|
@ -48,6 +48,7 @@
|
|
|
|
|
|
|
|
|
|
#if defined(QT_THREAD_SUPPORT)
|
|
|
|
|
# include "qmutex.h"
|
|
|
|
|
# include "qthread.h"
|
|
|
|
|
#endif // QT_THREAD_SUPPORT
|
|
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
@ -79,7 +80,7 @@ static GSourceFuncs qt_gsource_funcs = {
|
|
|
|
|
// forward main loop callbacks to QEventLoop methods!
|
|
|
|
|
|
|
|
|
|
static gboolean qt_gsource_prepare ( GSource *source,
|
|
|
|
|
gint *timeout )
|
|
|
|
|
gint *timeout )
|
|
|
|
|
{
|
|
|
|
|
QtGSource * qtGSource;
|
|
|
|
|
qtGSource = (QtGSource*) source;
|
|
|
|
@ -97,9 +98,18 @@ static gboolean qt_gsource_dispatch ( GSource *source,
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(callback);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -171,7 +181,7 @@ void QEventLoop::init()
|
|
|
|
|
{
|
|
|
|
|
// initialize ProcessEventFlags (all events & wait for more)
|
|
|
|
|
d->pev_flags = AllEvents | WaitForMore;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// initialize the common parts of the event loop
|
|
|
|
|
if (pipe( d->thread_pipe ) < 0) {
|
|
|
|
|
// Error!
|
|
|
|
@ -185,35 +195,33 @@ void QEventLoop::init()
|
|
|
|
|
d->xfd = XConnectionNumber( QPaintDevice::x11AppDisplay() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
// init main loop and attach gsource
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_QT_GLIBMAINLOOP
|
|
|
|
|
printf("inside init(1)\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
g_main_loop_new (NULL, 1);
|
|
|
|
|
|
|
|
|
|
g_source_attach( (GSource*)qtGSource, NULL );
|
|
|
|
|
|
|
|
|
|
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 && QApplication::isGuiThread() ) {
|
|
|
|
|
d->x_gPollFD.fd = d->xfd;
|
|
|
|
|
d->x_gPollFD.events = G_IO_IN | G_IO_HUP;
|
|
|
|
|
g_source_add_poll(d->gSource, &d->x_gPollFD);
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
@ -231,10 +239,13 @@ void QEventLoop::cleanup()
|
|
|
|
|
close( d->thread_pipe[0] );
|
|
|
|
|
close( d->thread_pipe[1] );
|
|
|
|
|
cleanupTimers();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cleanup the X11 parts of the event loop
|
|
|
|
|
d->xfd = -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// unref the main context
|
|
|
|
|
g_main_context_unref(d->ctx);
|
|
|
|
|
|
|
|
|
|
// todo: destroy gsource
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -251,7 +262,7 @@ bool QEventLoop::processEvents( ProcessEventsFlags 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;
|
|
|
|
|
|
|
|
|
@ -411,40 +422,30 @@ bool QEventLoop::gsourcePrepare(GSource *gs, int * timeout)
|
|
|
|
|
for ( it = qt_preselect_handler->begin(); it != end; ++it )
|
|
|
|
|
(**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
|
|
|
|
|
printf("inside gsourcePrepare(2.1) canwait=%d\n", canWait);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// do we have to dispatch events?
|
|
|
|
|
if (hasPendingEvents()) {
|
|
|
|
|
if (hasPendingEvents()) {
|
|
|
|
|
*timeout = 0; // no time to stay in poll
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_QT_GLIBMAINLOOP
|
|
|
|
|
printf("inside gsourcePrepare(3a)\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_QT_GLIBMAINLOOP
|
|
|
|
|
printf("inside gsourcePrepare(3a)\n");
|
|
|
|
|
#endif
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// stay in poll until something happens?
|
|
|
|
|
if (!tm) { // fixme
|
|
|
|
|
*timeout = -1; // wait forever
|
|
|
|
|
#ifdef DEBUG_QT_GLIBMAINLOOP
|
|
|
|
|
printf("inside gsourcePrepare(3b) timeout=%d \n", *timeout);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_QT_GLIBMAINLOOP
|
|
|
|
|
printf("inside gsourcePrepare(3b) timeout=%d \n", *timeout);
|
|
|
|
|
#endif
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// else timeout >=0
|
|
|
|
|
// else timeout >=0
|
|
|
|
|
*timeout = tm->tv_sec * 1000 + tm->tv_usec/1000;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_QT_GLIBMAINLOOP
|
|
|
|
@ -529,7 +530,7 @@ 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;
|
|
|
|
@ -598,13 +599,13 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {
|
|
|
|
|
qt_reset_color_avail();
|
|
|
|
|
|
|
|
|
|
#if defined(QT_THREAD_SUPPORT)
|
|
|
|
|
locker.mutex()->unlock();
|
|
|
|
|
if (locker.mutex()) locker.mutex()->unlock();
|
|
|
|
|
#endif
|
|
|
|
|
processX11Events();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
#if defined(QT_THREAD_SUPPORT)
|
|
|
|
|
locker.mutex()->unlock();
|
|
|
|
|
if (locker.mutex()) locker.mutex()->unlock();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|