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 .
25 #include <com/sun/star/awt/SystemPointer.hpp>
26 #include <cppuhelper/supportsservice.hxx>
31 #define AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Window_DirectX"
32 #define AVMEDIA_WIN_WINDOW_SERVICENAME "com.sun.star.media.Window_DirectX"
34 using namespace ::com::sun::star
;
36 namespace avmedia
{ namespace win
{
38 static LRESULT CALLBACK
MediaPlayerWndProc( HWND hWnd
,UINT nMsg
, WPARAM nPar1
, LPARAM nPar2
)
40 Window
* pWindow
= reinterpret_cast<Window
*>(GetWindowLongPtrW( hWnd
, 0 ));
41 bool bProcessed
= true;
48 pWindow
->updatePointer();
52 pWindow
->processGraphEvent();
62 PostMessage(pWindow
->getParentWnd(), nMsg
, nPar1
, nPar2
);
67 const awt::FocusEvent aUNOEvt
;
68 pWindow
->fireSetFocusEvent( aUNOEvt
);
80 return( bProcessed
? 0 : DefWindowProcW( hWnd
, nMsg
, nPar1
, nPar2
) );
83 static WNDCLASSW
* lcl_getWndClass()
85 WNDCLASSW
* s_pWndClass
= new WNDCLASSW
;
87 memset( s_pWndClass
, 0, sizeof( *s_pWndClass
) );
88 s_pWndClass
->hInstance
= GetModuleHandleW( nullptr );
89 s_pWndClass
->cbWndExtra
= sizeof( DWORD_PTR
);
90 s_pWndClass
->lpfnWndProc
= MediaPlayerWndProc
;
91 s_pWndClass
->lpszClassName
= L
"com_sun_star_media_PlayerWnd";
92 s_pWndClass
->hbrBackground
= static_cast<HBRUSH
>(::GetStockObject( BLACK_BRUSH
));
93 s_pWndClass
->hCursor
= ::LoadCursor( nullptr, IDC_ARROW
);
95 RegisterClassW( s_pWndClass
);
100 Window::Window( const uno::Reference
< lang::XMultiServiceFactory
>& rxMgr
, Player
& rPlayer
) :
102 maListeners( maMutex
),
103 meZoomLevel( media::ZoomLevel_NOT_AVAILABLE
),
105 mnFrameWnd( nullptr ),
106 mnParentWnd( nullptr ),
107 mnPointerType( awt::SystemPointer::ARROW
)
114 ::DestroyWindow( mnFrameWnd
);
117 void Window::ImplLayoutVideoWindow()
119 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
)
121 awt::Size
aPrefSize( mrPlayer
.getPreferredPlayerWindowSize() );
122 awt::Rectangle aRect
= getPosSize();
123 int nW
= aRect
.Width
, nH
= aRect
.Height
;
124 int nVideoW
= nW
, nVideoH
= nH
;
125 int nX
= 0, nY
= 0, nWidth
= 0, nHeight
= 0;
126 bool bDone
= false, bZoom
= false;
128 if( media::ZoomLevel_ORIGINAL
== meZoomLevel
)
132 else if( media::ZoomLevel_ZOOM_1_TO_4
== meZoomLevel
)
134 aPrefSize
.Width
>>= 2;
135 aPrefSize
.Height
>>= 2;
138 else if( media::ZoomLevel_ZOOM_1_TO_2
== meZoomLevel
)
140 aPrefSize
.Width
>>= 1;
141 aPrefSize
.Height
>>= 1;
144 else if( media::ZoomLevel_ZOOM_2_TO_1
== meZoomLevel
)
146 aPrefSize
.Width
<<= 1;
147 aPrefSize
.Height
<<= 1;
150 else if( media::ZoomLevel_ZOOM_4_TO_1
== meZoomLevel
)
152 aPrefSize
.Width
<<= 2;
153 aPrefSize
.Height
<<= 2;
156 else if( media::ZoomLevel_FIT_TO_WINDOW
== meZoomLevel
)
165 if( ( aPrefSize
.Width
<= nVideoW
) && ( aPrefSize
.Height
<= nVideoH
) )
167 nX
= ( nVideoW
- aPrefSize
.Width
) >> 1;
168 nY
= ( nVideoH
- aPrefSize
.Height
) >> 1;
169 nWidth
= aPrefSize
.Width
;
170 nHeight
= aPrefSize
.Height
;
177 if( aPrefSize
.Width
> 0 && aPrefSize
.Height
> 0 && nVideoW
> 0 && nVideoH
> 0 )
179 double fPrefWH
= static_cast<double>(aPrefSize
.Width
) / aPrefSize
.Height
;
181 if( fPrefWH
< ( static_cast<double>(nVideoW
) / nVideoH
) )
182 nVideoW
= static_cast<int>( nVideoH
* fPrefWH
);
184 nVideoH
= static_cast<int>( nVideoW
/ fPrefWH
);
186 nX
= ( nW
- nVideoW
) >> 1;
187 nY
= ( nH
- nVideoH
) >> 1;
192 nX
= nY
= nWidth
= nHeight
= 0;
195 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
198 pVideoWindow
->SetWindowPosition( nX
, nY
, nWidth
, nHeight
);
202 bool Window::create( const uno::Sequence
< uno::Any
>& rArguments
)
204 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
205 static WNDCLASSW
* mpWndClass
= lcl_getWndClass();
207 if( !mnFrameWnd
&& pVideoWindow
&& mpWndClass
)
209 awt::Rectangle aRect
;
212 rArguments
[ 0 ] >>= nWnd
;
213 rArguments
[ 1 ] >>= aRect
;
215 mnParentWnd
= reinterpret_cast<HWND
>(nWnd
);
217 mnFrameWnd
= CreateWindowW( mpWndClass
->lpszClassName
, nullptr,
218 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
219 aRect
.X
, aRect
.Y
, aRect
.Width
, aRect
.Height
,
220 mnParentWnd
, nullptr, mpWndClass
->hInstance
, nullptr );
224 SetWindowLongPtrW( mnFrameWnd
, 0, reinterpret_cast<LONG_PTR
>(this) );
226 pVideoWindow
->put_Owner( reinterpret_cast<OAHWND
>(mnFrameWnd
) );
227 pVideoWindow
->put_MessageDrain( reinterpret_cast<OAHWND
>(mnFrameWnd
) );
228 pVideoWindow
->put_WindowStyle( WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
);
230 mrPlayer
.setNotifyWnd( mnFrameWnd
);
232 meZoomLevel
= media::ZoomLevel_FIT_TO_WINDOW
;
233 ImplLayoutVideoWindow();
237 return( mnFrameWnd
!= nullptr );
240 void Window::processGraphEvent()
242 mrPlayer
.processEvent();
245 void Window::updatePointer()
249 switch( mnPointerType
)
251 case awt::SystemPointer::CROSS
: pCursorName
= IDC_CROSS
; break;
252 case awt::SystemPointer::MOVE
: pCursorName
= IDC_SIZEALL
; break;
253 case awt::SystemPointer::WAIT
: pCursorName
= IDC_WAIT
; break;
256 pCursorName
= IDC_ARROW
;
260 SetCursor( LoadCursor( nullptr, pCursorName
) );
263 void SAL_CALL
Window::update( )
265 ::RedrawWindow( mnFrameWnd
, nullptr, nullptr, RDW_ALLCHILDREN
| RDW_INVALIDATE
| RDW_UPDATENOW
| RDW_ERASE
);
268 sal_Bool SAL_CALL
Window::setZoomLevel( media::ZoomLevel eZoomLevel
)
270 boolean bRet
= false;
272 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
&&
273 media::ZoomLevel_NOT_AVAILABLE
!= eZoomLevel
)
275 if( eZoomLevel
!= meZoomLevel
)
277 meZoomLevel
= eZoomLevel
;
278 ImplLayoutVideoWindow();
287 media::ZoomLevel SAL_CALL
Window::getZoomLevel( )
292 void SAL_CALL
Window::setPointerType( sal_Int32 nPointerType
)
294 mnPointerType
= nPointerType
;
297 void SAL_CALL
Window::setPosSize( sal_Int32 X
, sal_Int32 Y
, sal_Int32 Width
, sal_Int32 Height
, sal_Int16
)
301 ::SetWindowPos( mnFrameWnd
, HWND_TOP
, X
, Y
, Width
, Height
, 0 );
302 ImplLayoutVideoWindow();
306 awt::Rectangle SAL_CALL
Window::getPosSize()
314 if( ::GetClientRect( mnFrameWnd
, &aWndRect
) )
316 aRet
.X
= aWndRect
.left
;
317 aRet
.Y
= aWndRect
.top
;
318 aRet
.Width
= aWndRect
.right
- aWndRect
.left
+ 1;
319 aRet
.Height
= aWndRect
.bottom
- aWndRect
.top
+ 1;
326 void SAL_CALL
Window::setVisible( sal_Bool bVisible
)
330 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
333 pVideoWindow
->put_Visible( bVisible
? OATRUE
: OAFALSE
);
335 ::ShowWindow( mnFrameWnd
, bVisible
? SW_SHOW
: SW_HIDE
);
339 void SAL_CALL
Window::setEnable( sal_Bool bEnable
)
342 ::EnableWindow( mnFrameWnd
, bEnable
);
345 void SAL_CALL
Window::setFocus( )
348 ::SetFocus( mnFrameWnd
);
351 void SAL_CALL
Window::addWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
353 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
356 void SAL_CALL
Window::removeWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
358 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
361 void SAL_CALL
Window::addFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
363 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
366 void SAL_CALL
Window::removeFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
368 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
371 void SAL_CALL
Window::addKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
373 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
376 void SAL_CALL
Window::removeKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
378 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
381 void SAL_CALL
Window::addMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
383 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
386 void SAL_CALL
Window::removeMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
388 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
391 void SAL_CALL
Window::addMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
393 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
396 void SAL_CALL
Window::removeMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
398 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
401 void SAL_CALL
Window::addPaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
403 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
406 void SAL_CALL
Window::removePaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
408 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
411 void SAL_CALL
Window::dispose( )
415 void SAL_CALL
Window::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
417 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
420 void SAL_CALL
Window::removeEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
422 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
425 void Window::fireMousePressedEvent( const css::awt::MouseEvent
& rEvt
)
427 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XMouseListener
>::get());
431 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
433 while( aIter
.hasMoreElements() )
434 uno::Reference
< awt::XMouseListener
>( aIter
.next(), uno::UNO_QUERY_THROW
)->mousePressed( rEvt
);
438 void Window::fireMouseReleasedEvent( const css::awt::MouseEvent
& rEvt
)
440 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XMouseListener
>::get());
444 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
446 while( aIter
.hasMoreElements() )
447 uno::Reference
< awt::XMouseListener
>( aIter
.next(), uno::UNO_QUERY_THROW
)->mouseReleased( rEvt
);
451 void Window::fireMouseMovedEvent( const css::awt::MouseEvent
& rEvt
)
453 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XMouseMotionListener
>::get());
457 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
459 while( aIter
.hasMoreElements() )
460 uno::Reference
< awt::XMouseMotionListener
>( aIter
.next(), uno::UNO_QUERY_THROW
)->mouseMoved( rEvt
);
464 void Window::fireSetFocusEvent( const css::awt::FocusEvent
& rEvt
)
466 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XFocusListener
>::get());
470 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
472 while( aIter
.hasMoreElements() )
473 uno::Reference
< awt::XFocusListener
>( aIter
.next(), uno::UNO_QUERY_THROW
)->focusGained( rEvt
);
477 OUString SAL_CALL
Window::getImplementationName( )
479 return OUString( AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME
);
482 sal_Bool SAL_CALL
Window::supportsService( const OUString
& ServiceName
)
484 return cppu::supportsService(this, ServiceName
);
487 uno::Sequence
< OUString
> SAL_CALL
Window::getSupportedServiceNames( )
489 return { AVMEDIA_WIN_WINDOW_SERVICENAME
};
493 } // namespace avmedia
495 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */