fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / slideshow / source / engine / shapes / viewmediashape.cxx
blob60d86d0207ca305cf3d85cd081929d0cc6aba9ca
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 <config_features.h>
22 #include <canvas/debug.hxx>
23 #include <tools/diagnose_ex.h>
24 #include <canvas/verbosetrace.hxx>
26 #include <math.h>
28 #include <comphelper/anytostring.hxx>
29 #include <cppuhelper/exc_hlp.hxx>
31 #include <vcl/canvastools.hxx>
32 #include <vcl/syschild.hxx>
33 #include <vcl/sysdata.hxx>
34 #include <vcl/window.hxx>
35 #include <vcl/graph.hxx>
37 #include <basegfx/tools/canvastools.hxx>
38 #include <basegfx/matrix/b2dhommatrixtools.hxx>
39 #include <basegfx/numeric/ftools.hxx>
40 #include <basegfx/polygon/b2dpolygon.hxx>
41 #include <basegfx/point/b2dpoint.hxx>
42 #include <basegfx/matrix/b2dhommatrix.hxx>
43 #include <basegfx/polygon/b2dpolygontools.hxx>
44 #include <basegfx/range/b2irange.hxx>
45 #include <canvas/canvastools.hxx>
46 #include <cppcanvas/vclfactory.hxx>
47 #include <cppcanvas/basegfxfactory.hxx>
48 #include <avmedia/mediawindow.hxx>
49 #include <avmedia/modeltools.hxx>
51 #include <vcl/opengl/OpenGLContext.hxx>
53 #include <com/sun/star/media/XManager.hpp>
54 #include <com/sun/star/media/XPlayer.hpp>
55 #include <com/sun/star/media/XPlayerWindow.hpp>
56 #include <com/sun/star/beans/XPropertySet.hpp>
57 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
58 #include <com/sun/star/lang/NoSupportException.hpp>
59 #include <com/sun/star/awt/XWindow.hpp>
60 #include <com/sun/star/rendering/XCanvas.hpp>
61 #include <com/sun/star/lang/XComponent.hpp>
63 #include "viewmediashape.hxx"
64 #include "mediashape.hxx"
65 #include "tools.hxx"
66 #include "unoview.hxx"
68 using namespace ::com::sun::star;
70 namespace slideshow
72 namespace internal
74 ViewMediaShape::ViewMediaShape( const ViewLayerSharedPtr& rViewLayer,
75 const uno::Reference< drawing::XShape >& rxShape,
76 const uno::Reference< uno::XComponentContext >& rxContext ) :
77 mpViewLayer( rViewLayer ),
78 mpEventHandlerParent(0),
79 maWindowOffset( 0, 0 ),
80 maBounds(),
81 mxShape( rxShape ),
82 mxPlayer(),
83 mxPlayerWindow(),
84 mxComponentContext( rxContext ),
85 mbIsSoundEnabled(true)
87 ENSURE_OR_THROW( mxShape.is(), "ViewMediaShape::ViewMediaShape(): Invalid Shape" );
88 ENSURE_OR_THROW( mpViewLayer, "ViewMediaShape::ViewMediaShape(): Invalid View" );
89 ENSURE_OR_THROW( mpViewLayer->getCanvas(), "ViewMediaShape::ViewMediaShape(): Invalid ViewLayer canvas" );
90 ENSURE_OR_THROW( mxComponentContext.is(), "ViewMediaShape::ViewMediaShape(): Invalid component context" );
92 UnoViewSharedPtr pUnoView (::boost::dynamic_pointer_cast<UnoView>(rViewLayer));
93 if (pUnoView)
95 mbIsSoundEnabled = pUnoView->isSoundEnabled();
101 ViewMediaShape::~ViewMediaShape()
105 endMedia();
107 catch (uno::Exception &)
109 OSL_FAIL( OUStringToOString(
110 comphelper::anyToString(
111 cppu::getCaughtException() ),
112 RTL_TEXTENCODING_UTF8 ).getStr() );
118 ViewLayerSharedPtr ViewMediaShape::getViewLayer() const
120 return mpViewLayer;
125 bool ViewMediaShape::startMedia()
127 if( !mxPlayer.is() )
128 implInitialize( maBounds );
130 if (mxPlayer.is())
131 mxPlayer->start();
133 return true;
138 void ViewMediaShape::endMedia()
140 // shutdown player window
141 if( mxPlayerWindow.is() )
143 uno::Reference< lang::XComponent > xComponent( mxPlayerWindow, uno::UNO_QUERY );
145 if( xComponent.is() )
146 xComponent->dispose();
148 mxPlayerWindow.clear();
151 mpMediaWindow.disposeAndClear();
152 mpEventHandlerParent.disposeAndClear();
154 // shutdown player
155 if( mxPlayer.is() )
157 mxPlayer->stop();
159 uno::Reference< lang::XComponent > xComponent( mxPlayer, uno::UNO_QUERY );
161 if( xComponent.is() )
162 xComponent->dispose();
164 mxPlayer.clear();
170 void ViewMediaShape::pauseMedia()
172 if (mxPlayer.is())
173 mxPlayer->stop();
178 void ViewMediaShape::setMediaTime(double fTime)
180 if (mxPlayer.is())
181 mxPlayer->setMediaTime(fTime);
186 bool ViewMediaShape::render( const ::basegfx::B2DRectangle& rBounds ) const
188 #if !HAVE_FEATURE_AVMEDIA
189 (void) rBounds;
190 #else
191 ::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();
193 if( !pCanvas )
194 return false;
196 if( !mpMediaWindow.get() && !mxPlayerWindow.is() )
198 uno::Reference< graphic::XGraphic > xGraphic;
199 uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
200 if (xPropSet.is())
202 xPropSet->getPropertyValue("FallbackGraphic") >>= xGraphic;
205 Graphic aGraphic(xGraphic);
206 const BitmapEx aBmp = aGraphic.GetBitmapEx();
208 uno::Reference< rendering::XBitmap > xBitmap(vcl::unotools::xBitmapFromBitmapEx(
209 pCanvas->getUNOCanvas()->getDevice(), aBmp));
211 rendering::ViewState aViewState;
212 aViewState.AffineTransform = pCanvas->getViewState().AffineTransform;
214 rendering::RenderState aRenderState;
215 ::canvas::tools::initRenderState( aRenderState );
217 const ::Size aBmpSize( aBmp.GetSizePixel() );
219 const ::basegfx::B2DVector aScale( rBounds.getWidth() / aBmpSize.Width(),
220 rBounds.getHeight() / aBmpSize.Height() );
221 const basegfx::B2DHomMatrix aTranslation(basegfx::tools::createScaleTranslateB2DHomMatrix(
222 aScale, rBounds.getMinimum()));
223 ::canvas::tools::setRenderStateTransform( aRenderState, aTranslation );
225 pCanvas->getUNOCanvas()->drawBitmap( xBitmap,
226 aViewState,
227 aRenderState );
229 #endif
230 return true;
233 bool ViewMediaShape::resize( const ::basegfx::B2DRectangle& rNewBounds ) const
235 maBounds = rNewBounds;
237 ::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();
239 if( !pCanvas )
240 return false;
242 if( !mxPlayerWindow.is() )
243 return true;
245 uno::Reference< beans::XPropertySet > xPropSet( pCanvas->getUNOCanvas()->getDevice(),
246 uno::UNO_QUERY );
248 uno::Reference< awt::XWindow > xParentWindow;
249 if( xPropSet.is() &&
250 getPropertyValue( xParentWindow,
251 xPropSet,
252 OUString("Window" )) )
254 const awt::Rectangle aRect( xParentWindow->getPosSize() );
256 maWindowOffset.X = aRect.X;
257 maWindowOffset.Y = aRect.Y;
260 ::basegfx::B2DRange aTmpRange;
261 ::canvas::tools::calcTransformedRectBounds( aTmpRange,
262 rNewBounds,
263 mpViewLayer->getTransformation() );
264 const ::basegfx::B2IRange& rRangePix(
265 ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));
267 mxPlayerWindow->setEnable( !rRangePix.isEmpty() );
269 if( rRangePix.isEmpty() )
270 return true;
272 const Point aPosPixel( rRangePix.getMinX() + maWindowOffset.X,
273 rRangePix.getMinY() + maWindowOffset.Y );
274 const Size aSizePixel( rRangePix.getMaxX() - rRangePix.getMinX(),
275 rRangePix.getMaxY() - rRangePix.getMinY() );
277 if( mpMediaWindow.get() )
279 if( mpEventHandlerParent )
281 mpEventHandlerParent->SetPosSizePixel( aPosPixel, aSizePixel );
282 mpMediaWindow->SetPosSizePixel( Point(0,0), aSizePixel );
284 else
286 mpMediaWindow->SetPosSizePixel( aPosPixel, aSizePixel );
288 mxPlayerWindow->setPosSize( 0, 0,
289 aSizePixel.Width(), aSizePixel.Height(),
290 0 );
292 else
294 mxPlayerWindow->setPosSize( aPosPixel.X(), aPosPixel.Y(),
295 aSizePixel.Width(), aSizePixel.Height(),
296 0 );
299 return true;
304 bool ViewMediaShape::implInitialize( const ::basegfx::B2DRectangle& rBounds )
306 if( !mxPlayer.is() && mxShape.is() )
308 ENSURE_OR_RETURN_FALSE( mpViewLayer->getCanvas(),
309 "ViewMediaShape::implInitialize(): Invalid layer canvas" );
311 uno::Reference< rendering::XCanvas > xCanvas( mpViewLayer->getCanvas()->getUNOCanvas() );
313 if( xCanvas.is() )
315 uno::Reference< beans::XPropertySet > xPropSet;
318 xPropSet.set( mxShape, uno::UNO_QUERY );
319 OUString sMimeType;
321 // create Player
322 if (xPropSet.is())
324 OUString aURL;
325 xPropSet->getPropertyValue("MediaMimeType") >>= sMimeType;
326 if ((xPropSet->getPropertyValue(
327 OUString( "PrivateTempFileURL")) >>= aURL)
328 && !aURL.isEmpty())
330 implInitializeMediaPlayer( aURL, sMimeType );
332 else if (xPropSet->getPropertyValue(
333 OUString( "MediaURL")) >>= aURL)
335 implInitializeMediaPlayer( aURL, sMimeType );
339 // create visible object
340 uno::Sequence< uno::Any > aDeviceParams;
342 if( ::canvas::tools::getDeviceInfo( xCanvas, aDeviceParams ).getLength() > 1 )
344 implInitializePlayerWindow( rBounds, aDeviceParams, sMimeType );
347 // set player properties
348 implSetMediaProperties( xPropSet );
350 catch( uno::RuntimeException& )
352 throw;
354 catch( uno::Exception& )
356 OSL_FAIL( OUStringToOString(
357 comphelper::anyToString( cppu::getCaughtException() ),
358 RTL_TEXTENCODING_UTF8 ).getStr() );
363 return mxPlayer.is() || mxPlayerWindow.is();
368 void ViewMediaShape::implSetMediaProperties( const uno::Reference< beans::XPropertySet >& rxProps )
370 if( mxPlayer.is() )
372 mxPlayer->setMediaTime( 0.0 );
374 if( rxProps.is() )
376 bool bLoop( false );
377 getPropertyValue( bLoop,
378 rxProps,
379 OUString( "Loop" ));
380 mxPlayer->setPlaybackLoop( bLoop );
382 bool bMute( false );
383 getPropertyValue( bMute,
384 rxProps,
385 OUString( "Mute" ));
386 mxPlayer->setMute( bMute || !mbIsSoundEnabled);
388 sal_Int16 nVolumeDB(0);
389 getPropertyValue( nVolumeDB,
390 rxProps,
391 OUString( "VolumeDB" ));
392 mxPlayer->setVolumeDB( nVolumeDB );
394 if( mxPlayerWindow.is() )
396 media::ZoomLevel eZoom(media::ZoomLevel_FIT_TO_WINDOW);
397 getPropertyValue( eZoom,
398 rxProps,
399 OUString( "Zoom" ));
400 mxPlayerWindow->setZoomLevel( eZoom );
408 void ViewMediaShape::implInitializeMediaPlayer( const OUString& rMediaURL, const OUString& rMimeType )
410 #if !HAVE_FEATURE_AVMEDIA
411 (void) rMediaURL;
412 (void) rMimeType;
413 #else
414 if( !mxPlayer.is() )
418 if( !rMediaURL.isEmpty() )
420 mxPlayer.set( avmedia::MediaWindow::createPlayer( rMediaURL, ""/*TODO!*/, &rMimeType ),
421 uno::UNO_QUERY );
424 catch( uno::RuntimeException& )
426 throw;
428 catch( const uno::Exception& )
430 throw lang::NoSupportException( "No video support for " + rMediaURL );
433 #endif
438 bool ViewMediaShape::implInitializePlayerWindow( const ::basegfx::B2DRectangle& rBounds,
439 const uno::Sequence< uno::Any >& rVCLDeviceParams,
440 const OUString& rMimeType )
442 OSL_TRACE( "ViewMediaShape::implInitializePlayerWindow" );
443 if( !mpMediaWindow.get() && !rBounds.isEmpty() )
447 sal_Int64 aVal=0;
449 rVCLDeviceParams[ 1 ] >>= aVal;
451 vcl::Window* pWindow = reinterpret_cast< vcl::Window* >( aVal );
453 if( pWindow )
455 ::basegfx::B2DRange aTmpRange;
456 ::canvas::tools::calcTransformedRectBounds( aTmpRange,
457 rBounds,
458 mpViewLayer->getTransformation() );
459 const ::basegfx::B2IRange& rRangePix(
460 ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));
462 if( !rRangePix.isEmpty() )
464 uno::Sequence< uno::Any > aArgs( 3 );
465 awt::Rectangle aAWTRect( rRangePix.getMinX(),
466 rRangePix.getMinY(),
467 rRangePix.getMaxX() - rRangePix.getMinX(),
468 rRangePix.getMaxY() - rRangePix.getMinY() );
469 #if !HAVE_FEATURE_GLTF
470 (void)rMimeType;
471 #else
472 if( avmedia::IsModel(rMimeType) )
474 mpMediaWindow.disposeAndClear();
475 mpEventHandlerParent.disposeAndClear();
476 mpEventHandlerParent = VclPtr<vcl::Window>::Create(pWindow, WB_NOBORDER|WB_NODIALOGCONTROL);
477 mpEventHandlerParent->SetPosSizePixel( Point( aAWTRect.X, aAWTRect.Y ),
478 Size( aAWTRect.Width, aAWTRect.Height ) );
479 mpEventHandlerParent->EnablePaint(false);
480 mpEventHandlerParent->Show();
481 SystemWindowData aWinData = OpenGLContext::generateWinData(mpEventHandlerParent.get(), false);
482 mpMediaWindow = VclPtr<SystemChildWindow>::Create(mpEventHandlerParent.get(), 0, &aWinData);
483 mpMediaWindow->SetPosSizePixel( Point( 0, 0 ),
484 Size( aAWTRect.Width, aAWTRect.Height ) );
486 else
487 #endif
489 mpMediaWindow.disposeAndClear();
490 mpMediaWindow = VclPtr<SystemChildWindow>::Create( pWindow, WB_CLIPCHILDREN );
491 mpMediaWindow->SetPosSizePixel( Point( aAWTRect.X, aAWTRect.Y ),
492 Size( aAWTRect.Width, aAWTRect.Height ) );
494 mpMediaWindow->SetBackground( Color( COL_BLACK ) );
495 mpMediaWindow->SetParentClipMode( PARENTCLIPMODE_NOCLIP );
496 mpMediaWindow->EnableEraseBackground( false );
497 mpMediaWindow->EnablePaint( false );
498 mpMediaWindow->SetForwardKey( true );
499 mpMediaWindow->SetMouseTransparent( true );
500 mpMediaWindow->Show();
502 if( mxPlayer.is() )
504 aArgs[ 0 ] = uno::makeAny(
505 sal::static_int_cast< sal_IntPtr >( mpMediaWindow->GetParentWindowHandle() ) );
507 aAWTRect.X = aAWTRect.Y = 0;
508 aArgs[ 1 ] = uno::makeAny( aAWTRect );
509 aArgs[ 2 ] = uno::makeAny( reinterpret_cast< sal_IntPtr >( mpMediaWindow.get() ) );
511 mxPlayerWindow.set( mxPlayer->createPlayerWindow( aArgs ) );
513 if( mxPlayerWindow.is() )
515 mxPlayerWindow->setVisible( true );
516 mxPlayerWindow->setEnable( true );
520 if( !mxPlayerWindow.is() )
522 //if there was no playerwindow, then clear the mpMediaWindow too
523 //so that we can draw a placeholder instead in that space
524 mpMediaWindow.disposeAndClear();
525 mpEventHandlerParent.disposeAndClear();
530 catch( uno::RuntimeException& )
532 throw;
534 catch( uno::Exception& )
536 OSL_FAIL( OUStringToOString(
537 comphelper::anyToString( cppu::getCaughtException() ),
538 RTL_TEXTENCODING_UTF8 ).getStr() );
542 return mxPlayerWindow.is();
547 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */