1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #pragma warning(push, 1)
22 #pragma warning(disable: 4917)
27 #define STRSAFE_NO_DEPRECATE
32 #include <com/sun/star/awt/SystemPointer.hpp>
33 #include <cppuhelper/supportsservice.hxx>
38 #define AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Window_DirectX"
39 #define AVMEDIA_WIN_WINDOW_SERVICENAME "com.sun.star.media.Window_DirectX"
41 using namespace ::com::sun::star
;
43 namespace avmedia
{ namespace win
{
45 static ::osl::Mutex
& ImplGetOwnStaticMutex()
47 static ::osl::Mutex
* pMutex
= NULL
;
51 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
55 static ::osl::Mutex aMutex
;
63 LRESULT CALLBACK
MediaPlayerWndProc( HWND hWnd
,UINT nMsg
, WPARAM nPar1
, LPARAM nPar2
)
65 Window
* pWindow
= (Window
*) ::GetWindowLong( hWnd
, 0 );
66 bool bProcessed
= true;
73 pWindow
->updatePointer();
76 case( WM_GRAPHNOTIFY
):
77 pWindow
->processGraphEvent();
81 case( WM_LBUTTONDOWN
):
82 case( WM_MBUTTONDOWN
):
83 case( WM_RBUTTONDOWN
):
88 awt::MouseEvent aUNOEvt
;
91 if( !::GetCursorPos( &aWinPoint
) || !::ScreenToClient( hWnd
, &aWinPoint
) )
93 aWinPoint
.x
= GET_X_LPARAM( nPar2
);
94 aWinPoint
.y
= GET_Y_LPARAM( nPar2
);
96 aUNOEvt
.Modifiers
= 0;
98 aUNOEvt
.X
= aWinPoint
.x
;
99 aUNOEvt
.Y
= aWinPoint
.y
;
100 aUNOEvt
.PopupTrigger
= false;
103 if( nPar1
& MK_SHIFT
)
104 aUNOEvt
.Modifiers
|= awt::KeyModifier::SHIFT
;
106 if( nPar1
& MK_CONTROL
)
107 aUNOEvt
.Modifiers
|= awt::KeyModifier::MOD1
;
110 if( WM_LBUTTONDOWN
== nMsg
|| WM_LBUTTONUP
== nMsg
)
111 aUNOEvt
.Buttons
|= awt::MouseButton::LEFT
;
113 if( WM_MBUTTONDOWN
== nMsg
|| WM_MBUTTONUP
== nMsg
)
114 aUNOEvt
.Buttons
|= awt::MouseButton::MIDDLE
;
116 if( WM_RBUTTONDOWN
== nMsg
|| WM_RBUTTONUP
== nMsg
)
117 aUNOEvt
.Buttons
|= awt::MouseButton::RIGHT
;
120 if( WM_LBUTTONDOWN
== nMsg
||
121 WM_MBUTTONDOWN
== nMsg
||
122 WM_RBUTTONDOWN
== nMsg
)
124 aUNOEvt
.ClickCount
= 1;
125 pWindow
->fireMousePressedEvent( aUNOEvt
);
127 else if( WM_LBUTTONUP
== nMsg
||
128 WM_MBUTTONUP
== nMsg
||
129 WM_RBUTTONUP
== nMsg
)
131 aUNOEvt
.ClickCount
= 1;
132 pWindow
->fireMouseReleasedEvent( aUNOEvt
);
134 else if( WM_MOUSEMOVE
== nMsg
)
136 aUNOEvt
.ClickCount
= 0;
137 pWindow
->fireMouseMovedEvent( aUNOEvt
);
138 pWindow
->updatePointer();
145 const awt::FocusEvent aUNOEvt
;
146 pWindow
->fireSetFocusEvent( aUNOEvt
);
158 return( bProcessed
? 0 : DefWindowProc( hWnd
, nMsg
, nPar1
, nPar2
) );
161 WNDCLASS
* lcl_getWndClass()
163 static WNDCLASS
* s_pWndClass
= NULL
;
166 s_pWndClass
= new WNDCLASS
;
168 memset( s_pWndClass
, 0, sizeof( *s_pWndClass
) );
169 s_pWndClass
->hInstance
= GetModuleHandle( NULL
);
170 s_pWndClass
->cbWndExtra
= sizeof( DWORD
);
171 s_pWndClass
->lpfnWndProc
= MediaPlayerWndProc
;
172 s_pWndClass
->lpszClassName
= "com_sun_star_media_PlayerWnd";
173 s_pWndClass
->hbrBackground
= (HBRUSH
) ::GetStockObject( BLACK_BRUSH
);
174 s_pWndClass
->hCursor
= ::LoadCursor( NULL
, IDC_ARROW
);
176 ::RegisterClass( s_pWndClass
);
181 Window::Window( const uno::Reference
< lang::XMultiServiceFactory
>& rxMgr
, Player
& rPlayer
) :
184 meZoomLevel( media::ZoomLevel_NOT_AVAILABLE
),
187 maListeners( maMutex
),
188 mnPointerType( awt::SystemPointer::ARROW
)
190 ::osl::MutexGuard
aGuard( ImplGetOwnStaticMutex() );
198 ::DestroyWindow( (HWND
) mnFrameWnd
);
201 void Window::ImplLayoutVideoWindow()
203 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
)
205 awt::Size
aPrefSize( mrPlayer
.getPreferredPlayerWindowSize() );
206 awt::Rectangle aRect
= getPosSize();
207 int nW
= aRect
.Width
, nH
= aRect
.Height
;
208 int nVideoW
= nW
, nVideoH
= nH
;
209 int nX
= 0, nY
= 0, nWidth
= 0, nHeight
= 0;
210 bool bDone
= false, bZoom
= false;
212 if( media::ZoomLevel_ORIGINAL
== meZoomLevel
)
216 else if( media::ZoomLevel_ZOOM_1_TO_4
== meZoomLevel
)
218 aPrefSize
.Width
>>= 2;
219 aPrefSize
.Height
>>= 2;
222 else if( media::ZoomLevel_ZOOM_1_TO_2
== meZoomLevel
)
224 aPrefSize
.Width
>>= 1;
225 aPrefSize
.Height
>>= 1;
228 else if( media::ZoomLevel_ZOOM_2_TO_1
== meZoomLevel
)
230 aPrefSize
.Width
<<= 1;
231 aPrefSize
.Height
<<= 1;
234 else if( media::ZoomLevel_ZOOM_4_TO_1
== meZoomLevel
)
236 aPrefSize
.Width
<<= 2;
237 aPrefSize
.Height
<<= 2;
240 else if( media::ZoomLevel_FIT_TO_WINDOW
== meZoomLevel
)
249 if( ( aPrefSize
.Width
<= nVideoW
) && ( aPrefSize
.Height
<= nVideoH
) )
251 nX
= ( nVideoW
- aPrefSize
.Width
) >> 1;
252 nY
= ( nVideoH
- aPrefSize
.Height
) >> 1;
253 nWidth
= aPrefSize
.Width
;
254 nHeight
= aPrefSize
.Height
;
261 if( aPrefSize
.Width
> 0 && aPrefSize
.Height
> 0 && nVideoW
> 0 && nVideoH
> 0 )
263 double fPrefWH
= (double) aPrefSize
.Width
/ aPrefSize
.Height
;
265 if( fPrefWH
< ( (double) nVideoW
/ nVideoH
) )
266 nVideoW
= (int)( nVideoH
* fPrefWH
);
268 nVideoH
= (int)( nVideoW
/ fPrefWH
);
270 nX
= ( nW
- nVideoW
) >> 1;
271 nY
= ( nH
- nVideoH
) >> 1;
276 nX
= nY
= nWidth
= nHeight
= 0;
279 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
282 pVideoWindow
->SetWindowPosition( nX
, nY
, nWidth
, nHeight
);
286 bool Window::create( const uno::Sequence
< uno::Any
>& rArguments
)
288 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
289 WNDCLASS
* mpWndClass
= lcl_getWndClass();
291 if( !mnFrameWnd
&& pVideoWindow
&& mpWndClass
)
293 awt::Rectangle aRect
;
296 rArguments
[ 0 ] >>= nWnd
;
297 rArguments
[ 1 ] >>= aRect
;
299 mnParentWnd
= static_cast<int>(nWnd
);
301 mnFrameWnd
= (int) ::CreateWindow( mpWndClass
->lpszClassName
, NULL
,
302 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
303 aRect
.X
, aRect
.Y
, aRect
.Width
, aRect
.Height
,
304 (HWND
) mnParentWnd
, NULL
, mpWndClass
->hInstance
, 0 );
308 ::SetWindowLong( (HWND
) mnFrameWnd
, 0, (DWORD
) this );
310 pVideoWindow
->put_Owner( (OAHWND
) mnFrameWnd
);
311 pVideoWindow
->put_MessageDrain( (OAHWND
) mnFrameWnd
);
312 pVideoWindow
->put_WindowStyle( WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
);
314 mrPlayer
.setNotifyWnd( mnFrameWnd
);
316 meZoomLevel
= media::ZoomLevel_FIT_TO_WINDOW
;
317 ImplLayoutVideoWindow();
321 return( mnFrameWnd
!= 0 );
324 void Window::processGraphEvent()
326 mrPlayer
.processEvent();
329 void Window::updatePointer()
333 switch( mnPointerType
)
335 case( awt::SystemPointer::CROSS
): pCursorName
= IDC_CROSS
; break;
336 case( awt::SystemPointer::MOVE
): pCursorName
= IDC_SIZEALL
; break;
337 case( awt::SystemPointer::WAIT
): pCursorName
= IDC_WAIT
; break;
340 pCursorName
= IDC_ARROW
;
344 ::SetCursor( ::LoadCursor( NULL
, pCursorName
) );
347 void SAL_CALL
Window::update( )
348 throw (uno::RuntimeException
)
350 ::RedrawWindow( (HWND
) mnFrameWnd
, NULL
, NULL
, RDW_ALLCHILDREN
| RDW_INVALIDATE
| RDW_UPDATENOW
| RDW_ERASE
);
353 sal_Bool SAL_CALL
Window::setZoomLevel( media::ZoomLevel eZoomLevel
)
354 throw (uno::RuntimeException
)
356 boolean bRet
= false;
358 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
&&
359 media::ZoomLevel_NOT_AVAILABLE
!= eZoomLevel
)
361 if( eZoomLevel
!= meZoomLevel
)
363 meZoomLevel
= eZoomLevel
;
364 ImplLayoutVideoWindow();
373 media::ZoomLevel SAL_CALL
Window::getZoomLevel( )
374 throw (uno::RuntimeException
)
379 void SAL_CALL
Window::setPointerType( sal_Int32 nPointerType
)
380 throw (uno::RuntimeException
)
382 mnPointerType
= nPointerType
;
385 void SAL_CALL
Window::setPosSize( sal_Int32 X
, sal_Int32 Y
, sal_Int32 Width
, sal_Int32 Height
, sal_Int16
)
386 throw (uno::RuntimeException
)
390 ::SetWindowPos( (HWND
) mnFrameWnd
, HWND_TOP
, X
, Y
, Width
, Height
, 0 );
391 ImplLayoutVideoWindow();
395 awt::Rectangle SAL_CALL
Window::getPosSize()
396 throw (uno::RuntimeException
)
404 if( ::GetClientRect( (HWND
) mnFrameWnd
, &aWndRect
) )
406 aRet
.X
= aWndRect
.left
;
407 aRet
.Y
= aWndRect
.top
;
408 aRet
.Width
= aWndRect
.right
- aWndRect
.left
+ 1;
409 aRet
.Height
= aWndRect
.bottom
- aWndRect
.top
+ 1;
416 void SAL_CALL
Window::setVisible( sal_Bool bVisible
)
417 throw (uno::RuntimeException
)
421 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
424 pVideoWindow
->put_Visible( bVisible
? OATRUE
: OAFALSE
);
426 ::ShowWindow( (HWND
) mnFrameWnd
, bVisible
? SW_SHOW
: SW_HIDE
);
430 void SAL_CALL
Window::setEnable( sal_Bool bEnable
)
431 throw (uno::RuntimeException
)
434 ::EnableWindow( (HWND
) mnFrameWnd
, bEnable
);
437 void SAL_CALL
Window::setFocus( )
438 throw (uno::RuntimeException
)
441 ::SetFocus( (HWND
) mnFrameWnd
);
444 void SAL_CALL
Window::addWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
445 throw (uno::RuntimeException
)
447 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
450 void SAL_CALL
Window::removeWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
451 throw (uno::RuntimeException
)
453 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
456 void SAL_CALL
Window::addFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
457 throw (uno::RuntimeException
)
459 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
462 void SAL_CALL
Window::removeFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
463 throw (uno::RuntimeException
)
465 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
468 void SAL_CALL
Window::addKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
469 throw (uno::RuntimeException
)
471 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
474 void SAL_CALL
Window::removeKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
475 throw (uno::RuntimeException
)
477 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
480 void SAL_CALL
Window::addMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
481 throw (uno::RuntimeException
)
483 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
486 void SAL_CALL
Window::removeMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
487 throw (uno::RuntimeException
)
489 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
492 void SAL_CALL
Window::addMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
493 throw (uno::RuntimeException
)
495 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
498 void SAL_CALL
Window::removeMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
499 throw (uno::RuntimeException
)
501 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
504 void SAL_CALL
Window::addPaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
505 throw (uno::RuntimeException
)
507 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
510 void SAL_CALL
Window::removePaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
511 throw (uno::RuntimeException
)
513 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
516 void SAL_CALL
Window::dispose( )
517 throw (uno::RuntimeException
)
521 void SAL_CALL
Window::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
522 throw (uno::RuntimeException
)
524 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
527 void SAL_CALL
Window::removeEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
528 throw (uno::RuntimeException
)
530 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
533 void Window::fireMousePressedEvent( const ::com::sun::star::awt::MouseEvent
& rEvt
)
535 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XMouseListener
>::get());
539 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
541 while( aIter
.hasMoreElements() )
542 uno::Reference
< awt::XMouseListener
>( aIter
.next(), uno::UNO_QUERY
)->mousePressed( rEvt
);
546 void Window::fireMouseReleasedEvent( const ::com::sun::star::awt::MouseEvent
& rEvt
)
548 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XMouseListener
>::get());
552 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
554 while( aIter
.hasMoreElements() )
555 uno::Reference
< awt::XMouseListener
>( aIter
.next(), uno::UNO_QUERY
)->mouseReleased( rEvt
);
559 void Window::fireMouseMovedEvent( const ::com::sun::star::awt::MouseEvent
& rEvt
)
561 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XMouseMotionListener
>::get());
565 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
567 while( aIter
.hasMoreElements() )
568 uno::Reference
< awt::XMouseMotionListener
>( aIter
.next(), uno::UNO_QUERY
)->mouseMoved( rEvt
);
572 void Window::fireSetFocusEvent( const ::com::sun::star::awt::FocusEvent
& rEvt
)
574 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XFocusListener
>::get());
578 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
580 while( aIter
.hasMoreElements() )
581 uno::Reference
< awt::XFocusListener
>( aIter
.next(), uno::UNO_QUERY
)->focusGained( rEvt
);
585 OUString SAL_CALL
Window::getImplementationName( )
586 throw (uno::RuntimeException
)
588 return OUString( AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME
);
591 sal_Bool SAL_CALL
Window::supportsService( const OUString
& ServiceName
)
592 throw (uno::RuntimeException
)
594 return cppu::supportsService(this, ServiceName
);
597 uno::Sequence
< OUString
> SAL_CALL
Window::getSupportedServiceNames( )
598 throw (uno::RuntimeException
)
600 uno::Sequence
< OUString
> aRet(1);
601 aRet
[0] = AVMEDIA_WIN_WINDOW_SERVICENAME
;
607 } // namespace avmedia
609 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */