cid#1607171 Data race condition
[LibreOffice.git] / canvas / source / cairo / cairo_spritecanvas.cxx
blobbb97ae4bfb35cc1f8927a0d4ecc2946779a6f137
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
23 #include <basegfx/range/b2irange.hxx>
24 #include <basegfx/utils/canvastools.hxx>
25 #include <com/sun/star/awt/XTopWindow.hpp>
26 #include <com/sun/star/awt/Rectangle.hpp>
27 #include <com/sun/star/lang/NoSupportException.hpp>
28 #include <osl/mutex.hxx>
29 #include <toolkit/helper/vclunohelper.hxx>
30 #include <comphelper/diagnose_ex.hxx>
31 #include <cppuhelper/supportsservice.hxx>
33 #include "cairo_spritecanvas.hxx"
35 using namespace ::cairo;
36 using namespace ::com::sun::star;
38 namespace cairocanvas
40 SpriteCanvas::SpriteCanvas( const uno::Sequence< uno::Any >& aArguments,
41 const uno::Reference< uno::XComponentContext >& /*rxContext*/ ) :
42 maArguments(aArguments)
46 void SpriteCanvas::initialize()
48 SAL_INFO("canvas.cairo", "CairoSpriteCanvas created " << this);
50 // #i64742# Only call initialize when not in probe mode
51 if( !maArguments.hasElements() )
52 return;
54 /* maArguments:
55 0: ptr to creating instance (Window or VirtualDevice)
56 1: current bounds of creating instance
57 2: bool, denoting always on top state for Window (always false for VirtualDevice)
58 3: XWindow for creating Window (or empty for VirtualDevice)
59 4: SystemGraphicsData as a streamed Any
61 ENSURE_ARG_OR_THROW( maArguments.getLength() >= 4 &&
62 maArguments[0].getValueTypeClass() == uno::TypeClass_HYPER &&
63 maArguments[3].getValueTypeClass() == uno::TypeClass_INTERFACE,
64 "CairoSpriteCanvas::initialize: wrong number of arguments, or wrong types" );
66 awt::Rectangle aRect;
67 maArguments[1] >>= aRect;
69 bool bIsFullscreen( false );
70 maArguments[2] >>= bIsFullscreen;
72 uno::Reference< awt::XWindow > xParentWindow;
73 maArguments[3] >>= xParentWindow;
75 VclPtr<vcl::Window> pParentWindow = VCLUnoHelper::GetWindow(xParentWindow);
76 if( !pParentWindow )
77 throw lang::NoSupportException(
78 u"Parent window not VCL window, or canvas out-of-process!"_ustr, nullptr);
80 bool bHasCairo = pParentWindow->GetOutDev()->SupportsCairo();
81 ENSURE_ARG_OR_THROW(bHasCairo,
82 "CairoSpriteCanvas::SpriteCanvas: No Cairo capability");
84 Size aPixelSize( pParentWindow->GetOutputSizePixel() );
85 const ::basegfx::B2ISize aSize( aPixelSize.Width(),
86 aPixelSize.Height() );
88 // setup helper
89 maDeviceHelper.init( *pParentWindow,
90 *this,
91 aSize,
92 bIsFullscreen );
94 setWindow(uno::Reference<awt::XWindow2>(xParentWindow, uno::UNO_QUERY_THROW));
96 maCanvasHelper.init( maRedrawManager,
97 *this,
98 aSize );
100 maArguments.realloc(0);
103 void SpriteCanvas::disposeThis()
105 ::osl::MutexGuard aGuard( m_aMutex );
107 // forward to parent
108 SpriteCanvasBaseT::disposeThis();
111 sal_Bool SAL_CALL SpriteCanvas::showBuffer( sal_Bool bUpdateAll )
113 return updateScreen( bUpdateAll );
116 sal_Bool SAL_CALL SpriteCanvas::switchBuffer( sal_Bool bUpdateAll )
118 return updateScreen( bUpdateAll );
121 sal_Bool SAL_CALL SpriteCanvas::updateScreen( sal_Bool bUpdateAll )
123 ::osl::MutexGuard aGuard( m_aMutex );
125 // avoid repaints on hidden window (hidden: not mapped to
126 // screen). Return failure, since the screen really has _not_
127 // been updated (caller should try again later)
128 return mbIsVisible && maCanvasHelper.updateScreen(
129 ::basegfx::unotools::b2IRectangleFromAwtRectangle(maBounds),
130 bUpdateAll,
131 mbSurfaceDirty);
134 OUString SAL_CALL SpriteCanvas::getServiceName( )
136 return u"com.sun.star.rendering.SpriteCanvas.Cairo"_ustr;
139 // XServiceInfo
140 sal_Bool SpriteCanvas::supportsService(const OUString& sServiceName)
142 return cppu::supportsService(this, sServiceName);
145 OUString SpriteCanvas::getImplementationName()
147 return u"com.sun.star.comp.rendering.SpriteCanvas.Cairo"_ustr;
149 css::uno::Sequence< OUString > SpriteCanvas::getSupportedServiceNames()
151 return { getServiceName() };
154 SurfaceSharedPtr SpriteCanvas::getSurface()
156 return maDeviceHelper.getBufferSurface();
159 SurfaceSharedPtr SpriteCanvas::createSurface( const ::basegfx::B2ISize& rSize, int aContent )
161 return maDeviceHelper.createSurface( rSize, aContent );
164 SurfaceSharedPtr SpriteCanvas::createSurface( ::Bitmap& rBitmap )
166 BitmapSystemData aData;
167 if( rBitmap.GetSystemData( aData ) ) {
168 const Size aSize = rBitmap.GetSizePixel();
170 return maDeviceHelper.createSurface( aData, aSize );
173 return SurfaceSharedPtr();
176 SurfaceSharedPtr SpriteCanvas::changeSurface()
178 // non-modifiable surface here
179 return SurfaceSharedPtr();
182 OutputDevice* SpriteCanvas::getOutputDevice()
184 return maDeviceHelper.getOutputDevice();
187 SurfaceSharedPtr const & SpriteCanvas::getBufferSurface() const
189 return maDeviceHelper.getBufferSurface();
192 SurfaceSharedPtr const & SpriteCanvas::getWindowSurface() const
194 return maDeviceHelper.getWindowSurface();
197 const ::basegfx::B2ISize& SpriteCanvas::getSizePixel() const
199 return maDeviceHelper.getSizePixel();
202 void SpriteCanvas::setSizePixel( const ::basegfx::B2ISize& rSize )
204 maCanvasHelper.setSize( rSize );
205 // re-set background surface, in case it needed recreation
206 maCanvasHelper.setSurface( maDeviceHelper.getBufferSurface(),
207 false );
210 void SpriteCanvas::flush()
212 maDeviceHelper.flush();
215 bool SpriteCanvas::repaint( const SurfaceSharedPtr& pSurface,
216 const rendering::ViewState& viewState,
217 const rendering::RenderState& renderState )
219 return maCanvasHelper.repaint( pSurface, viewState, renderState );
223 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
224 com_sun_star_comp_rendering_SpriteCanvas_Cairo_get_implementation(
225 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
227 rtl::Reference<cairocanvas::SpriteCanvas> p = new cairocanvas::SpriteCanvas(args, context);
228 p->initialize();
229 return cppu::acquire(p.get());
232 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */