[Libreoffice-commits] core.git: Branch 'feature/opengl-vcl' - 2 commits - include/vcl vcl/inc vcl/Library_vclplug_gen.mk vcl/opengl vcl/source vcl/unx

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Sat Nov 8 12:33:34 PST 2014


 include/vcl/opengl/OpenGLHelper.hxx      |    1 
 vcl/Library_vclplug_gen.mk               |    4 
 vcl/inc/opengl/x11/gdiimpl.hxx           |   42 +++++
 vcl/inc/openglgdiimpl.hxx                |   15 +
 vcl/inc/salgdiimpl.hxx                   |    4 
 vcl/inc/unx/gtk/gtkgdi.hxx               |    5 
 vcl/inc/unx/pixmap.hxx                   |   46 ++++++
 vcl/inc/unx/salgdi.h                     |   10 +
 vcl/inc/unx/x11/x11gdiimpl.h             |   27 +++
 vcl/opengl/gdiimpl.cxx                   |   38 ----
 vcl/opengl/textureFragmentShader.glsl    |    2 
 vcl/opengl/x11/gdiimpl.cxx               |  139 ++++++++++++++++++
 vcl/source/opengl/OpenGLHelper.cxx       |   50 ++++++
 vcl/unx/generic/gdi/gdiimpl.cxx          |   61 +++++++-
 vcl/unx/generic/gdi/gdiimpl.hxx          |   16 +-
 vcl/unx/generic/gdi/pixmap.cxx           |   49 ++++++
 vcl/unx/generic/gdi/salgdi.cxx           |   26 ---
 vcl/unx/generic/gdi/salgdi2.cxx          |   15 +
 vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx |  236 +++++++++++++++++--------------
 19 files changed, 595 insertions(+), 191 deletions(-)

New commits:
commit 19ddf5f4148499301f2c94e6aafb9582b1811dfd
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Sat Nov 8 13:14:14 2014 -0500

    vcl: Initial work to have native widgets rendered with OpenGL
    
    Change-Id: I8b244a5bdd12a64a65ca1bab14dfe6917a175ccf

diff --git a/include/vcl/opengl/OpenGLHelper.hxx b/include/vcl/opengl/OpenGLHelper.hxx
index b237fc8..d49f579 100644
--- a/include/vcl/opengl/OpenGLHelper.hxx
+++ b/include/vcl/opengl/OpenGLHelper.hxx
@@ -60,6 +60,7 @@ public:
 
 #if defined UNX && !defined MACOSX && !defined IOS && !defined ANDROID
     static bool GetVisualInfo(Display* pDisplay, int nScreen, XVisualInfo& rVI);
+    static GLXFBConfig GetPixmapFBConfig( Display* pDisplay, bool& bInverted );
 #endif
 };
 
diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index 36e52ee..bec6f4c 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -63,6 +63,8 @@ $(eval $(call gb_Library_add_libs,vclplug_gen,\
 	-lXext \
 	-lSM \
 	-lICE \
+	-lGL \
+	-lGLU \
 ))
 
 $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
@@ -104,6 +106,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
     vcl/unx/generic/window/salobj \
     vcl/unx/x11/x11sys \
     vcl/unx/x11/xlimits \
+	vcl/opengl/x11/gdiimpl \
 ))
 
 # ultimately we want to split the x11 dependencies out
diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx
new file mode 100644
index 0000000..878c7c2
--- /dev/null
+++ b/vcl/inc/opengl/x11/gdiimpl.hxx
@@ -0,0 +1,42 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
+#define INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
+
+#include <vcl/dllapi.h>
+
+#include "unx/salgdi.h"
+#include "unx/x11/x11gdiimpl.h"
+#include "openglgdiimpl.hxx"
+
+class VCL_PLUGIN_PUBLIC X11OpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl, public X11GraphicsImpl
+{
+private:
+    X11SalGraphics&     mrParent;
+
+public:
+    X11OpenGLSalGraphicsImpl( X11SalGraphics& rParent );
+    virtual ~X11OpenGLSalGraphicsImpl();
+
+protected:
+    GLfloat GetWidth() const SAL_OVERRIDE;
+    GLfloat GetHeight() const SAL_OVERRIDE;
+
+public:
+    // implementation of X11GraphicsImpl
+
+    void Init() SAL_OVERRIDE;
+    X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) SAL_OVERRIDE;
+    bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE;
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index ef80d34..b05a520 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -30,7 +30,7 @@ class SalVirtualDevice;
 
 class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
 {
-private:
+protected:
 
     OpenGLContext maContext;
     SalFrame* mpFrame;
@@ -55,9 +55,6 @@ private:
     GLuint mnMaskUniform;
     GLuint mnMaskColorUniform;
 
-    inline GLfloat GetWidth() const;
-    inline GLfloat GetHeight() const;
-
     bool CreateSolidProgram( void );
     bool CreateTextureProgram( void );
     bool CreateMaskedTextureProgram( void );
@@ -81,6 +78,13 @@ private:
     void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const SalTwoRect& rPosAry );
     void DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& rPosAry );
 
+protected:
+    // get the width of the device
+    virtual GLfloat GetWidth() const = 0;
+
+    // get the height of the device
+    virtual GLfloat GetHeight() const = 0;
+
 
 public:
     virtual ~OpenGLSalGraphicsImpl ();
@@ -89,9 +93,6 @@ public:
 
     virtual void freeResources() SAL_OVERRIDE;
 
-    virtual void Init( SalFrame* pFrame ) SAL_OVERRIDE;
-    virtual void Init( SalVirtualDevice* pVDev ) SAL_OVERRIDE;
-
     virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
     //
     // get the depth of the device
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index dc8c580..5d49952 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -44,10 +44,6 @@ public:
 
     virtual ~SalGraphicsImpl();
 
-    virtual void Init( SalFrame* pFrame ) = 0;
-
-    virtual void Init( SalVirtualDevice* pVDev ) = 0;
-
     virtual void freeResources() = 0;
 
     virtual bool setClipRegion( const vcl::Region& ) = 0;
diff --git a/vcl/inc/unx/pixmap.hxx b/vcl/inc/unx/pixmap.hxx
index f8b23c7..40bc11f 100644
--- a/vcl/inc/unx/pixmap.hxx
+++ b/vcl/inc/unx/pixmap.hxx
@@ -12,6 +12,7 @@
 
 #include <prex.h>
 #include <postx.h>
+#include <tools/gen.hxx>
 #include <unx/saltype.h>
 #include <vclpluginapi.h>
 
@@ -27,6 +28,7 @@ public:
     Drawable GetDrawable() const { return mpPixmap; };
     int GetWidth() const { return mnWidth; };
     int GetHeight() const { return mnHeight; };
+    Size GetSize() const { return Size( mnWidth, mnHeight ); };
     int GetDepth() const { return mnDepth; };
     SalX11Screen GetScreen() const { return mnScreen; }
 
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 0fa4c00..c288292 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -45,6 +45,7 @@ class SalFrame;
 class X11Pixmap;
 class X11SalVirtualDevice;
 class X11SalGraphicsImpl;
+class X11OpenGLSalGraphicsImpl;
 class PspSalPrinter;
 class PspSalInfoPrinter;
 class ServerFont;
@@ -63,6 +64,7 @@ class VCLPLUG_GEN_PUBLIC X11SalGraphics : public SalGraphics
 {
     friend class ServerFontLayout;
     friend class X11SalGraphicsImpl;
+    friend class X11OpenGLSalGraphicsImpl;
     friend class X11CairoTextRender;
 
 private:
diff --git a/vcl/inc/unx/x11/x11gdiimpl.h b/vcl/inc/unx/x11/x11gdiimpl.h
new file mode 100644
index 0000000..911ea71
--- /dev/null
+++ b/vcl/inc/unx/x11/x11gdiimpl.h
@@ -0,0 +1,27 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_INC_UNX_X11_X11GDIIMPL_HXX
+#define INCLUDED_VCL_INC_UNX_X11_X11GDIIMPL_HXX
+
+#include "unx/pixmap.hxx"
+
+class X11GraphicsImpl
+{
+public:
+    virtual ~X11GraphicsImpl() {};
+
+    virtual void Init() = 0;
+    virtual X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) = 0;
+    virtual bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) = 0;
+};
+
+#endif // INCLUDED_VCL_INC_UNX_X11_X11GDIIMPL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 835d344..9288260 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -49,16 +49,6 @@ void OpenGLSalGraphicsImpl::freeResources()
     // Delete shaders, programs and textures if not shared
 }
 
-void OpenGLSalGraphicsImpl::Init( SalFrame* pFrame )
-{
-    mpFrame = pFrame;
-}
-
-void OpenGLSalGraphicsImpl::Init(SalVirtualDevice* pVDev)
-{
-    mpVDev = pVDev;
-}
-
 bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
 {
     const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() );
@@ -94,34 +84,6 @@ long OpenGLSalGraphicsImpl::GetGraphicsWidth() const
     return GetWidth();
 }
 
-inline GLfloat OpenGLSalGraphicsImpl::GetWidth() const
-{
-    if( mpFrame )
-        return mpFrame->maGeometry.nWidth;
-    else if (mpVDev)
-    {
-        long nWidth = 0;
-        long nHeight = 0;
-        mpVDev->GetSize(nWidth, nHeight);
-        return nWidth;
-    }
-    return 1;
-}
-
-inline GLfloat OpenGLSalGraphicsImpl::GetHeight() const
-{
-    if( mpFrame )
-        return mpFrame->maGeometry.nHeight;
-    else if (mpVDev)
-    {
-        long nWidth = 0;
-        long nHeight = 0;
-        mpVDev->GetSize(nWidth, nHeight);
-        return nHeight;
-    }
-    return 1;
-}
-
 // set the clip region to empty
 void OpenGLSalGraphicsImpl::ResetClipRegion()
 {
diff --git a/vcl/opengl/textureFragmentShader.glsl b/vcl/opengl/textureFragmentShader.glsl
index 81d68c7..cc95f2f 100644
--- a/vcl/opengl/textureFragmentShader.glsl
+++ b/vcl/opengl/textureFragmentShader.glsl
@@ -12,7 +12,7 @@ varying vec2 tex_coord;
 uniform sampler2D sampler;
 
 void main() {
-   gl_FragColor = texture2D(sampler, tex_coord);
+    gl_FragColor = texture2D(sampler, tex_coord);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
new file mode 100644
index 0000000..11735edb
--- /dev/null
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -0,0 +1,139 @@
+/* -*- 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/salbtype.hxx"
+
+#include "unx/pixmap.hxx"
+#include "unx/saldisp.hxx"
+#include "unx/salframe.h"
+#include "unx/salgdi.h"
+#include "unx/salvd.h"
+
+#include "opengl/x11/gdiimpl.hxx"
+
+#include <vcl/opengl/OpenGLContext.hxx>
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+X11OpenGLSalGraphicsImpl::X11OpenGLSalGraphicsImpl( X11SalGraphics& rParent ):
+    OpenGLSalGraphicsImpl(),
+    mrParent(rParent)
+{
+}
+
+X11OpenGLSalGraphicsImpl::~X11OpenGLSalGraphicsImpl()
+{
+}
+
+GLfloat X11OpenGLSalGraphicsImpl::GetWidth() const
+{
+    if( mrParent.m_pFrame )
+        return mrParent.m_pFrame->maGeometry.nWidth;
+    else if( mrParent.m_pVDev )
+    {
+        long nWidth = 0;
+        long nHeight = 0;
+        mrParent.m_pVDev->GetSize( nWidth, nHeight );
+        return nWidth;
+    }
+    return 1;
+}
+
+GLfloat X11OpenGLSalGraphicsImpl::GetHeight() const
+{
+    if( mrParent.m_pFrame )
+        return mrParent.m_pFrame->maGeometry.nHeight;
+    else if( mrParent.m_pVDev )
+    {
+        long nWidth = 0;
+        long nHeight = 0;
+        mrParent.m_pVDev->GetSize( nWidth, nHeight );
+        return nHeight;
+    }
+    return 1;
+}
+
+void X11OpenGLSalGraphicsImpl::Init()
+{
+    if( mrParent.m_pFrame && dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame) )
+    {
+        Window aWin = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame)->GetX11Window();
+        maContext.init( mrParent.GetXDisplay(), aWin, mrParent.m_nXScreen.getXScreen());
+    }
+    else if( mrParent.m_pVDev )
+    {
+        maContext.init( mrParent.GetXDisplay(), mrParent.m_pVDev->GetDrawable(),
+                        mrParent.m_pVDev->GetWidth(), mrParent.m_pVDev->GetHeight(),
+                        mrParent.m_nXScreen.getXScreen() );
+    }
+    else
+    {
+        SAL_WARN( "vcl.opengl", "what happened here?" );
+    }
+}
+
+X11Pixmap* X11OpenGLSalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect )
+{
+    Display* pDisplay = mrParent.GetXDisplay();
+    SalX11Screen nScreen = mrParent.GetScreenNumber();
+
+    SAL_INFO( "vcl.opengl", "GetPixmapFromScreen" );
+    return new X11Pixmap( pDisplay, nScreen, rRect.GetWidth(), rRect.GetHeight(), 24 );
+}
+
+bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY )
+{
+    const int aAttribs[] = {
+        GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
+        GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
+        None
+    };
+    Display* pDisplay = mrParent.GetXDisplay();
+    GLXFBConfig pFbConfig;
+    GLXPixmap pGlxPixmap;
+    GLuint nTexture;
+    SalTwoRect aPosAry;
+    bool bInverted;
+
+    SAL_INFO( "vcl.opengl", "RenderPixmapToScreen (" << nX << " " << nY << ")" );
+
+    aPosAry.mnSrcX = 0;
+    aPosAry.mnSrcY = 0;
+    aPosAry.mnDestX = nX;
+    aPosAry.mnDestY = nY;
+    aPosAry.mnSrcWidth = aPosAry.mnDestWidth = pPixmap->GetWidth();
+    aPosAry.mnSrcHeight = aPosAry.mnDestHeight = pPixmap->GetHeight();
+
+    XSync( pDisplay, 0 );
+    pFbConfig = OpenGLHelper::GetPixmapFBConfig( pDisplay, bInverted );
+    pGlxPixmap = glXCreatePixmap( pDisplay, pFbConfig, pPixmap->GetPixmap(), aAttribs);
+    XSync( pDisplay, 0 );
+
+    maContext.makeCurrent();
+    glViewport( 0, 0, GetWidth(), GetHeight() );
+
+    glGenTextures( 1, &nTexture );
+    glActiveTexture( GL_TEXTURE0 );
+    glBindTexture( GL_TEXTURE_2D, nTexture );
+
+    //TODO: lfrb: glXGetProc to get the functions
+    glXBindTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT, NULL );
+
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+    DrawTexture( nTexture, pPixmap->GetSize(), aPosAry );
+
+    glXReleaseTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT );
+    glDeleteTextures( 1, &nTexture );
+    glXDestroyPixmap( pDisplay, pGlxPixmap );
+
+    return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index 4705e3f..5823b80 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -387,6 +387,56 @@ bool OpenGLHelper::GetVisualInfo(Display* pDisplay, int nScreen, XVisualInfo& rV
     return true;
 }
 
+GLXFBConfig OpenGLHelper::GetPixmapFBConfig( Display* pDisplay, bool& bInverted )
+{
+    int nScreen = DefaultScreen( pDisplay );
+    GLXFBConfig *aFbConfigs;
+    int i, nFbConfigs, nValue;
+
+    aFbConfigs = glXGetFBConfigs( pDisplay, nScreen, &nFbConfigs );
+    for( i = 0; i < nFbConfigs; i++ )
+    {
+        glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_DRAWABLE_TYPE, &nValue );
+        if( !(nValue & GLX_PIXMAP_BIT) )
+            continue;
+
+        glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &nValue );
+        if( !(nValue & GLX_TEXTURE_2D_BIT_EXT) )
+            continue;
+
+        glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_DEPTH_SIZE, &nValue );
+        if( nValue != 24 )
+            continue;
+
+        glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_RED_SIZE, &nValue );
+        if( nValue != 8 )
+            continue;
+        SAL_INFO( "vcl.opengl", "Red is " << nValue );
+
+        // TODO: lfrb: Make it configurable wrt RGB/RGBA
+        glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_BIND_TO_TEXTURE_RGB_EXT, &nValue );
+        if( nValue == False )
+        {
+            glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_BIND_TO_TEXTURE_RGBA_EXT, &nValue );
+            if( nValue == False )
+                continue;
+        }
+
+        glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_Y_INVERTED_EXT, &nValue );
+        bInverted = (nValue == True) ? true : false;
+
+        break;
+    }
+
+    if( i == nFbConfigs )
+    {
+        SAL_WARN( "vcl.opengl", "Unable to find FBconfig for pixmap texturing" );
+        return 0;
+    }
+
+    return aFbConfigs[i];
+}
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx
index f2ccf90..172ebd6 100644
--- a/vcl/unx/generic/gdi/gdiimpl.cxx
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -153,16 +153,69 @@ X11SalGraphicsImpl::~X11SalGraphicsImpl()
 {
 }
 
-void X11SalGraphicsImpl::Init( SalFrame* /*pFrame*/ )
+void X11SalGraphicsImpl::Init()
 {
     mnPenPixel = mrParent.GetPixel( mnPenColor );
     mnBrushPixel = mrParent.GetPixel( mnBrushColor );
 }
 
-void X11SalGraphicsImpl::Init( SalVirtualDevice* /*pVDev*/ )
+X11Pixmap* X11SalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect )
 {
-    mnPenPixel = mrParent.GetPixel( mnPenColor );
-    mnBrushPixel = mrParent.GetPixel( mnBrushColor );
+    //TODO lfrb: don't hardcode the depth
+    Display* pDpy = mrParent.GetXDisplay();
+    X11Pixmap* pPixmap = new X11Pixmap( pDpy, mrParent.GetScreenNumber(),
+                                        rRect.GetWidth(), rRect.GetHeight(), 24 );
+    GC aTmpGC = XCreateGC( pDpy, pPixmap->GetPixmap(), 0, NULL );
+
+    if( !pPixmap || !aTmpGC )
+    {
+        if ( pPixmap )
+            delete pPixmap;
+        if ( aTmpGC )
+            XFreeGC( pDpy, aTmpGC );
+        SAL_WARN( "vcl", "Could not get valid pixmap from screen" );
+        return NULL;
+    }
+
+    // Copy the background of the screen into a composite pixmap
+    mrParent.CopyScreenArea( mrParent.GetXDisplay(),
+                             mrParent.GetDrawable(), mrParent.GetScreenNumber(),
+                             mrParent.GetVisual().GetDepth(),
+                             pPixmap->GetDrawable(), pPixmap->GetScreen(),
+                             pPixmap->GetDepth(),
+                             aTmpGC,
+                             rRect.Left(), rRect.Top(),
+                             rRect.GetWidth(), rRect.GetHeight(),
+                             0, 0 );
+
+    XFreeGC( pDpy, aTmpGC );
+    return pPixmap;
+}
+
+bool X11SalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY )
+{
+    GC aFontGC = mrParent.GetFontGC();
+
+    // The GC can't be null, otherwise we'd have no clip region
+    if( aFontGC == NULL )
+    {
+        SAL_WARN( "vcl", "no valid GC to render pixmap" );
+        return false;
+    }
+
+    if( !pPixmap )
+        return false;
+
+    mrParent.CopyScreenArea( mrParent.GetXDisplay(),
+                             pPixmap->GetDrawable(), pPixmap->GetScreen(),
+                             pPixmap->GetDepth(),
+                             mrParent.GetDrawable(), mrParent.m_nXScreen,
+                             mrParent.GetVisual().GetDepth(),
+                             aFontGC,
+                             0, 0,
+                             pPixmap->GetWidth(), pPixmap->GetHeight(),
+                             nX, nY );
+    return true;
 }
 
 XID X11SalGraphicsImpl::GetXRenderPicture()
diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx
index 799e05c..252fe35 100644
--- a/vcl/unx/generic/gdi/gdiimpl.hxx
+++ b/vcl/unx/generic/gdi/gdiimpl.hxx
@@ -24,6 +24,7 @@
 #include <postx.h>
 
 #include "unx/saltype.h"
+#include "unx/x11/x11gdiimpl.h"
 
 #include "salgdiimpl.hxx"
 
@@ -35,10 +36,8 @@ class SalPolyLine;
 class X11SalGraphics;
 class Gradient;
 
-class X11SalGraphicsImpl : public SalGraphicsImpl
+class X11SalGraphicsImpl : public SalGraphicsImpl, public X11GraphicsImpl
 {
-    friend X11SalGraphics;
-
 private:
     X11SalGraphics& mrParent;
 
@@ -108,10 +107,6 @@ public:
 
     virtual ~X11SalGraphicsImpl();
 
-    virtual void Init( SalFrame* pFrame ) SAL_OVERRIDE;
-
-    virtual void Init( SalVirtualDevice* pVDev ) SAL_OVERRIDE;
-
     virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
     //
     // get the depth of the device
@@ -269,6 +264,13 @@ public:
     virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) SAL_OVERRIDE;
 
     virtual bool swapBuffers() SAL_OVERRIDE { return false; }
+
+public:
+    // implementation of X11GraphicsImpl
+
+    void Init() SAL_OVERRIDE;
+    X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) SAL_OVERRIDE;
+    bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE;
 };
 
 #endif
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 0607cac..b4df486 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -48,13 +48,14 @@
 #include "unx/salgdi.h"
 #include "unx/salframe.h"
 #include "unx/salvd.h"
+#include "unx/x11/x11gdiimpl.h"
 #include <unx/x11/xlimits.hxx>
 
 #include "salgdiimpl.hxx"
 #include "unx/x11windowprovider.hxx"
 #include "textrender.hxx"
 #include "gdiimpl.hxx"
-#include "openglgdiimpl.hxx"
+#include "opengl/x11/gdiimpl.hxx"
 #include "x11cairotextrender.hxx"
 
 #include "generic/printergfx.hxx"
@@ -86,7 +87,7 @@ X11SalGraphics::X11SalGraphics():
     static bool bOpenGLPossible = OpenGLHelper::supportsVCLOpenGL();
     bool bUseOpenGL = bOpenGLPossible ? officecfg::Office::Common::VCL::UseOpenGL::get() : false;
     if (bUseOpenGL)
-        mpImpl.reset(new OpenGLSalGraphicsImpl());
+        mpImpl.reset(new X11OpenGLSalGraphicsImpl(*this));
     else
         mpImpl.reset(new X11SalGraphicsImpl(*this));
 
@@ -142,26 +143,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
 
     if( hDrawable_ )
     {
-        OpenGLSalGraphicsImpl* pOpenGLImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get());
-        if (pOpenGLImpl)
-        {
-            if (m_pFrame && dynamic_cast<X11WindowProvider*>(m_pFrame))
-            {
-                Window aWin = dynamic_cast<X11WindowProvider*>(m_pFrame)->GetX11Window();
-                pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(),
-                        aWin, m_nXScreen.getXScreen());
-                mpImpl->Init( m_pFrame );
-            }
-            else if (m_pVDev)
-            {
-                pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(),
-                        m_pVDev->GetDrawable(), m_pVDev->GetWidth(), m_pVDev->GetHeight(), m_nXScreen.getXScreen());
-                mpImpl->Init(m_pVDev);
-            }
-            else
-                SAL_WARN("vcl.opengl", "what happened here?");
-        }
-
+        dynamic_cast<X11GraphicsImpl*>(mpImpl.get())->Init();
         // TODO: moggi: FIXME nTextPixel_     = GetPixel( nTextColor_ );
     }
 }
diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx
index e4d5b3c..63ab32b 100644
--- a/vcl/unx/generic/gdi/salgdi2.cxx
+++ b/vcl/unx/generic/gdi/salgdi2.cxx
@@ -31,6 +31,7 @@
 #include "unx/salgdi.h"
 #include "unx/salframe.h"
 #include "unx/salvd.h"
+#include "unx/x11/x11gdiimpl.h"
 #include <unx/x11/xlimits.hxx>
 #include "xrender_peer.hxx"
 
@@ -84,59 +85,15 @@ void X11SalGraphics::CopyScreenArea( Display* pDisplay,
 
 X11Pixmap* X11SalGraphics::GetPixmapFromScreen( const Rectangle& rRect )
 {
-    Display* pDpy = GetXDisplay();
-    X11Pixmap* pPixmap = new X11Pixmap( pDpy, GetScreenNumber(), rRect.GetWidth(), rRect.GetHeight(), 24 );
-    GC aTmpGC = XCreateGC( pDpy, pPixmap->GetPixmap(), 0, NULL );
-
-    if( !pPixmap || !aTmpGC )
-    {
-        if ( pPixmap )
-            delete pPixmap;
-        if ( aTmpGC )
-            XFreeGC( pDpy, aTmpGC );
-        SAL_WARN( "vcl", "Could not get valid pixmap from screen" );
-        return NULL;
-    }
-
-    // Copy the background of the screen into a composite pixmap
-    CopyScreenArea( GetXDisplay(),
-                    GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(),
-                    pPixmap->GetDrawable(), pPixmap->GetScreen(), pPixmap->GetDepth(),
-                    aTmpGC,
-                    rRect.Left(), rRect.Top(), rRect.GetWidth(), rRect.GetHeight(), 0, 0 );
-
-    XFreeGC( pDpy, aTmpGC );
-    return pPixmap;
+    X11GraphicsImpl* pImpl = dynamic_cast<X11GraphicsImpl*>(mpImpl.get());
+    return pImpl->GetPixmapFromScreen( rRect );
 }
 
 bool X11SalGraphics::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY )
 {
     SAL_INFO( "vcl", "RenderPixmapToScreen" );
-    /*if( UseOpenGL() )
-    {
-        X11OpenGLTexture pTexture( pPixmap );
-        pTexture.Draw( nX, nY );
-        return true;
-    }*/
-
-    GC aFontGC = GetFontGC();
-
-    // The GC can't be null, otherwise we'd have no clip region
-    if( aFontGC == NULL )
-    {
-        SAL_WARN( "vcl", "no valid GC to render pixmap" );
-        return false;
-    }
-
-    if( !pPixmap )
-        return false;
-
-    CopyScreenArea( GetXDisplay(),
-                    pPixmap->GetDrawable(), pPixmap->GetScreen(), pPixmap->GetDepth(),
-                    GetDrawable(), m_nXScreen, GetVisual().GetDepth(),
-                    aFontGC,
-                    0, 0, pPixmap->GetWidth(), pPixmap->GetHeight(), nX, nY );
-    return true;
+    X11GraphicsImpl* pImpl = dynamic_cast<X11GraphicsImpl*>(mpImpl.get());
+    return pImpl->RenderPixmapToScreen( pPixmap, nX, nY );
 }
 
 extern "C"
commit 969e75db2c230cbac21ada63acaf8d2bd1d44681
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Fri Nov 7 17:29:44 2014 -0500

    vcl: Add GetPixmapFromScreen and RenderPixmapToScreen to X11SalGraphics
    
    Change-Id: I007408885b5752f3abf55075ef025aa6dacbabde

diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index fe9f4f6..36e52ee 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -92,6 +92,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
     vcl/unx/generic/gdi/x11cairotextrender \
     vcl/unx/generic/gdi/gcach_xpeer \
 	vcl/unx/generic/gdi/gdiimpl \
+	vcl/unx/generic/gdi/pixmap \
     vcl/unx/generic/gdi/salbmp \
     vcl/unx/generic/gdi/salgdi2 \
     vcl/unx/generic/gdi/salgdi3 \
diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx
index b8b145b..05d763c 100644
--- a/vcl/inc/unx/gtk/gtkgdi.hxx
+++ b/vcl/inc/unx/gtk/gtkgdi.hxx
@@ -114,6 +114,7 @@ private:
 
 #else
 
+class GdkX11Pixmap;
 class GtkSalGraphics : public X11SalGraphics
 {
     GtkWidget           *m_pWindow;
@@ -162,8 +163,8 @@ public:
 protected:
     typedef std::list< Rectangle > clipList;
 
-    GdkPixmap* NWGetPixmapFromScreen( Rectangle srcRect );
-    bool NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect );
+    GdkX11Pixmap* NWGetPixmapFromScreen( Rectangle srcRect );
+    bool NWRenderPixmapToScreen( GdkX11Pixmap* pPixmap, Rectangle dstRect );
 
     bool NWPaintGTKArrow( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
diff --git a/vcl/inc/unx/pixmap.hxx b/vcl/inc/unx/pixmap.hxx
new file mode 100644
index 0000000..f8b23c7
--- /dev/null
+++ b/vcl/inc/unx/pixmap.hxx
@@ -0,0 +1,44 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_INC_UNX_PIXMAP_HXX
+#define INCLUDED_VCL_INC_UNX_PIXMAP_HXX
+
+#include <prex.h>
+#include <postx.h>
+#include <unx/saltype.h>
+#include <vclpluginapi.h>
+
+class VCLPLUG_GEN_PUBLIC X11Pixmap
+{
+public:
+    X11Pixmap();
+    X11Pixmap( Display *pDisplay, SalX11Screen nScreen, int nWidth, int nHeight, int nDepth );
+    X11Pixmap( X11Pixmap& rOther );
+    virtual ~X11Pixmap();
+
+    Pixmap GetPixmap() const { return mpPixmap; };
+    Drawable GetDrawable() const { return mpPixmap; };
+    int GetWidth() const { return mnWidth; };
+    int GetHeight() const { return mnHeight; };
+    int GetDepth() const { return mnDepth; };
+    SalX11Screen GetScreen() const { return mnScreen; }
+
+protected:
+    Display*        mpDisplay;
+    SalX11Screen    mnScreen;
+    Pixmap          mpPixmap;
+    int             mnWidth;
+    int             mnHeight;
+    int             mnDepth;
+};
+
+#endif // INCLUDED_VCL_INC_UNX_PIXMAP_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index b4e05bc..0fa4c00 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -42,6 +42,7 @@ class SalBitmap;
 class SalColormap;
 class SalDisplay;
 class SalFrame;
+class X11Pixmap;
 class X11SalVirtualDevice;
 class X11SalGraphicsImpl;
 class PspSalPrinter;
@@ -264,6 +265,13 @@ public:
 
     virtual bool               SwapBuffers() SAL_OVERRIDE;
 
+    // create a pixmap from a screen region
+    X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect );
+
+    // render a pixmap to the screen
+    bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY );
+
+
     /*  use to handle GraphicsExpose/NoExpose after XCopyArea & friends
      *  if pFrame is not NULL, corresponding Paint events are generated
      *  and dispatched to pFrame
diff --git a/vcl/unx/generic/gdi/pixmap.cxx b/vcl/unx/generic/gdi/pixmap.cxx
new file mode 100644
index 0000000..beb5589
--- /dev/null
+++ b/vcl/unx/generic/gdi/pixmap.cxx
@@ -0,0 +1,49 @@
+/* -*- 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 "unx/pixmap.hxx"
+
+X11Pixmap::X11Pixmap()
+: mpDisplay( NULL )
+, mnScreen( 0 )
+, mnWidth( -1 )
+, mnHeight( -1 )
+, mnDepth( 0 )
+{
+}
+
+X11Pixmap::X11Pixmap( Display* pDisplay, SalX11Screen nScreen, int nWidth, int nHeight, int nDepth )
+: mpDisplay( pDisplay )
+, mnScreen( nScreen )
+, mnWidth( nWidth )
+, mnHeight( nHeight )
+, mnDepth( nDepth )
+{
+    Window root = RootWindow( pDisplay, 0 );
+    mpPixmap = XCreatePixmap( pDisplay, root, nWidth, nHeight, nDepth );
+}
+
+X11Pixmap::X11Pixmap( X11Pixmap& rOther )
+: mpDisplay( rOther.mpDisplay )
+, mnScreen( rOther.mnScreen )
+, mnWidth( rOther.mnWidth )
+, mnHeight( rOther.mnHeight )
+, mnDepth( rOther.mnDepth )
+{
+    mpPixmap = rOther.mpPixmap;
+    rOther.mpPixmap = 0;
+}
+
+X11Pixmap::~X11Pixmap()
+{
+    if( mpPixmap )
+        XFreePixmap( mpDisplay, mpPixmap );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx
index aa2732a..e4d5b3c 100644
--- a/vcl/unx/generic/gdi/salgdi2.cxx
+++ b/vcl/unx/generic/gdi/salgdi2.cxx
@@ -23,6 +23,7 @@
 
 #include "vcl/salbtype.hxx"
 
+#include "unx/pixmap.hxx"
 #include "unx/salunx.h"
 #include "unx/saldata.hxx"
 #include "unx/saldisp.hxx"
@@ -81,6 +82,63 @@ void X11SalGraphics::CopyScreenArea( Display* pDisplay,
     }
 }
 
+X11Pixmap* X11SalGraphics::GetPixmapFromScreen( const Rectangle& rRect )
+{
+    Display* pDpy = GetXDisplay();
+    X11Pixmap* pPixmap = new X11Pixmap( pDpy, GetScreenNumber(), rRect.GetWidth(), rRect.GetHeight(), 24 );
+    GC aTmpGC = XCreateGC( pDpy, pPixmap->GetPixmap(), 0, NULL );
+
+    if( !pPixmap || !aTmpGC )
+    {
+        if ( pPixmap )
+            delete pPixmap;
+        if ( aTmpGC )
+            XFreeGC( pDpy, aTmpGC );
+        SAL_WARN( "vcl", "Could not get valid pixmap from screen" );
+        return NULL;
+    }
+
+    // Copy the background of the screen into a composite pixmap
+    CopyScreenArea( GetXDisplay(),
+                    GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(),
+                    pPixmap->GetDrawable(), pPixmap->GetScreen(), pPixmap->GetDepth(),
+                    aTmpGC,
+                    rRect.Left(), rRect.Top(), rRect.GetWidth(), rRect.GetHeight(), 0, 0 );
+
+    XFreeGC( pDpy, aTmpGC );
+    return pPixmap;
+}
+
+bool X11SalGraphics::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY )
+{
+    SAL_INFO( "vcl", "RenderPixmapToScreen" );
+    /*if( UseOpenGL() )
+    {
+        X11OpenGLTexture pTexture( pPixmap );
+        pTexture.Draw( nX, nY );
+        return true;
+    }*/
+
+    GC aFontGC = GetFontGC();
+
+    // The GC can't be null, otherwise we'd have no clip region
+    if( aFontGC == NULL )
+    {
+        SAL_WARN( "vcl", "no valid GC to render pixmap" );
+        return false;
+    }
+
+    if( !pPixmap )
+        return false;
+
+    CopyScreenArea( GetXDisplay(),
+                    pPixmap->GetDrawable(), pPixmap->GetScreen(), pPixmap->GetDepth(),
+                    GetDrawable(), m_nXScreen, GetVisual().GetDepth(),
+                    aFontGC,
+                    0, 0, pPixmap->GetWidth(), pPixmap->GetHeight(), nX, nY );
+    return true;
+}
+
 extern "C"
 {
     static Bool GraphicsExposePredicate( Display*, XEvent* pEvent, XPointer pFrameWindow )
diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
index bab4f5c..50cb193 100644
--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
@@ -26,6 +26,7 @@
 #include "unx/gtk/gtkinst.hxx"
 #include "unx/gtk/gtkgdi.hxx"
 
+#include "unx/pixmap.hxx"
 #include "unx/saldata.hxx"
 #include "unx/saldisp.hxx"
 
@@ -257,6 +258,71 @@ static int getFrameWidth(GtkWidget* widget);
 
 static Rectangle NWGetScrollButtonRect(    SalX11Screen nScreen, ControlPart nPart, Rectangle aAreaRect );
 
+
+/************************************************************************
+ * GDK implementation of X11Pixmap
+ ************************************************************************/
+
+class GdkX11Pixmap : public X11Pixmap
+{
+public:
+    GdkX11Pixmap( int nWidth, int nHeight, int nDepth );
+    GdkX11Pixmap( X11Pixmap& rOther, GdkWindow *pWindow );
+    virtual ~GdkX11Pixmap();
+
+    GdkPixmap*   GetGdkPixmap() const;
+    GdkDrawable* GetGdkDrawable() const;
+
+protected:
+    GdkPixmap* mpGdkPixmap;
+};
+
+GdkX11Pixmap::GdkX11Pixmap( int nWidth, int nHeight, int nDepth )
+{
+    mpGdkPixmap = gdk_pixmap_new( NULL, nWidth, nHeight, nDepth );
+
+    //mpDisplay = ?
+    mnScreen = SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(mpGdkPixmap) ) ) );
+    mnWidth = nWidth;
+    mnHeight = nHeight;
+    mnDepth = nDepth;
+    mpPixmap = GDK_PIXMAP_XID( mpGdkPixmap );
+}
+
+GdkX11Pixmap::GdkX11Pixmap( X11Pixmap& rOther, GdkWindow *pWindow )
+: X11Pixmap( rOther )
+{
+    GdkColormap* pColormap;
+
+#if GTK_CHECK_VERSION(2,10,0)
+    GdkScreen *pScreen = gdk_window_get_screen( pWindow );
+    mpGdkPixmap = gdk_pixmap_foreign_new_for_screen( pScreen, mpPixmap,
+                                                     mnWidth, mnHeight,
+                                                     mnDepth );
+#else
+    mpGdkPixmap = gdk_pixmap_foreign_new( mpPixmap );
+#endif
+
+    pColormap = gdk_drawable_get_colormap( pWindow );
+    gdk_drawable_set_colormap( GDK_DRAWABLE (mpGdkPixmap), pColormap );
+}
+
+GdkX11Pixmap::~GdkX11Pixmap()
+{
+    g_object_unref( mpGdkPixmap );
+}
+
+GdkPixmap* GdkX11Pixmap::GetGdkPixmap() const
+{
+    return mpGdkPixmap;
+}
+
+GdkDrawable* GdkX11Pixmap::GetGdkDrawable() const
+{
+    return GDK_DRAWABLE( mpGdkPixmap );
+}
+
+
 /*********************************************************
  * PixmapCache
  *********************************************************/
