1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove 25*b1cdbd2cSJim Jagielski #include "precompiled_canvas.hxx" 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski #include <canvas/debug.hxx> 28*b1cdbd2cSJim Jagielski #include <canvas/verbosetrace.hxx> 29*b1cdbd2cSJim Jagielski #include <canvas/canvastools.hxx> 30*b1cdbd2cSJim Jagielski #include <tools/diagnose_ex.h> 31*b1cdbd2cSJim Jagielski 32*b1cdbd2cSJim Jagielski #include <osl/mutex.hxx> 33*b1cdbd2cSJim Jagielski 34*b1cdbd2cSJim Jagielski #include <com/sun/star/registry/XRegistryKey.hpp> 35*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XSingleServiceFactory.hpp> 36*b1cdbd2cSJim Jagielski #include <com/sun/star/uno/XComponentContext.hpp> 37*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/NoSupportException.hpp> 38*b1cdbd2cSJim Jagielski 39*b1cdbd2cSJim Jagielski #include <toolkit/helper/vclunohelper.hxx> 40*b1cdbd2cSJim Jagielski 41*b1cdbd2cSJim Jagielski #include <basegfx/matrix/b2dhommatrix.hxx> 42*b1cdbd2cSJim Jagielski #include <basegfx/point/b2dpoint.hxx> 43*b1cdbd2cSJim Jagielski #include <basegfx/tools/canvastools.hxx> 44*b1cdbd2cSJim Jagielski #include <basegfx/numeric/ftools.hxx> 45*b1cdbd2cSJim Jagielski 46*b1cdbd2cSJim Jagielski #include "cairo_spritecanvas.hxx" 47*b1cdbd2cSJim Jagielski 48*b1cdbd2cSJim Jagielski using namespace ::cairo; 49*b1cdbd2cSJim Jagielski using namespace ::com::sun::star; 50*b1cdbd2cSJim Jagielski 51*b1cdbd2cSJim Jagielski namespace cairocanvas 52*b1cdbd2cSJim Jagielski { SpriteCanvas(const uno::Sequence<uno::Any> & aArguments,const uno::Reference<uno::XComponentContext> & rxContext)53*b1cdbd2cSJim Jagielski SpriteCanvas::SpriteCanvas( const uno::Sequence< uno::Any >& aArguments, 54*b1cdbd2cSJim Jagielski const uno::Reference< uno::XComponentContext >& rxContext ) : 55*b1cdbd2cSJim Jagielski maArguments(aArguments), 56*b1cdbd2cSJim Jagielski mxComponentContext( rxContext ) 57*b1cdbd2cSJim Jagielski { 58*b1cdbd2cSJim Jagielski } 59*b1cdbd2cSJim Jagielski initialize()60*b1cdbd2cSJim Jagielski void SpriteCanvas::initialize() 61*b1cdbd2cSJim Jagielski { 62*b1cdbd2cSJim Jagielski VERBOSE_TRACE("CairoSpriteCanvas created %p\n", this); 63*b1cdbd2cSJim Jagielski 64*b1cdbd2cSJim Jagielski // #i64742# Only call initialize when not in probe mode 65*b1cdbd2cSJim Jagielski if( maArguments.getLength() == 0 ) 66*b1cdbd2cSJim Jagielski return; 67*b1cdbd2cSJim Jagielski 68*b1cdbd2cSJim Jagielski /* maArguments: 69*b1cdbd2cSJim Jagielski 0: ptr to creating instance (Window or VirtualDevice) 70*b1cdbd2cSJim Jagielski 1: SystemEnvData as a streamed Any (or empty for VirtualDevice) 71*b1cdbd2cSJim Jagielski 2: current bounds of creating instance 72*b1cdbd2cSJim Jagielski 3: bool, denoting always on top state for Window (always false for VirtualDevice) 73*b1cdbd2cSJim Jagielski 4: XWindow for creating Window (or empty for VirtualDevice) 74*b1cdbd2cSJim Jagielski 5: SystemGraphicsData as a streamed Any 75*b1cdbd2cSJim Jagielski */ 76*b1cdbd2cSJim Jagielski ENSURE_ARG_OR_THROW( maArguments.getLength() >= 4 && 77*b1cdbd2cSJim Jagielski maArguments[0].getValueTypeClass() == uno::TypeClass_HYPER && 78*b1cdbd2cSJim Jagielski maArguments[4].getValueTypeClass() == uno::TypeClass_INTERFACE, 79*b1cdbd2cSJim Jagielski "CairoSpriteCanvas::initialize: wrong number of arguments, or wrong types" ); 80*b1cdbd2cSJim Jagielski 81*b1cdbd2cSJim Jagielski awt::Rectangle aRect; 82*b1cdbd2cSJim Jagielski maArguments[2] >>= aRect; 83*b1cdbd2cSJim Jagielski 84*b1cdbd2cSJim Jagielski sal_Bool bIsFullscreen( sal_False ); 85*b1cdbd2cSJim Jagielski maArguments[3] >>= bIsFullscreen; 86*b1cdbd2cSJim Jagielski 87*b1cdbd2cSJim Jagielski uno::Reference< awt::XWindow > xParentWindow; 88*b1cdbd2cSJim Jagielski maArguments[4] >>= xParentWindow; 89*b1cdbd2cSJim Jagielski 90*b1cdbd2cSJim Jagielski Window* pParentWindow = VCLUnoHelper::GetWindow(xParentWindow); 91*b1cdbd2cSJim Jagielski if( !pParentWindow ) 92*b1cdbd2cSJim Jagielski throw lang::NoSupportException( 93*b1cdbd2cSJim Jagielski ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 94*b1cdbd2cSJim Jagielski "Parent window not VCL window, or canvas out-of-process!")), 95*b1cdbd2cSJim Jagielski NULL); 96*b1cdbd2cSJim Jagielski 97*b1cdbd2cSJim Jagielski bool bHasXRender = IsCairoWorking(pParentWindow); 98*b1cdbd2cSJim Jagielski ENSURE_ARG_OR_THROW( bHasXRender == true, 99*b1cdbd2cSJim Jagielski "CairoSpriteCanvas::SpriteCanvas: No RENDER extension" ); 100*b1cdbd2cSJim Jagielski 101*b1cdbd2cSJim Jagielski Size aPixelSize( pParentWindow->GetOutputSizePixel() ); 102*b1cdbd2cSJim Jagielski const ::basegfx::B2ISize aSize( aPixelSize.Width(), 103*b1cdbd2cSJim Jagielski aPixelSize.Height() ); 104*b1cdbd2cSJim Jagielski 105*b1cdbd2cSJim Jagielski ENSURE_ARG_OR_THROW( pParentWindow != NULL, 106*b1cdbd2cSJim Jagielski "CairoSpriteCanvas::initialize: invalid Window pointer" ); 107*b1cdbd2cSJim Jagielski 108*b1cdbd2cSJim Jagielski // setup helper 109*b1cdbd2cSJim Jagielski maDeviceHelper.init( *pParentWindow, 110*b1cdbd2cSJim Jagielski *this, 111*b1cdbd2cSJim Jagielski aSize, 112*b1cdbd2cSJim Jagielski bIsFullscreen ); 113*b1cdbd2cSJim Jagielski 114*b1cdbd2cSJim Jagielski setWindow(uno::Reference<awt::XWindow2>(xParentWindow, uno::UNO_QUERY_THROW)); 115*b1cdbd2cSJim Jagielski 116*b1cdbd2cSJim Jagielski maCanvasHelper.init( maRedrawManager, 117*b1cdbd2cSJim Jagielski *this, 118*b1cdbd2cSJim Jagielski aSize ); 119*b1cdbd2cSJim Jagielski 120*b1cdbd2cSJim Jagielski maArguments.realloc(0); 121*b1cdbd2cSJim Jagielski } 122*b1cdbd2cSJim Jagielski disposing()123*b1cdbd2cSJim Jagielski void SAL_CALL SpriteCanvas::disposing() 124*b1cdbd2cSJim Jagielski { 125*b1cdbd2cSJim Jagielski ::osl::MutexGuard aGuard( m_aMutex ); 126*b1cdbd2cSJim Jagielski 127*b1cdbd2cSJim Jagielski mxComponentContext.clear(); 128*b1cdbd2cSJim Jagielski 129*b1cdbd2cSJim Jagielski // forward to parent 130*b1cdbd2cSJim Jagielski SpriteCanvasBaseT::disposing(); 131*b1cdbd2cSJim Jagielski } 132*b1cdbd2cSJim Jagielski showBuffer(::sal_Bool bUpdateAll)133*b1cdbd2cSJim Jagielski ::sal_Bool SAL_CALL SpriteCanvas::showBuffer( ::sal_Bool bUpdateAll ) throw (uno::RuntimeException) 134*b1cdbd2cSJim Jagielski { 135*b1cdbd2cSJim Jagielski return updateScreen( bUpdateAll ); 136*b1cdbd2cSJim Jagielski } 137*b1cdbd2cSJim Jagielski switchBuffer(::sal_Bool bUpdateAll)138*b1cdbd2cSJim Jagielski ::sal_Bool SAL_CALL SpriteCanvas::switchBuffer( ::sal_Bool bUpdateAll ) throw (uno::RuntimeException) 139*b1cdbd2cSJim Jagielski { 140*b1cdbd2cSJim Jagielski return updateScreen( bUpdateAll ); 141*b1cdbd2cSJim Jagielski } 142*b1cdbd2cSJim Jagielski updateScreen(sal_Bool bUpdateAll)143*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL SpriteCanvas::updateScreen( sal_Bool bUpdateAll ) throw (uno::RuntimeException) 144*b1cdbd2cSJim Jagielski { 145*b1cdbd2cSJim Jagielski ::osl::MutexGuard aGuard( m_aMutex ); 146*b1cdbd2cSJim Jagielski 147*b1cdbd2cSJim Jagielski // avoid repaints on hidden window (hidden: not mapped to 148*b1cdbd2cSJim Jagielski // screen). Return failure, since the screen really has _not_ 149*b1cdbd2cSJim Jagielski // been updated (caller should try again later) 150*b1cdbd2cSJim Jagielski return !mbIsVisible ? false : maCanvasHelper.updateScreen( 151*b1cdbd2cSJim Jagielski ::basegfx::unotools::b2IRectangleFromAwtRectangle(maBounds), 152*b1cdbd2cSJim Jagielski bUpdateAll, 153*b1cdbd2cSJim Jagielski mbSurfaceDirty); 154*b1cdbd2cSJim Jagielski } 155*b1cdbd2cSJim Jagielski getServiceName()156*b1cdbd2cSJim Jagielski ::rtl::OUString SAL_CALL SpriteCanvas::getServiceName( ) throw (uno::RuntimeException) 157*b1cdbd2cSJim Jagielski { 158*b1cdbd2cSJim Jagielski return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SPRITECANVAS_SERVICE_NAME ) ); 159*b1cdbd2cSJim Jagielski } 160*b1cdbd2cSJim Jagielski getSurface()161*b1cdbd2cSJim Jagielski SurfaceSharedPtr SpriteCanvas::getSurface() 162*b1cdbd2cSJim Jagielski { 163*b1cdbd2cSJim Jagielski return maDeviceHelper.getBufferSurface(); 164*b1cdbd2cSJim Jagielski } 165*b1cdbd2cSJim Jagielski createSurface(const::basegfx::B2ISize & rSize,Content aContent)166*b1cdbd2cSJim Jagielski SurfaceSharedPtr SpriteCanvas::createSurface( const ::basegfx::B2ISize& rSize, Content aContent ) 167*b1cdbd2cSJim Jagielski { 168*b1cdbd2cSJim Jagielski return maDeviceHelper.createSurface( rSize, aContent ); 169*b1cdbd2cSJim Jagielski } 170*b1cdbd2cSJim Jagielski createSurface(::Bitmap & rBitmap)171*b1cdbd2cSJim Jagielski SurfaceSharedPtr SpriteCanvas::createSurface( ::Bitmap& rBitmap ) 172*b1cdbd2cSJim Jagielski { 173*b1cdbd2cSJim Jagielski BitmapSystemData aData; 174*b1cdbd2cSJim Jagielski if( rBitmap.GetSystemData( aData ) ) { 175*b1cdbd2cSJim Jagielski const Size& rSize = rBitmap.GetSizePixel(); 176*b1cdbd2cSJim Jagielski 177*b1cdbd2cSJim Jagielski return maDeviceHelper.createSurface( aData, rSize ); 178*b1cdbd2cSJim Jagielski } 179*b1cdbd2cSJim Jagielski 180*b1cdbd2cSJim Jagielski return SurfaceSharedPtr(); 181*b1cdbd2cSJim Jagielski } 182*b1cdbd2cSJim Jagielski changeSurface(bool,bool)183*b1cdbd2cSJim Jagielski SurfaceSharedPtr SpriteCanvas::changeSurface( bool, bool ) 184*b1cdbd2cSJim Jagielski { 185*b1cdbd2cSJim Jagielski // non-modifiable surface here 186*b1cdbd2cSJim Jagielski return SurfaceSharedPtr(); 187*b1cdbd2cSJim Jagielski } 188*b1cdbd2cSJim Jagielski getOutputDevice()189*b1cdbd2cSJim Jagielski OutputDevice* SpriteCanvas::getOutputDevice() 190*b1cdbd2cSJim Jagielski { 191*b1cdbd2cSJim Jagielski return maDeviceHelper.getOutputDevice(); 192*b1cdbd2cSJim Jagielski } 193*b1cdbd2cSJim Jagielski getBufferSurface()194*b1cdbd2cSJim Jagielski SurfaceSharedPtr SpriteCanvas::getBufferSurface() 195*b1cdbd2cSJim Jagielski { 196*b1cdbd2cSJim Jagielski return maDeviceHelper.getBufferSurface(); 197*b1cdbd2cSJim Jagielski } 198*b1cdbd2cSJim Jagielski getWindowSurface()199*b1cdbd2cSJim Jagielski SurfaceSharedPtr SpriteCanvas::getWindowSurface() 200*b1cdbd2cSJim Jagielski { 201*b1cdbd2cSJim Jagielski return maDeviceHelper.getWindowSurface(); 202*b1cdbd2cSJim Jagielski } 203*b1cdbd2cSJim Jagielski getSizePixel()204*b1cdbd2cSJim Jagielski const ::basegfx::B2ISize& SpriteCanvas::getSizePixel() 205*b1cdbd2cSJim Jagielski { 206*b1cdbd2cSJim Jagielski return maDeviceHelper.getSizePixel(); 207*b1cdbd2cSJim Jagielski } 208*b1cdbd2cSJim Jagielski setSizePixel(const::basegfx::B2ISize & rSize)209*b1cdbd2cSJim Jagielski void SpriteCanvas::setSizePixel( const ::basegfx::B2ISize& rSize ) 210*b1cdbd2cSJim Jagielski { 211*b1cdbd2cSJim Jagielski maCanvasHelper.setSize( rSize ); 212*b1cdbd2cSJim Jagielski // re-set background surface, in case it needed recreation 213*b1cdbd2cSJim Jagielski maCanvasHelper.setSurface( maDeviceHelper.getBufferSurface(), 214*b1cdbd2cSJim Jagielski false ); 215*b1cdbd2cSJim Jagielski } 216*b1cdbd2cSJim Jagielski flush()217*b1cdbd2cSJim Jagielski void SpriteCanvas::flush() 218*b1cdbd2cSJim Jagielski { 219*b1cdbd2cSJim Jagielski maDeviceHelper.flush(); 220*b1cdbd2cSJim Jagielski } 221*b1cdbd2cSJim Jagielski repaint(const SurfaceSharedPtr & pSurface,const rendering::ViewState & viewState,const rendering::RenderState & renderState)222*b1cdbd2cSJim Jagielski bool SpriteCanvas::repaint( const SurfaceSharedPtr& pSurface, 223*b1cdbd2cSJim Jagielski const rendering::ViewState& viewState, 224*b1cdbd2cSJim Jagielski const rendering::RenderState& renderState ) 225*b1cdbd2cSJim Jagielski { 226*b1cdbd2cSJim Jagielski return maCanvasHelper.repaint( pSurface, viewState, renderState ); 227*b1cdbd2cSJim Jagielski } 228*b1cdbd2cSJim Jagielski } 229