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::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( Player
& rPlayer
) :
101 maListeners( maMutex
),
102 meZoomLevel( media::ZoomLevel_NOT_AVAILABLE
),
104 mnFrameWnd( nullptr ),
105 mnParentWnd( nullptr ),
106 mnPointerType( awt::SystemPointer::ARROW
)
113 ::DestroyWindow( mnFrameWnd
);
116 void Window::ImplLayoutVideoWindow()
118 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
)
120 awt::Size
aPrefSize( mrPlayer
.getPreferredPlayerWindowSize() );
121 awt::Rectangle aRect
= getPosSize();
122 int nW
= aRect
.Width
, nH
= aRect
.Height
;
123 int nVideoW
= nW
, nVideoH
= nH
;
124 int nX
= 0, nY
= 0, nWidth
= 0, nHeight
= 0;
125 bool bDone
= false, bZoom
= false;
127 if( media::ZoomLevel_ORIGINAL
== meZoomLevel
)
131 else if( media::ZoomLevel_ZOOM_1_TO_4
== meZoomLevel
)
133 aPrefSize
.Width
>>= 2;
134 aPrefSize
.Height
>>= 2;
137 else if( media::ZoomLevel_ZOOM_1_TO_2
== meZoomLevel
)
139 aPrefSize
.Width
>>= 1;
140 aPrefSize
.Height
>>= 1;
143 else if( media::ZoomLevel_ZOOM_2_TO_1
== meZoomLevel
)
145 aPrefSize
.Width
<<= 1;
146 aPrefSize
.Height
<<= 1;
149 else if( media::ZoomLevel_ZOOM_4_TO_1
== meZoomLevel
)
151 aPrefSize
.Width
<<= 2;
152 aPrefSize
.Height
<<= 2;
155 else if( media::ZoomLevel_FIT_TO_WINDOW
== meZoomLevel
)
164 if( ( aPrefSize
.Width
<= nVideoW
) && ( aPrefSize
.Height
<= nVideoH
) )
166 nX
= ( nVideoW
- aPrefSize
.Width
) >> 1;
167 nY
= ( nVideoH
- aPrefSize
.Height
) >> 1;
168 nWidth
= aPrefSize
.Width
;
169 nHeight
= aPrefSize
.Height
;
176 if( aPrefSize
.Width
> 0 && aPrefSize
.Height
> 0 && nVideoW
> 0 && nVideoH
> 0 )
178 double fPrefWH
= static_cast<double>(aPrefSize
.Width
) / aPrefSize
.Height
;
180 if( fPrefWH
< ( static_cast<double>(nVideoW
) / nVideoH
) )
181 nVideoW
= static_cast<int>( nVideoH
* fPrefWH
);
183 nVideoH
= static_cast<int>( nVideoW
/ fPrefWH
);
185 nX
= ( nW
- nVideoW
) >> 1;
186 nY
= ( nH
- nVideoH
) >> 1;
191 nX
= nY
= nWidth
= nHeight
= 0;
194 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
197 pVideoWindow
->SetWindowPosition( nX
, nY
, nWidth
, nHeight
);
201 bool Window::create( const uno::Sequence
< uno::Any
>& rArguments
)
203 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
204 static WNDCLASSW
* mpWndClass
= lcl_getWndClass();
206 if( !mnFrameWnd
&& pVideoWindow
&& mpWndClass
)
208 awt::Rectangle aRect
;
211 rArguments
[ 0 ] >>= nWnd
;
212 rArguments
[ 1 ] >>= aRect
;
214 mnParentWnd
= reinterpret_cast<HWND
>(nWnd
);
216 mnFrameWnd
= CreateWindowW( mpWndClass
->lpszClassName
, nullptr,
217 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
218 aRect
.X
, aRect
.Y
, aRect
.Width
, aRect
.Height
,
219 mnParentWnd
, nullptr, mpWndClass
->hInstance
, nullptr );
223 SetWindowLongPtrW( mnFrameWnd
, 0, reinterpret_cast<LONG_PTR
>(this) );
225 pVideoWindow
->put_Owner( reinterpret_cast<OAHWND
>(mnFrameWnd
) );
226 pVideoWindow
->put_MessageDrain( reinterpret_cast<OAHWND
>(mnFrameWnd
) );
227 pVideoWindow
->put_WindowStyle( WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
);
229 mrPlayer
.setNotifyWnd( mnFrameWnd
);
231 meZoomLevel
= media::ZoomLevel_FIT_TO_WINDOW
;
232 ImplLayoutVideoWindow();
236 return( mnFrameWnd
!= nullptr );
239 void Window::processGraphEvent()
241 mrPlayer
.processEvent();
244 void Window::updatePointer()
248 switch( mnPointerType
)
250 case awt::SystemPointer::CROSS
: pCursorName
= IDC_CROSS
; break;
251 case awt::SystemPointer::MOVE
: pCursorName
= IDC_SIZEALL
; break;
252 case awt::SystemPointer::WAIT
: pCursorName
= IDC_WAIT
; break;
255 pCursorName
= IDC_ARROW
;
259 SetCursor( LoadCursor( nullptr, pCursorName
) );
262 void SAL_CALL
Window::update( )
264 ::RedrawWindow( mnFrameWnd
, nullptr, nullptr, RDW_ALLCHILDREN
| RDW_INVALIDATE
| RDW_UPDATENOW
| RDW_ERASE
);
267 sal_Bool SAL_CALL
Window::setZoomLevel( media::ZoomLevel eZoomLevel
)
271 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
&&
272 media::ZoomLevel_NOT_AVAILABLE
!= eZoomLevel
)
274 if( eZoomLevel
!= meZoomLevel
)
276 meZoomLevel
= eZoomLevel
;
277 ImplLayoutVideoWindow();
286 media::ZoomLevel SAL_CALL
Window::getZoomLevel( )
291 void SAL_CALL
Window::setPointerType( sal_Int32 nPointerType
)
293 mnPointerType
= nPointerType
;
296 void SAL_CALL
Window::setPosSize( sal_Int32 X
, sal_Int32 Y
, sal_Int32 Width
, sal_Int32 Height
, sal_Int16
)
300 ::SetWindowPos( mnFrameWnd
, HWND_TOP
, X
, Y
, Width
, Height
, 0 );
301 ImplLayoutVideoWindow();
305 awt::Rectangle SAL_CALL
Window::getPosSize()
313 if( ::GetClientRect( mnFrameWnd
, &aWndRect
) )
315 aRet
.X
= aWndRect
.left
;
316 aRet
.Y
= aWndRect
.top
;
317 aRet
.Width
= aWndRect
.right
- aWndRect
.left
+ 1;
318 aRet
.Height
= aWndRect
.bottom
- aWndRect
.top
+ 1;
325 void SAL_CALL
Window::setVisible( sal_Bool bVisible
)
329 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
332 pVideoWindow
->put_Visible( bVisible
? OATRUE
: OAFALSE
);
334 ::ShowWindow( mnFrameWnd
, bVisible
? SW_SHOW
: SW_HIDE
);
338 void SAL_CALL
Window::setEnable( sal_Bool bEnable
)
341 ::EnableWindow( mnFrameWnd
, bEnable
);
344 void SAL_CALL
Window::setFocus( )
347 ::SetFocus( mnFrameWnd
);
350 void SAL_CALL
Window::addWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
352 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
355 void SAL_CALL
Window::removeWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
357 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
360 void SAL_CALL
Window::addFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
362 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
365 void SAL_CALL
Window::removeFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
367 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
370 void SAL_CALL
Window::addKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
372 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
375 void SAL_CALL
Window::removeKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
377 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
380 void SAL_CALL
Window::addMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
382 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
385 void SAL_CALL
Window::removeMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
387 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
390 void SAL_CALL
Window::addMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
392 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
395 void SAL_CALL
Window::removeMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
397 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
400 void SAL_CALL
Window::addPaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
402 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
405 void SAL_CALL
Window::removePaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
407 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
410 void SAL_CALL
Window::dispose( )
414 void SAL_CALL
Window::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
416 maListeners
.addInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
419 void SAL_CALL
Window::removeEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
421 maListeners
.removeInterface( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
424 void Window::fireMousePressedEvent( const css::awt::MouseEvent
& rEvt
)
426 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XMouseListener
>::get());
430 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
432 while( aIter
.hasMoreElements() )
433 uno::Reference
< awt::XMouseListener
>( aIter
.next(), uno::UNO_QUERY_THROW
)->mousePressed( rEvt
);
437 void Window::fireMouseReleasedEvent( const css::awt::MouseEvent
& rEvt
)
439 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XMouseListener
>::get());
443 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
445 while( aIter
.hasMoreElements() )
446 uno::Reference
< awt::XMouseListener
>( aIter
.next(), uno::UNO_QUERY_THROW
)->mouseReleased( rEvt
);
450 void Window::fireMouseMovedEvent( const css::awt::MouseEvent
& rEvt
)
452 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XMouseMotionListener
>::get());
456 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
458 while( aIter
.hasMoreElements() )
459 uno::Reference
< awt::XMouseMotionListener
>( aIter
.next(), uno::UNO_QUERY_THROW
)->mouseMoved( rEvt
);
463 void Window::fireSetFocusEvent( const css::awt::FocusEvent
& rEvt
)
465 ::cppu::OInterfaceContainerHelper
* pContainer
= maListeners
.getContainer( cppu::UnoType
<awt::XFocusListener
>::get());
469 ::cppu::OInterfaceIteratorHelper
aIter( *pContainer
);
471 while( aIter
.hasMoreElements() )
472 uno::Reference
< awt::XFocusListener
>( aIter
.next(), uno::UNO_QUERY_THROW
)->focusGained( rEvt
);
476 OUString SAL_CALL
Window::getImplementationName( )
478 return AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME
;
481 sal_Bool SAL_CALL
Window::supportsService( const OUString
& ServiceName
)
483 return cppu::supportsService(this, ServiceName
);
486 uno::Sequence
< OUString
> SAL_CALL
Window::getSupportedServiceNames( )
488 return { AVMEDIA_WIN_WINDOW_SERVICENAME
};
491 } // namespace avmedia::win
494 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */