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>
37 #define AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Window_DirectX"
38 #define AVMEDIA_WIN_WINDOW_SERVICENAME "com.sun.star.media.Window_DirectX"
40 using namespace ::com::sun::star
;
42 namespace avmedia
{ namespace win
{
44 static ::osl::Mutex
& ImplGetOwnStaticMutex()
46 static ::osl::Mutex
* pMutex
= NULL
;
50 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
54 static ::osl::Mutex aMutex
;
62 LRESULT CALLBACK
MediaPlayerWndProc( HWND hWnd
,UINT nMsg
, WPARAM nPar1
, LPARAM nPar2
)
64 Window
* pWindow
= (Window
*) ::GetWindowLong( hWnd
, 0 );
65 bool bProcessed
= true;
72 pWindow
->updatePointer();
75 case( WM_GRAPHNOTIFY
):
76 pWindow
->processGraphEvent();
80 case( WM_LBUTTONDOWN
):
81 case( WM_MBUTTONDOWN
):
82 case( WM_RBUTTONDOWN
):
87 awt::MouseEvent aUNOEvt
;
90 if( !::GetCursorPos( &aWinPoint
) || !::ScreenToClient( hWnd
, &aWinPoint
) )
92 aWinPoint
.x
= GET_X_LPARAM( nPar2
);
93 aWinPoint
.y
= GET_Y_LPARAM( nPar2
);
95 aUNOEvt
.Modifiers
= 0;
97 aUNOEvt
.X
= aWinPoint
.x
;
98 aUNOEvt
.Y
= aWinPoint
.y
;
99 aUNOEvt
.PopupTrigger
= false;
102 if( nPar1
& MK_SHIFT
)
103 aUNOEvt
.Modifiers
|= awt::KeyModifier::SHIFT
;
105 if( nPar1
& MK_CONTROL
)
106 aUNOEvt
.Modifiers
|= awt::KeyModifier::MOD1
;
109 if( WM_LBUTTONDOWN
== nMsg
|| WM_LBUTTONUP
== nMsg
)
110 aUNOEvt
.Buttons
|= awt::MouseButton::LEFT
;
112 if( WM_MBUTTONDOWN
== nMsg
|| WM_MBUTTONUP
== nMsg
)
113 aUNOEvt
.Buttons
|= awt::MouseButton::MIDDLE
;
115 if( WM_RBUTTONDOWN
== nMsg
|| WM_RBUTTONUP
== nMsg
)
116 aUNOEvt
.Buttons
|= awt::MouseButton::RIGHT
;
119 if( WM_LBUTTONDOWN
== nMsg
||
120 WM_MBUTTONDOWN
== nMsg
||
121 WM_RBUTTONDOWN
== nMsg
)
123 aUNOEvt
.ClickCount
= 1;
124 pWindow
->fireMousePressedEvent( aUNOEvt
);
126 else if( WM_LBUTTONUP
== nMsg
||
127 WM_MBUTTONUP
== nMsg
||
128 WM_RBUTTONUP
== nMsg
)
130 aUNOEvt
.ClickCount
= 1;
131 pWindow
->fireMouseReleasedEvent( aUNOEvt
);
133 else if( WM_MOUSEMOVE
== nMsg
)
135 aUNOEvt
.ClickCount
= 0;
136 pWindow
->fireMouseMovedEvent( aUNOEvt
);
137 pWindow
->updatePointer();
144 const awt::FocusEvent aUNOEvt
;
145 pWindow
->fireSetFocusEvent( aUNOEvt
);
157 return( bProcessed
? 0 : DefWindowProc( hWnd
, nMsg
, nPar1
, nPar2
) );
160 WNDCLASS
* lcl_getWndClass()
162 static WNDCLASS
* s_pWndClass
= NULL
;
165 s_pWndClass
= new WNDCLASS
;
167 memset( s_pWndClass
, 0, sizeof( *s_pWndClass
) );
168 s_pWndClass
->hInstance
= GetModuleHandle( NULL
);
169 s_pWndClass
->cbWndExtra
= sizeof( DWORD
);
170 s_pWndClass
->lpfnWndProc
= MediaPlayerWndProc
;
171 s_pWndClass
->lpszClassName
= "com_sun_star_media_PlayerWnd";
172 s_pWndClass
->hbrBackground
= (HBRUSH
) ::GetStockObject( BLACK_BRUSH
);
173 s_pWndClass
->hCursor
= ::LoadCursor( NULL
, IDC_ARROW
);
175 ::RegisterClass( s_pWndClass
);
180 Window::Window( const uno::Reference
< lang::XMultiServiceFactory
>& rxMgr
, Player
& rPlayer
) :
183 meZoomLevel( media::ZoomLevel_NOT_AVAILABLE
),
186 maListeners( maMutex
),
187 mnPointerType( awt::SystemPointer::ARROW
)
189 ::osl::MutexGuard
aGuard( ImplGetOwnStaticMutex() );
197 ::DestroyWindow( (HWND
) mnFrameWnd
);
200 void Window::ImplLayoutVideoWindow()
202 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
)
204 awt::Size
aPrefSize( mrPlayer
.getPreferredPlayerWindowSize() );
205 awt::Rectangle aRect
= getPosSize();
206 int nW
= aRect
.Width
, nH
= aRect
.Height
;
207 int nVideoW
= nW
, nVideoH
= nH
;
208 int nX
= 0, nY
= 0, nWidth
= 0, nHeight
= 0;
209 bool bDone
= false, bZoom
= false;
211 if( media::ZoomLevel_ORIGINAL
== meZoomLevel
)
215 else if( media::ZoomLevel_ZOOM_1_TO_4
== meZoomLevel
)
217 aPrefSize
.Width
>>= 2;
218 aPrefSize
.Height
>>= 2;
221 else if( media::ZoomLevel_ZOOM_1_TO_2
== meZoomLevel
)
223 aPrefSize
.Width
>>= 1;
224 aPrefSize
.Height
>>= 1;
227 else if( media::ZoomLevel_ZOOM_2_TO_1
== meZoomLevel
)
229 aPrefSize
.Width
<<= 1;
230 aPrefSize
.Height
<<= 1;
233 else if( media::ZoomLevel_ZOOM_4_TO_1
== meZoomLevel
)
235 aPrefSize
.Width
<<= 2;
236 aPrefSize
.Height
<<= 2;
239 else if( media::ZoomLevel_FIT_TO_WINDOW
== meZoomLevel
)
248 if( ( aPrefSize
.Width
<= nVideoW
) && ( aPrefSize
.Height
<= nVideoH
) )
250 nX
= ( nVideoW
- aPrefSize
.Width
) >> 1;
251 nY
= ( nVideoH
- aPrefSize
.Height
) >> 1;
252 nWidth
= aPrefSize
.Width
;
253 nHeight
= aPrefSize
.Height
;
260 if( aPrefSize
.Width
> 0 && aPrefSize
.Height
> 0 && nVideoW
> 0 && nVideoH
> 0 )
262 double fPrefWH
= (double) aPrefSize
.Width
/ aPrefSize
.Height
;
264 if( fPrefWH
< ( (double) nVideoW
/ nVideoH
) )
265 nVideoW
= (int)( nVideoH
* fPrefWH
);
267 nVideoH
= (int)( nVideoW
/ fPrefWH
);
269 nX
= ( nW
- nVideoW
) >> 1;
270 nY
= ( nH
- nVideoH
) >> 1;
275 nX
= nY
= nWidth
= nHeight
= 0;
278 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
281 pVideoWindow
->SetWindowPosition( nX
, nY
, nWidth
, nHeight
);
285 bool Window::create( const uno::Sequence
< uno::Any
>& rArguments
)
287 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
288 WNDCLASS
* mpWndClass
= lcl_getWndClass();
290 if( !mnFrameWnd
&& pVideoWindow
&& mpWndClass
)
292 awt::Rectangle aRect
;
295 rArguments
[ 0 ] >>= nWnd
;
296 rArguments
[ 1 ] >>= aRect
;
298 mnParentWnd
= static_cast<int>(nWnd
);
300 mnFrameWnd
= (int) ::CreateWindow( mpWndClass
->lpszClassName
, NULL
,
301 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
302 aRect
.X
, aRect
.Y
, aRect
.Width
, aRect
.Height
,
303 (HWND
) mnParentWnd
, NULL
, mpWndClass
->hInstance
, 0 );
305 // if the last CreateWindow failed...
306 if( mnFrameWnd
== 0 )
308 // try again and this time assume that mnParent is indeed a dc
309 mnParentWnd
= reinterpret_cast<int>(::WindowFromDC( (HDC
)mnParentWnd
));
310 mnFrameWnd
= (int) ::CreateWindow( mpWndClass
->lpszClassName
, NULL
,
311 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
312 aRect
.X
, aRect
.Y
, aRect
.Width
, aRect
.Height
,
313 (HWND
)mnParentWnd
, NULL
, mpWndClass
->hInstance
, 0 );
318 ::SetWindowLong( (HWND
) mnFrameWnd
, 0, (DWORD
) this );
320 pVideoWindow
->put_Owner( (OAHWND
) mnFrameWnd
);
321 pVideoWindow
->put_MessageDrain( (OAHWND
) mnFrameWnd
);
322 pVideoWindow
->put_WindowStyle( WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
);
324 mrPlayer
.setNotifyWnd( mnFrameWnd
);
326 meZoomLevel
= media::ZoomLevel_FIT_TO_WINDOW
;
327 ImplLayoutVideoWindow();
331 return( mnFrameWnd
!= 0 );
334 void Window::processGraphEvent()
336 mrPlayer
.processEvent();
339 void Window::updatePointer()
343 switch( mnPointerType
)
345 case( awt::SystemPointer::CROSS
): pCursorName
= IDC_CROSS
; break;
346 case( awt::SystemPointer::MOVE
): pCursorName
= IDC_SIZEALL
; break;
347 case( awt::SystemPointer::WAIT
): pCursorName
= IDC_WAIT
; break;
350 pCursorName
= IDC_ARROW
;
354 ::SetCursor( ::LoadCursor( NULL
, pCursorName
) );
357 void SAL_CALL
Window::update( )
358 throw (uno::RuntimeException
)
360 ::RedrawWindow( (HWND
) mnFrameWnd
, NULL
, NULL
, RDW_ALLCHILDREN
| RDW_INVALIDATE
| RDW_UPDATENOW
| RDW_ERASE
);
363 sal_Bool SAL_CALL
Window::setZoomLevel( media::ZoomLevel eZoomLevel
)
364 throw (uno::RuntimeException
)
366 boolean bRet
= false;
368 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
&&
369 media::ZoomLevel_NOT_AVAILABLE
!= eZoomLevel
)
371 if( eZoomLevel
!= meZoomLevel
)
373 meZoomLevel
= eZoomLevel
;
374 ImplLayoutVideoWindow();
383 media::ZoomLevel SAL_CALL
Window::getZoomLevel( )
384 throw (uno::RuntimeException
)
389 void SAL_CALL
Window::setPointerType( sal_Int32 nPointerType
)
390 throw (uno::RuntimeException
)
392 mnPointerType
= nPointerType
;
395 void SAL_CALL
Window::setPosSize( sal_Int32 X
, sal_Int32 Y
, sal_Int32 Width
, sal_Int32 Height
, sal_Int16
)
396 throw (uno::RuntimeException
)
400 ::SetWindowPos( (HWND
) mnFrameWnd
, HWND_TOP
, X
, Y
, Width
, Height
, 0 );
401 ImplLayoutVideoWindow();
405 awt::Rectangle SAL_CALL
Window::getPosSize()
406 throw (uno::RuntimeException
)
414 if( ::GetClientRect( (HWND
) mnFrameWnd
, &aWndRect
) )
416 aRet
.X
= aWndRect
.left
;
417 aRet
.Y
= aWndRect
.top
;
418 aRet
.Width
= aWndRect
.right
- aWndRect
.left
+ 1;
419 aRet
.Height
= aWndRect
.bottom
- aWndRect
.top
+ 1;
426 void SAL_CALL
Window::setVisible( sal_Bool bVisible
)
427 throw (uno::RuntimeException
)
431 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
434 pVideoWindow
->put_Visible( bVisible
? OATRUE
: OAFALSE
);
436 ::ShowWindow( (HWND
) mnFrameWnd
, bVisible
? SW_SHOW
: SW_HIDE
);
440 void SAL_CALL
Window::setEnable( sal_Bool bEnable
)
441 throw (uno::RuntimeException
)
444 ::EnableWindow( (HWND
) mnFrameWnd
, bEnable
);
447 void SAL_CALL
Window::setFocus( )
448 throw (uno::RuntimeException
)
451 ::SetFocus( (HWND
) mnFrameWnd
);
454 void SAL_CALL
Window::addWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
455 throw (uno::RuntimeException
)
457 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
460 void SAL_CALL
Window::removeWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
461 throw (uno::RuntimeException
)
463 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
466 void SAL_CALL
Window::addFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
467 throw (uno::RuntimeException
)
469 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
472 void SAL_CALL
Window::removeFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
473 throw (uno::RuntimeException
)
475 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
478 void SAL_CALL
Window::addKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
479 throw (uno::RuntimeException
)
481 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
484 void SAL_CALL
Window::removeKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
485 throw (uno::RuntimeException
)
487 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
490 void SAL_CALL
Window::addMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
491 throw (uno::RuntimeException
)
493 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
496 void SAL_CALL
Window::removeMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
497 throw (uno::RuntimeException
)
499 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
502 void SAL_CALL
Window::addMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
503 throw (uno::RuntimeException
)
505 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
508 void SAL_CALL
Window::removeMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
509 throw (uno::RuntimeException
)
511 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
514 void SAL_CALL
Window::addPaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
515 throw (uno::RuntimeException
)
517 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
520 void SAL_CALL
Window::removePaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
521 throw (uno::RuntimeException
)
523 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
526 void SAL_CALL
Window::dispose( )
527 throw (uno::RuntimeException
)
531 void SAL_CALL
Window::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
532 throw (uno::RuntimeException
)
534 maListeners
.addInterface( getCppuType( &xListener
), xListener
);
537 void SAL_CALL
Window::removeEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
538 throw (uno::RuntimeException
)
540 maListeners
.removeInterface( getCppuType( &xListener
), xListener
);
543 void Window::fireMousePressedEvent( const ::com::sun::star::awt::MouseEvent
& rEvt
)
545 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( getCppuType( (uno::Reference
< awt::XMouseListener
>*) 0 ) );
549 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
551 while( aIter
.hasMoreElements() )
552 uno::Reference
< awt::XMouseListener
>( aIter
.next(), uno::UNO_QUERY
)->mousePressed( rEvt
);
556 void Window::fireMouseReleasedEvent( const ::com::sun::star::awt::MouseEvent
& rEvt
)
558 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( getCppuType( (uno::Reference
< awt::XMouseListener
>*) 0 ) );
562 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
564 while( aIter
.hasMoreElements() )
565 uno::Reference
< awt::XMouseListener
>( aIter
.next(), uno::UNO_QUERY
)->mouseReleased( rEvt
);
569 void Window::fireMouseMovedEvent( const ::com::sun::star::awt::MouseEvent
& rEvt
)
571 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( getCppuType( (uno::Reference
< awt::XMouseMotionListener
>*) 0 ) );
575 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
577 while( aIter
.hasMoreElements() )
578 uno::Reference
< awt::XMouseMotionListener
>( aIter
.next(), uno::UNO_QUERY
)->mouseMoved( rEvt
);
582 void Window::fireSetFocusEvent( const ::com::sun::star::awt::FocusEvent
& rEvt
)
584 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( getCppuType( (uno::Reference
< awt::XFocusListener
>*) 0 ) );
588 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
590 while( aIter
.hasMoreElements() )
591 uno::Reference
< awt::XFocusListener
>( aIter
.next(), uno::UNO_QUERY
)->focusGained( rEvt
);
595 OUString SAL_CALL
Window::getImplementationName( )
596 throw (uno::RuntimeException
)
598 return OUString( AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME
);
601 sal_Bool SAL_CALL
Window::supportsService( const OUString
& ServiceName
)
602 throw (uno::RuntimeException
)
604 return ServiceName
== AVMEDIA_WIN_WINDOW_SERVICENAME
;
607 uno::Sequence
< OUString
> SAL_CALL
Window::getSupportedServiceNames( )
608 throw (uno::RuntimeException
)
610 uno::Sequence
< OUString
> aRet(1);
611 aRet
[0] = AVMEDIA_WIN_WINDOW_SERVICENAME
;
617 } // namespace avmedia
619 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */