1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
30 #include <slideshowviewimpl.hxx>
31 #include <slideshowimpl.hxx>
32 #include <vos/mutex.hxx>
33 
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 
36 #include <basegfx/polygon/b2dpolygon.hxx>
37 #include <basegfx/polygon/b2dpolygontools.hxx>
38 #include <basegfx/matrix/b2dhommatrixtools.hxx>
39 
40 #include <cppcanvas/vclfactory.hxx>
41 #include <cppcanvas/basegfxfactory.hxx>
42 
43 
44 using ::com::sun::star::uno::UNO_QUERY;
45 using ::com::sun::star::uno::XInterface;
46 using ::com::sun::star::uno::Reference;
47 using ::com::sun::star::uno::WeakReference;
48 using ::com::sun::star::uno::RuntimeException;
49 using ::com::sun::star::lang::XComponent;
50 using ::com::sun::star::uno::Exception;
51 using ::com::sun::star::presentation::XSlideShow;
52 using ::com::sun::star::presentation::XSlideShowView;
53 using ::com::sun::star::presentation::XShapeEventListener;
54 using ::com::sun::star::presentation::XSlideShowListener;
55 using ::comphelper::ImplementationReference;
56 
57 using ::rtl::OUString;
58 using namespace ::com::sun::star;
59 using namespace ::com::sun::star;
60 
61 namespace sd
62 {
63 
64 ///////////////////////////////////////////////////////////////////////
65 // SlideShowViewListeners
66 ///////////////////////////////////////////////////////////////////////
67 
68 SlideShowViewListeners::SlideShowViewListeners( ::osl::Mutex& rMutex )
69 :	mrMutex( rMutex )
70 {
71 }
72 
73 void SlideShowViewListeners::addListener( const Reference< util::XModifyListener >& _rxListener )
74 {
75     ::osl::MutexGuard aGuard( mrMutex );
76 
77 	WeakReference< util::XModifyListener > xWeak( _rxListener );
78 	if( std::find( maListeners.begin(), maListeners.end(), xWeak ) == maListeners.end() )
79 		maListeners.push_back( xWeak );
80 }
81 
82 void SlideShowViewListeners::removeListener( const Reference< util::XModifyListener >& _rxListener )
83 {
84     ::osl::MutexGuard aGuard( mrMutex );
85 
86 	WeakReference< util::XModifyListener > xWeak( _rxListener );
87 	ViewListenerVector::iterator aIter( std::find( maListeners.begin(), maListeners.end(), xWeak ) );
88 	if( aIter != maListeners.end() )
89 		maListeners.erase( aIter );
90 }
91 
92 bool SlideShowViewListeners::notify( const lang::EventObject& _rEvent ) throw( com::sun::star::uno::Exception )
93 {
94 	::osl::MutexGuard aGuard( mrMutex );
95 
96 	ViewListenerVector::iterator aIter( maListeners.begin() );
97 	while( aIter != maListeners.end() )
98 	{
99 		Reference< util::XModifyListener > xListener( (*aIter) );
100 		if( xListener.is() )
101 		{
102 			xListener->modified( _rEvent );
103 			aIter++;
104 		}
105 		else
106 		{
107 			aIter = maListeners.erase( aIter );
108 		}
109 	}
110 	return true;
111 }
112 
113 void SlideShowViewListeners::disposing( const lang::EventObject& _rEventSource )
114 {
115     ::osl::MutexGuard aGuard( mrMutex );
116 
117 	ViewListenerVector::iterator aIter( maListeners.begin() );
118 	while( aIter != maListeners.end() )
119 	{
120 		Reference< util::XModifyListener > xListener( (*aIter++) );
121 		if( xListener.is() )
122 			xListener->disposing( _rEventSource );
123 	}
124 
125 	maListeners.clear();
126 }
127 
128 ///////////////////////////////////////////////////////////////////////
129 // SlideShowViewPaintListeners
130 ///////////////////////////////////////////////////////////////////////
131 
132 SlideShowViewPaintListeners::SlideShowViewPaintListeners( ::osl::Mutex& rMutex )
133 :	SlideShowViewPaintListeners_Base( rMutex )
134 {
135 }
136 
137 bool SlideShowViewPaintListeners::implTypedNotify( const Reference< awt::XPaintListener >& rListener,
138                                               const awt::PaintEvent& 				  rEvent ) throw( uno::Exception )
139 {
140     rListener->windowPaint( rEvent );
141     return true; // continue calling listeners
142 }
143 
144 ///////////////////////////////////////////////////////////////////////
145 // SlideShowViewMouseListeners
146 ///////////////////////////////////////////////////////////////////////
147 
148 SlideShowViewMouseListeners::SlideShowViewMouseListeners( ::osl::Mutex& rMutex ) :
149     SlideShowViewMouseListeners_Base( rMutex )
150 {
151 }
152 
153 bool SlideShowViewMouseListeners::implTypedNotify( const Reference< awt::XMouseListener >&	rListener,
154                                               const WrappedMouseEvent& 			  		rEvent ) throw( uno::Exception )
155 {
156     switch( rEvent.meType )
157     {
158         case WrappedMouseEvent::PRESSED:
159             rListener->mousePressed( rEvent.maEvent );
160             break;
161 
162         case WrappedMouseEvent::RELEASED:
163             rListener->mouseReleased( rEvent.maEvent );
164             break;
165 
166         case WrappedMouseEvent::ENTERED:
167             rListener->mouseEntered( rEvent.maEvent );
168             break;
169 
170         case WrappedMouseEvent::EXITED:
171             rListener->mouseExited( rEvent.maEvent );
172             break;
173     }
174 
175     return true; // continue calling listeners
176 }
177 
178 ///////////////////////////////////////////////////////////////////////
179 // SlideShowViewMouseMotionListeners
180 ///////////////////////////////////////////////////////////////////////
181 
182 SlideShowViewMouseMotionListeners::SlideShowViewMouseMotionListeners( ::osl::Mutex& rMutex ) :
183     SlideShowViewMouseMotionListeners_Base( rMutex )
184 {
185 }
186 
187 bool SlideShowViewMouseMotionListeners::implTypedNotify( const Reference< awt::XMouseMotionListener >&	rListener,
188                                                     const WrappedMouseMotionEvent& 		  			rEvent ) throw( uno::Exception )
189 {
190     switch( rEvent.meType )
191     {
192         case WrappedMouseMotionEvent::DRAGGED:
193             rListener->mouseDragged( rEvent.maEvent );
194             break;
195 
196         case WrappedMouseMotionEvent::MOVED:
197             rListener->mouseMoved( rEvent.maEvent );
198             break;
199     }
200 
201     return true; // continue calling listeners
202 }
203 
204 ///////////////////////////////////////////////////////////////////////
205 // SlideShowView
206 ///////////////////////////////////////////////////////////////////////
207 
208 SlideShowView::SlideShowView( ShowWindow&     rOutputWindow,
209                               SdDrawDocument* pDoc,
210                               AnimationMode   eAnimationMode,
211                               SlideshowImpl*  pSlideShow,
212                               bool            bFullScreen )
213 :	SlideShowView_Base( m_aMutex ),
214     mpCanvas( ::cppcanvas::VCLFactory::getInstance().createSpriteCanvas( rOutputWindow ) ),
215     mxWindow( VCLUnoHelper::GetInterface( &rOutputWindow ), uno::UNO_QUERY_THROW ),
216     mxWindowPeer( mxWindow, uno::UNO_QUERY_THROW ),
217     mxPointer(),
218 	mpSlideShow( pSlideShow ),
219     mrOutputWindow( rOutputWindow ),
220     mpViewListeners( new SlideShowViewListeners( m_aMutex ) ),
221 	mpPaintListeners( new SlideShowViewPaintListeners( m_aMutex ) ),
222 	mpMouseListeners( new SlideShowViewMouseListeners( m_aMutex ) ),
223     mpMouseMotionListeners( new SlideShowViewMouseMotionListeners( m_aMutex ) ),
224 	mpDoc( pDoc ),
225 	mbIsMouseMotionListener( false ),
226 	meAnimationMode( eAnimationMode ),
227 	mbFirstPaint( true ),
228     mbFullScreen( bFullScreen ),
229 	mbMousePressedEaten( false )
230 {
231     init();
232 }
233 
234 /// Dispose all internal references
235 void SAL_CALL SlideShowView::dispose() throw (RuntimeException)
236 {
237     ::osl::MutexGuard aGuard( m_aMutex );
238 
239 	mpSlideShow = 0;
240 
241     // deregister listeners
242 	if( mxWindow.is() )
243     {
244 		mxWindow->removeWindowListener( this );
245 		mxWindow->removeMouseListener( this );
246 
247         if( mbIsMouseMotionListener )
248             mxWindow->removeMouseMotionListener( this );
249     }
250 
251     mpCanvas.reset();
252     mxWindow.clear();
253 
254     // clear all listener containers
255     disposing( lang::EventObject() );
256 
257     // call base
258     WeakComponentImplHelperBase::dispose();
259 }
260 
261 /// Disposing our broadcaster
262 void SAL_CALL SlideShowView::disposing( const lang::EventObject& ) throw(RuntimeException)
263 {
264     ::osl::MutexGuard aGuard( m_aMutex );
265 
266     // notify all listeners that _we_ are going down (send a disposing()),
267     // then delete listener containers:
268     lang::EventObject const evt( static_cast<OWeakObject *>(this) );
269     if (mpViewListeners.get() != 0) {
270         mpViewListeners->disposing( evt );
271         mpViewListeners.reset();
272     }
273     if (mpPaintListeners.get() != 0) {
274         mpPaintListeners->disposing( evt );
275         mpPaintListeners.reset();
276     }
277     if (mpMouseListeners.get() != 0) {
278         mpMouseListeners->disposing( evt );
279         mpMouseListeners.reset();
280     }
281     if (mpMouseMotionListeners.get() != 0) {
282         mpMouseMotionListeners->disposing( evt );
283         mpMouseMotionListeners.reset();
284     }
285 }
286 
287 void SAL_CALL SlideShowView::paint( const awt::PaintEvent& e ) throw (RuntimeException)
288 {
289     ::osl::ClearableMutexGuard aGuard( m_aMutex );
290 
291 	if( mbFirstPaint )
292 	{
293 		mbFirstPaint = false;
294 		SlideshowImpl* pSlideShow = mpSlideShow;
295 		aGuard.clear();
296 		if( pSlideShow )
297 			pSlideShow->onFirstPaint();
298 	}
299     else
300     {
301 		// Change event source, to enable listeners to match event
302 		// with view
303 		awt::PaintEvent aEvent( e );
304 		aEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
305 		mpPaintListeners->notify( aEvent );
306 		updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
307 	}
308 }
309 
310 // XSlideShowView methods
311 Reference< rendering::XSpriteCanvas > SAL_CALL SlideShowView::getCanvas(  ) throw (RuntimeException)
312 {
313     ::osl::MutexGuard aGuard( m_aMutex );
314 
315     return mpCanvas.get() ? mpCanvas->getUNOSpriteCanvas() : Reference< rendering::XSpriteCanvas >();
316 }
317 
318 void SAL_CALL SlideShowView::clear() throw (::com::sun::star::uno::RuntimeException)
319 {
320     // paint background in black
321     ::osl::MutexGuard aGuard( m_aMutex );
322 	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
323 
324     // fill the bounds rectangle in black
325     // ----------------------------------
326 
327     const Size aWindowSize( mrOutputWindow.GetSizePixel() );
328 
329     ::basegfx::B2DPolygon aPoly( ::basegfx::tools::createPolygonFromRect(
330                                      ::basegfx::B2DRectangle(0.0,0.0,
331                                                              aWindowSize.Width(),
332                                                              aWindowSize.Height() ) ) );
333     ::cppcanvas::PolyPolygonSharedPtr pPolyPoly(
334         ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( mpCanvas, aPoly ) );
335 
336     if( pPolyPoly.get() )
337     {
338         pPolyPoly->setRGBAFillColor( 0x000000FFU );
339         pPolyPoly->draw();
340     }
341 }
342 
343 geometry::AffineMatrix2D SAL_CALL SlideShowView::getTransformation(  ) throw (RuntimeException)
344 {
345     ::osl::MutexGuard aGuard( m_aMutex );
346 	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
347 
348 	const Size& rTmpSize( mrOutputWindow.GetSizePixel() );
349 
350     if (rTmpSize.Width()<=0 || rTmpSize.Height()<=0)
351     {
352         return geometry::AffineMatrix2D (1,0,0,0,1,0);
353     }
354 
355     // Reduce available width by one, as the slides might actually
356     // render one pixel wider and higher as aPageSize below specifies
357     // (when shapes of page size have visible border lines)
358 	const Size  aWindowSize( rTmpSize.Width()-1,
359                              rTmpSize.Height()-1 );
360     Size aOutputSize( aWindowSize );
361 
362 	if( meAnimationMode != ANIMATIONMODE_SHOW )
363 	{
364 		aOutputSize.Width() = (long)( aOutputSize.Width() / 1.03 );
365 		aOutputSize.Height() = (long)( aOutputSize.Height() / 1.03 );
366 	}
367 
368 	SdPage* pP = mpDoc->GetSdPage( 0, PK_STANDARD );
369 	Size aPageSize( pP->GetSize() );
370 
371 	const double page_ratio = (double)aPageSize.Width() / (double)aPageSize.Height();
372 	const double output_ratio = (double)aOutputSize.Width() / (double)aOutputSize.Height();
373 
374 	if( page_ratio > output_ratio )
375 	{
376 		aOutputSize.Height() = ( aOutputSize.Width() * aPageSize.Height() ) / aPageSize.Width();
377 	}
378 	else if( page_ratio < output_ratio )
379 	{
380 		aOutputSize.Width() = ( aOutputSize.Height() * aPageSize.Width() ) / aPageSize.Height();
381 	}
382 
383 	Point aOutputOffset( ( aWindowSize.Width() - aOutputSize.Width() ) >> 1,
384 							( aWindowSize.Height() - aOutputSize.Height() ) >> 1 );
385 
386 	maPresentationArea = Rectangle( aOutputOffset, aOutputSize );
387 	mrOutputWindow.SetPresentationArea( maPresentationArea );
388 
389     // scale presentation into available window rect (minus 10%); center in the window
390 	const basegfx::B2DHomMatrix aMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix(
391 		aOutputSize.Width(), aOutputSize.Height(), aOutputOffset.X(), aOutputOffset.Y()));
392 
393     geometry::AffineMatrix2D aRes;
394 
395     return ::basegfx::unotools::affineMatrixFromHomMatrix( aRes, aMatrix );
396 }
397 
398 void SAL_CALL SlideShowView::addTransformationChangedListener( const Reference< util::XModifyListener >& xListener ) throw (RuntimeException)
399 {
400     ::osl::MutexGuard aGuard( m_aMutex );
401 
402 	if( mpViewListeners.get() )
403 		mpViewListeners->addListener( xListener );
404 }
405 
406 void SAL_CALL SlideShowView::removeTransformationChangedListener( const Reference< util::XModifyListener >& xListener ) throw (RuntimeException)
407 {
408     ::osl::MutexGuard aGuard( m_aMutex );
409 
410 	if( mpViewListeners.get() )
411 	    mpViewListeners->removeListener( xListener );
412 }
413 
414 void SAL_CALL SlideShowView::addPaintListener( const Reference< awt::XPaintListener >& xListener ) throw (RuntimeException)
415 {
416     ::osl::MutexGuard aGuard( m_aMutex );
417 
418 	if( mpPaintListeners.get() )
419 		mpPaintListeners->addTypedListener( xListener );
420 }
421 
422 void SAL_CALL SlideShowView::removePaintListener( const Reference< awt::XPaintListener >& xListener ) throw (RuntimeException)
423 {
424     ::osl::MutexGuard aGuard( m_aMutex );
425 
426 	if( mpPaintListeners.get() )
427 		mpPaintListeners->removeTypedListener( xListener );
428 }
429 
430 void SAL_CALL SlideShowView::addMouseListener( const Reference< awt::XMouseListener >& xListener ) throw (RuntimeException)
431 {
432     ::osl::MutexGuard aGuard( m_aMutex );
433 
434 	if( mpMouseListeners.get() )
435 		mpMouseListeners->addTypedListener( xListener );
436 }
437 
438 void SAL_CALL SlideShowView::removeMouseListener( const Reference< awt::XMouseListener >& xListener ) throw (RuntimeException)
439 {
440     ::osl::MutexGuard aGuard( m_aMutex );
441 
442 	if( mpMouseListeners.get() )
443 	    mpMouseListeners->removeTypedListener( xListener );
444 }
445 
446 void SAL_CALL SlideShowView::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& xListener ) throw (RuntimeException)
447 {
448     ::osl::MutexGuard aGuard( m_aMutex );
449 
450     if( !mbIsMouseMotionListener && mxWindow.is() )
451     {
452         // delay motion event registration, until we really
453         // need it
454         mbIsMouseMotionListener = true;
455         mxWindow->addMouseMotionListener( this );
456     }
457 
458 	if( mpMouseMotionListeners.get() )
459 		mpMouseMotionListeners->addTypedListener( xListener );
460 }
461 
462 void SAL_CALL SlideShowView::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& xListener ) throw (RuntimeException)
463 {
464     ::osl::MutexGuard aGuard( m_aMutex );
465 
466 	if( mpMouseMotionListeners.get() )
467 		mpMouseMotionListeners->removeTypedListener( xListener );
468 
469     // TODO(P1): Might be nice to deregister for mouse motion
470     // events, when the last listener is gone.
471 }
472 
473 void SAL_CALL SlideShowView::setMouseCursor( sal_Int16 nPointerShape ) throw (RuntimeException)
474 {
475     ::osl::MutexGuard aGuard( m_aMutex );
476 
477     // forward to window
478     if( mxPointer.is() )
479 		mxPointer->setType( nPointerShape );
480 
481 	if( mxWindowPeer.is() )
482 		mxWindowPeer->setPointer( mxPointer );
483 }
484 
485 awt::Rectangle SAL_CALL SlideShowView::getCanvasArea(  ) throw (RuntimeException)
486 {
487     awt::Rectangle aRectangle;
488 
489     if( mxWindow.is() )
490 	return mxWindow->getPosSize();
491 
492     aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0;
493 
494     return aRectangle;
495 }
496 
497 void SlideShowView::updateimpl( ::osl::ClearableMutexGuard& rGuard, SlideshowImpl* pSlideShow )
498 {
499 	if( pSlideShow )
500 	{
501 		::rtl::Reference< SlideshowImpl > aSLGuard( pSlideShow );
502 		rGuard.clear();
503 		pSlideShow->startUpdateTimer();
504 	}
505 }
506 
507 // XWindowListener methods
508 void SAL_CALL SlideShowView::windowResized( const awt::WindowEvent& e ) throw (RuntimeException)
509 {
510 	::osl::ClearableMutexGuard aGuard( m_aMutex );
511 
512 	if( mpViewListeners.get() )
513 	{
514 		// Change event source, to enable listeners to match event
515 		// with view
516 		awt::WindowEvent aEvent( e );
517 		aEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
518 
519 		mpViewListeners->notify( aEvent );
520 		updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
521 	}
522 }
523 
524 void SAL_CALL SlideShowView::windowMoved( const awt::WindowEvent& ) throw (RuntimeException)
525 {
526     // ignored
527 }
528 
529 void SAL_CALL SlideShowView::windowShown( const lang::EventObject& ) throw (RuntimeException)
530 {
531     // ignored
532 }
533 
534 void SAL_CALL SlideShowView::windowHidden( const lang::EventObject& ) throw (RuntimeException)
535 {
536     // ignored
537 }
538 
539 // XMouseListener implementation
540 void SAL_CALL SlideShowView::mousePressed( const awt::MouseEvent& e ) throw (uno::RuntimeException)
541 {
542 	::osl::ClearableMutexGuard aGuard( m_aMutex );
543 	if( mpSlideShow && mpSlideShow->isInputFreezed() )
544 	{
545 		mbMousePressedEaten = true;
546 	}
547 	else
548 	{
549 		mbMousePressedEaten = false;
550 
551 		// Change event source, to enable listeners to match event
552 		// with view
553 		WrappedMouseEvent aEvent;
554 		aEvent.meType = WrappedMouseEvent::PRESSED;
555 		aEvent.maEvent = e;
556 		aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
557 
558 		if( mpMouseListeners.get() )
559 			mpMouseListeners->notify( aEvent );
560 		updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
561 	}
562 }
563 
564 void SAL_CALL SlideShowView::mouseReleased( const awt::MouseEvent& e ) throw (uno::RuntimeException)
565 {
566 	::osl::ClearableMutexGuard aGuard( m_aMutex );
567 	if( mbMousePressedEaten )
568 	{
569 		// if mouse button down was ignored, also ignore mouse button up
570 		mbMousePressedEaten = false;
571 	}
572 	else if( mpSlideShow && !mpSlideShow->isInputFreezed() )
573 	{
574 		// Change event source, to enable listeners to match event
575 		// with view
576 		WrappedMouseEvent aEvent;
577 		aEvent.meType = WrappedMouseEvent::RELEASED;
578 		aEvent.maEvent = e;
579 		aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
580 
581 		if( mpMouseListeners.get() )
582 			mpMouseListeners->notify( aEvent );
583 		updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
584 	}
585 }
586 
587 void SAL_CALL SlideShowView::mouseEntered( const awt::MouseEvent& e ) throw (uno::RuntimeException)
588 {
589     ::osl::ClearableMutexGuard aGuard( m_aMutex );
590 
591     // Change event source, to enable listeners to match event
592     // with view
593     WrappedMouseEvent aEvent;
594     aEvent.meType = WrappedMouseEvent::ENTERED;
595     aEvent.maEvent = e;
596     aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
597 
598 	if( mpMouseListeners.get() )
599 		mpMouseListeners->notify( aEvent );
600 	updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
601 }
602 
603 void SAL_CALL SlideShowView::mouseExited( const awt::MouseEvent& e ) throw (uno::RuntimeException)
604 {
605     ::osl::ClearableMutexGuard aGuard( m_aMutex );
606 
607     // Change event source, to enable listeners to match event
608     // with view
609     WrappedMouseEvent aEvent;
610     aEvent.meType = WrappedMouseEvent::EXITED;
611     aEvent.maEvent = e;
612     aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
613 
614 	if( mpMouseListeners.get() )
615 		mpMouseListeners->notify( aEvent );
616 	updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
617 }
618 
619 // XMouseMotionListener implementation
620 void SAL_CALL SlideShowView::mouseDragged( const awt::MouseEvent& e ) throw (uno::RuntimeException)
621 {
622     ::osl::ClearableMutexGuard aGuard( m_aMutex );
623 
624     // Change event source, to enable listeners to match event
625     // with view
626     WrappedMouseMotionEvent aEvent;
627     aEvent.meType = WrappedMouseMotionEvent::DRAGGED;
628     aEvent.maEvent = e;
629     aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
630 
631 	if( mpMouseMotionListeners.get() )
632 		mpMouseMotionListeners->notify( aEvent );
633 	updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
634 }
635 
636 void SAL_CALL SlideShowView::mouseMoved( const awt::MouseEvent& e ) throw (uno::RuntimeException)
637 {
638     ::osl::ClearableMutexGuard aGuard( m_aMutex );
639 
640     // Change event source, to enable listeners to match event
641     // with view
642     WrappedMouseMotionEvent aEvent;
643     aEvent.meType = WrappedMouseMotionEvent::MOVED;
644     aEvent.maEvent = e;
645     aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
646 
647 	if( mpMouseMotionListeners.get() )
648 		mpMouseMotionListeners->notify( aEvent );
649 	updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
650 }
651 
652 void SlideShowView::init()
653 {
654     mxWindow->addWindowListener( this );
655     mxWindow->addMouseListener( this );
656 
657     Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(),
658                                                             uno::UNO_QUERY_THROW );
659 
660 	if( xFactory.is() )
661 	    mxPointer.set( xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Pointer")) ),
662 		                uno::UNO_QUERY );
663 
664 	getTransformation();
665 
666     // #i48939# only switch on kind of hacky scroll optimisation, when
667     // running fullscreen. this minimizes the probability that other
668     // windows partially cover the show.
669     if( mbFullScreen )
670     {
671         try
672         {
673             Reference< beans::XPropertySet > xCanvasProps( getCanvas(),
674                                                            uno::UNO_QUERY_THROW );
675             xCanvasProps->setPropertyValue(
676                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UnsafeScrolling")),
677                 uno::makeAny( true ) );
678         }
679         catch( uno::Exception& )
680         {
681         }
682     }
683 }
684 
685 } // namespace ::sd
686