1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_canvas.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <tools/prex.h> 32*cdf0e10cSrcweir #include <X11/extensions/Xrender.h> 33*cdf0e10cSrcweir #include <X11/Xlib.h> 34*cdf0e10cSrcweir #include <tools/postx.h> 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include "cairo_xlib_cairo.hxx" 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include <vcl/sysdata.hxx> 39*cdf0e10cSrcweir #include <vcl/bitmap.hxx> 40*cdf0e10cSrcweir #include <vcl/virdev.hxx> 41*cdf0e10cSrcweir #include <basegfx/vector/b2isize.hxx> 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir namespace cairo 44*cdf0e10cSrcweir { 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir #include <cairo-xlib.h> 47*cdf0e10cSrcweir #include <cairo-xlib-xrender.h> 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir // TODO(F3): svp headless case! 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir bool IsCairoWorking( OutputDevice* pOutDev ) 52*cdf0e10cSrcweir { 53*cdf0e10cSrcweir if( !pOutDev ) 54*cdf0e10cSrcweir return false; 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir Display* pDisplay = (Display*)pOutDev->GetSystemGfxData().pDisplay; 57*cdf0e10cSrcweir int nDummy; 58*cdf0e10cSrcweir return XQueryExtension( pDisplay, "RENDER", &nDummy, &nDummy, &nDummy ); 59*cdf0e10cSrcweir } 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir X11SysData::X11SysData() : 62*cdf0e10cSrcweir pDisplay(NULL), 63*cdf0e10cSrcweir hDrawable(0), 64*cdf0e10cSrcweir pVisual(NULL), 65*cdf0e10cSrcweir nScreen(0), 66*cdf0e10cSrcweir nDepth(-1), 67*cdf0e10cSrcweir aColormap(-1), 68*cdf0e10cSrcweir pRenderFormat(NULL) 69*cdf0e10cSrcweir {} 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir X11SysData::X11SysData( const SystemGraphicsData& pSysDat ) : 72*cdf0e10cSrcweir pDisplay(pSysDat.pDisplay), 73*cdf0e10cSrcweir hDrawable(pSysDat.hDrawable), 74*cdf0e10cSrcweir pVisual(pSysDat.pVisual), 75*cdf0e10cSrcweir nScreen(pSysDat.nScreen), 76*cdf0e10cSrcweir nDepth(pSysDat.nDepth), 77*cdf0e10cSrcweir aColormap(pSysDat.aColormap), 78*cdf0e10cSrcweir pRenderFormat(pSysDat.pRenderFormat) 79*cdf0e10cSrcweir {} 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir X11SysData::X11SysData( const SystemEnvData& pSysDat ) : 82*cdf0e10cSrcweir pDisplay(pSysDat.pDisplay), 83*cdf0e10cSrcweir hDrawable(pSysDat.aWindow), 84*cdf0e10cSrcweir pVisual(pSysDat.pVisual), 85*cdf0e10cSrcweir nScreen(pSysDat.nScreen), 86*cdf0e10cSrcweir nDepth(pSysDat.nDepth), 87*cdf0e10cSrcweir aColormap(pSysDat.aColormap), 88*cdf0e10cSrcweir pRenderFormat(NULL) 89*cdf0e10cSrcweir {} 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir X11Pixmap::~X11Pixmap() 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir if( mpDisplay && mhDrawable ) 94*cdf0e10cSrcweir XFreePixmap( (Display*)mpDisplay, mhDrawable ); 95*cdf0e10cSrcweir } 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir /** 98*cdf0e10cSrcweir * Surface::Surface: Create Canvas surface with existing data 99*cdf0e10cSrcweir * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx) 100*cdf0e10cSrcweir * @param pSurface Cairo surface 101*cdf0e10cSrcweir * 102*cdf0e10cSrcweir * pSysData contains the platform native Drawable reference 103*cdf0e10cSrcweir * This constructor only stores data, it does no processing. 104*cdf0e10cSrcweir * It is used by e.g. Surface::getSimilar() 105*cdf0e10cSrcweir * 106*cdf0e10cSrcweir * Set the mpSurface as pSurface 107*cdf0e10cSrcweir **/ 108*cdf0e10cSrcweir X11Surface::X11Surface( const X11SysData& rSysData, 109*cdf0e10cSrcweir const X11PixmapSharedPtr& rPixmap, 110*cdf0e10cSrcweir const CairoSurfaceSharedPtr& pSurface ) : 111*cdf0e10cSrcweir maSysData(rSysData), 112*cdf0e10cSrcweir mpPixmap(rPixmap), 113*cdf0e10cSrcweir mpSurface(pSurface) 114*cdf0e10cSrcweir {} 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir /** 117*cdf0e10cSrcweir * Surface::Surface: Create generic Canvas surface using given Cairo Surface 118*cdf0e10cSrcweir * 119*cdf0e10cSrcweir * @param pSurface Cairo Surface 120*cdf0e10cSrcweir * 121*cdf0e10cSrcweir * This constructor only stores data, it does no processing. 122*cdf0e10cSrcweir * It is used with e.g. cairo_image_surface_create_for_data() 123*cdf0e10cSrcweir * Unlike other constructors, mpSysData is set to NULL 124*cdf0e10cSrcweir * 125*cdf0e10cSrcweir * Set the mpSurface as pSurface 126*cdf0e10cSrcweir **/ 127*cdf0e10cSrcweir X11Surface::X11Surface( const CairoSurfaceSharedPtr& pSurface ) : 128*cdf0e10cSrcweir maSysData(), 129*cdf0e10cSrcweir mpPixmap(), 130*cdf0e10cSrcweir mpSurface(pSurface) 131*cdf0e10cSrcweir {} 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir /** 134*cdf0e10cSrcweir * Surface::Surface: Create Canvas surface from Window reference. 135*cdf0e10cSrcweir * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx) 136*cdf0e10cSrcweir * @param x horizontal location of the new surface 137*cdf0e10cSrcweir * @param y vertical location of the new surface 138*cdf0e10cSrcweir * @param width width of the new surface 139*cdf0e10cSrcweir * @param height height of the new surface 140*cdf0e10cSrcweir * 141*cdf0e10cSrcweir * pSysData contains the platform native Window reference. 142*cdf0e10cSrcweir * 143*cdf0e10cSrcweir * pSysData is used to create a surface on the Window 144*cdf0e10cSrcweir * 145*cdf0e10cSrcweir * Set the mpSurface to the new surface or NULL 146*cdf0e10cSrcweir **/ 147*cdf0e10cSrcweir X11Surface::X11Surface( const X11SysData& rSysData, int x, int y, int width, int height ) : 148*cdf0e10cSrcweir maSysData(rSysData), 149*cdf0e10cSrcweir mpPixmap(), 150*cdf0e10cSrcweir mpSurface( 151*cdf0e10cSrcweir cairo_xlib_surface_create( (Display*)rSysData.pDisplay, 152*cdf0e10cSrcweir rSysData.hDrawable, 153*cdf0e10cSrcweir (Visual*)rSysData.pVisual, 154*cdf0e10cSrcweir width + x, height + y ), 155*cdf0e10cSrcweir &cairo_surface_destroy) 156*cdf0e10cSrcweir { 157*cdf0e10cSrcweir cairo_surface_set_device_offset(mpSurface.get(), x, y ); 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir /** 161*cdf0e10cSrcweir * Surface::Surface: Create platfrom native Canvas surface from BitmapSystemData 162*cdf0e10cSrcweir * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx) 163*cdf0e10cSrcweir * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx) 164*cdf0e10cSrcweir * @param width width of the new surface 165*cdf0e10cSrcweir * @param height height of the new surface 166*cdf0e10cSrcweir * 167*cdf0e10cSrcweir * The pBmpData provides the imagedata that the created surface should contain. 168*cdf0e10cSrcweir * 169*cdf0e10cSrcweir * Set the mpSurface to the new surface or NULL 170*cdf0e10cSrcweir **/ 171*cdf0e10cSrcweir X11Surface::X11Surface( const X11SysData& rSysData, 172*cdf0e10cSrcweir const BitmapSystemData& rData ) : 173*cdf0e10cSrcweir maSysData( rSysData ), 174*cdf0e10cSrcweir mpPixmap(), 175*cdf0e10cSrcweir mpSurface( 176*cdf0e10cSrcweir cairo_xlib_surface_create( (Display*)rSysData.pDisplay, 177*cdf0e10cSrcweir (Drawable)rData.aPixmap, 178*cdf0e10cSrcweir (Visual*) rSysData.pVisual, 179*cdf0e10cSrcweir rData.mnWidth, rData.mnHeight ), 180*cdf0e10cSrcweir &cairo_surface_destroy) 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir /** 185*cdf0e10cSrcweir * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface 186*cdf0e10cSrcweir * 187*cdf0e10cSrcweir * @return new Cairo or NULL 188*cdf0e10cSrcweir **/ 189*cdf0e10cSrcweir CairoSharedPtr X11Surface::getCairo() const 190*cdf0e10cSrcweir { 191*cdf0e10cSrcweir return CairoSharedPtr( cairo_create(mpSurface.get()), 192*cdf0e10cSrcweir &cairo_destroy ); 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir /** 196*cdf0e10cSrcweir * Surface::getSimilar: Create new similar Canvas surface 197*cdf0e10cSrcweir * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h) 198*cdf0e10cSrcweir * @param width width of the new surface 199*cdf0e10cSrcweir * @param height height of the new surface 200*cdf0e10cSrcweir * 201*cdf0e10cSrcweir * Creates a new Canvas surface. This normally creates platform native surface, even though 202*cdf0e10cSrcweir * generic function is used. 203*cdf0e10cSrcweir * 204*cdf0e10cSrcweir * Cairo surface from aContent (cairo_content_t) 205*cdf0e10cSrcweir * 206*cdf0e10cSrcweir * @return new surface or NULL 207*cdf0e10cSrcweir **/ 208*cdf0e10cSrcweir SurfaceSharedPtr X11Surface::getSimilar( Content aContent, int width, int height ) const 209*cdf0e10cSrcweir { 210*cdf0e10cSrcweir Pixmap hPixmap; 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir if( maSysData.pDisplay && maSysData.hDrawable ) 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir XRenderPictFormat* pFormat; 215*cdf0e10cSrcweir int nFormat; 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir switch (aContent) 218*cdf0e10cSrcweir { 219*cdf0e10cSrcweir case CAIRO_CONTENT_ALPHA: 220*cdf0e10cSrcweir nFormat = PictStandardA8; 221*cdf0e10cSrcweir break; 222*cdf0e10cSrcweir case CAIRO_CONTENT_COLOR: 223*cdf0e10cSrcweir nFormat = PictStandardRGB24; 224*cdf0e10cSrcweir break; 225*cdf0e10cSrcweir case CAIRO_CONTENT_COLOR_ALPHA: 226*cdf0e10cSrcweir default: 227*cdf0e10cSrcweir nFormat = PictStandardARGB32; 228*cdf0e10cSrcweir break; 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir pFormat = XRenderFindStandardFormat( (Display*)maSysData.pDisplay, nFormat ); 232*cdf0e10cSrcweir hPixmap = XCreatePixmap( (Display*)maSysData.pDisplay, maSysData.hDrawable, 233*cdf0e10cSrcweir width > 0 ? width : 1, height > 0 ? height : 1, 234*cdf0e10cSrcweir pFormat->depth ); 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir X11SysData aSysData(maSysData); 237*cdf0e10cSrcweir aSysData.pRenderFormat = pFormat; 238*cdf0e10cSrcweir return SurfaceSharedPtr( 239*cdf0e10cSrcweir new X11Surface( aSysData, 240*cdf0e10cSrcweir X11PixmapSharedPtr( 241*cdf0e10cSrcweir new X11Pixmap(hPixmap, maSysData.pDisplay)), 242*cdf0e10cSrcweir CairoSurfaceSharedPtr( 243*cdf0e10cSrcweir cairo_xlib_surface_create_with_xrender_format( 244*cdf0e10cSrcweir (Display*)maSysData.pDisplay, 245*cdf0e10cSrcweir hPixmap, 246*cdf0e10cSrcweir ScreenOfDisplay((Display *)maSysData.pDisplay, maSysData.nScreen), 247*cdf0e10cSrcweir pFormat, width, height ), 248*cdf0e10cSrcweir &cairo_surface_destroy) )); 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir else 251*cdf0e10cSrcweir return SurfaceSharedPtr( 252*cdf0e10cSrcweir new X11Surface( maSysData, 253*cdf0e10cSrcweir X11PixmapSharedPtr(), 254*cdf0e10cSrcweir CairoSurfaceSharedPtr( 255*cdf0e10cSrcweir cairo_surface_create_similar( mpSurface.get(), aContent, width, height ), 256*cdf0e10cSrcweir &cairo_surface_destroy ))); 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir boost::shared_ptr<VirtualDevice> X11Surface::createVirtualDevice() const 260*cdf0e10cSrcweir { 261*cdf0e10cSrcweir SystemGraphicsData aSystemGraphicsData; 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir aSystemGraphicsData.nSize = sizeof(SystemGraphicsData); 264*cdf0e10cSrcweir aSystemGraphicsData.hDrawable = getDrawable(); 265*cdf0e10cSrcweir aSystemGraphicsData.pRenderFormat = getRenderFormat(); 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir return boost::shared_ptr<VirtualDevice>( 268*cdf0e10cSrcweir new VirtualDevice( &aSystemGraphicsData, getDepth() )); 269*cdf0e10cSrcweir } 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir /** 272*cdf0e10cSrcweir * Surface::Resize: Resizes the Canvas surface. 273*cdf0e10cSrcweir * @param width new width of the surface 274*cdf0e10cSrcweir * @param height new height of the surface 275*cdf0e10cSrcweir * 276*cdf0e10cSrcweir * Only used on X11. 277*cdf0e10cSrcweir * 278*cdf0e10cSrcweir * @return The new surface or NULL 279*cdf0e10cSrcweir **/ 280*cdf0e10cSrcweir void X11Surface::Resize( int width, int height ) 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir cairo_xlib_surface_set_size( mpSurface.get(), width, height ); 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir void X11Surface::flush() const 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir XSync( (Display*)maSysData.pDisplay, false ); 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir /** 291*cdf0e10cSrcweir * Surface::getDepth: Get the color depth of the Canvas surface. 292*cdf0e10cSrcweir * 293*cdf0e10cSrcweir * @return color depth 294*cdf0e10cSrcweir **/ 295*cdf0e10cSrcweir int X11Surface::getDepth() const 296*cdf0e10cSrcweir { 297*cdf0e10cSrcweir if( maSysData.pRenderFormat ) 298*cdf0e10cSrcweir return ((XRenderPictFormat*) maSysData.pRenderFormat)->depth; 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir return -1; 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir return SurfaceSharedPtr(new X11Surface(rSurface)); 306*cdf0e10cSrcweir } 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir static X11SysData getSysData( const Window& rWindow ) 309*cdf0e10cSrcweir { 310*cdf0e10cSrcweir const SystemEnvData* pSysData = GetSysData(&rWindow); 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir if( !pSysData ) 313*cdf0e10cSrcweir return X11SysData(); 314*cdf0e10cSrcweir else 315*cdf0e10cSrcweir return X11SysData(*pSysData); 316*cdf0e10cSrcweir } 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir static X11SysData getSysData( const VirtualDevice& rVirDev ) 319*cdf0e10cSrcweir { 320*cdf0e10cSrcweir return X11SysData( rVirDev.GetSystemGfxData() ); 321*cdf0e10cSrcweir } 322*cdf0e10cSrcweir 323*cdf0e10cSrcweir SurfaceSharedPtr createSurface( const OutputDevice& rRefDevice, 324*cdf0e10cSrcweir int x, int y, int width, int height ) 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW ) 327*cdf0e10cSrcweir return SurfaceSharedPtr(new X11Surface(getSysData((const Window&)rRefDevice), 328*cdf0e10cSrcweir x,y,width,height)); 329*cdf0e10cSrcweir else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV ) 330*cdf0e10cSrcweir return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice&)rRefDevice), 331*cdf0e10cSrcweir x,y,width,height)); 332*cdf0e10cSrcweir else 333*cdf0e10cSrcweir return SurfaceSharedPtr(); 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir SurfaceSharedPtr createBitmapSurface( const OutputDevice& rRefDevice, 337*cdf0e10cSrcweir const BitmapSystemData& rData, 338*cdf0e10cSrcweir const Size& rSize ) 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir OSL_TRACE( "requested size: %d x %d available size: %d x %d", 341*cdf0e10cSrcweir rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight ); 342*cdf0e10cSrcweir if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() ) 343*cdf0e10cSrcweir { 344*cdf0e10cSrcweir if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW ) 345*cdf0e10cSrcweir return SurfaceSharedPtr(new X11Surface(getSysData((const Window&)rRefDevice), rData )); 346*cdf0e10cSrcweir else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV ) 347*cdf0e10cSrcweir return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice&)rRefDevice), rData )); 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir return SurfaceSharedPtr(); 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir } 353