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