@@ -271,13 +337,13 @@ class NWPixmapCacheData
 public:
     ControlType m_nType;
     ControlState m_nState;
-    Rectangle   m_pixmapRect;
-    GdkPixmap*  m_pixmap;
+    Rectangle      m_pixmapRect;
+    GdkX11Pixmap*  m_pixmap;
 
     NWPixmapCacheData() : m_nType(0), m_nState(0), m_pixmap(0) {}
     ~NWPixmapCacheData()
         { SetPixmap( NULL ); };
-    void SetPixmap( GdkPixmap* pPixmap );
+    void SetPixmap( GdkX11Pixmap* pPixmap );
 };
 
 class NWPixmapCache
@@ -294,8 +360,8 @@ public:
         { delete [] pData; m_idx = 0; m_size = n; pData = new NWPixmapCacheData[m_size]; }
     int GetSize() const { return m_size; }
 
-    bool Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap** pPixmap );
-    void Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap* pPixmap );
+    bool Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap** pPixmap );
+    void Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap* pPixmap );
 
     void ThemeChanged();
 };
@@ -312,15 +378,12 @@ public:
 
 // --- implementation ---
 
-void NWPixmapCacheData::SetPixmap( GdkPixmap* pPixmap )
+void NWPixmapCacheData::SetPixmap( GdkX11Pixmap* pPixmap )
 {
     if( m_pixmap )
-        g_object_unref( m_pixmap );
+        delete m_pixmap;
 
     m_pixmap = pPixmap;
-
-    if( m_pixmap )
-        g_object_ref( m_pixmap );
 }
 
 NWPixmapCache::NWPixmapCache( SalX11Screen nScreen )
@@ -346,7 +409,7 @@ void NWPixmapCache::ThemeChanged()
         pData[i].SetPixmap( NULL );
 }
 
-bool  NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap** pPixmap )
+bool  NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap** pPixmap )
 {
     aState &= ~CTRL_CACHING_ALLOWED; // mask clipping flag
     int i;
@@ -365,7 +428,7 @@ bool  NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectang
     return false;
 }
 
