Kaydet (Commit) 28b1f4ca authored tarafından Michael Meeks's avatar Michael Meeks

gtk3: make AnyInput to behave itself properly

üst 2e48ed93
...@@ -51,7 +51,7 @@ class VCL_DLLPUBLIC SalGenericData : public SalData ...@@ -51,7 +51,7 @@ class VCL_DLLPUBLIC SalGenericData : public SalData
// for transient storage of unicode strings eg. 'u123' by input methods // for transient storage of unicode strings eg. 'u123' by input methods
rtl::OUString m_aUnicodeEntry; rtl::OUString m_aUnicodeEntry;
public: public:
SalGenericData( SalGenericDataType t ) : SalData(), m_eType( t ) {} SalGenericData( SalGenericDataType t ) : SalData(), m_eType( t ), m_pDisplay( NULL ) {}
virtual ~SalGenericData() {} virtual ~SalGenericData() {}
virtual void Dispose() {} virtual void Dispose() {}
......
...@@ -82,19 +82,14 @@ public: ...@@ -82,19 +82,14 @@ public:
class GtkSalTimer; class GtkSalTimer;
#if GTK_CHECK_VERSION(3,0,0) #if GTK_CHECK_VERSION(3,0,0)
class GtkInstance : public SvpSalInstance class GtkInstance : public SvpSalInstance
{
public:
GtkInstance( SalYieldMutex* pMutex )
: SvpSalInstance( pMutex )
#else #else
class GtkInstance : public X11SalInstance class GtkInstance : public X11SalInstance
#endif
{ {
public: public:
GtkInstance( SalYieldMutex* pMutex ) GtkInstance( SalYieldMutex* pMutex );
: X11SalInstance( pMutex )
#endif
{}
virtual ~GtkInstance(); virtual ~GtkInstance();
void Init();
virtual SalFrame* CreateFrame( SalFrame* pParent, sal_uLong nStyle ); virtual SalFrame* CreateFrame( SalFrame* pParent, sal_uLong nStyle );
virtual SalFrame* CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle ); virtual SalFrame* CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle );
...@@ -112,9 +107,17 @@ public: ...@@ -112,9 +107,17 @@ public:
virtual bool AnyInput( sal_uInt16 nType ); virtual bool AnyInput( sal_uInt16 nType );
void RemoveTimer (SalTimer *pTimer); void RemoveTimer (SalTimer *pTimer);
// for managing a mirror of the in-flight un-dispatched gdk event queue
void addEvent( sal_uInt16 nMask );
void subtractEvent( sal_uInt16 nMask );
private: private:
std::vector<GtkSalTimer *> m_aTimers; std::vector<GtkSalTimer *> m_aTimers;
bool IsTimerExpired(); bool IsTimerExpired();
// count of in-flight un-dispatched gdk events of a given input type
sal_uInt32 m_nAnyInput[16];
void resetEvents();
}; };
#endif // _VCL_GTKINST_HXX #endif // _VCL_GTKINST_HXX
......
...@@ -167,6 +167,7 @@ bool X11SalInstance::AnyInput(sal_uInt16 nType) ...@@ -167,6 +167,7 @@ bool X11SalInstance::AnyInput(sal_uInt16 nType)
bRet = aInput.bRet; bRet = aInput.bRet;
} }
fprintf( stderr, "AnyInput 0x%x = %s\n", nType, bRet ? "true" : "false" );
return bRet; return bRet;
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
// MARKER(update_precomp.py): autogen include statement, do not remove // MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx" #include "precompiled_vcl.hxx"
#include <string.h>
#include <osl/module.h> #include <osl/module.h>
#include <unx/gtk/gtkdata.hxx> #include <unx/gtk/gtkdata.hxx>
#include <unx/gtk/gtkinst.hxx> #include <unx/gtk/gtkinst.hxx>
...@@ -193,14 +194,130 @@ extern "C" ...@@ -193,14 +194,130 @@ extern "C"
pSalData->Init(); pSalData->Init();
pSalData->initNWF(); pSalData->initNWF();
pInstance->Init();
InitAtkBridge(); InitAtkBridge();
return pInstance; return pInstance;
} }
} }
// Handling the event queue
void GtkInstance::resetEvents()
{
memset( m_nAnyInput, 0, sizeof( m_nAnyInput ) );
}
void GtkInstance::addEvent( sal_uInt16 nMask )
{
sal_uInt16 nShift = 1;
for (int i = 0; i < 16; i++) {
if( nMask & nShift )
m_nAnyInput[i]++;
nShift <<= 1;
}
}
void GtkInstance::subtractEvent( sal_uInt16 nMask )
{
sal_uInt16 nShift = 1;
for (int i = 0; i < 16; i++) {
if( nMask & nShift && m_nAnyInput[i] > 0 )
m_nAnyInput[i]--;
nShift <<= 1;
}
}
extern "C" {
// We catch events as they pop out of X and into gdk
static GdkFilterReturn _sal_gtk_instance_filter_fn (GdkXEvent *_xevent,
GdkEvent *event,
gpointer data)
{
// FIXME: in theory this could be for non-X events but in reality it never is.
XEvent *pXEvent = (XEvent *)_xevent;
sal_uInt16 nType;
switch( pXEvent->type ) {
case ButtonPress:
case ButtonRelease:
case MotionNotify:
case EnterNotify:
case LeaveNotify:
nType = INPUT_MOUSE;
break;
case XLIB_KeyPress:
nType = INPUT_KEYBOARD;
break;
case Expose:
case GraphicsExpose:
case NoExpose:
nType = INPUT_PAINT;
break;
default:
nType = INPUT_OTHER;
break;
}
((GtkInstance *)data)->addEvent( nType );
return GDK_FILTER_CONTINUE;
}
// And then again as they pop out of gdk and into gtk+
static void _sal_gtk_event_handler_fn (GdkEvent *pEvent, gpointer data)
{
sal_uInt16 nType = 0;
switch( pEvent->type ) {
case GDK_MOTION_NOTIFY:
case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
case GDK_SCROLL:
nType = INPUT_MOUSE;
break;
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
nType = INPUT_KEYBOARD;
break;
case GDK_EXPOSE:
nType = INPUT_PAINT;
break;
default:
nType = INPUT_OTHER;
break;
}
((GtkInstance *)data)->subtractEvent( nType );
gtk_main_do_event( pEvent );
}
}
GtkInstance::GtkInstance( SalYieldMutex* pMutex )
#if GTK_CHECK_VERSION(3,0,0)
: SvpSalInstance( pMutex )
#else
: X11SalInstance( pMutex )
#endif
{
resetEvents();
}
// This has to happen after gtk_init has been called by saldata.cxx's
// Init or our handlers just get clobbered.
void GtkInstance::Init()
{
gdk_window_add_filter( NULL, _sal_gtk_instance_filter_fn, this );
gdk_event_handler_set( _sal_gtk_event_handler_fn, this, NULL );
}
GtkInstance::~GtkInstance() GtkInstance::~GtkInstance()
{ {
gdk_event_handler_set( (GdkEventFunc)gtk_main_do_event, NULL, NULL );
gdk_window_remove_filter( NULL, _sal_gtk_instance_filter_fn, this );
while( !m_aTimers.empty() ) while( !m_aTimers.empty() )
delete *m_aTimers.begin(); delete *m_aTimers.begin();
DeInitAtkBridge(); DeInitAtkBridge();
...@@ -213,9 +330,7 @@ SalFrame* GtkInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle ) ...@@ -213,9 +330,7 @@ SalFrame* GtkInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
SalFrame* GtkInstance::CreateChildFrame( SystemParentData* pParentData, sal_uLong ) SalFrame* GtkInstance::CreateChildFrame( SystemParentData* pParentData, sal_uLong )
{ {
SalFrame* pFrame = new GtkSalFrame( pParentData ); return new GtkSalFrame( pParentData );
return pFrame;
} }
SalObject* GtkInstance::CreateObject( SalFrame* pParent, SystemWindowData* pWindowData, sal_Bool bShow ) SalObject* GtkInstance::CreateObject( SalFrame* pParent, SystemWindowData* pWindowData, sal_Bool bShow )
...@@ -273,7 +388,6 @@ void GtkInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const r ...@@ -273,7 +388,6 @@ void GtkInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const r
#endif #endif
} }
/* /*
* Obsolete, non-working, and crufty code from the * Obsolete, non-working, and crufty code from the
* beginning of time. When we update our base platform * beginning of time. When we update our base platform
...@@ -462,6 +576,9 @@ void GtkInstance::RemoveTimer (SalTimer *pTimer) ...@@ -462,6 +576,9 @@ void GtkInstance::RemoveTimer (SalTimer *pTimer)
void GtkInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) void GtkInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
{ {
GetGtkSalData()->Yield( bWait, bHandleAllCurrentEvents ); GetGtkSalData()->Yield( bWait, bHandleAllCurrentEvents );
if( !gdk_events_pending() )
resetEvents();
} }
bool GtkInstance::IsTimerExpired() bool GtkInstance::IsTimerExpired()
...@@ -485,13 +602,17 @@ bool GtkInstance::AnyInput( sal_uInt16 nType ) ...@@ -485,13 +602,17 @@ bool GtkInstance::AnyInput( sal_uInt16 nType )
if( (nType & INPUT_TIMER) && IsTimerExpired() ) if( (nType & INPUT_TIMER) && IsTimerExpired() )
return true; return true;
else else
#warning FIXME: this is really not ideal - we should snoop for misc. types {
/* FIXME: AnyInput is also extremely fragile ... if we just return bool bRet = false;
!!gtk_events_pending(); we hang on start [!] ... amazing ...*/ sal_uInt16 nShift = 1;
return false; for (int i = 0; i < 16; i++) {
#if 0 bRet |= (nType & nShift) && m_nAnyInput[i] > 0;
return X11SalInstance::AnyInput( nType ); nShift <<= 1;
#endif }
// fprintf( stderr, "AnyInput 0x%x => %s\n",
// nType, bRet ? "true" : "false" );
return bRet;
}
} }
#if GTK_CHECK_VERSION(3,0,0) #if GTK_CHECK_VERSION(3,0,0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment