diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2016-11-13 06:13:22 +0100 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2017-07-13 12:10:25 +0200 |
commit | 3e20ce802ee2ab49c4f2a98880f6e999657686bb (patch) | |
tree | 36371101121e00c047e7b99755c55bb3336ea620 /vcl/unx/gtk3 | |
parent | 1fedc1c38a141bf071c707fda6a3ae1a5bf8fd41 (diff) |
GTK+ simplifiy system timer implementation
Instead of implementing an own GSource, this implements the glib
based system timer using the g_timeout_source_new() function.
It removes the vector of GtkSalTimer and changes the remaining
timer to be single-shot, just like the Windows and KDE platforms.
The ownership handling is a little bit strange and should generally
be changed to use std::shared_ptr as the result of CreateSalTimer
for all backends.
Change-Id: Iea40a6284bdc5c121235af5a6079a92a679391ca
Diffstat (limited to 'vcl/unx/gtk3')
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkdata.cxx | 148 |
1 files changed, 29 insertions, 119 deletions
diff --git a/vcl/unx/gtk3/gtk3gtkdata.cxx b/vcl/unx/gtk3/gtk3gtkdata.cxx index 3e074489bfd5..57cc1084460f 100644 --- a/vcl/unx/gtk3/gtk3gtkdata.cxx +++ b/vcl/unx/gtk3/gtk3gtkdata.cxx @@ -614,161 +614,71 @@ bool GtkData::ErrorTrapPop( bool bIgnoreError ) return gdk_error_trap_pop () != 0; } -extern "C" { - - struct SalGtkTimeoutSource { - GSource aParent; - GTimeVal aFireTime; - GtkSalTimer *pInstance; - }; - - static void sal_gtk_timeout_defer( SalGtkTimeoutSource *pTSource ) - { - g_get_current_time( &pTSource->aFireTime ); - g_time_val_add( &pTSource->aFireTime, pTSource->pInstance->m_nTimeoutMS * 1000 ); - } - - static gboolean sal_gtk_timeout_expired( SalGtkTimeoutSource *pTSource, - gint *nTimeoutMS, GTimeVal *pTimeNow ) - { - glong nDeltaSec = pTSource->aFireTime.tv_sec - pTimeNow->tv_sec; - glong nDeltaUSec = pTSource->aFireTime.tv_usec - pTimeNow->tv_usec; - if( nDeltaSec < 0 || ( nDeltaSec == 0 && nDeltaUSec < 0) ) - { - *nTimeoutMS = 0; - return TRUE; - } - if( nDeltaUSec < 0 ) - { - nDeltaUSec += 1000000; - nDeltaSec -= 1; - } - // if the clock changes backwards we need to cope ... - if( (unsigned long) nDeltaSec > 1 + ( pTSource->pInstance->m_nTimeoutMS / 1000 ) ) - { - sal_gtk_timeout_defer( pTSource ); - return TRUE; - } - - *nTimeoutMS = MIN( G_MAXINT, ( nDeltaSec * 1000 + (nDeltaUSec + 999) / 1000 ) ); - - return *nTimeoutMS == 0; - } - - static gboolean sal_gtk_timeout_prepare( GSource *pSource, gint *nTimeoutMS ) - { - SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource); - - GTimeVal aTimeNow; - g_get_current_time( &aTimeNow ); - - return sal_gtk_timeout_expired( pTSource, nTimeoutMS, &aTimeNow ); - } - - static gboolean sal_gtk_timeout_check( GSource *pSource ) - { - SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource); - - GTimeVal aTimeNow; - g_get_current_time( &aTimeNow ); - - return ( pTSource->aFireTime.tv_sec < aTimeNow.tv_sec || - ( pTSource->aFireTime.tv_sec == aTimeNow.tv_sec && - pTSource->aFireTime.tv_usec < aTimeNow.tv_usec ) ); - } +#if !GLIB_CHECK_VERSION(2,32,0) +#define G_SOURCE_REMOVE FALSE +#endif - static gboolean sal_gtk_timeout_dispatch( GSource *pSource, GSourceFunc, gpointer ) +extern "C" { + static gboolean sal_gtk_timeout_function( gpointer ) { - SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource); - - if( !pTSource->pInstance ) - return FALSE; - GtkData *pSalData = static_cast< GtkData* >( GetSalData()); - osl::Guard< comphelper::SolarMutex > aGuard( pSalData->m_pInstance->GetYieldMutex() ); - sal_gtk_timeout_defer( pTSource ); - ImplSVData* pSVData = ImplGetSVData(); if( pSVData->maSchedCtx.mpSalTimer ) pSVData->maSchedCtx.mpSalTimer->CallCallback(); - - return TRUE; + return G_SOURCE_REMOVE; } - - static GSourceFuncs sal_gtk_timeout_funcs = - { - sal_gtk_timeout_prepare, - sal_gtk_timeout_check, - sal_gtk_timeout_dispatch, - nullptr, nullptr, nullptr - }; -} - -static SalGtkTimeoutSource * -create_sal_gtk_timeout( GtkSalTimer *pTimer ) -{ - GSource *pSource = g_source_new( &sal_gtk_timeout_funcs, sizeof( SalGtkTimeoutSource ) ); - SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource); - pTSource->pInstance = pTimer; - - // #i36226# timers should be executed with lower priority - // than XEvents like in generic plugin - g_source_set_priority( pSource, G_PRIORITY_LOW ); - g_source_set_can_recurse( pSource, TRUE ); - g_source_set_callback( pSource, - /* unused dummy */ g_idle_remove_by_data, - nullptr, nullptr ); - g_source_attach( pSource, g_main_context_default() ); -#ifdef DBG_UTIL - g_source_set_name( pSource, "VCL timeout source" ); -#endif - - sal_gtk_timeout_defer( pTSource ); - - return pTSource; } GtkSalTimer::GtkSalTimer() : m_pTimeout(nullptr) - , m_nTimeoutMS(0) { } GtkSalTimer::~GtkSalTimer() { GtkInstance *pInstance = static_cast<GtkInstance *>(GetSalData()->m_pInstance); - pInstance->RemoveTimer( this ); + pInstance->RemoveTimer(); Stop(); } bool GtkSalTimer::Expired() { - if( !m_pTimeout ) + if( !m_pTimeout || g_source_is_destroyed( m_pTimeout ) ) return false; - - gint nDummy = 0; - GTimeVal aTimeNow; - g_get_current_time( &aTimeNow ); - return !!sal_gtk_timeout_expired( m_pTimeout, &nDummy, &aTimeNow); + return (g_get_monotonic_time() > g_source_get_ready_time( m_pTimeout )); } void GtkSalTimer::Start( sal_uLong nMS ) { // glib is not 64bit safe in this regard. - assert( nMS <= G_MAXINT ); - m_nTimeoutMS = nMS; // for restarting - Stop(); // FIXME: ideally re-use an existing m_pTimeout - m_pTimeout = create_sal_gtk_timeout( this ); + if ( nMS > G_MAXINT ) + nMS = G_MAXINT; + + Stop(); + assert( nullptr == m_pTimeout ); + + m_pTimeout = g_timeout_source_new ( nMS ); + // #i36226# timers should be executed with lower priority + // than XEvents like in generic plugin + g_source_set_priority( m_pTimeout, G_PRIORITY_LOW ); + g_source_set_can_recurse( m_pTimeout, TRUE ); + g_source_set_callback( m_pTimeout, + sal_gtk_timeout_function, + this, nullptr ); + g_source_attach( m_pTimeout, g_main_context_default() ); +#ifdef DBG_UTIL + g_source_set_name( m_pTimeout, "VCL timeout source" ); +#endif } void GtkSalTimer::Stop() { if( m_pTimeout ) { - g_source_destroy( &m_pTimeout->aParent ); - g_source_unref( &m_pTimeout->aParent ); + g_source_destroy( m_pTimeout ); + g_source_unref( m_pTimeout ); m_pTimeout = nullptr; } } |