[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - avmedia/Library_avmediagst.mk avmedia/source include/vcl vcl/inc vcl/Library_vcl.mk vcl/opengl vcl/unx

Caolán McNamara caolanm at redhat.com
Fri Feb 19 14:55:29 UTC 2016


 avmedia/Library_avmediagst.mk                      |   16 +
 avmedia/source/gstreamer/gstplayer.cxx             |  226 +++++++++++----------
 avmedia/source/gstreamer/gstplayer.hxx             |    8 
 include/vcl/sysdata.hxx                            |    2 
 vcl/Library_vcl.mk                                 |    2 
 vcl/inc/unx/gtk/gtkframe.hxx                       |    8 
 vcl/inc/unx/nativewindowhandleprovider.hxx         |   25 ++
 vcl/inc/unx/salframe.h                             |    6 
 vcl/inc/unx/x11/x11display.hxx                     |   25 --
 vcl/inc/unx/x11windowprovider.hxx                  |   28 --
 vcl/opengl/x11/gdiimpl.cxx                         |    4 
 vcl/unx/generic/app/saldata.cxx                    |   56 +++++
 vcl/unx/generic/gdi/nativewindowhandleprovider.cxx |   17 +
 vcl/unx/generic/gdi/salgdi.cxx                     |    2 
 vcl/unx/generic/gdi/x11windowprovider.cxx          |   72 ------
 vcl/unx/generic/window/salframe.cxx                |    2 
 vcl/unx/gtk/gtkobject.cxx                          |   22 --
 vcl/unx/gtk/gtksalframe.cxx                        |    3 
 vcl/unx/gtk3/gtk3gtkframe.cxx                      |   37 ++-
 vcl/unx/gtk3/gtk3gtkobject.cxx                     |  180 ++++++++++++++++
 20 files changed, 475 insertions(+), 266 deletions(-)

New commits:
commit 05eccaef907c9fca4f874b8ffa608d4815fbeebd
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Feb 12 16:55:12 2016 +0000

    gtk3+wayland: implement video playback under gtk3 + wayland
    
    split the gtk2 and gtk3 gtkobjects
    
    (cherry picked from commit 31fa4545985acc1594107e087cedc2d99b3d0f0b)
    
    Change-Id: I32084232c44a12e9641010b51e75710abc827695
    
    rename X11WindowProvider to a NativeWindowHandle provider
    
    sort of thing and genericize it
    
    (cherry picked from commit e35e762d564da18b0b508112f3e4d78fd26ba99c)
    
    Change-Id: I27e1e47f2b371e5269db079cfc1262d056105f80
    
    implement wayland handle passing for gstreamer
    
    Change-Id: I3b0effe35ad7b37ff7ab3de2a3b78b6312779139
    (cherry picked from commit c0d4f3ad3307c7a0d0fddd8c413ef0cc91d382ae)
    
    gtk3+wayland: play video via gtksink gstreamer element
    
    (cherry picked from commit 8543fbc72fafc0d71a8760752ca2ef5b7119cb5c)
    
    Change-Id: Ib371fa06eda73962cbe94739e69a68b46c26e4bf
    Reviewed-on: https://gerrit.libreoffice.org/22462
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/avmedia/Library_avmediagst.mk b/avmedia/Library_avmediagst.mk
index a20a32b..35a56ac 100644
--- a/avmedia/Library_avmediagst.mk
+++ b/avmedia/Library_avmediagst.mk
@@ -16,7 +16,21 @@ $(eval $(call gb_Library_set_include,avmediagst,\
 	-I$(SRCDIR)/avmedia/source/inc \
 	$(GSTREAMER_1_0_CFLAGS) \
 ))
-$(eval $(call gb_Library_add_libs,avmediagst,$(GSTREAMER_1_0_LIBS)))
+
+$(eval $(call gb_Library_add_libs,avmediagst,\
+    $(GSTREAMER_1_0_LIBS) \
+))
+
+ifneq ($(ENABLE_GTK3),)
+$(eval $(call gb_Library_add_cxxflags,avmediagst,\
+    $$(GTK3_CFLAGS) \
+    -DENABLE_GTKSINK \
+))
+
+$(eval $(call gb_Library_add_libs,avmediagst,\
+    $(GTK3_LIBS) \
+))
+endif
 
 $(eval $(call gb_Library_use_external,avmediagst,boost_headers))
 
diff --git a/avmedia/source/gstreamer/gstplayer.cxx b/avmedia/source/gstreamer/gstplayer.cxx
index 6dd0f5c..2215479 100644
--- a/avmedia/source/gstreamer/gstplayer.cxx
+++ b/avmedia/source/gstreamer/gstplayer.cxx
@@ -53,18 +53,11 @@
 #include <gst/pbutils/missing-plugins.h>
 #include <gst/pbutils/pbutils.h>
 
-#if !defined DBG
-# if OSL_DEBUG_LEVEL > 2
 #ifdef AVMEDIA_GST_0_10
 #  define AVVERSION "gst 0.10: "
 #else
 #  define AVVERSION "gst 1.0: "
 #endif
-#define DBG(...) do { fprintf (stderr, "%s", AVVERSION); fprintf (stderr, __VA_ARGS__); fprintf (stderr, "\n"); } while (0);
-# else
-#define DBG(...)
-# endif
-#endif
 
 using namespace ::com::sun::star;
 
@@ -289,6 +282,10 @@ Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) :
     GstPlayer_BASE( m_aMutex ),
     mxMgr( rxMgr ),
     mpPlaybin( nullptr ),
+#if defined(ENABLE_GTKSINK)
+    mpGtkWidget( nullptr ),
+#endif
+    mbUseGtkSink( false ),
     mbFakeVideo (false ),
     mnUnmutedVolume( 0 ),
     mbPlayPending ( false ),
@@ -312,12 +309,12 @@ Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) :
 
     mbInitialized = gst_init_check( &argc, &argv, &pError );
 
-    DBG( "%p Player::Player", this );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " Player::Player" );
 
     if (pError != nullptr)
     {
         // TODO: throw an exception?
-        DBG( "%p Player::Player error '%s'", this, pError->message );
+        SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " Player::Player error '" << pError->message << "'" );
         g_error_free (pError);
     }
 }
@@ -326,7 +323,7 @@ Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) :
 
 Player::~Player()
 {
-    DBG( "%p Player::~Player", this );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " Player::~Player" );
     if( mbInitialized )
         disposing();
 }
@@ -339,11 +336,19 @@ void SAL_CALL Player::disposing()
 
     stop();
 
-    DBG( "%p Player::disposing", this );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " Player::disposing" );
 
     // Release the elements and pipeline
     if( mbInitialized )
     {
+#if defined(ENABLE_GTKSINK)
+        if (mpGtkWidget)
+        {
+            gtk_widget_destroy(mpGtkWidget);
+            mpGtkWidget = nullptr;
+        }
+#endif
+
         if( mpPlaybin )
         {
             gst_element_set_state( mpPlaybin, GST_STATE_NULL );
@@ -391,18 +396,20 @@ void Player::processMessage( GstMessage *message )
             start();
         break;
     case GST_MESSAGE_STATE_CHANGED:
-        if( message->src == GST_OBJECT( mpPlaybin ) ) {
+        if (message->src == GST_OBJECT(mpPlaybin))
+        {
             GstState newstate, pendingstate;
 
             gst_message_parse_state_changed (message, nullptr, &newstate, &pendingstate);
 
-            if( newstate == GST_STATE_PAUSED &&
-                pendingstate == GST_STATE_VOID_PENDING &&
-                mpXOverlay )
-                gst_video_overlay_expose( mpXOverlay );
+            if (!mbUseGtkSink && newstate == GST_STATE_PAUSED &&
+                pendingstate == GST_STATE_VOID_PENDING && mpXOverlay)
+            {
+                gst_video_overlay_expose(mpXOverlay);
+            }
 
-        if (mbPlayPending)
-            mbPlayPending = ((newstate == GST_STATE_READY) || (newstate == GST_STATE_PAUSED));
+            if (mbPlayPending)
+                mbPlayPending = ((newstate == GST_STATE_READY) || (newstate == GST_STATE_PAUSED));
         }
     default:
         break;
@@ -431,8 +438,6 @@ static gboolean wrap_element_query_duration (GstElement *element, GstFormat form
 
 GstBusSyncReply Player::processSyncMessage( GstMessage *message )
 {
-//    DBG( "%p processSyncMessage has handle: %s", this, GST_MESSAGE_TYPE_NAME( message ) );
-
 #if OSL_DEBUG_LEVEL > 0
     if ( GST_MESSAGE_TYPE( message ) == GST_MESSAGE_ERROR )
     {
@@ -441,29 +446,32 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
 
         gst_message_parse_error( message, &error, &error_debug );
         SAL_WARN(
-            "avmedia",
-            "gstreamer error: '" << error->message << "' debug: '"
+            "avmedia.gstreamer",
+            "error: '" << error->message << "' debug: '"
                 << error_debug << "'");
     }
 #endif
 
+    if (!mbUseGtkSink)
+    {
 #ifdef AVMEDIA_GST_0_10
-    if (message->structure &&
-        !strcmp( gst_structure_get_name( message->structure ), "prepare-xwindow-id" ) )
+        if (message->structure &&
+            !strcmp( gst_structure_get_name( message->structure ), "prepare-xwindow-id" ) )
 #else
-    if (gst_is_video_overlay_prepare_window_handle_message (message) )
+        if (gst_is_video_overlay_prepare_window_handle_message (message) )
 #endif
-    {
-        DBG( "%p processSyncMessage prepare window id: %s %d", this,
-             GST_MESSAGE_TYPE_NAME( message ), (int)mnWindowID );
-        if( mpXOverlay )
-            g_object_unref( G_OBJECT ( mpXOverlay ) );
-        g_object_set( GST_MESSAGE_SRC( message ), "force-aspect-ratio", FALSE, NULL );
-        mpXOverlay = GST_VIDEO_OVERLAY( GST_MESSAGE_SRC( message ) );
-        g_object_ref( G_OBJECT ( mpXOverlay ) );
-        if ( mnWindowID != 0 )
-            gst_video_overlay_set_window_handle( mpXOverlay, mnWindowID );
-        return GST_BUS_DROP;
+        {
+            SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " processSyncMessage prepare window id: " <<
+                      GST_MESSAGE_TYPE_NAME( message ) << " " << (int)mnWindowID );
+            if( mpXOverlay )
+                g_object_unref( G_OBJECT ( mpXOverlay ) );
+            g_object_set( GST_MESSAGE_SRC( message ), "force-aspect-ratio", FALSE, nullptr );
+            mpXOverlay = GST_VIDEO_OVERLAY( GST_MESSAGE_SRC( message ) );
+            g_object_ref( G_OBJECT ( mpXOverlay ) );
+            if ( mnWindowID != 0 )
+                gst_video_overlay_set_window_handle( mpXOverlay, mnWindowID );
+            return GST_BUS_DROP;
+        }
     }
 
 #ifdef AVMEDIA_GST_0_10
@@ -473,12 +481,11 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
 
             gst_message_parse_state_changed (message, nullptr, &newstate, &pendingstate);
 
-            DBG( "%p state change received, new state %d pending %d", this,
-                 (int)newstate, (int)pendingstate );
+            SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " state change received, new state " << (int)newState << " pending " << (int)pendingstate );
             if( newstate == GST_STATE_PAUSED &&
                 pendingstate == GST_STATE_VOID_PENDING ) {
 
-                DBG( "%p change to paused received", this );
+                SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " change to paused received" );
 
                 if( mnDuration == 0) {
                     gint64 gst_duration = 0L;
@@ -489,7 +496,7 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
                 if( mnWidth == 0 ) {
                     GList *pStreamInfo = nullptr;
 
-                    g_object_get( G_OBJECT( mpPlaybin ), "stream-info", &pStreamInfo, NULL );
+                    g_object_get( G_OBJECT( mpPlaybin ), "stream-info", &pStreamInfo, nullptr );
 
                     for ( ; pStreamInfo != nullptr; pStreamInfo = pStreamInfo->next) {
                         GObject *pInfo = G_OBJECT( pStreamInfo->data );
@@ -498,7 +505,7 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
                             continue;
 
                         int nType;
-                        g_object_get( pInfo, "type", &nType, NULL );
+                        g_object_get( pInfo, "type", &nType, nullptr );
                         GEnumValue *pValue = g_enum_get_value( G_PARAM_SPEC_ENUM( g_object_class_find_property( G_OBJECT_GET_CLASS( pInfo ), "type" ) )->enum_class,
                                                                nType );
 
@@ -506,12 +513,12 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
                             GstStructure *pStructure;
                             GstPad *pPad;
 
-                            g_object_get( pInfo, "object", &pPad, NULL );
+                            g_object_get( pInfo, "object", &pPad, nullptr );
                             pStructure = gst_caps_get_structure( GST_PAD_CAPS( pPad ), 0 );
                             if( pStructure ) {
                                 gst_structure_get_int( pStructure, "width", &mnWidth );
                                 gst_structure_get_int( pStructure, "height", &mnHeight );
-                                DBG( "queried size: %d x %d", mnWidth, mnHeight );
+                                SAL_INFO( "avmedia.gstreamer", AVVERSION "queried size: " << mnWidth << "x" << mnHeight );
                             }
                             g_object_unref (pPad);
                         }
@@ -542,11 +549,11 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
                 if( gst_structure_get( gst_caps_get_structure( caps, 0 ),
                                        "width", G_TYPE_INT, &w,
                                        "height", G_TYPE_INT, &h,
-                                       NULL ) ) {
+                                       nullptr ) ) {
                     mnWidth = w;
                     mnHeight = h;
 
-                    DBG( "queried size: %d x %d", mnWidth, mnHeight );
+                    SAL_INFO( "avmedia.gstreamer", AVVERSION "queried size: " << mnWidth << "x" << mnHeight );
 
                     maSizeCondition.set();
                 }
@@ -562,7 +569,6 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
             maSizeCondition.set();
         }
     } else if( GST_MESSAGE_TYPE( message ) == GST_MESSAGE_ERROR ) {
-        DBG( "Error !\n" );
         if( mnWidth == 0 ) {
             // an error occurred, set condition so that OOo thread doesn't wait for us
             maSizeCondition.set();
@@ -574,41 +580,48 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
 
 void Player::preparePlaybin( const OUString& rURL, GstElement *pSink )
 {
-        GstBus *pBus;
+#if defined(ENABLE_GTKSINK)
+    if (mpGtkWidget)
+    {
+        gtk_widget_destroy(mpGtkWidget);
+        mpGtkWidget = nullptr;
+    }
+#endif
 
-        if( mpPlaybin != nullptr ) {
-            gst_element_set_state( mpPlaybin, GST_STATE_NULL );
-            mbPlayPending = false;
-            g_object_unref( mpPlaybin );
-        }
+    if (mpPlaybin != nullptr)
+    {
+        gst_element_set_state( mpPlaybin, GST_STATE_NULL );
+        mbPlayPending = false;
+        g_object_unref( mpPlaybin );
+    }
 
-        mpPlaybin = gst_element_factory_make( "playbin", nullptr );
-        if( pSink != nullptr ) // used for getting preferred size etc.
-        {
-            g_object_set( G_OBJECT( mpPlaybin ), "video-sink", pSink, NULL );
-            mbFakeVideo = true;
-        }
-        else
-            mbFakeVideo = false;
+    mpPlaybin = gst_element_factory_make( "playbin", nullptr );
+    if( pSink != nullptr ) // used for getting preferred size etc.
+    {
+        g_object_set( G_OBJECT( mpPlaybin ), "video-sink", pSink, nullptr );
+        mbFakeVideo = true;
+    }
+    else
+        mbFakeVideo = false;
 
-        OString ascURL = OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 );
-        g_object_set( G_OBJECT( mpPlaybin ), "uri", ascURL.getStr() , NULL );
+    OString ascURL = OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 );
+    g_object_set( G_OBJECT( mpPlaybin ), "uri", ascURL.getStr() , nullptr );
 
-        pBus = gst_element_get_bus( mpPlaybin );
-        if (mbWatchID)
-        {
-            g_source_remove(mnWatchID);
-            mbWatchID = false;
-        }
-        mnWatchID = gst_bus_add_watch( pBus, pipeline_bus_callback, this );
-        mbWatchID = true;
-        DBG( "%p set sync handler", this );
+    GstBus *pBus = gst_element_get_bus( mpPlaybin );
+    if (mbWatchID)
+    {
+        g_source_remove(mnWatchID);
+        mbWatchID = false;
+    }
+    mnWatchID = gst_bus_add_watch( pBus, pipeline_bus_callback, this );
+    mbWatchID = true;
+    SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " set sync handler" );
 #ifdef AVMEDIA_GST_0_10
-        gst_bus_set_sync_handler( pBus, pipeline_bus_sync_handler, this );
+    gst_bus_set_sync_handler( pBus, pipeline_bus_sync_handler, this );
 #else
-        gst_bus_set_sync_handler( pBus, pipeline_bus_sync_handler, this, nullptr );
+    gst_bus_set_sync_handler( pBus, pipeline_bus_sync_handler, this, nullptr );
 #endif
-        g_object_unref( pBus );
+    g_object_unref( pBus );
 }
 
 bool Player::create( const OUString& rURL )
@@ -617,7 +630,7 @@ bool Player::create( const OUString& rURL )
 
     // create all the elements and link them
 
-    DBG("create player, URL: %s", OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 ).getStr());
+    SAL_INFO( "avmedia.gstreamer", "create player, URL: '" << rURL << "'" );
 
     if( mbInitialized && !rURL.isEmpty() )
     {
@@ -665,7 +678,7 @@ void SAL_CALL Player::stop()
         gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
 
     mbPlayPending = false;
-    DBG( "stop %p", mpPlaybin );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION "stop " << mpPlaybin );
 }
 
 
