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 #include <tools/prex.h>
29 #include <tools/postx.h>
30 
31 #include <com/sun/star/awt/SystemPointer.hdl>
32 
33 #include "gstwindow.hxx"
34 #include "gstplayer.hxx"
35 #include <vcl/syschild.hxx>
36 #include <vcl/sysdata.hxx>
37 
38 using namespace ::com::sun::star;
39 
40 namespace avmedia
41 {
42 namespace gst
43 {
44 // ---------------------
45 // - PlayerChildWindow -
46 // ---------------------
47 
48 class PlayerChildWindow : public SystemChildWindow
49 {
50 public:
51 
52                     PlayerChildWindow( Window* pParent );
53                     ~PlayerChildWindow();
54 
55 protected:
56 
57     virtual void    MouseMove( const MouseEvent& rMEvt );
58     virtual void    MouseButtonDown( const MouseEvent& rMEvt );
59     virtual void    MouseButtonUp( const MouseEvent& rMEvt );
60     virtual void    KeyInput( const KeyEvent& rKEvt );
61     virtual void    KeyUp( const KeyEvent& rKEvt );
62     virtual void    Command( const CommandEvent& rCEvt );
63 };
64 
65 // ---------------------------------------------------------------------
66 
67 PlayerChildWindow::PlayerChildWindow( Window* pParent ) :
68     SystemChildWindow( pParent, WB_CLIPCHILDREN )
69 {
70 }
71 
72 // ---------------------------------------------------------------------
73 
74 PlayerChildWindow::~PlayerChildWindow()
75 {
76 }
77 
78 // ---------------------------------------------------------------------
79 
80 void PlayerChildWindow::MouseMove( const MouseEvent& rMEvt )
81 {
82     const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
83                                         rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
84 
85     SystemChildWindow::MouseMove( rMEvt );
86     GetParent()->MouseMove( aTransformedEvent );
87 }
88 
89 // ---------------------------------------------------------------------
90 
91 void PlayerChildWindow::MouseButtonDown( const MouseEvent& rMEvt )
92 {
93     const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
94                                         rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
95 
96     SystemChildWindow::MouseButtonDown( rMEvt );
97     GetParent()->MouseButtonDown( aTransformedEvent );
98 }
99 
100 // ---------------------------------------------------------------------
101 
102 void PlayerChildWindow::MouseButtonUp( const MouseEvent& rMEvt )
103 {
104     const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
105                                         rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
106 
107     SystemChildWindow::MouseButtonUp( rMEvt );
108     GetParent()->MouseButtonUp( aTransformedEvent );
109 }
110 
111 // ---------------------------------------------------------------------
112 
113 void PlayerChildWindow::KeyInput( const KeyEvent& rKEvt )
114 {
115     SystemChildWindow::KeyInput( rKEvt );
116     GetParent()->KeyInput( rKEvt );
117 }
118 
119 // ---------------------------------------------------------------------
120 
121 void PlayerChildWindow::KeyUp( const KeyEvent& rKEvt )
122 {
123     SystemChildWindow::KeyUp( rKEvt );
124     GetParent()->KeyUp( rKEvt );
125 }
126 
127 // ---------------------------------------------------------------------
128 
129 void PlayerChildWindow::Command( const CommandEvent& rCEvt )
130 {
131     const CommandEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rCEvt.GetMousePosPixel() ) ),
132                                           rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetData() );
133 
134     SystemChildWindow::Command( rCEvt );
135     GetParent()->Command( aTransformedEvent );
136 }
137 
138 // ---------------
139 // - Window -
140 // ---------------
141 Window::Window( ::avmedia::gst::Player& rPlayer ) :
142     maListeners( maMutex ),
143     maWindowRect( 0, 0, 0, 0 ),
144     mrPlayer( rPlayer ),
145     mpPlayerWindow( NULL ),
146     meZoomLevel( media::ZoomLevel_NOT_AVAILABLE ),
147     mnPointerType( awt::SystemPointer::ARROW )
148 {}
149 
150 // ------------------------------------------------------------------------------
151 
152 Window::~Window()
153 {
154     dispose();
155 }
156 
157 // ------------------------------------------------------------------------------
158 
159 void Window::implLayoutVideoWindow()
160 {
161     if( mpPlayerWindow && ( media::ZoomLevel_NOT_AVAILABLE != meZoomLevel ) )
162     {
163         awt::Size aPrefSize( mrPlayer.getPreferredPlayerWindowSize() );
164         awt::Rectangle aRect = getPosSize();
165         int nW = aRect.Width, nH = aRect.Height;
166         int nVideoW = nW, nVideoH = nH;
167         int nX = 0, nY = 0, nWidth = 0, nHeight = 0;
168         bool bDone = false, bZoom = false;
169 
170         if( media::ZoomLevel_ORIGINAL == meZoomLevel )
171         {
172             bZoom = true;
173         }
174         else if( media::ZoomLevel_ZOOM_1_TO_4 == meZoomLevel )
175         {
176             aPrefSize.Width >>= 2;
177             aPrefSize.Height >>= 2;
178             bZoom = true;
179         }
180         else if( media::ZoomLevel_ZOOM_1_TO_2 == meZoomLevel )
181         {
182             aPrefSize.Width >>= 1;
183             aPrefSize.Height >>= 1;
184             bZoom = true;
185         }
186         else if( media::ZoomLevel_ZOOM_2_TO_1 == meZoomLevel )
187         {
188             aPrefSize.Width <<= 1;
189             aPrefSize.Height <<= 1;
190             bZoom = true;
191         }
192         else if( media::ZoomLevel_ZOOM_4_TO_1 == meZoomLevel )
193         {
194             aPrefSize.Width <<= 2;
195             aPrefSize.Height <<= 2;
196             bZoom = true;
197         }
198         else if( media::ZoomLevel_FIT_TO_WINDOW == meZoomLevel )
199         {
200             nWidth = nVideoW;
201             nHeight = nVideoH;
202             bDone = true;
203         }
204 
205         if( bZoom )
206         {
207             if( ( aPrefSize.Width <= nVideoW ) && ( aPrefSize.Height <= nVideoH ) )
208             {
209                 nX = ( nVideoW - aPrefSize.Width ) >> 1;
210                 nY = ( nVideoH - aPrefSize.Height ) >> 1;
211                 nWidth = aPrefSize.Width;
212                 nHeight = aPrefSize.Height;
213                 bDone = true;
214             }
215         }
216 
217         if( !bDone )
218         {
219             if( ( aPrefSize.Width > 0 ) && ( aPrefSize.Height > 0 ) && ( nVideoW > 0 ) && ( nVideoH > 0 ) )
220             {
221                 double fPrefWH = (double) aPrefSize.Width / aPrefSize.Height;
222 
223                 if( fPrefWH < ( (double) nVideoW / nVideoH ) )
224                 {
225                     nVideoW = (int) ( nVideoH * fPrefWH );
226                 }
227                 else
228                 {
229                     nVideoH = (int) ( nVideoW / fPrefWH );
230                 }
231 
232                 nX = ( nW - nVideoW ) >> 1;
233                 nY = ( nH - nVideoH ) >> 1;
234                 nWidth = nVideoW;
235                 nHeight = nVideoH;
236             }
237             else
238             {
239                 nX = nY = nWidth = nHeight = 0;
240             }
241         }
242 
243         mpPlayerWindow->SetPosSizePixel( Point( nX, nY ), Size( nWidth, nHeight ) );
244     }
245 }
246 
247 // ------------------------------------------------------------------------------
248 
249 bool Window::create( const uno::Sequence< uno::Any >& rArguments )
250 {
251     OSL_ASSERT( !mpPlayerWindow );
252     OSL_ENSURE( rArguments.getLength() > 2,
253 "::avmedia::gst::Windiow::create: GStreamer backend needs \
254 valid parent SystemChildWindow pointer (sal_IntPtr) as third Any \
255 value in sequence of arguments" );
256 
257     bool bRet = false;
258 
259     if( !mpPlayerWindow && ( rArguments.getLength() > 2 ) )
260     {
261         SystemChildWindow* pParentWindow = NULL;
262         sal_IntPtr pIntPtr = 0;
263 
264         // we are not interested in the first argument, which is a pure X11 window handle;
265         // this backend relies on a SystemChildWindow as parent for the PlayerWindow, given
266         // as third Sal_IntPtr value within the argument Sequence
267         rArguments[ 1 ] >>= maWindowRect;
268 
269         rArguments[ 2 ] >>= pIntPtr;
270         pParentWindow = reinterpret_cast< SystemChildWindow* >( pIntPtr );
271 
272         if( pParentWindow )
273         {
274             meZoomLevel = media::ZoomLevel_FIT_TO_WINDOW;
275 
276             mpPlayerWindow = new PlayerChildWindow( pParentWindow );
277             mpPlayerWindow->SetBackground( Color( COL_BLACK ) );
278             mpPlayerWindow->SetPosSizePixel( Point( maWindowRect.X, maWindowRect.Y ),
279                                             Size( maWindowRect.Width, maWindowRect.Height ) );
280             mpPlayerWindow->Show();
281 
282             bRet = true;
283         }
284     }
285 
286     return( bRet );
287 }
288 
289 // ------------------------------------------------------------------------------
290 
291 void SAL_CALL Window::update()
292      throw( uno::RuntimeException )
293 {
294     if( mpPlayerWindow )
295     {
296         mpPlayerWindow->Invalidate( INVALIDATE_UPDATE );
297         mpPlayerWindow->Sync();
298     }
299 }
300 
301 // ------------------------------------------------------------------------------
302 
303 sal_Bool SAL_CALL Window::setZoomLevel( media::ZoomLevel eZoomLevel )
304      throw(uno::RuntimeException)
305 {
306     bool bRet = false;
307 
308     if( ( media::ZoomLevel_NOT_AVAILABLE != meZoomLevel ) &&
309        ( media::ZoomLevel_NOT_AVAILABLE != eZoomLevel ) )
310     {
311         if( eZoomLevel != meZoomLevel )
312         {
313             meZoomLevel = eZoomLevel;
314             implLayoutVideoWindow();
315         }
316 
317         bRet = true;
318     }
319 
320     return( bRet );
321 }
322 
323 // ------------------------------------------------------------------------------
324 
325 media::ZoomLevel SAL_CALL Window::getZoomLevel()
326      throw( uno::RuntimeException )
327 {
328     return( meZoomLevel );
329 }
330 
331 // ------------------------------------------------------------------------------
332 
333 void SAL_CALL Window::setPointerType( sal_Int32 nPointerType )
334      throw( uno::RuntimeException )
335 {
336     if( mpPlayerWindow )
337     {
338         Pointer ePointer = POINTER_ARROW;
339 
340         switch( nPointerType )
341         {
342             case (awt::SystemPointer::CROSS) :
343             {
344                 ePointer = POINTER_CROSS;
345             }
346             break;
347 
348             case (awt::SystemPointer::HAND) :
349             {
350                 ePointer = POINTER_HAND;
351             }
352             break;
353 
354             case (awt::SystemPointer::MOVE) :
355             {
356                 ePointer = POINTER_MOVE;
357             }
358             break;
359 
360             case (awt::SystemPointer::WAIT) :
361             {
362                 ePointer = POINTER_WAIT;
363             }
364             break;
365 
366             default:
367             break;
368         }
369 
370         mpPlayerWindow->SetPointer( ePointer );
371     }
372 }
373 
374 // ------------------------------------------------------------------------------
375 
376 void SAL_CALL Window::setPosSize( sal_Int32 nX,
377                                   sal_Int32 nY,
378                                   sal_Int32 nWidth,
379                                   sal_Int32 nHeight,
380                                   sal_Int16 /* Flags */ )
381      throw( uno::RuntimeException )
382 {
383     maWindowRect.X = nX;
384     maWindowRect.Y = nY;
385     maWindowRect.Width = nWidth;
386     maWindowRect.Height = nHeight;
387 
388     implLayoutVideoWindow();
389 }
390 
391 // ------------------------------------------------------------------------------
392 
393 awt::Rectangle SAL_CALL Window::getPosSize()
394      throw( uno::RuntimeException )
395 {
396     return( maWindowRect );
397 }
398 
399 // ------------------------------------------------------------------------------
400 
401 void SAL_CALL Window::setVisible( sal_Bool bVisible )
402      throw( uno::RuntimeException )
403 {
404     if( mpPlayerWindow )
405     {
406         bVisible ? mpPlayerWindow->Show() : mpPlayerWindow->Hide();
407     }
408 }
409 
410 // ------------------------------------------------------------------------------
411 
412 void SAL_CALL Window::setEnable( sal_Bool bEnable )
413      throw( uno::RuntimeException )
414 {
415     if( mpPlayerWindow )
416     {
417         mpPlayerWindow->Enable( bEnable );
418     }
419 }
420 
421 // ------------------------------------------------------------------------------
422 
423 void SAL_CALL Window::setFocus()
424      throw( uno::RuntimeException )
425 {
426     if( mpPlayerWindow )
427     {
428         mpPlayerWindow->GrabFocus();
429     }
430 }
431 
432 // ------------------------------------------------------------------------------
433 
434 void SAL_CALL Window::addWindowListener( const uno::Reference< awt::XWindowListener >& xListener )
435      throw( uno::RuntimeException )
436 {
437     maListeners.addInterface( getCppuType( &xListener ), xListener );
438 }
439 
440 // ------------------------------------------------------------------------------
441 
442 void SAL_CALL Window::removeWindowListener( const uno::Reference< awt::XWindowListener >& xListener )
443      throw( uno::RuntimeException )
444 {
445     maListeners.removeInterface( getCppuType( &xListener ), xListener );
446 }
447 
448 // ------------------------------------------------------------------------------
449 
450 void SAL_CALL Window::addFocusListener( const uno::Reference< awt::XFocusListener >& xListener )
451      throw( uno::RuntimeException )
452 {
453     maListeners.addInterface( getCppuType( &xListener ), xListener );
454 }
455 
456 // ------------------------------------------------------------------------------
457 
458 void SAL_CALL Window::removeFocusListener( const uno::Reference< awt::XFocusListener >& xListener )
459      throw( uno::RuntimeException )
460 {
461     maListeners.removeInterface( getCppuType( &xListener ), xListener );
462 }
463 
464 // ------------------------------------------------------------------------------
465 
466 void SAL_CALL Window::addKeyListener( const uno::Reference< awt::XKeyListener >& xListener )
467      throw( uno::RuntimeException )
468 {
469     maListeners.addInterface( getCppuType( &xListener ), xListener );
470 }
471 
472 // ------------------------------------------------------------------------------
473 
474 void SAL_CALL Window::removeKeyListener( const uno::Reference< awt::XKeyListener >& xListener )
475      throw( uno::RuntimeException )
476 {
477     maListeners.removeInterface( getCppuType( &xListener ), xListener );
478 }
479 
480 // ------------------------------------------------------------------------------
481 
482 void SAL_CALL Window::addMouseListener( const uno::Reference< awt::XMouseListener >& xListener )
483      throw( uno::RuntimeException )
484 {
485     maListeners.addInterface( getCppuType( &xListener ), xListener );
486 }
487 
488 // ------------------------------------------------------------------------------
489 
490 void SAL_CALL Window::removeMouseListener( const uno::Reference< awt::XMouseListener >& xListener )
491      throw( uno::RuntimeException )
492 {
493     maListeners.removeInterface( getCppuType( &xListener ), xListener );
494 }
495 
496 // ------------------------------------------------------------------------------
497 
498 void SAL_CALL Window::addMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& xListener )
499      throw( uno::RuntimeException )
500 {
501     maListeners.addInterface( getCppuType( &xListener ), xListener );
502 }
503 
504 // ------------------------------------------------------------------------------
505 
506 void SAL_CALL Window::removeMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& xListener )
507      throw( uno::RuntimeException )
508 {
509     maListeners.removeInterface( getCppuType( &xListener ), xListener );
510 }
511 
512 // ------------------------------------------------------------------------------
513 
514 void SAL_CALL Window::addPaintListener( const uno::Reference< awt::XPaintListener >& xListener )
515      throw( uno::RuntimeException )
516 {
517     maListeners.addInterface( getCppuType( &xListener ), xListener );
518 }
519 
520 // ------------------------------------------------------------------------------
521 
522 void SAL_CALL Window::removePaintListener( const uno::Reference< awt::XPaintListener >& xListener )
523      throw( uno::RuntimeException )
524 {
525     maListeners.removeInterface( getCppuType( &xListener ), xListener );
526 }
527 
528 // ------------------------------------------------------------------------------
529 
530 void SAL_CALL Window::dispose()
531      throw( uno::RuntimeException )
532 {
533     delete mpPlayerWindow;
534     mpPlayerWindow = NULL;
535 }
536 
537 // ------------------------------------------------------------------------------
538 
539 void SAL_CALL Window::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
540      throw( uno::RuntimeException )
541 {
542     maListeners.addInterface( getCppuType( &xListener ), xListener );
543 }
544 
545 // ------------------------------------------------------------------------------
546 
547 void SAL_CALL Window::removeEventListener( const uno::Reference< lang::XEventListener >&
548                                            xListener )
549      throw( uno::RuntimeException )
550 {
551     maListeners.removeInterface( getCppuType( &xListener ), xListener );
552 }
553 
554 // ------------------------------------------------------------------------------
555 
556 void Window::fireMousePressedEvent( const ::com::sun::star::awt::MouseEvent& rEvt )
557 {
558     ::cppu::OInterfaceContainerHelper* pContainer =
559         maListeners.getContainer( getCppuType( ( uno::Reference< awt::XMouseListener >* ) 0 ) );
560 
561     if( pContainer )
562     {
563         ::cppu::OInterfaceIteratorHelper aIter( *pContainer );
564 
565         while( aIter.hasMoreElements() )
566         {
567             uno::Reference< awt::XMouseListener >( aIter.next(),
568                                                    uno::UNO_QUERY )->mousePressed( rEvt );
569         }
570     }
571 }
572 
573 // -----------------------------------------------------------------------------
574 
575 void Window::fireMouseReleasedEvent( const ::com::sun::star::awt::MouseEvent& rEvt )
576 {
577     ::cppu::OInterfaceContainerHelper* pContainer =
578         maListeners.getContainer( getCppuType( ( uno::Reference< awt::XMouseListener >* ) 0 ) );
579 
580     if( pContainer )
581     {
582         ::cppu::OInterfaceIteratorHelper aIter( *pContainer );
583 
584         while( aIter.hasMoreElements() )
585         {
586             uno::Reference< awt::XMouseListener >( aIter.next(),
587                                                    uno::UNO_QUERY )->mouseReleased( rEvt );
588         }
589     }
590 }
591 
592 // -----------------------------------------------------------------------------
593 
594 void Window::fireMouseMovedEvent( const ::com::sun::star::awt::MouseEvent& rEvt )
595 {
596     ::cppu::OInterfaceContainerHelper* pContainer =
597         maListeners.getContainer( getCppuType( ( uno::Reference< awt::XMouseMotionListener >* )
598                                               0 ) );
599 
600     if( pContainer )
601     {
602         ::cppu::OInterfaceIteratorHelper aIter( *pContainer );
603 
604         while( aIter.hasMoreElements() )
605         {
606             uno::Reference< awt::XMouseMotionListener >( aIter.next(),
607                                                          uno::UNO_QUERY )->mouseMoved( rEvt );
608         }
609     }
610 }
611 
612 // -----------------------------------------------------------------------------
613 
614 void Window::fireSetFocusEvent( const ::com::sun::star::awt::FocusEvent& rEvt )
615 {
616     ::cppu::OInterfaceContainerHelper* pContainer =
617         maListeners.getContainer( getCppuType( ( uno::Reference< awt::XFocusListener >* ) 0 ) );
618 
619     if( pContainer )
620     {
621         ::cppu::OInterfaceIteratorHelper aIter( *pContainer );
622 
623         while( aIter.hasMoreElements() )
624         {
625             uno::Reference< awt::XFocusListener >( aIter.next(),
626                                                    uno::UNO_QUERY )->focusGained( rEvt );
627         }
628     }
629 }
630 
631 // ------------------------------------------------------------------------------
632 
633 long Window::getXWindowHandle() const
634 {
635     return( mpPlayerWindow ? mpPlayerWindow->GetSystemData()->aWindow : 0 );
636 }
637 
638 
639 // ------------------------------------------------------------------------------
640 
641 ::rtl::OUString SAL_CALL Window::getImplementationName()
642      throw( uno::RuntimeException )
643 {
644     return( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
645                                 AVMEDIA_GSTREAMER_WINDOW_IMPLEMENTATIONNAME ) ) );
646 }
647 
648 // ------------------------------------------------------------------------------
649 
650 sal_Bool SAL_CALL Window::supportsService( const ::rtl::OUString& ServiceName )
651      throw( uno::RuntimeException )
652 {
653     return( ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
654                                          AVMEDIA_GSTREAMER_WINDOW_SERVICENAME ) ) );
655 }
656 
657 // ------------------------------------------------------------------------------
658 
659 uno::Sequence< ::rtl::OUString > SAL_CALL Window::getSupportedServiceNames()
660      throw( uno::RuntimeException )
661 {
662     uno::Sequence< ::rtl::OUString > aRet( 1 );
663     aRet[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_GSTREAMER_WINDOW_SERVICENAME ) );
664 
665     return( aRet );
666 }
667 } // namespace gst
668 } // namespace avmedia
669