File fix-x11-time-wrap.diff of Package kdelibs3
------------------------------------------------------------------------
r528573 | lunakl | 2006-04-11 14:48:50 +0200 (Tue, 11 Apr 2006) | 3 lines
Handle X timestamp wrapping correctly even on 64bit platforms.
------------------------------------------------------------------------
Index: kdecore/kapplication.cpp
===================================================================
--- kdecore/kapplication.cpp (revision 528572)
+++ kdecore/kapplication.cpp (revision 528573)
@@ -1683,7 +1683,7 @@ bool KApplication::x11EventFilter( XEven
&& _event->xclient.data.l[ 3 ] != 0 )
{
if( qt_x_user_time == 0
- || ( _event->xclient.data.l[ 3 ] - qt_x_user_time ) < 100000U )
+ || NET::timestampCompare( _event->xclient.data.l[ 3 ], qt_x_user_time ) > 0 )
{ // and the timestamp looks reasonable
qt_x_user_time = _event->xclient.data.l[ 3 ]; // update our qt_x_user_time from it
}
@@ -1691,7 +1691,7 @@ bool KApplication::x11EventFilter( XEven
else // normal DND, only needed until Qt updates qt_x_user_time from XdndDrop
{
if( qt_x_user_time == 0
- || ( _event->xclient.data.l[ 2 ] - qt_x_user_time ) < 100000U )
+ || NET::timestampCompare( _event->xclient.data.l[ 2 ], qt_x_user_time ) > 0 )
{ // the timestamp looks reasonable
qt_x_user_time = _event->xclient.data.l[ 2 ]; // update our qt_x_user_time from it
}
@@ -1811,7 +1811,7 @@ void KApplication::updateUserTimestamp(
XDestroyWindow( qt_xdisplay(), w );
}
if( qt_x_user_time == 0
- || time - qt_x_user_time < 1000000000U ) // check time > qt_x_user_time, handle wrapping
+ || NET::timestampCompare( time, qt_x_user_time ) > 0 ) // check time > qt_x_user_time
qt_x_user_time = time;
#endif
}
Index: kdecore/netwm_def.h
===================================================================
--- kdecore/netwm_def.h (revision 528572)
+++ kdecore/netwm_def.h (revision 528573)
@@ -606,6 +606,20 @@ public:
FromApplication,
FromTool
};
+
+ /**
+ Compares two X timestamps, taking into account wrapping and 64bit architectures.
+ Return value is like with strcmp(), 0 for equal, -1 for time1 < time2, 1 for time1 > time2.
+ @since 3.5.3
+ */
+ static int timestampCompare( unsigned long time1, unsigned long time2 );
+ /**
+ Returns a difference of two X timestamps, time2 - time1, where time2 must be later than time1,
+ as returned by timestampCompare().
+ @since 3.5.3
+ */
+ static int timestampDiff( unsigned long time1_, unsigned long time2_ );
+
};
Index: kdecore/kxerrorhandler.cpp
===================================================================
--- kdecore/kxerrorhandler.cpp (revision 528572)
+++ kdecore/kxerrorhandler.cpp (revision 528573)
@@ -28,6 +28,7 @@
#include "kxerrorhandler.h"
#include <assert.h>
#include <stdlib.h>
+#include <netwm_def.h>
KXErrorHandler** KXErrorHandler::handlers = NULL;
int KXErrorHandler::pos = 0;
@@ -101,7 +102,8 @@ int KXErrorHandler::handler_wrapper( Dis
int KXErrorHandler::handle( Display* dpy, XErrorEvent* e )
{
if( dpy == display
- && e->serial - first_request < 1000000000 ) // e->serial > first_request, with wrapping
+ // e->serial > first_request , compare like X timestamps to handle wrapping
+ && NET::timestampCompare( e->serial, first_request ) > 0 )
{ // it's for us
//qDebug( "Handling: %p", static_cast< void* >( this ));
if( user_handler1 != NULL && user_handler1( e->request_code, e->error_code, e->resourceid ))
Index: kdecore/netwm.cpp
===================================================================
--- kdecore/netwm.cpp (revision 528572)
+++ kdecore/netwm.cpp (revision 528573)
@@ -4401,4 +4401,38 @@ void NETRootInfo::virtual_hook( int, voi
void NETWinInfo::virtual_hook( int, void* )
{ /*BASE::virtual_hook( id, data );*/ }
+// Functions for X timestamp comparing. For Time being 32bit they're fairly simple
+// (the #if 0 part), but on 64bit architectures Time is 64bit unsigned long,
+// so there special care needs to be taken to always use only the lower 32bits.
+#if 0
+int NET::timestampCompare( Time time1, Time time2 ) // like strcmp()
+ {
+ if( time1 == time2 )
+ return 0;
+ return ( time1 - time2 ) < 0x7fffffffU ? 1 : -1; // time1 > time2 -> 1, handle wrapping
+ }
+
+Time NET::timestampDiff( Time time1, Time time2 ) // returns time2 - time1
+ { // no need to handle wrapping?
+ return time2 - time1;
+ }
+#else
+int NET::timestampCompare( unsigned long time1_, unsigned long time2_ ) // like strcmp()
+ {
+ Q_UINT32 time1 = time1_;
+ Q_UINT32 time2 = time2_;
+ if( time1 == time2 )
+ return 0;
+ return Q_UINT32( time1 - time2 ) < 0x7fffffffU ? 1 : -1; // time1 > time2 -> 1, handle wrapping
+ }
+
+int NET::timestampDiff( unsigned long time1_, unsigned long time2_ ) // returns time2 - time1
+ { // no need to handle wrapping?
+ Q_UINT32 time1 = time1_;
+ Q_UINT32 time2 = time2_;
+ return Q_UINT32( time2 - time1 );
+ }
+#endif
+
+
#endif