-void NWPixmapCache::Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap* pPixmap )
+void NWPixmapCache::Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap* pPixmap )
 {
     if( !(aState & CTRL_CACHING_ALLOWED) )
         return;
@@ -801,7 +864,7 @@ bool GtkSalGraphics::drawNativeControl(    ControlType nType,
 
     clipList aClip;
     GdkDrawable* gdkDrawable = GDK_DRAWABLE( GetGdkWindow() );
-    GdkPixmap* pixmap = NULL;
+    GdkX11Pixmap* pixmap = NULL;
     Rectangle aPixmapRect;
     if( ( bNeedPixmapPaint )
         && nType != CTRL_SCROLLBAR
@@ -819,7 +882,7 @@ bool GtkSalGraphics::drawNativeControl(    ControlType nType,
         pixmap = NWGetPixmapFromScreen( aPixmapRect );
         if( ! pixmap )
             return false;
-        gdkDrawable = GDK_DRAWABLE( pixmap );
+        gdkDrawable = pixmap->GetGdkDrawable();
         aCtrlRect = Rectangle( Point(1,1), aCtrlRect.GetSize() );
         aClip.push_back( aCtrlRect );
     }
@@ -956,7 +1019,7 @@ bool GtkSalGraphics::drawNativeControl(    ControlType nType,
     if( pixmap )
     {
         returnVal = NWRenderPixmapToScreen( pixmap, aPixmapRect ) && returnVal;
-        g_object_unref( pixmap );
+        delete pixmap;
     }
 
     return( returnVal );
@@ -1742,7 +1805,7 @@ bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart,
 {
     assert(aValue.getType() == CTRL_SCROLLBAR);
     const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(aValue);
-    GdkPixmap*      pixmap = NULL;
+    GdkX11Pixmap*    pixmap = NULL;
     Rectangle        pixmapRect, scrollbarRect;
     GtkStateType    stateType;
     GtkShadowType    shadowType;
@@ -1930,7 +1993,7 @@ bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart,
     w = pixmapRect.GetWidth();
     h = pixmapRect.GetHeight();
 
-    GdkDrawable* const &gdkDrawable = GDK_DRAWABLE( pixmap );
+    GdkDrawable* const &gdkDrawable = pixmap->GetGdkDrawable();
     GdkRectangle* gdkRect = NULL;
 
     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
@@ -2051,14 +2114,10 @@ bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart,
                          arrowRect.GetWidth(), arrowRect.GetHeight() );
     }
 
-    if( !NWRenderPixmapToScreen(pixmap, pixmapRect) )
-    {
-        g_object_unref( pixmap );
-        return false;
-    }
-    g_object_unref( pixmap );
+    bool bRet = NWRenderPixmapToScreen( pixmap, pixmapRect );
+    delete pixmap;
 
-    return true;
+    return bRet;
 }
 
 static Rectangle NWGetScrollButtonRect(    SalX11Screen nScreen, ControlPart nPart, Rectangle aAreaRect )
@@ -2282,7 +2341,8 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
                                         const ImplControlValue& aValue,
                                         const OUString& rCaption )
 {
-    GdkPixmap    *        pixmap;
+    GdkX11Pixmap *       pixmap;
+    GdkPixmap *          gdkPixmap;
     Rectangle            pixmapRect;
     GtkStateType        stateType;
     GtkShadowType        shadowType;
@@ -2326,9 +2386,10 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
     pixmap = NWGetPixmapFromScreen( pixmapRect );
     if ( !pixmap )
         return false;
+    gdkPixmap = pixmap->GetGdkPixmap();
 
     // First render background
-    gtk_paint_flat_box(m_pWindow->style,pixmap,GTK_STATE_NORMAL,GTK_SHADOW_NONE,NULL,m_pWindow,"base",
+    gtk_paint_flat_box(m_pWindow->style,gdkPixmap,GTK_STATE_NORMAL,GTK_SHADOW_NONE,NULL,m_pWindow,"base",
             -pixmapRect.Left(),
             -pixmapRect.Top(),
             pixmapRect.Right(),
@@ -2348,7 +2409,7 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
             aEditBoxRect.setX( 0 );
         aEditBoxRect.setY( 0 );
 
-        NWPaintOneEditBox( m_nXScreen, pixmap, NULL, nType, nPart, aEditBoxRect, nState, aValue, rCaption );
+        NWPaintOneEditBox( m_nXScreen, gdkPixmap, NULL, nType, nPart, aEditBoxRect, nState, aValue, rCaption );
     }
 
     NWSetWidgetState( gWidgetData[m_nXScreen].gSpinButtonWidget, nState, stateType );
@@ -2359,23 +2420,19 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
         Rectangle        shadowRect( upBtnRect );
 
         shadowRect.Union( downBtnRect );
-        gtk_paint_box( gWidgetData[m_nXScreen].gSpinButtonWidget->style, pixmap, GTK_STATE_NORMAL, shadowType, NULL,
+        gtk_paint_box( gWidgetData[m_nXScreen].gSpinButtonWidget->style, gdkPixmap, GTK_STATE_NORMAL, shadowType, NULL,
             gWidgetData[m_nXScreen].gSpinButtonWidget, "spinbutton",
             (shadowRect.Left() - pixmapRect.Left()), (shadowRect.Top() - pixmapRect.Top()),
             shadowRect.GetWidth(), shadowRect.GetHeight() );
     }
 
-    NWPaintOneSpinButton( m_nXScreen, pixmap, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption );
-    NWPaintOneSpinButton( m_nXScreen, pixmap, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption );
+    NWPaintOneSpinButton( m_nXScreen, gdkPixmap, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption );
+    NWPaintOneSpinButton( m_nXScreen, gdkPixmap, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption );
 
-    if( !NWRenderPixmapToScreen(pixmap, pixmapRect) )
-    {
-        g_object_unref( pixmap );
-        return false;
-    }
+    bool bRet = NWRenderPixmapToScreen( pixmap, pixmapRect );
+    delete pixmap;
 
-    g_object_unref( pixmap );
-    return true;
+    return bRet;
 }
 
 static Rectangle NWGetSpinButtonRect( SalX11Screen nScreen,
@@ -2609,7 +2666,8 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
                                         const OUString& )
 {
     OSL_ASSERT( nType != CTRL_TAB_ITEM || aValue.getType() == CTRL_TAB_ITEM );
-    GdkPixmap *    pixmap;
+    GdkX11Pixmap *   pixmap;
+    GdkPixmap *      gdkPixmap;
     Rectangle        pixmapRect;
     Rectangle        tabRect;
     GtkStateType    stateType;
@@ -2681,14 +2739,15 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
             return NWRenderPixmapToScreen( pixmap, pixmapRect );
     }
 
-    pixmap = gdk_pixmap_new( NULL, pixmapRect.GetWidth(), pixmapRect.GetHeight(),
-                             GetGenericData()->GetSalDisplay()->GetVisual( m_nXScreen ).GetDepth() );
+    pixmap = new GdkX11Pixmap( pixmapRect.GetWidth(), pixmapRect.GetHeight(),
+                               GetGenericData()->GetSalDisplay()->GetVisual( m_nXScreen ).GetDepth() );
+    gdkPixmap = pixmap->GetGdkPixmap();
     GdkRectangle paintRect;
     paintRect.x = paintRect.y = 0;
     paintRect.width = pixmapRect.GetWidth();
     paintRect.height = pixmapRect.GetHeight();
 
-    gtk_paint_flat_box( m_pWindow->style, pixmap, GTK_STATE_NORMAL,
+    gtk_paint_flat_box( m_pWindow->style, gdkPixmap, GTK_STATE_NORMAL,
                         GTK_SHADOW_NONE, &paintRect, m_pWindow, "base",
                         -rControlRectangle.Left(),
                         -rControlRectangle.Top(),
@@ -2703,7 +2762,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
             break;
 
         case CTRL_TAB_PANE:
-            gtk_paint_box_gap( gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
+            gtk_paint_box_gap( gWidgetData[m_nXScreen].gNotebookWidget->style, gdkPixmap, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
                 (char *)"notebook", 0, 0, pixmapRect.GetWidth(), pixmapRect.GetHeight(), GTK_POS_TOP, 0, 0 );
             break;
 
@@ -2712,7 +2771,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
             stateType = ( nState & CTRL_STATE_SELECTED ) ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE;
 
             // First draw the background
-            gtk_paint_flat_box(gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap,
+            gtk_paint_flat_box(gWidgetData[m_nXScreen].gNotebookWidget->style, gdkPixmap,
                                    GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, m_pWindow, "base",
                                    -rControlRectangle.Left(),
                                    -rControlRectangle.Top(),
@@ -2721,17 +2780,17 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
 
             // Now the tab itself
             if( nState & CTRL_STATE_ROLLOVER )
-                g_object_set_data(G_OBJECT(pixmap),tabPrelitDataName,reinterpret_cast<gpointer>(TRUE));
+                g_object_set_data(G_OBJECT(gdkPixmap),tabPrelitDataName,reinterpret_cast<gpointer>(TRUE));
 
-            gtk_paint_extension( gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, stateType, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
+            gtk_paint_extension( gWidgetData[m_nXScreen].gNotebookWidget->style, gdkPixmap, stateType, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
                 (char *)"tab", (tabRect.Left() - pixmapRect.Left()), (tabRect.Top() - pixmapRect.Top()),
                 tabRect.GetWidth(), tabRect.GetHeight(), GTK_POS_BOTTOM );
 
-            g_object_steal_data(G_OBJECT(pixmap),tabPrelitDataName);
+            g_object_steal_data(G_OBJECT(gdkPixmap),tabPrelitDataName);
 
             if ( nState & CTRL_STATE_SELECTED )
             {
-                gtk_paint_flat_box( m_pWindow->style, pixmap, stateType, GTK_SHADOW_NONE, NULL, m_pWindow,
+                gtk_paint_flat_box( m_pWindow->style, gdkPixmap, stateType, GTK_SHADOW_NONE, NULL, m_pWindow,
                     "base", 0, (pixmapRect.GetHeight() - 1), pixmapRect.GetWidth(), 1 );
             }
             break;
@@ -2747,8 +2806,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
     else
         aCachePage.Fill( nType, nState, pixmapRect, pixmap );
 
-    bool bSuccess = NWRenderPixmapToScreen(pixmap, pixmapRect);
-    g_object_unref( pixmap );
+    bool bSuccess = NWRenderPixmapToScreen( pixmap, pixmapRect );
     return bSuccess;
 }
 
@@ -3324,11 +3382,11 @@ bool GtkSalGraphics::NWPaintGTKListNode(
             break;
     }
 
-    GdkPixmap* pixmap = NWGetPixmapFromScreen( aRect );
+    GdkX11Pixmap* pixmap = NWGetPixmapFromScreen( aRect );
     if( ! pixmap )
         return false;
 
-    GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
+    GdkDrawable* const &pixDrawable = pixmap->GetGdkDrawable();
     gtk_paint_expander( gWidgetData[m_nXScreen].gTreeView->style,
                         pixDrawable,
                         stateType,
@@ -3339,7 +3397,7 @@ bool GtkSalGraphics::NWPaintGTKListNode(
                         eStyle );
 
     bool bRet = NWRenderPixmapToScreen( pixmap, aRect );
-    g_object_unref( pixmap );
+    delete pixmap;
 
     return bRet;
 }
@@ -3360,11 +3418,11 @@ bool GtkSalGraphics::NWPaintGTKProgress(
 
     long nProgressWidth = rValue.getNumericVal();
 
-    GdkPixmap* pixmap = NWGetPixmapFromScreen( Rectangle( Point( 0, 0 ), Size( w, h ) ) );
+    GdkX11Pixmap* pixmap = NWGetPixmapFromScreen( Rectangle( Point( 0, 0 ), Size( w, h ) ) );
     if( ! pixmap )
         return false;
 
-    GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
+    GdkDrawable* const &pixDrawable = pixmap->GetGdkDrawable();
 
     // paint background
     gtk_paint_flat_box(gWidgetData[m_nXScreen].gProgressBar->style, pixDrawable,
@@ -3408,7 +3466,7 @@ bool GtkSalGraphics::NWPaintGTKProgress(
     }
 
     bool bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle );
-    g_object_unref( pixmap );
+    delete pixmap;
 
     return bRet;
 }
@@ -3430,11 +3488,11 @@ bool GtkSalGraphics::NWPaintGTKSlider(
 
     const SliderValue* pVal = static_cast<const SliderValue*>(&rValue);
 
-    GdkPixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle );
+    GdkX11Pixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle );
     if( ! pixmap )
         return false;
 
-    GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
+    GdkDrawable* const &pixDrawable = pixmap->GetGdkDrawable();
     GtkWidget* pWidget = (nPart == PART_TRACK_HORZ_AREA)
                          ? GTK_WIDGET(gWidgetData[m_nXScreen].gHScale)
                          : GTK_WIDGET(gWidgetData[m_nXScreen].gVScale);
@@ -3496,7 +3554,7 @@ bool GtkSalGraphics::NWPaintGTKSlider(
     }
 
     bool bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle );
-    g_object_unref( pixmap );
+    delete pixmap;
 
     return bRet;
 }
@@ -4070,62 +4128,28 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
  * Create a GdkPixmap filled with the contents of an area of an Xlib window
  ************************************************************************/
 
-GdkPixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect )
+GdkX11Pixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect )
 {
-    // Create a new pixmap to hold the composite of the window background and the control
-    GdkPixmap * pPixmap        = gdk_pixmap_new( GDK_DRAWABLE(GetGdkWindow()), srcRect.GetWidth(), srcRect.GetHeight(), -1 );
-    GdkGC *     pPixmapGC      = gdk_gc_new( pPixmap );
-
-    if( !pPixmap || !pPixmapGC )
-    {
-        if ( pPixmap )
-            g_object_unref( pPixmap );
-        if ( pPixmapGC )
-            g_object_unref( pPixmapGC );
-        std::fprintf( stderr, "salnativewidgets-gtk.cxx: could not get valid pixmap from screen\n" );
-        return( NULL );
-    }
-
-    // Copy the background of the screen into a composite pixmap
-    CopyScreenArea( GetXDisplay(),
-                    GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(),
-                    gdk_x11_drawable_get_xid(pPixmap),
-                    SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ) ),
-                    gdk_drawable_get_depth( GDK_DRAWABLE( pPixmap ) ),
-                    gdk_x11_gc_get_xgc(pPixmapGC),
-                    srcRect.Left(), srcRect.Top(), srcRect.GetWidth(), srcRect.GetHeight(), 0, 0 );
-
-    g_object_unref( pPixmapGC );
-    return( pPixmap );
+    X11Pixmap* pPixmap;
+    GdkX11Pixmap* pResult;
+
+    pPixmap = GetPixmapFromScreen( srcRect );
+    if( pPixmap == NULL )
+        return NULL;
+
+    pResult = new GdkX11Pixmap( *pPixmap, GetGdkWindow() );
+    delete pPixmap;
+
+    return pResult;
 }
 
 /************************************************************************
  * Copy an alpha pixmap to screen using a gc with clipping
  ************************************************************************/
 
-bool GtkSalGraphics::NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect )
+bool GtkSalGraphics::NWRenderPixmapToScreen( GdkX11Pixmap* pPixmap, Rectangle dstRect )
 {
-    // The GC can't be null, otherwise we'd have no clip region
-    GC aFontGC = GetFontGC();
-    if( aFontGC == NULL )
-    {
-        std::fprintf(stderr, "salnativewidgets.cxx: no valid GC\n" );
-        return false;
-    }
-
-    if ( !pPixmap )
-        return false;
-
-    // Copy the background of the screen into a composite pixmap
-    CopyScreenArea( GetXDisplay(),
-                    GDK_DRAWABLE_XID(pPixmap),
-                    SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ) ),
-                    gdk_drawable_get_depth( GDK_DRAWABLE(pPixmap) ),
-                    GetDrawable(), m_nXScreen, GetVisual().GetDepth(),
-                    aFontGC,
-                    0, 0, dstRect.GetWidth(), dstRect.GetHeight(), dstRect.Left(), dstRect.Top() );
-
-    return true;
+    return RenderPixmapToScreen( pPixmap, dstRect.Left(), dstRect.Top() );
 }
 
 /************************************************************************


More information about the Libreoffice-commits mailing list