@ -39,7 +39,6 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "qeventloop_glib_p.h" // includes qplatformdefs.h
# include "ntqeventloop.h"
# include "ntqapplication.h"
@ -49,12 +48,15 @@
# if defined(QT_THREAD_SUPPORT)
# include "ntqmutex.h"
# include "ntqthread.h"
# endif // QT_THREAD_SUPPORT
# include <errno.h>
# include <glib.h>
// #define DEBUG_QT_GLIBMAINLOOP 1
// TQt-GSource Structure and Callbacks
typedef struct {
@ -62,11 +64,9 @@ typedef struct {
TQEventLoop * qeventLoop ;
} TQtGSource ;
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 )
{
TQtGSource * qtGSource ;
qtGSource = ( TQtGSource * ) source ;
return qtGSource - > qeventLoop - > gsourcePrepare ( source , timeout ) ;
TQtGSource * qtGSource = ( TQtGSource * ) source ;
TQEventLoop * candidateEventLoop = qtGSource - > qeventLoop ;
TQEventLoop * activeThreadEventLoop = TQApplication : : eventLoop ( ) ;
if ( candidateEventLoop = = activeThreadEventLoop ) {
return candidateEventLoop - > gsourcePrepare ( source , timeout ) ;
}
else {
// Prepare failed
return FALSE ;
}
}
static gboolean qt_gsource_check ( GSource * source )
{
TQtGSource * qtGSource = ( TQtGSource * ) source ;
return qtGSource - > qeventLoop - > gsourceCheck ( source ) ;
TQEventLoop * candidateEventLoop = qtGSource - > qeventLoop ;
TQEventLoop * activeThreadEventLoop = TQApplication : : 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 ) ;
TQtGSource * qtGSource = ( TQtGSource * ) source ;
return qtGSource - > qeventLoop - > gsourceDispatch ( source ) ;
TQEventLoop * candidateEventLoop = qtGSource - > qeventLoop ;
TQEventLoop * activeThreadEventLoop = TQApplication : : eventLoop ( ) ;
if ( candidateEventLoop = = activeThreadEventLoop ) {
return candidateEventLoop - > gsourceDispatch ( source ) ;
}
else {
// Dispatch failed
return FALSE ;
}
}
@ -134,38 +160,43 @@ static TQVFuncList *qt_postselect_handler = 0;
void qt_install_preselect_handler ( VFPTR handler )
{
if ( ! qt_preselect_handler )
if ( ! qt_preselect_handler ) {
qt_preselect_handler = new TQVFuncList ;
}
qt_preselect_handler - > append ( handler ) ;
}
void qt_remove_preselect_handler ( VFPTR handler )
{
if ( qt_preselect_handler ) {
TQVFuncList : : 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 TQVFuncList ;
}
qt_postselect_handler - > prepend ( handler ) ;
}
void qt_remove_postselect_handler ( VFPTR handler )
{
if ( qt_postselect_handler ) {
TQVFuncList : : 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 TQEventLoop : : init ( )
{
// initialize ProcessEventFlags (all events & wait for more)
d - > pev_flags = AllEvents | WaitForMore ;
// initialize the common parts of the event loop
@ -177,44 +208,38 @@ void TQEventLoop::init()
// intitialize the X11 parts of the event loop
d - > xfd = - 1 ;
if ( tqt_is_gui_used )
if ( tqt_is_gui_used & & TQApplication : : isGuiThread ( ) ) {
d - > xfd = XConnectionNumber ( TQPaintDevice : : x11AppDisplay ( ) ) ;
}
// new GSource
TQtGSource * qtGSource = ( TQtGSource * ) g_source_new ( & qt_gsource_funcs ,
sizeof ( TQtGSource ) ) ;
// new main context for thread
d - > ctx = g_main_context_new ( ) ;
g_main_context_push_thread_default ( d - > ctx ) ;
// new GSource
TQtGSource * qtGSource = ( TQtGSource * ) g_source_new ( & qt_gsource_funcs , sizeof ( TQtGSource ) ) ;
g_source_set_can_recurse ( ( GSource * ) qtGSource , TRUE ) ;
qtGSource - > qeventLoop = this ;
// 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 ( tqt_is_gui_used ) {
if ( tqt_is_gui_used & & TQApplication : : 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 ) ;
@ -234,6 +259,9 @@ void TQEventLoop::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
}
@ -243,13 +271,14 @@ bool TQEventLoop::processEvents( ProcessEventsFlags flags )
# ifdef DEBUG_QT_GLIBMAINLOOP
printf ( " inside processEvents(1) looplevel=%d \n " , d - > looplevel ) ;
# 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 ;
@ -276,6 +305,7 @@ bool TQEventLoop::processX11Events()
if ( tqt_is_gui_used ) {
TQApplication : : sendPostedEvents ( ) ;
if ( TQApplication : : isGuiThread ( ) ) {
// Two loops so that posted events accumulate
while ( XPending ( TQPaintDevice : : x11AppDisplay ( ) ) ) {
// also flushes output buffer
@ -322,11 +352,13 @@ bool TQEventLoop::processX11Events()
}
nevents + + ;
if ( tqApp - > x11ProcessEvent ( & event ) = = 1 )
if ( tqApp - > x11ProcessEvent ( & event ) = = 1 ) {
return TRUE ;
}
}
}
}
}
if ( d - > shortcut ) {
return FALSE ;
@ -336,8 +368,7 @@ bool TQEventLoop::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 ;
@ -369,15 +400,15 @@ bool TQEventLoop::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 ) ) {
TQPtrListIterator < TQSockNotGPollFD > it ( d - > sn_list ) ;
TQSockNotGPollFD * sn ;
@ -385,7 +416,8 @@ bool TQEventLoop::gsourcePrepare(GSource *gs, int * timeout)
+ + it ;
sn - > gPollFD . events = sn - > events ; // restore poll events
}
} else {
}
else {
TQPtrListIterator < TQSockNotGPollFD > it ( d - > sn_list ) ;
TQSockNotGPollFD * sn ;
while ( ( sn = it . current ( ) ) ) {
@ -398,9 +430,9 @@ bool TQEventLoop::gsourcePrepare(GSource *gs, int * timeout)
printf ( " inside gsourcePrepare(2) canwait=%d \n " , canWait ) ;
# endif
if ( canWait )
if ( canWait ) {
emit aboutToBlock ( ) ;
}
if ( qt_preselect_handler ) {
TQVFuncList : : Iterator it , end = qt_preselect_handler - > end ( ) ;
@ -408,12 +440,6 @@ bool TQEventLoop::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
printf ( " inside gsourcePrepare(2.1) canwait=%d \n " , canWait ) ;
# endif
@ -421,11 +447,9 @@ bool TQEventLoop::gsourcePrepare(GSource *gs, int * timeout)
// do we have to dispatch events?
if ( hasPendingEvents ( ) ) {
* timeout = 0 ; // no time to stay in poll
# ifdef DEBUG_QT_GLIBMAINLOOP
printf ( " inside gsourcePrepare(3a) \n " ) ;
# endif
return FALSE ;
}
@ -435,8 +459,6 @@ bool TQEventLoop::gsourcePrepare(GSource *gs, int * timeout)
# ifdef DEBUG_QT_GLIBMAINLOOP
printf ( " inside gsourcePrepare(3b) timeout=%d \n " , * timeout ) ;
# endif
return FALSE ;
}
@ -447,7 +469,6 @@ bool TQEventLoop::gsourcePrepare(GSource *gs, int * timeout)
printf ( " inside gsourcePrepare(3c) timeout=%d \n " , * timeout ) ;
# endif
return FALSE ;
}
@ -459,14 +480,9 @@ bool TQEventLoop::gsourceCheck(GSource *gs) {
printf ( " inside gsourceCheck(1) \n " ) ;
# endif
// Socketnotifier events?
TQPtrList < TQSockNotGPollFD > * list = & d - > sn_list ;
//if ( list ) {
TQSockNotGPollFD * sn = list - > first ( ) ;
while ( sn ) {
if ( sn - > gPollFD . revents )
@ -496,10 +512,9 @@ bool TQEventLoop::gsourceCheck(GSource *gs) {
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
printf ( " inside gsourceCheck(2) qtwaittimer! \n " ) ;
@ -509,7 +524,6 @@ bool TQEventLoop::gsourceCheck(GSource *gs) {
}
// nothing to dispatch
# ifdef DEBUG_QT_GLIBMAINLOOP
printf ( " inside gsourceCheck(2) nothing to dispatch! \n " ) ;
# endif
@ -526,11 +540,10 @@ bool TQEventLoop::gsourceDispatch(GSource *gs) {
TQMutexLocker locker ( TQApplication : : tqt_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
@ -562,8 +575,6 @@ bool TQEventLoop::gsourceDispatch(GSource *gs) {
// if select says data is ready on any socket, then set the socket notifier
// to pending
// if ( &d->sn_list ) {
TQPtrList < TQSockNotGPollFD > * list = & d - > sn_list ;
TQSockNotGPollFD * sn = list - > first ( ) ;
while ( sn ) {
@ -582,30 +593,28 @@ bool TQEventLoop::gsourceDispatch(GSource *gs) {
nevents + = activateTimers ( ) ;
}
// return true if we handled events, false otherwise
//return (nevents > 0);
// now process x11 events!
# ifdef DEBUG_QT_GLIBMAINLOOP
printf ( " inside gsourceDispatch(2) hasPendingEvents=%d \n " , hasPendingEvents ( ) ) ;
# 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 TQEventLoop::gsourceDispatch(GSource *gs) {
bool TQEventLoop : : hasPendingEvents ( ) const
{
extern uint qGlobalPostedEventsCount ( ) ; // from qapplication.cpp
return ( qGlobalPostedEventsCount ( ) | | ( tqt_is_gui_used ? XPending ( TQPaintDevice : : x11AppDisplay ( ) ) : 0 ) ) ;
return ( qGlobalPostedEventsCount ( ) | | ( ( tqt_is_gui_used & & TQApplication : : isGuiThread ( ) ) ? XPending ( TQPaintDevice : : x11AppDisplay ( ) ) : 0 ) ) ;
}
void TQEventLoop : : appStartingUp ( )
{
if ( tqt_is_gui_used )
if ( tqt_is_gui_used ) {
d - > xfd = XConnectionNumber ( TQPaintDevice : : x11AppDisplay ( ) ) ;
if ( ( d - > x_gPollFD . fd = = - 1 ) & & TQApplication : : 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 TQEventLoop : : appClosingDown ( )