[Libreoffice-commits] .: Branch 'feature/gtk3' - 2 commits - vcl/inc vcl/unx

Michael Meeks michael at kemper.freedesktop.org
Fri Oct 7 03:10:46 PDT 2011


 vcl/inc/generic/gendata.hxx     |    2 
 vcl/inc/unx/gtk/gtkinst.hxx     |   19 +++--
 vcl/inc/unx/saldisp.hxx         |    1 
 vcl/unx/generic/app/salinst.cxx |    1 
 vcl/unx/gtk/app/gtkinst.cxx     |  143 ++++++++++++++++++++++++++++++++++++----
 5 files changed, 145 insertions(+), 21 deletions(-)

New commits:
commit 68c653195aa42877fc83a108cc1d625bf5dabf69
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Fri Oct 7 10:43:17 2011 +0100

    generic: remove mistaken m_aFrames hiding parent's frame list

diff --git a/vcl/inc/unx/saldisp.hxx b/vcl/inc/unx/saldisp.hxx
index 73e5277..ac97bad 100644
--- a/vcl/inc/unx/saldisp.hxx
+++ b/vcl/inc/unx/saldisp.hxx
@@ -327,7 +327,6 @@ protected:
     bool            m_bXinerama;
     std::vector< Rectangle > m_aXineramaScreens;
     std::vector< int > m_aXineramaScreenIndexMap;
-    std::list<SalFrame*> m_aFrames;
     std::list<SalObject*> m_aSalObjects;
 
     bool            m_bUseRandRWrapper; // don't use randr on gtk, use gdk signals there
commit 1f5344aec735288894a3a4c2a6afb57a93f20ede
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Thu Oct 6 22:22:39 2011 +0100

    gtk3: make AnyInput to behave itself properly

diff --git a/vcl/inc/generic/gendata.hxx b/vcl/inc/generic/gendata.hxx
index ef7725f..10b0a09 100644
--- a/vcl/inc/generic/gendata.hxx
+++ b/vcl/inc/generic/gendata.hxx
@@ -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() {}
 
diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index 3df5218..80497dd 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -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
diff --git a/vcl/unx/generic/app/salinst.cxx b/vcl/unx/generic/app/salinst.cxx
index 1f1ab0b..a63ebae 100644
--- a/vcl/unx/generic/app/salinst.cxx
+++ b/vcl/unx/generic/app/salinst.cxx
@@ -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;
 }
 
diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx
index 6e0cb6d..156e0d3 100644
--- a/vcl/unx/gtk/app/gtkinst.cxx
+++ b/vcl/unx/gtk/app/gtkinst.cxx
@@ -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)


More information about the Libreoffice-commits mailing list