1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: window.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <tools/prewin.h>
33 #pragma warning(push, 1)
34 #pragma warning(disable: 4917)
44 #include <tools/postwin.h>
45 #include <com/sun/star/awt/SystemPointer.hdl>
50 #define AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Window_DirectX"
51 #define AVMEDIA_WIN_WINDOW_SERVICENAME "com.sun.star.media.Window_DirectX"
53 using namespace ::com::sun::star
;
55 namespace avmedia
{ namespace win
{
61 static ::osl::Mutex
& ImplGetOwnStaticMutex()
63 static ::osl::Mutex
* pMutex
= NULL
;
67 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
71 static ::osl::Mutex aMutex
;
83 LRESULT CALLBACK
MediaPlayerWndProc( HWND hWnd
,UINT nMsg
, WPARAM nPar1
, LPARAM nPar2
)
85 Window
* pWindow
= (Window
*) ::GetWindowLong( hWnd
, 0 );
86 bool bProcessed
= true;
93 pWindow
->updatePointer();
96 case( WM_GRAPHNOTIFY
):
97 pWindow
->processGraphEvent();
100 case( WM_MOUSEMOVE
):
101 case( WM_LBUTTONDOWN
):
102 case( WM_MBUTTONDOWN
):
103 case( WM_RBUTTONDOWN
):
104 case( WM_LBUTTONUP
):
105 case( WM_MBUTTONUP
):
106 case( WM_RBUTTONUP
):
108 awt::MouseEvent aUNOEvt
;
111 if( !::GetCursorPos( &aWinPoint
) || !::ScreenToClient( hWnd
, &aWinPoint
) )
113 aWinPoint
.x
= GET_X_LPARAM( nPar2
);
114 aWinPoint
.y
= GET_Y_LPARAM( nPar2
);
116 aUNOEvt
.Modifiers
= 0;
118 aUNOEvt
.X
= aWinPoint
.x
;
119 aUNOEvt
.Y
= aWinPoint
.y
;
120 aUNOEvt
.PopupTrigger
= false;
123 if( nPar1
& MK_SHIFT
)
124 aUNOEvt
.Modifiers
|= awt::KeyModifier::SHIFT
;
126 if( nPar1
& MK_CONTROL
)
127 aUNOEvt
.Modifiers
|= awt::KeyModifier::MOD1
;
130 if( WM_LBUTTONDOWN
== nMsg
|| WM_LBUTTONUP
== nMsg
)
131 aUNOEvt
.Buttons
|= awt::MouseButton::LEFT
;
133 if( WM_MBUTTONDOWN
== nMsg
|| WM_MBUTTONUP
== nMsg
)
134 aUNOEvt
.Buttons
|= awt::MouseButton::MIDDLE
;
136 if( WM_RBUTTONDOWN
== nMsg
|| WM_RBUTTONUP
== nMsg
)
137 aUNOEvt
.Buttons
|= awt::MouseButton::RIGHT
;
140 if( WM_LBUTTONDOWN
== nMsg
||
141 WM_MBUTTONDOWN
== nMsg
||
142 WM_RBUTTONDOWN
== nMsg
)
144 aUNOEvt
.ClickCount
= 1;
145 pWindow
->fireMousePressedEvent( aUNOEvt
);
147 else if( WM_LBUTTONUP
== nMsg
||
148 WM_MBUTTONUP
== nMsg
||
149 WM_RBUTTONUP
== nMsg
)
151 aUNOEvt
.ClickCount
= 1;
152 pWindow
->fireMouseReleasedEvent( aUNOEvt
);
154 else if( WM_MOUSEMOVE
== nMsg
)
156 aUNOEvt
.ClickCount
= 0;
157 pWindow
->fireMouseMovedEvent( aUNOEvt
);
158 pWindow
->updatePointer();
165 const awt::FocusEvent aUNOEvt
;
166 pWindow
->fireSetFocusEvent( aUNOEvt
);
178 return( bProcessed
? 0 : DefWindowProc( hWnd
, nMsg
, nPar1
, nPar2
) );
185 WNDCLASS
* Window::mpWndClass
= NULL
;
187 // ------------------------------------------------------------------------------
189 Window::Window( const uno::Reference
< lang::XMultiServiceFactory
>& rxMgr
, Player
& rPlayer
) :
192 meZoomLevel( media::ZoomLevel_NOT_AVAILABLE
),
195 maListeners( maMutex
),
196 mnPointerType( awt::SystemPointer::ARROW
)
198 ::osl::MutexGuard
aGuard( ImplGetOwnStaticMutex() );
202 mpWndClass
= new WNDCLASS
;
204 memset( mpWndClass
, 0, sizeof( *mpWndClass
) );
205 mpWndClass
->hInstance
= GetModuleHandle( NULL
);
206 mpWndClass
->cbWndExtra
= sizeof( DWORD
);
207 mpWndClass
->lpfnWndProc
= MediaPlayerWndProc
;
208 mpWndClass
->lpszClassName
= "com_sun_star_media_PlayerWnd";
209 mpWndClass
->hbrBackground
= (HBRUSH
) ::GetStockObject( BLACK_BRUSH
);
210 mpWndClass
->hCursor
= ::LoadCursor( NULL
, IDC_ARROW
);
212 ::RegisterClass( mpWndClass
);
216 // ------------------------------------------------------------------------------
221 ::DestroyWindow( (HWND
) mnFrameWnd
);
224 // ------------------------------------------------------------------------------
226 void Window::ImplLayoutVideoWindow()
228 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
)
230 awt::Size
aPrefSize( mrPlayer
.getPreferredPlayerWindowSize() );
231 awt::Rectangle aRect
= getPosSize();
232 int nW
= aRect
.Width
, nH
= aRect
.Height
;
233 int nVideoW
= nW
, nVideoH
= nH
;
234 int nX
= 0, nY
= 0, nWidth
= 0, nHeight
= 0;
235 bool bDone
= false, bZoom
= false;
237 if( media::ZoomLevel_ORIGINAL
== meZoomLevel
)
241 else if( media::ZoomLevel_ZOOM_1_TO_4
== meZoomLevel
)
243 aPrefSize
.Width
>>= 2;
244 aPrefSize
.Height
>>= 2;
247 else if( media::ZoomLevel_ZOOM_1_TO_2
== meZoomLevel
)
249 aPrefSize
.Width
>>= 1;
250 aPrefSize
.Height
>>= 1;
253 else if( media::ZoomLevel_ZOOM_2_TO_1
== meZoomLevel
)
255 aPrefSize
.Width
<<= 1;
256 aPrefSize
.Height
<<= 1;
259 else if( media::ZoomLevel_ZOOM_4_TO_1
== meZoomLevel
)
261 aPrefSize
.Width
<<= 2;
262 aPrefSize
.Height
<<= 2;
265 else if( media::ZoomLevel_FIT_TO_WINDOW
== meZoomLevel
)
274 if( ( aPrefSize
.Width
<= nVideoW
) && ( aPrefSize
.Height
<= nVideoH
) )
276 nX
= ( nVideoW
- aPrefSize
.Width
) >> 1;
277 nY
= ( nVideoH
- aPrefSize
.Height
) >> 1;
278 nWidth
= aPrefSize
.Width
;
279 nHeight
= aPrefSize
.Height
;
286 if( aPrefSize
.Width
> 0 && aPrefSize
.Height
> 0 && nVideoW
> 0 && nVideoH
> 0 )
288 double fPrefWH
= (double) aPrefSize
.Width
/ aPrefSize
.Height
;
290 if( fPrefWH
< ( (double) nVideoW
/ nVideoH
) )
291 nVideoW
= (int)( nVideoH
* fPrefWH
);
293 nVideoH
= (int)( nVideoW
/ fPrefWH
);
295 nX
= ( nW
- nVideoW
) >> 1;
296 nY
= ( nH
- nVideoH
) >> 1;
301 nX
= nY
= nWidth
= nHeight
= 0;
304 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
307 pVideoWindow
->SetWindowPosition( nX
, nY
, nWidth
, nHeight
);
311 // ------------------------------------------------------------------------------
313 bool Window::create( const uno::Sequence
< uno::Any
>& rArguments
)
315 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
317 if( !mnFrameWnd
&& pVideoWindow
&& mpWndClass
)
319 awt::Rectangle aRect
;
322 rArguments
[ 0 ] >>= nWnd
;
323 rArguments
[ 1 ] >>= aRect
;
325 mnParentWnd
= static_cast<int>(nWnd
);
327 mnFrameWnd
= (int) ::CreateWindow( mpWndClass
->lpszClassName
, NULL
,
328 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
329 aRect
.X
, aRect
.Y
, aRect
.Width
, aRect
.Height
,
330 (HWND
) mnParentWnd
, NULL
, mpWndClass
->hInstance
, 0 );
332 // if the last CreateWindow failed...
333 if( mnFrameWnd
== 0 )
335 // try again and this time assume that mnParent is indeed a dc
336 mnParentWnd
= reinterpret_cast<int>(::WindowFromDC( (HDC
)mnParentWnd
));
337 mnFrameWnd
= (int) ::CreateWindow( mpWndClass
->lpszClassName
, NULL
,
338 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
339 aRect
.X
, aRect
.Y
, aRect
.Width
, aRect
.Height
,
340 (HWND
)mnParentWnd
, NULL
, mpWndClass
->hInstance
, 0 );
345 ::SetWindowLong( (HWND
) mnFrameWnd
, 0, (DWORD
) this );
347 #ifdef DDRAW_TEST_OUTPUT
348 IDirectDraw7
* pDDraw
;
349 IDirectDrawSurface7
* pDDSurface
;
350 IDirectDrawClipper
* pDDClipper
;
352 if( DD_OK
== DirectDrawCreateEx( NULL
, (void**) &pDDraw
, IID_IDirectDraw7
, NULL
) )
354 if( DD_OK
== pDDraw
->SetCooperativeLevel( (HWND
) mnParentWnd
, DDSCL_NORMAL
) )
356 DDSURFACEDESC2 aDDDesc
;
358 memset( &aDDDesc
, 0, sizeof( aDDDesc
) );
359 aDDDesc
.dwSize
= sizeof( aDDDesc
);
360 aDDDesc
.dwFlags
= DDSD_CAPS
;
361 aDDDesc
.ddsCaps
.dwCaps
|= DDSCAPS_PRIMARYSURFACE
;
363 if( DD_OK
== pDDraw
->CreateSurface( &aDDDesc
, &pDDSurface
, NULL
) )
365 if( DD_OK
== pDDraw
->CreateClipper( 0, &pDDClipper
, NULL
) )
367 pDDClipper
->SetHWnd( 0, (HWND
) mnFrameWnd
);
368 pDDSurface
->SetClipper( pDDClipper
);
371 mrPlayer
.setDDrawParams( (IDirectDraw
*) pDDraw
, (IDirectDrawSurface
*) pDDSurface
);
374 pVideoWindow
->put_Owner( (OAHWND
) mnFrameWnd
);
375 pVideoWindow
->put_MessageDrain( (OAHWND
) mnFrameWnd
);
376 pVideoWindow
->put_WindowStyle( WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
);
378 mrPlayer
.setNotifyWnd( mnFrameWnd
);
380 meZoomLevel
= media::ZoomLevel_ORIGINAL
;
381 ImplLayoutVideoWindow();
382 #ifdef DDRAW_TEST_OUTPUT
390 return( mnFrameWnd
!= 0 );
393 // ------------------------------------------------------------------------------
395 void Window::processGraphEvent()
397 mrPlayer
.processEvent();
400 // ------------------------------------------------------------------------------
402 void Window::updatePointer()
406 switch( mnPointerType
)
408 case( awt::SystemPointer::CROSS
): pCursorName
= IDC_CROSS
; break;
409 //case( awt::SystemPointer::HAND ): pCursorName = IDC_HAND; break;
410 case( awt::SystemPointer::MOVE
): pCursorName
= IDC_SIZEALL
; break;
411 case( awt::SystemPointer::WAIT
): pCursorName
= IDC_WAIT
; break;
414 pCursorName
= IDC_ARROW
;
418 ::SetCursor( ::LoadCursor( NULL
, pCursorName
) );
421 // ------------------------------------------------------------------------------
423 void SAL_CALL
Window::update( )
424 throw (uno::RuntimeException
)
426 ::RedrawWindow( (HWND
) mnFrameWnd
, NULL
, NULL
, RDW_ALLCHILDREN
| RDW_INVALIDATE
| RDW_UPDATENOW
| RDW_ERASE
);
429 // ------------------------------------------------------------------------------
431 sal_Bool SAL_CALL
Window::setZoomLevel( media::ZoomLevel eZoomLevel
)
432 throw (uno::RuntimeException
)
434 boolean bRet
= false;
436 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
&&
437 media::ZoomLevel_NOT_AVAILABLE
!= eZoomLevel
)
439 if( eZoomLevel
!= meZoomLevel
)
441 meZoomLevel
= eZoomLevel
;
442 ImplLayoutVideoWindow();
451 // ------------------------------------------------------------------------------
453 media::ZoomLevel SAL_CALL
Window::getZoomLevel( )
454 throw (uno::RuntimeException
)
459 // ------------------------------------------------------------------------------
461 void SAL_CALL
Window::setPointerType( sal_Int32 nPointerType
)
462 throw (uno::RuntimeException
)
464 mnPointerType
= nPointerType
;
467 // ------------------------------------------------------------------------------
469 void SAL_CALL
Window::setPosSize( sal_Int32 X
, sal_Int32 Y
, sal_Int32 Width
, sal_Int32 Height
, sal_Int16
)
470 throw (uno::RuntimeException
)
474 ::SetWindowPos( (HWND
) mnFrameWnd
, HWND_TOP
, X
, Y
, Width
, Height
, 0 );
475 ImplLayoutVideoWindow();
479 // ------------------------------------------------------------------------------
481 awt::Rectangle SAL_CALL
Window::getPosSize()
482 throw (uno::RuntimeException
)
490 if( ::GetClientRect( (HWND
) mnFrameWnd
, &aWndRect
) )
492 aRet
.X
= aWndRect
.left
;
493 aRet
.Y
= aWndRect
.top
;
494 aRet
.Width
= aWndRect
.right
- aWndRect
.left
+ 1;
495 aRet
.Height
= aWndRect
.bottom
- aWndRect
.top
+ 1;
502 // ------------------------------------------------------------------------------
504 void SAL_CALL
Window::setVisible( sal_Bool bVisible
)
505 throw (uno::RuntimeException
)
509 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
512 pVideoWindow
->put_Visible( bVisible
? OATRUE
: OAFALSE
);
514 ::ShowWindow( (HWND
) mnFrameWnd
, bVisible
? SW_SHOW
: SW_HIDE
);
518 // ------------------------------------------------------------------------------
520 void SAL_CALL
Window::setEnable( sal_Bool bEnable
)
521 throw (uno::RuntimeException
)
524 ::EnableWindow( (HWND
) mnFrameWnd
, bEnable
);
527 // ------------------------------------------------------------------------------
529 void SAL_CALL
Window::setFocus( )
530 throw (uno::RuntimeException
)
533 ::SetFocus( (HWND
) mnFrameWnd
);
536 // ------------------------------------------------------------------------------
538 void SAL_CALL
Window::addWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
539 throw (uno::RuntimeException
)
541 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
544 // ------------------------------------------------------------------------------
546 void SAL_CALL
Window::removeWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
547 throw (uno::RuntimeException
)
549 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
552 // ------------------------------------------------------------------------------
554 void SAL_CALL
Window::addFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
555 throw (uno::RuntimeException
)
557 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
560 // ------------------------------------------------------------------------------
562 void SAL_CALL
Window::removeFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
563 throw (uno::RuntimeException
)
565 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
568 // ------------------------------------------------------------------------------
570 void SAL_CALL
Window::addKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
571 throw (uno::RuntimeException
)
573 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
576 // ------------------------------------------------------------------------------
578 void SAL_CALL
Window::removeKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
579 throw (uno::RuntimeException
)
581 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
584 // ------------------------------------------------------------------------------
586 void SAL_CALL
Window::addMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
587 throw (uno::RuntimeException
)
589 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
592 // ------------------------------------------------------------------------------
594 void SAL_CALL
Window::removeMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
595 throw (uno::RuntimeException
)
597 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
600 // ------------------------------------------------------------------------------
602 void SAL_CALL
Window::addMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
603 throw (uno::RuntimeException
)
605 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
608 // ------------------------------------------------------------------------------
610 void SAL_CALL
Window::removeMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
611 throw (uno::RuntimeException
)
613 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
616 // ------------------------------------------------------------------------------
618 void SAL_CALL
Window::addPaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
619 throw (uno::RuntimeException
)
621 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
624 // ------------------------------------------------------------------------------
626 void SAL_CALL
Window::removePaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
627 throw (uno::RuntimeException
)
629 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
632 // ------------------------------------------------------------------------------
634 void SAL_CALL
Window::dispose( )
635 throw (uno::RuntimeException
)
639 // ------------------------------------------------------------------------------
641 void SAL_CALL
Window::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
642 throw (uno::RuntimeException
)
644 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
647 // ------------------------------------------------------------------------------
649 void SAL_CALL
Window::removeEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
650 throw (uno::RuntimeException
)
652 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
655 // ------------------------------------------------------------------------------
657 void Window::fireMousePressedEvent( const ::com::sun::star::awt::MouseEvent
& rEvt
)
659 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( getCppuType( (uno::Reference
< awt::XMouseListener
>*) 0 ) );
663 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
665 while( aIter
.hasMoreElements() )
666 uno::Reference
< awt::XMouseListener
>( aIter
.next(), uno::UNO_QUERY
)->mousePressed( rEvt
);
670 // -----------------------------------------------------------------------------
672 void Window::fireMouseReleasedEvent( const ::com::sun::star::awt::MouseEvent
& rEvt
)
674 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( getCppuType( (uno::Reference
< awt::XMouseListener
>*) 0 ) );
678 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
680 while( aIter
.hasMoreElements() )
681 uno::Reference
< awt::XMouseListener
>( aIter
.next(), uno::UNO_QUERY
)->mouseReleased( rEvt
);
685 // -----------------------------------------------------------------------------
687 void Window::fireMouseMovedEvent( const ::com::sun::star::awt::MouseEvent
& rEvt
)
689 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( getCppuType( (uno::Reference
< awt::XMouseMotionListener
>*) 0 ) );
693 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
695 while( aIter
.hasMoreElements() )
696 uno::Reference
< awt::XMouseMotionListener
>( aIter
.next(), uno::UNO_QUERY
)->mouseMoved( rEvt
);
700 // -----------------------------------------------------------------------------
702 void Window::fireSetFocusEvent( const ::com::sun::star::awt::FocusEvent
& rEvt
)
704 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( getCppuType( (uno::Reference
< awt::XFocusListener
>*) 0 ) );
708 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
710 while( aIter
.hasMoreElements() )
711 uno::Reference
< awt::XFocusListener
>( aIter
.next(), uno::UNO_QUERY
)->focusGained( rEvt
);
715 // ------------------------------------------------------------------------------
717 ::rtl::OUString SAL_CALL
Window::getImplementationName( )
718 throw (uno::RuntimeException
)
720 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME
) );
723 // ------------------------------------------------------------------------------
725 sal_Bool SAL_CALL
Window::supportsService( const ::rtl::OUString
& ServiceName
)
726 throw (uno::RuntimeException
)
728 return ServiceName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_WIN_WINDOW_SERVICENAME
) );
731 // ------------------------------------------------------------------------------
733 uno::Sequence
< ::rtl::OUString
> SAL_CALL
Window::getSupportedServiceNames( )
734 throw (uno::RuntimeException
)
736 uno::Sequence
< ::rtl::OUString
> aRet(1);
737 aRet
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_WIN_WINDOW_SERVICENAME
) );
743 } // namespace avmedia