@@ -683,7 +696,7 @@ sal_Bool SAL_CALL Player::isPlaying()
         bRet = GST_STATE_PLAYING == GST_STATE( mpPlaybin );
     }
 
-    DBG( "isPlaying %d", bRet );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION "isPlaying " << bRet );
 
     return bRet;
 }
@@ -723,7 +736,7 @@ void SAL_CALL Player::setMediaTime( double fTime )
         if( !isPlaying() )
             gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
 
-        DBG( "seek to: %" SAL_PRIdINT64 " ns original: %lf s", gst_position, fTime );
+        SAL_INFO( "avmedia.gstreamer", AVVERSION "seek to: " << gst_position << " ns original: " << fTime << " s" );
     }
 }
 
@@ -771,7 +784,7 @@ void SAL_CALL Player::setMute( sal_Bool bSet )
 {
     ::osl::MutexGuard aGuard(m_aMutex);
 
-    DBG( "set mute: %d muted: %d unmuted volume: %lf", bSet, mbMuted, mnUnmutedVolume );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION "set mute: " << bSet << " muted: " << mbMuted << " unmuted volume: " << mnUnmutedVolume );
 
     // change the volume to 0 or the unmuted volume
     if(  mpPlaybin && mbMuted != bool(bSet) )
@@ -782,7 +795,7 @@ void SAL_CALL Player::setMute( sal_Bool bSet )
             nVolume = 0.0;
         }
 
-        g_object_set( G_OBJECT( mpPlaybin ), "volume", nVolume, NULL );
+        g_object_set( G_OBJECT( mpPlaybin ), "volume", nVolume, nullptr );
 
         mbMuted = bSet;
     }
@@ -807,12 +820,12 @@ void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB )
 
     mnUnmutedVolume = pow( 10.0, nVolumeDB / 20.0 );
 
