[Libreoffice-commits] core.git: Branch 'private/jmux/master-fixes' - vcl/inc vcl/unx
Jan-Marek Glogowski
glogow at fbihome.de
Thu Jan 5 09:20:26 UTC 2017
Rebased ref, commits from common ancestor:
commit c9f1c7257f70c2caf70820b652f6b57b9e0520ba
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Sun Nov 13 06:13:22 2016 +0100
GTK simplify 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.
Change-Id: Iea40a6284bdc5c121235af5a6079a92a679391ca
diff --git a/vcl/inc/unx/gtk/gtkdata.hxx b/vcl/inc/unx/gtk/gtkdata.hxx
index ffb0fb7..62ce891 100644
--- a/vcl/inc/unx/gtk/gtkdata.hxx
+++ b/vcl/inc/unx/gtk/gtkdata.hxx
@@ -81,15 +81,13 @@ inline void widget_set_can_default(GtkWidget *widget, gboolean can_default)
class GtkSalTimer : public SalTimer
{
- struct SalGtkTimeoutSource *m_pTimeout;
+ GSource *m_pTimeout;
public:
GtkSalTimer();
virtual ~GtkSalTimer() override;
virtual void Start( sal_uLong nMS ) override;
virtual void Stop() override;
bool Expired();
-
- sal_uLong m_nTimeoutMS;
};
class GtkData : public SalGenericData
diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index e20ca9d..2a4ab33 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -246,12 +246,12 @@ public:
const cairo_font_options_t* GetLastSeenCairoFontOptions();
void ResetLastSeenCairoFontOptions();
- void RemoveTimer (SalTimer *pTimer);
+ void RemoveTimer();
std::shared_ptr<vcl::unx::GtkPrintWrapper> const & getPrintWrapper() const;
private:
- std::vector<GtkSalTimer *> m_aTimers;
+ GtkSalTimer* m_pTimer;
#if GTK_CHECK_VERSION(3,0,0)
std::unordered_map< GdkAtom, css::uno::Reference<css::uno::XInterface> > m_aClipboards;
#endif
diff --git a/vcl/unx/gtk/gtkdata.cxx b/vcl/unx/gtk/gtkdata.cxx
index e621f47..0016f40 100644
--- a/vcl/unx/gtk/gtkdata.cxx
+++ b/vcl/unx/gtk/gtkdata.cxx
@@ -666,165 +666,76 @@ 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 user_data )
{
- 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();
+ assert( pSVData->mpSalTimer == user_data );
if( pSVData->mpSalTimer )
{
// TODO: context_pending should be probably checked too, but it causes locking assertion failures
bool idle = !pSalData->BlockIdleTimeout() && /*!g_main_context_pending( NULL ) &&*/ !gdk_events_pending();
pSVData->mpSalTimer->CallCallback( idle );
}
-
- 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;
}
}
diff --git a/vcl/unx/gtk/gtkinst.cxx b/vcl/unx/gtk/gtkinst.cxx
index e01a267b..86cc58d 100644
--- a/vcl/unx/gtk/gtkinst.cxx
+++ b/vcl/unx/gtk/gtkinst.cxx
@@ -156,6 +156,7 @@ GtkInstance::GtkInstance( SalYieldMutex* pMutex )
#else
: X11SalInstance( pMutex )
#endif
+ , m_pTimer(nullptr)
, bNeedsInit(true)
, m_pLastCairoFontOptions(nullptr)
{
@@ -200,8 +201,7 @@ void GtkInstance::EnsureInit()
GtkInstance::~GtkInstance()
{
- while( !m_aTimers.empty() )
- delete *m_aTimers.begin();
+ delete m_pTimer;
DeInitAtkBridge();
ResetLastSeenCairoFontOptions();
}
@@ -405,18 +405,17 @@ void GtkInstance::DestroyMenuItem( SalMenuItem* ) {}
SalTimer* GtkInstance::CreateSalTimer()
{
EnsureInit();
- GtkSalTimer *pTimer = new GtkSalTimer();
- m_aTimers.push_back( pTimer );
- return pTimer;
+ assert( nullptr == m_pTimer );
+ RemoveTimer();
+ m_pTimer = new GtkSalTimer();
+ return m_pTimer;
}
-void GtkInstance::RemoveTimer (SalTimer *pTimer)
+void GtkInstance::RemoveTimer()
{
EnsureInit();
- std::vector<GtkSalTimer *>::iterator it;
- it = std::find( m_aTimers.begin(), m_aTimers.end(), pTimer );
- if( it != m_aTimers.end() )
- m_aTimers.erase( it );
+ delete m_pTimer;
+ m_pTimer = nullptr;
}
SalYieldResult GtkInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong const nReleased)
@@ -430,12 +429,7 @@ SalYieldResult GtkInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sa
bool GtkInstance::IsTimerExpired()
{
EnsureInit();
- for( std::vector<GtkSalTimer *>::iterator it = m_aTimers.begin();
- it != m_aTimers.end(); ++it )
- if( (*it)->Expired() )
- return true;
-
- return false;
+ return (m_pTimer && m_pTimer->Expired());
}
bool GtkInstance::AnyInput( VclInputFlags nType )
diff --git a/vcl/unx/gtk3/gtk3gtkdata.cxx b/vcl/unx/gtk3/gtk3gtkdata.cxx
index f911d38..daf6523 100644
--- a/vcl/unx/gtk3/gtk3gtkdata.cxx
+++ b/vcl/unx/gtk3/gtk3gtkdata.cxx
@@ -620,165 +620,76 @@ 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 user_data )
{
- 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();
+ assert( pSVData->mpSalTimer == user_data );
if( pSVData->mpSalTimer )
{
// TODO: context_pending should be probably checked too, but it causes locking assertion failures
bool idle = !pSalData->BlockIdleTimeout() && /*!g_main_context_pending( NULL ) &&*/ !gdk_events_pending();
pSVData->mpSalTimer->CallCallback( idle );
}
-
- 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;
}
}
More information about the Libreoffice-commits
mailing list