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
// for transient storage of unicode strings eg. 'u123' by input methods
rtl::OUString m_aUnicodeEntry;
public:
SalGenericData( SalGenericDataType t ) : SalData(), m_eType( t ) {}
SalGenericData( SalGenericDataType t ) : SalData(), m_eType( t ), m_pDisplay( NULL ) {}
virtual ~SalGenericData() {}
virtual void Dispose() {}
......
......@@ -82,19 +82,14 @@ public:
class GtkSalTimer;
#if GTK_CHECK_VERSION(3,0,0)
class GtkInstance : public SvpSalInstance
{
public:
GtkInstance( SalYieldMutex* pMutex )
: SvpSalInstance( pMutex )
#else
class GtkInstance : public X11SalInstance
#endif
{
public:
GtkInstance( SalYieldMutex* pMutex )
: X11SalInstance( pMutex )
#endif
{}
GtkInstance( SalYieldMutex* pMutex );
virtual ~GtkInstance();
void Init();
virtual SalFrame* CreateFrame( SalFrame* pParent, sal_uLong nStyle );
virtual SalFrame* CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle );
......@@ -112,9 +107,17 @@ public:
virtual bool AnyInput( sal_uInt16 nType );
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:
std::vector<GtkSalTimer *> m_aTimers;
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
......
......@@ -167,6 +167,7 @@ bool X11SalInstance::AnyInput(sal_uInt16 nType)
bRet = aInput.bRet;
}
fprintf( stderr, "AnyInput 0x%x = %s\n", nType, bRet ? "true" : "false" );
return bRet;
}
......
......@@ -29,6 +29,7 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#include <string.h>
#include <osl/module.h>
#include <unx/gtk/gtkdata.hxx>
#include <unx/gtk/gtkinst.hxx>
......@@ -193,14 +194,130 @@ extern "C"
pSalData->Init();
pSalData->initNWF();
pInstance->Init();
InitAtkBridge();
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()
{
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() )
delete *m_aTimers.begin();
DeInitAtkBridge();
......@@ -213,9 +330,7 @@ SalFrame* GtkInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
SalFrame* GtkInstance::CreateChildFrame( SystemParentData* pParentData, sal_uLong )
{
SalFrame* pFrame = new GtkSalFrame( pParentData );
return pFrame;
return new GtkSalFrame( pParentData );
}
SalObject* GtkInstance::CreateObject( SalFrame* pParent, SystemWindowData* pWindowData, sal_Bool bShow )
......@@ -273,7 +388,6 @@ void GtkInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const r
#endif
}
/*
* Obsolete, non-working, and crufty code from the
* beginning of time. When we update our base platform
......@@ -462,6 +576,9 @@ void GtkInstance::RemoveTimer (SalTimer *pTimer)
void GtkInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
{
GetGtkSalData()->Yield( bWait, bHandleAllCurrentEvents );
if( !gdk_events_pending() )
resetEvents();
}
bool GtkInstance::IsTimerExpired()
......@@ -485,13 +602,17 @@ bool GtkInstance::AnyInput( sal_uInt16 nType )
if( (nType & INPUT_TIMER) && IsTimerExpired() )
return true;
else
#warning FIXME: this is really not ideal - we should snoop for misc. types
/* FIXME: AnyInput is also extremely fragile ... if we just return
!!gtk_events_pending(); we hang on start [!] ... amazing ...*/
return false;
#if 0
return X11SalInstance::AnyInput( nType );
#endif
{
bool bRet = false;
sal_uInt16 nShift = 1;
for (int i = 0; i < 16; i++) {
bRet |= (nType & nShift) && m_nAnyInput[i] > 0;
nShift <<= 1;
}
// fprintf( stderr, "AnyInput 0x%x => %s\n",
// nType, bRet ? "true" : "false" );
return bRet;
}
}
#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