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