-    DBG( "set volume: %d gst volume: %lf", nVolumeDB, mnUnmutedVolume );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION "set volume: " << nVolumeDB << " gst volume: " << mnUnmutedVolume );
 
     // change volume
      if( !mbMuted && mpPlaybin )
      {
-         g_object_set( G_OBJECT( mpPlaybin ), "volume", (gdouble) mnUnmutedVolume, NULL );
+         g_object_set( G_OBJECT( mpPlaybin ), "volume", (gdouble) mnUnmutedVolume, nullptr );
      }
 }
 
@@ -828,7 +841,7 @@ sal_Int16 SAL_CALL Player::getVolumeDB()
     if( mpPlaybin ) {
         double nGstVolume = 0.0;
 
-        g_object_get( G_OBJECT( mpPlaybin ), "volume", &nGstVolume, NULL );
+        g_object_get( G_OBJECT( mpPlaybin ), "volume", &nGstVolume, nullptr );
 
         nVolumeDB = (sal_Int16) ( 20.0*log10 ( nGstVolume ) );
     }
@@ -847,18 +860,15 @@ awt::Size SAL_CALL Player::getPreferredPlayerWindowSize()
 
     if( maURL.isEmpty() )
     {
-        DBG( "%p Player::getPreferredPlayerWindowSize - empty URL => 0x0", this );
+        SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " Player::getPreferredPlayerWindowSize - empty URL => 0x0" );
         return aSize;
     }
 
-    DBG( "%p pre-Player::getPreferredPlayerWindowSize, member %d x %d", this, mnWidth, mnHeight );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " pre-Player::getPreferredPlayerWindowSize, member " << mnWidth << "x" << mnHeight );
 
-#if OSL_DEBUG_LEVEL > 2
-    osl::Condition::Result aResult =
-#endif
-                                 maSizeCondition.wait( std::chrono::seconds(10) );
+    osl::Condition::Result aResult = maSizeCondition.wait( std::chrono::seconds(10) );
 
-    DBG( "%p Player::getPreferredPlayerWindowSize after waitCondition %d, member %d x %d", this, aResult, mnWidth, mnHeight );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " Player::getPreferredPlayerWindowSize after waitCondition " << aResult << ", member " << mnWidth << "x" << mnHeight );
 
     if( mnWidth != 0 && mnHeight != 0 ) {
         aSize.Width = mnWidth;
@@ -881,7 +891,7 @@ uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( co
     if( mbFakeVideo )
         preparePlaybin( maURL, nullptr );
 
-    DBG( "Player::createPlayerWindow %d %d length: %d", aSize.Width, aSize.Height, rArguments.getLength() );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION << "Player::createPlayerWindow " << aSize.Width << "x" << aSize.Height << " length: " << rArguments.getLength() );
 
     if( aSize.Width > 0 && aSize.Height > 0 )
     {
@@ -898,11 +908,31 @@ uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( co
             OSL_ASSERT(pEnvData);
             if (pEnvData)
             {
-                mnWindowID = pEnvData->aWindow;
-                DBG( "set window id to %d XOverlay %p\n", (int)mnWindowID, mpXOverlay);
-                gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
-                if ( mpXOverlay != nullptr )
-                    gst_video_overlay_set_window_handle( mpXOverlay, mnWindowID );
+#if defined(ENABLE_GTKSINK)
+                GstElement *pVideosink = g_strcmp0(pEnvData->pToolkit, "gtk3") == 0 ?
+                                           gst_element_factory_make("gtksink", "gtksink") : nullptr;
+                if (pVideosink)
+                {
+                    mbUseGtkSink = true;
+                    g_object_get(pVideosink, "widget", &mpGtkWidget, nullptr);
+                    GtkWidget *pParent = static_cast<GtkWidget*>(pEnvData->pWidget);
+                    gtk_container_add (GTK_CONTAINER(pParent), mpGtkWidget);
+
+                    g_object_set( G_OBJECT( mpPlaybin ), "video-sink", pVideosink, nullptr);
+                    g_object_set( G_OBJECT( mpPlaybin ), "force-aspect-ratio", FALSE, nullptr);
+
+                    gtk_widget_show_all (pParent);
+                }
+                else
+#endif
+                {
+                    mbUseGtkSink = false;
+                    mnWindowID = pEnvData->aWindow;
+                    SAL_INFO( "avmedia.gstreamer", AVVERSION "set window id to " << (int)mnWindowID << " XOverlay " << mpXOverlay);
+                    gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
+                    if ( mpXOverlay != nullptr )
+                        gst_video_overlay_set_window_handle( mpXOverlay, mnWindowID );
+                }
             }
         }
     }
@@ -910,8 +940,6 @@ uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( co
     return xRet;
 }
 
-
-
 uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber()
     throw (uno::RuntimeException, std::exception)
 {
@@ -921,7 +949,7 @@ uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber()
 
     if( ( aPrefSize.Width > 0 ) && ( aPrefSize.Height > 0 ) )
         pFrameGrabber = FrameGrabber::create( maURL );
-    DBG( "created FrameGrabber %p", pFrameGrabber );
+    SAL_INFO( "avmedia.gstreamer", AVVERSION << "created FrameGrabber " << pFrameGrabber );
 
     return pFrameGrabber;
 }
diff --git a/avmedia/source/gstreamer/gstplayer.hxx b/avmedia/source/gstreamer/gstplayer.hxx
index 52095b0..ffc5133 100644
--- a/avmedia/source/gstreamer/gstplayer.hxx
+++ b/avmedia/source/gstreamer/gstplayer.hxx
@@ -27,6 +27,10 @@
 #include <cppuhelper/compbase.hxx>
 #include <cppuhelper/basemutex.hxx>
 
+#if defined(ENABLE_GTKSINK)
+#    include <gtk/gtk.h>
+#endif
+
 typedef struct _GstVideoOverlay GstVideoOverlay;
 
 namespace avmedia { namespace gstreamer {
@@ -83,6 +87,10 @@ protected:
 
     // Add elements and pipeline here
     GstElement*             mpPlaybin;  // the playbin is also a pipeline
+#if defined(ENABLE_GTKSINK)
+    GtkWidget*              mpGtkWidget;
+#endif
+    bool                    mbUseGtkSink;
     bool                    mbFakeVideo;
 
     gdouble                 mnUnmutedVolume;
diff --git a/include/vcl/sysdata.hxx b/include/vcl/sysdata.hxx
index 5ae9947..02e0c1e 100644
--- a/include/vcl/sysdata.hxx
+++ b/include/vcl/sysdata.hxx
@@ -72,6 +72,7 @@ struct SystemEnvData
     void*               pAppContext;    // the application context in use
     long                aShellWindow;   // the window of the frame's shell
     void*               pShellWidget;   // the frame's shell widget
+    const char*         pToolkit;       // the toolkit in use (gtk2 vs gtk3)
 #endif
 
     SystemEnvData()
@@ -95,6 +96,7 @@ struct SystemEnvData
         , pAppContext(nullptr)
         , aShellWindow(0)
         , pShellWidget(nullptr)
+        , pToolkit(nullptr)
 #endif
     {
     }
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index a9fe72f..da80ab6 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -581,7 +581,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/unx/generic/plugadapt/salplug \
     vcl/unx/generic/printer/jobdata \
     vcl/unx/generic/printer/ppdparser \
-    vcl/unx/generic/gdi/x11windowprovider \
+    vcl/unx/generic/gdi/nativewindowhandleprovider \
     vcl/unx/generic/window/screensaverinhibitor \
     $(if $(filter TRUE,$(ENABLE_CUPS)),\
         vcl/unx/generic/printer/cupsmgr \
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index da629b7..20a1e84 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -33,7 +33,7 @@
 
 #include <salframe.hxx>
 #include <vcl/sysdata.hxx>
-#include <unx/x11windowprovider.hxx>
+#include <unx/nativewindowhandleprovider.hxx>
 #include <unx/saltype.h>
 #include <unx/screensaverinhibitor.hxx>
 
@@ -66,7 +66,8 @@ class GtkDnDTransferable;
     typedef void GDBusConnection;
 #endif
 
-class GtkSalFrame : public SalFrame, public X11WindowProvider
+class GtkSalFrame : public SalFrame
+                  , public NativeWindowHandleProvider
 {
     struct IMHandler
     {
@@ -518,7 +519,8 @@ public:
 
     static GtkSalFrame         *getFromWindow( GtkWindow *pWindow );
 
-    virtual Window              GetX11Window() override;
+    sal_uIntPtr                 GetNativeWindowHandle(GtkWidget *pWidget);
+    virtual sal_uIntPtr         GetNativeWindowHandle() override;
 
     static void                 KeyCodeToGdkKey(const vcl::KeyCode& rKeyCode,
         guint* pGdkKeyCode, GdkModifierType *pGdkModifiers);
diff --git a/vcl/inc/unx/x11windowprovider.hxx b/vcl/inc/unx/nativewindowhandleprovider.hxx
similarity index 63%
rename from vcl/inc/unx/x11windowprovider.hxx
rename to vcl/inc/unx/nativewindowhandleprovider.hxx
index 776c8e4..1d85cb4 100644
--- a/vcl/inc/unx/x11windowprovider.hxx
+++ b/vcl/inc/unx/nativewindowhandleprovider.hxx
@@ -7,20 +7,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#ifndef INCLUDED_VCL_UNX_X11WINDOWPROVIDER
-#define INCLUDED_VCL_UNX_X11WINDOWPROVIDER
-
-#include <prex.h>
-#include <postx.h>
+#ifndef INCLUDED_VCL_UNX_NATIVEWINDOWHANDLEPROVIDER
+#define INCLUDED_VCL_UNX_NATIVEWINDOWHANDLEPROVIDER
 
 #include <vcl/dllapi.h>
 
-class VCL_PLUGIN_PUBLIC X11WindowProvider
+class VCL_PLUGIN_PUBLIC NativeWindowHandleProvider
 {
 public:
-    virtual ~X11WindowProvider();
+    virtual ~NativeWindowHandleProvider();
 
-    virtual Window GetX11Window() = 0;
+    virtual sal_uIntPtr GetNativeWindowHandle() = 0;
 };
 
 #endif
diff --git a/vcl/inc/unx/salframe.h b/vcl/inc/unx/salframe.h
index 9ba1957..9848e1e 100644
--- a/vcl/inc/unx/salframe.h
+++ b/vcl/inc/unx/salframe.h
@@ -27,7 +27,7 @@
 #include <unx/saltype.h>
 #include <unx/saldisp.hxx>
 #include <unx/screensaverinhibitor.hxx>
-#include <unx/x11windowprovider.hxx>
+#include <unx/nativewindowhandleprovider.hxx>
 #include <salframe.hxx>
 #include <salwtype.hxx>
 #include <salinst.hxx>
@@ -50,7 +50,7 @@ namespace vcl_sal { class WMAdaptor; class NetWMAdaptor; class GnomeWMAdaptor; }
 #define SHOWSTATE_NORMAL        1
 #define SHOWSTATE_HIDDEN        2
 
-class VCLPLUG_GEN_PUBLIC X11SalFrame : public SalFrame, public X11WindowProvider
+class VCLPLUG_GEN_PUBLIC X11SalFrame : public SalFrame, public NativeWindowHandleProvider
 {
     friend class vcl_sal::WMAdaptor;
     friend class vcl_sal::NetWMAdaptor;
@@ -261,7 +261,7 @@ public:
     // done setting up the clipregion
     virtual void                    EndSetClipRegion() override;
 
-    virtual Window GetX11Window() override;
+    virtual sal_uIntPtr         GetNativeWindowHandle() override;
 
     /// @internal
     void setPendingSizeEvent();
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index b1bc724..fc49e25 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -47,12 +47,12 @@ void X11OpenGLSalGraphicsImpl::Init()
 
 rtl::Reference<OpenGLContext> X11OpenGLSalGraphicsImpl::CreateWinContext()
 {
-    X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
+    NativeWindowHandleProvider *pProvider = dynamic_cast<NativeWindowHandleProvider*>(mrParent.m_pFrame);
 
     if( !pProvider )
         return nullptr;
 
-    Window aWin = pProvider->GetX11Window();
+    sal_uIntPtr aWin = pProvider->GetNativeWindowHandle();
     rtl::Reference<OpenGLContext> pContext = OpenGLContext::Create();
     pContext->setVCLOnly();
     pContext->init( mrParent.GetXDisplay(), aWin,
diff --git a/vcl/unx/generic/app/saldata.cxx b/vcl/unx/generic/app/saldata.cxx
index 3f9d184..92f4679 100644
--- a/vcl/unx/generic/app/saldata.cxx
+++ b/vcl/unx/generic/app/saldata.cxx
@@ -48,7 +48,9 @@
 #include "unx/sm.hxx"
 #include "unx/i18n_im.hxx"
 #include "unx/i18n_xkb.hxx"
-#include "unx/x11/x11display.hxx"
+#include <prex.h>
+#include <X11/Xproto.h>
+#include <postx.h>
 #include "salinst.hxx"
 
 #include <osl/signal.h>
@@ -374,6 +376,58 @@ SalXLib::~SalXLib()
     close (m_pTimeoutFDS[1]);
 }
 
+static Display *OpenX11Display(OString& rDisplay)
+{
+    /*
+     * open connection to X11 Display
+     * try in this order:
+     *  o  -display command line parameter,
+     *  o  $DISPLAY environment variable
+     *  o  default display
+     */
+
+    Display *pDisp = nullptr;
+
+    // is there a -display command line parameter?
+
+    sal_uInt32 nParams = osl_getCommandArgCount();
+    OUString aParam;
+    for (sal_uInt32 i=0; i<nParams; i++)
+    {
+        osl_getCommandArg(i, &aParam.pData);
+        if ( aParam == "-display" )
+        {
+            osl_getCommandArg(i+1, &aParam.pData);
+            rDisplay = OUStringToOString(
+                   aParam, osl_getThreadTextEncoding());
+
+            if ((pDisp = XOpenDisplay(rDisplay.getStr()))!=nullptr)
+            {
+                /*
+                 * if a -display switch was used, we need
+                 * to set the environment accordingly since
+                 * the clipboard build another connection
+                 * to the xserver using $DISPLAY
+                 */
+                OUString envVar("DISPLAY");
+                osl_setEnvironment(envVar.pData, aParam.pData);
+            }
+            break;
+        }
+    }
+
+    if (!pDisp && rDisplay.isEmpty())
+    {
+        // Open $DISPLAY or default...
+        char *pDisplay = getenv("DISPLAY");
+        if (pDisplay != nullptr)
+            rDisplay = OString(pDisplay);
+        pDisp  = XOpenDisplay(pDisplay);
+    }
+
+    return pDisp;
+}
+
 void SalXLib::Init()
 {
     SalI18N_InputMethod* pInputMethod = new SalI18N_InputMethod;
diff --git a/vcl/inc/unx/x11/x11display.hxx b/vcl/unx/generic/gdi/nativewindowhandleprovider.cxx
similarity index 55%
rename from vcl/inc/unx/x11/x11display.hxx
rename to vcl/unx/generic/gdi/nativewindowhandleprovider.cxx
index 9cb2ea5..3afd26e 100644
--- a/vcl/inc/unx/x11/x11display.hxx
+++ b/vcl/unx/generic/gdi/nativewindowhandleprovider.cxx
@@ -7,19 +7,11 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#ifndef INCLUDED_VCL_INC_UNX_X11_X11DISPLAY_HXX
-#define INCLUDED_VCL_INC_UNX_X11_X11DISPLAY_HXX
+#include "unx/nativewindowhandleprovider.hxx"
 
-#include <prex.h>
-#include <X11/Xproto.h>
-#include <postx.h>
+NativeWindowHandleProvider::~NativeWindowHandleProvider()
+{
+}
 
-#include <rtl/string.hxx>
-
-#include <vcl/dllapi.h>
-
-VCL_DLLPUBLIC Display* OpenX11Display(OString& rDisplay);
-
-#endif // INCLUDED_VCL_INC_UNX_X11_X11DISPLAY_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 738d59b..f5ffead 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -53,7 +53,7 @@
 #include <unx/x11/xlimits.hxx>
 
 #include "salgdiimpl.hxx"
-#include "unx/x11windowprovider.hxx"
+#include "unx/nativewindowhandleprovider.hxx"
 #include "textrender.hxx"
 #include "gdiimpl.hxx"
 #include "opengl/x11/gdiimpl.hxx"
diff --git a/vcl/unx/generic/gdi/x11windowprovider.cxx b/vcl/unx/generic/gdi/x11windowprovider.cxx
deleted file mode 100644
index 5f7d289..0000000
--- a/vcl/unx/generic/gdi/x11windowprovider.cxx
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#include <vcl/svapp.hxx>
-
-#include "unx/x11windowprovider.hxx"
-#include "unx/x11/x11display.hxx"
-
-X11WindowProvider::~X11WindowProvider()
-{
-}
-
-Display *OpenX11Display(OString& rDisplay)
-{
-    /*
-     * open connection to X11 Display
-     * try in this order:
-     *  o  -display command line parameter,
-     *  o  $DISPLAY environment variable
-     *  o  default display
-     */
-
-    Display *pDisp = nullptr;
-
-    // is there a -display command line parameter?
-
-    sal_uInt32 nParams = osl_getCommandArgCount();
-    OUString aParam;
-    for (sal_uInt32 i=0; i<nParams; i++)
-    {
-        osl_getCommandArg(i, &aParam.pData);
-        if ( aParam == "-display" )
-        {
-            osl_getCommandArg(i+1, &aParam.pData);
-            rDisplay = OUStringToOString(
-                   aParam, osl_getThreadTextEncoding());
-
-            if ((pDisp = XOpenDisplay(rDisplay.getStr()))!=nullptr)
-            {
-                /*
-                 * if a -display switch was used, we need
-                 * to set the environment accoringly since
-                 * the clipboard build another connection
-                 * to the xserver using $DISPLAY
-                 */
-                OUString envVar("DISPLAY");
-                osl_setEnvironment(envVar.pData, aParam.pData);
-            }
-            break;
-        }
-    }
-
-    if (!pDisp && rDisplay.isEmpty())
-    {
-        // Open $DISPLAY or default...
-        char *pDisplay = getenv("DISPLAY");
-        if (pDisplay != nullptr)
-            rDisplay = OString(pDisplay);
-        pDisp  = XOpenDisplay(pDisplay);
-    }
-
-    return pDisp;
-}
-
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index c0e3e75..63f7c9d 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -4133,7 +4133,7 @@ void X11SalFrame::EndSetClipRegion()
 
 }
 
-Window X11SalFrame::GetX11Window()
+sal_uIntPtr X11SalFrame::GetNativeWindowHandle()
 {
     return mhWindow;
 }
diff --git a/vcl/unx/gtk/gtkobject.cxx b/vcl/unx/gtk/gtkobject.cxx
index 35084aa..18aa63a 100644
--- a/vcl/unx/gtk/gtkobject.cxx
+++ b/vcl/unx/gtk/gtkobject.cxx
@@ -51,7 +51,6 @@ GtkSalObject::GtkSalObject( GtkSalFrame* pParent, bool bShow )
 
         // system data
         m_aSystemData.nSize         = sizeof( SystemEnvData );
-#if !GTK_CHECK_VERSION(3,0,0)
         SalDisplay* pDisp = vcl_sal::getSalDisplay(GetGenericData());
         m_aSystemData.pDisplay      = pDisp->GetDisplay();
         m_aSystemData.pVisual       = pDisp->GetVisual(pParent->getXScreenNumber()).GetVisual();
@@ -59,17 +58,12 @@ GtkSalObject::GtkSalObject( GtkSalFrame* pParent, bool bShow )
         m_aSystemData.aColormap     = pDisp->GetColormap(pParent->getXScreenNumber()).GetXColormap();
         m_aSystemData.aWindow       = GDK_WINDOW_XWINDOW(widget_get_window(m_pSocket));
         m_aSystemData.aShellWindow  = GDK_WINDOW_XWINDOW(widget_get_window(GTK_WIDGET(pParent->getWindow())));
-#else
-        static int nWindow = 0;
-        m_aSystemData.aWindow       = nWindow;
-        ++nWindow;
-        m_aSystemData.aShellWindow  = reinterpret_cast<long>(this);
-#endif
         m_aSystemData.pSalFrame     = nullptr;
         m_aSystemData.pWidget       = m_pSocket;
         m_aSystemData.nScreen       = pParent->getXScreenNumber().getXScreen();
         m_aSystemData.pAppContext   = nullptr;
         m_aSystemData.pShellWidget  = GTK_WIDGET(pParent->getWindow());
+        m_aSystemData.pToolkit      = "gtk2";
 
         g_signal_connect( G_OBJECT(m_pSocket), "button-press-event", G_CALLBACK(signalButton), this );
         g_signal_connect( G_OBJECT(m_pSocket), "button-release-event", G_CALLBACK(signalButton), this );
@@ -86,11 +80,7 @@ GtkSalObject::~GtkSalObject()
 {
     if( m_pRegion )
     {
-#if GTK_CHECK_VERSION(3,0,0)
-        cairo_region_destroy( m_pRegion );
-#else
         gdk_region_destroy( m_pRegion );
-#endif
     }
     if( m_pSocket )
     {
@@ -119,15 +109,9 @@ sal_uInt16 GtkSalObject::GetClipRegionType()
 
 void GtkSalObject::BeginSetClipRegion( sal_uLong )
 {
-#if GTK_CHECK_VERSION(3,0,0)
-    if( m_pRegion )
-        cairo_region_destroy( m_pRegion );
-    m_pRegion = cairo_region_create();
-#else
     if( m_pRegion )
         gdk_region_destroy( m_pRegion );
     m_pRegion = gdk_region_new();
-#endif
 }
 
 void GtkSalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
@@ -138,11 +122,7 @@ void GtkSalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight
     aRect.width     = nWidth;
     aRect.height    = nHeight;
 
-#if GTK_CHECK_VERSION(3,0,0)
-    cairo_region_union_rectangle( m_pRegion, &aRect );
-#else
     gdk_region_union_with_rect( m_pRegion, &aRect );
-#endif
 }
 
 void GtkSalObject::EndSetClipRegion()
diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx
index 3b6caa6..7a7c293 100644
--- a/vcl/unx/gtk/gtksalframe.cxx
+++ b/vcl/unx/gtk/gtksalframe.cxx
@@ -1022,6 +1022,7 @@ void GtkSalFrame::InitCommon()
     m_aSystemData.nScreen       = m_nXScreen.getXScreen();
     m_aSystemData.pAppContext   = nullptr;
     m_aSystemData.pShellWidget  = m_aSystemData.pWidget;
+    m_aSystemData.pToolkit      = "gtk2";
 
     m_bGraphics = false;
     m_pGraphics = NULL;
@@ -3929,7 +3930,7 @@ Size GtkSalDisplay::GetScreenSize( int nDisplayScreen )
     return Size( aRect.GetWidth(), aRect.GetHeight() );
 }
 
-Window GtkSalFrame::GetX11Window()
+sal_uIntPtr GtkSalFrame::GetNativeWindowHandle()
 {
     return widget_get_xid(m_pWindow);
 }
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index 70e0c9b..f3bdfb2 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -48,7 +48,12 @@
 #include <gtk/gtk.h>
 #include <prex.h>
 #include <X11/Xatom.h>
-#include <gdk/gdkx.h>
+#if defined(GDK_WINDOWING_X11)
+#   include <gdk/gdkx.h>
+#endif
+#if defined(GDK_WINDOWING_WAYLAND)
+#   include <gdk/gdkwayland.h>
+#endif
 #include <postx.h>
 
 #include <dlfcn.h>
@@ -1085,15 +1090,14 @@ void GtkSalFrame::InitCommon()
 
     //system data
     m_aSystemData.nSize         = sizeof( SystemEnvData );
-    static int nWindow = 0;
-    m_aSystemData.aWindow       = nWindow;
-    ++nWindow;
+    m_aSystemData.aWindow       = GetNativeWindowHandle(m_pWindow);
     m_aSystemData.aShellWindow  = reinterpret_cast<long>(this);
     m_aSystemData.pSalFrame     = this;
     m_aSystemData.pWidget       = m_pWindow;
     m_aSystemData.nScreen       = m_nXScreen.getXScreen();
     m_aSystemData.pAppContext   = nullptr;
     m_aSystemData.pShellWidget  = m_aSystemData.pWidget;
+    m_aSystemData.pToolkit      = "gtk3";
 
     m_bGraphics = false;
     m_pGraphics = nullptr;
@@ -3926,9 +3930,30 @@ Size GtkSalDisplay::GetScreenSize( int nDisplayScreen )
     return Size( aRect.GetWidth(), aRect.GetHeight() );
 }
 
-Window GtkSalFrame::GetX11Window()
+sal_uIntPtr GtkSalFrame::GetNativeWindowHandle(GtkWidget *pWidget)
+{
+    (void) this;                // Silence loplugin:staticmethods
+    GdkDisplay *pDisplay = getGdkDisplay();
+    GdkWindow *pWindow = gtk_widget_get_window(pWidget);
+
+#if defined(GDK_WINDOWING_X11)
+    if (GDK_IS_X11_DISPLAY(pDisplay))
+    {
+        return GDK_WINDOW_XID(pWindow);
+    }
+#endif
+#if defined(GDK_WINDOWING_WAYLAND)
+    if (GDK_IS_WAYLAND_DISPLAY(pDisplay))
+    {
+        return reinterpret_cast<sal_uIntPtr>(gdk_wayland_window_get_wl_surface(pWindow));
+    }
+#endif
+    return 0;
+}
+
+sal_uIntPtr GtkSalFrame::GetNativeWindowHandle()
 {
-    return widget_get_xid(m_pWindow);
+    return GetNativeWindowHandle(m_pWindow);
 }
 
 void GtkDragSource::startDrag(const datatransfer::dnd::DragGestureEvent& rEvent,
diff --git a/vcl/unx/gtk3/gtk3gtkobject.cxx b/vcl/unx/gtk3/gtk3gtkobject.cxx
index 96c1527..8f1c032 100644
--- a/vcl/unx/gtk3/gtk3gtkobject.cxx
+++ b/vcl/unx/gtk3/gtk3gtkobject.cxx
@@ -5,8 +5,186 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include "../gtk/gtkobject.cxx"
+#ifdef AIX
+#define _LINUX_SOURCE_COMPAT
+#include <sys/timer.h>
+#undef _LINUX_SOURCE_COMPAT
+#endif
+
+#include <unx/gtk/gtkobject.hxx>
+#include <unx/gtk/gtkframe.hxx>
+#include <unx/gtk/gtkdata.hxx>
+#include <unx/gtk/gtkinst.hxx>
+#include <unx/gtk/gtkgdi.hxx>
+
+GtkSalObject::GtkSalObject( GtkSalFrame* pParent, bool bShow )
+        : m_pSocket( nullptr ),
+          m_pRegion( nullptr )
+{
+    if( pParent )
+    {
+        // our plug window
+        m_pSocket = gtk_grid_new();
+        Show( bShow );
+        // insert into container
+        gtk_fixed_put( pParent->getFixedContainer(),
+                       m_pSocket,
+                       0, 0 );
+        // realize so we can get a window id
+        gtk_widget_realize( m_pSocket );
+
+        // system data
+        m_aSystemData.nSize         = sizeof( SystemEnvData );
+        m_aSystemData.aWindow       = pParent->GetNativeWindowHandle(m_pSocket);
+        m_aSystemData.aShellWindow  = reinterpret_cast<long>(this);
+        m_aSystemData.pSalFrame     = nullptr;
+        m_aSystemData.pWidget       = m_pSocket;
+        m_aSystemData.nScreen       = pParent->getXScreenNumber().getXScreen();
+        m_aSystemData.pAppContext   = nullptr;
+        m_aSystemData.pShellWidget  = GTK_WIDGET(pParent->getWindow());
+        m_aSystemData.pToolkit      = "gtk3";
+
+        g_signal_connect( G_OBJECT(m_pSocket), "button-press-event", G_CALLBACK(signalButton), this );
+        g_signal_connect( G_OBJECT(m_pSocket), "button-release-event", G_CALLBACK(signalButton), this );
+        g_signal_connect( G_OBJECT(m_pSocket), "focus-in-event", G_CALLBACK(signalFocus), this );
+        g_signal_connect( G_OBJECT(m_pSocket), "focus-out-event", G_CALLBACK(signalFocus), this );
+        g_signal_connect( G_OBJECT(m_pSocket), "destroy", G_CALLBACK(signalDestroy), this );
+
+        // #i59255# necessary due to sync effects with java child windows
+        pParent->Flush();
+    }
+}
+
+GtkSalObject::~GtkSalObject()
+{
+    if( m_pRegion )
+    {
+        cairo_region_destroy( m_pRegion );
+    }
+    if( m_pSocket )
+    {
+        // remove socket from parent frame's fixed container
+        gtk_container_remove( GTK_CONTAINER(gtk_widget_get_parent(m_pSocket)),
+                              m_pSocket );
+        // get rid of the socket
+        // actually the gtk_container_remove should let the ref count
+        // of the socket sink to 0 and destroy it (see signalDestroy)
+        // this is just a sanity check
+        if( m_pSocket )
+            gtk_widget_destroy( m_pSocket );
+    }
+}
+
+void GtkSalObject::ResetClipRegion()
+{
+    if( m_pSocket )
+        gdk_window_shape_combine_region( widget_get_window(m_pSocket), nullptr, 0, 0 );
+}
+
+sal_uInt16 GtkSalObject::GetClipRegionType()
+{
+    return SAL_OBJECT_CLIP_INCLUDERECTS;
+}
+
+void GtkSalObject::BeginSetClipRegion( sal_uLong )
+{
+    if( m_pRegion )
+        cairo_region_destroy( m_pRegion );
+    m_pRegion = cairo_region_create();
+}
+
+void GtkSalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+    GdkRectangle aRect;
+    aRect.x         = nX;
+    aRect.y         = nY;
+    aRect.width     = nWidth;
+    aRect.height    = nHeight;
+
+    cairo_region_union_rectangle( m_pRegion, &aRect );
+}
+
+void GtkSalObject::EndSetClipRegion()
+{
+    if( m_pSocket )
+        gdk_window_shape_combine_region( widget_get_window(m_pSocket), m_pRegion, 0, 0 );
+}
+
+void GtkSalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
+{
+    if( m_pSocket )
+    {
+        GtkFixed* pContainer = GTK_FIXED(gtk_widget_get_parent(m_pSocket));
+        gtk_fixed_move( pContainer, m_pSocket, nX, nY );
+        gtk_widget_set_size_request( m_pSocket, nWidth, nHeight );
+        gtk_container_resize_children( GTK_CONTAINER(pContainer) );
+    }
+}
+
+void GtkSalObject::Show( bool bVisible )
+{
+    if( m_pSocket )
+    {
+        if( bVisible )
+            gtk_widget_show( m_pSocket );
+        else
+            gtk_widget_hide( m_pSocket );
+    }
+}
+
+const SystemEnvData* GtkSalObject::GetSystemData() const
+{
+    return &m_aSystemData;
+}
+
+gboolean GtkSalObject::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer object )
+{
+    GtkSalObject* pThis = static_cast<GtkSalObject*>(object);
+
+    if( pEvent->type == GDK_BUTTON_PRESS )
+    {
+        pThis->CallCallback( SALOBJ_EVENT_TOTOP, nullptr );
+    }
+
+    return FALSE;
+}
+
+gboolean GtkSalObject::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer object )
+{
+    GtkSalObject* pThis = static_cast<GtkSalObject*>(object);
+
+    pThis->CallCallback( pEvent->in ? SALOBJ_EVENT_GETFOCUS : SALOBJ_EVENT_LOSEFOCUS, nullptr );
+
+    return FALSE;
+}
+
+void GtkSalObject::signalDestroy( GtkWidget* pObj, gpointer object )
+{
+    GtkSalObject* pThis = static_cast<GtkSalObject*>(object);
+    if( pObj == pThis->m_pSocket )
+    {
+        pThis->m_pSocket = nullptr;
+    }
+}
+
+void GtkSalObject::SetForwardKey( bool bEnable )
+{
+    if( bEnable )
+        gtk_widget_add_events( GTK_WIDGET( m_pSocket ), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE );
+    else
+        gtk_widget_set_events( GTK_WIDGET( m_pSocket ), ~(GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE) & gtk_widget_get_events( GTK_WIDGET( m_pSocket ) ) );
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list