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 constexpr OUStringLiteral AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME
= u
"com.sun.star.comp.avmedia.Window_DirectX";
32 constexpr OUString AVMEDIA_WIN_WINDOW_SERVICENAME
= u
"com.sun.star.media.Window_DirectX"_ustr
;
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 meZoomLevel( media::ZoomLevel_NOT_AVAILABLE
),
103 mnFrameWnd( nullptr ),
104 mnParentWnd( nullptr ),
105 mnPointerType( awt::SystemPointer::ARROW
)
112 ::DestroyWindow( mnFrameWnd
);
115 void Window::ImplLayoutVideoWindow()
117 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
)
119 awt::Size
aPrefSize( mrPlayer
.getPreferredPlayerWindowSize() );
120 awt::Rectangle aRect
= getPosSize();
121 int nW
= aRect
.Width
, nH
= aRect
.Height
;
122 int nVideoW
= nW
, nVideoH
= nH
;
123 int nX
= 0, nY
= 0, nWidth
= 0, nHeight
= 0;
124 bool bDone
= false, bZoom
= false;
126 if( media::ZoomLevel_ORIGINAL
== meZoomLevel
)
130 else if( media::ZoomLevel_ZOOM_1_TO_4
== meZoomLevel
)
132 aPrefSize
.Width
>>= 2;
133 aPrefSize
.Height
>>= 2;
136 else if( media::ZoomLevel_ZOOM_1_TO_2
== meZoomLevel
)
138 aPrefSize
.Width
>>= 1;
139 aPrefSize
.Height
>>= 1;
142 else if( media::ZoomLevel_ZOOM_2_TO_1
== meZoomLevel
)
144 aPrefSize
.Width
<<= 1;
145 aPrefSize
.Height
<<= 1;
148 else if( media::ZoomLevel_ZOOM_4_TO_1
== meZoomLevel
)
150 aPrefSize
.Width
<<= 2;
151 aPrefSize
.Height
<<= 2;
154 else if( media::ZoomLevel_FIT_TO_WINDOW
== meZoomLevel
)
163 if( ( aPrefSize
.Width
<= nVideoW
) && ( aPrefSize
.Height
<= nVideoH
) )
165 nX
= ( nVideoW
- aPrefSize
.Width
) >> 1;
166 nY
= ( nVideoH
- aPrefSize
.Height
) >> 1;
167 nWidth
= aPrefSize
.Width
;
168 nHeight
= aPrefSize
.Height
;
175 if( aPrefSize
.Width
> 0 && aPrefSize
.Height
> 0 && nVideoW
> 0 && nVideoH
> 0 )
177 double fPrefWH
= static_cast<double>(aPrefSize
.Width
) / aPrefSize
.Height
;
179 if( fPrefWH
< ( static_cast<double>(nVideoW
) / nVideoH
) )
180 nVideoW
= static_cast<int>( nVideoH
* fPrefWH
);
182 nVideoH
= static_cast<int>( nVideoW
/ fPrefWH
);
184 nX
= ( nW
- nVideoW
) >> 1;
185 nY
= ( nH
- nVideoH
) >> 1;
190 nX
= nY
= nWidth
= nHeight
= 0;
193 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
196 pVideoWindow
->SetWindowPosition( nX
, nY
, nWidth
, nHeight
);
200 bool Window::create( const uno::Sequence
< uno::Any
>& rArguments
)
202 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
203 static WNDCLASSW
* mpWndClass
= lcl_getWndClass();
205 if( !mnFrameWnd
&& pVideoWindow
&& mpWndClass
)
207 awt::Rectangle aRect
;
210 rArguments
[ 0 ] >>= nWnd
;
211 rArguments
[ 1 ] >>= aRect
;
213 mnParentWnd
= reinterpret_cast<HWND
>(nWnd
);
215 mnFrameWnd
= CreateWindowW( mpWndClass
->lpszClassName
, nullptr,
216 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
217 aRect
.X
, aRect
.Y
, aRect
.Width
, aRect
.Height
,
218 mnParentWnd
, nullptr, mpWndClass
->hInstance
, nullptr );
222 SetWindowLongPtrW( mnFrameWnd
, 0, reinterpret_cast<LONG_PTR
>(this) );
224 pVideoWindow
->put_Owner( reinterpret_cast<OAHWND
>(mnFrameWnd
) );
225 pVideoWindow
->put_MessageDrain( reinterpret_cast<OAHWND
>(mnFrameWnd
) );
226 pVideoWindow
->put_WindowStyle( WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
);
228 mrPlayer
.setNotifyWnd( mnFrameWnd
);
230 meZoomLevel
= media::ZoomLevel_FIT_TO_WINDOW
;
231 ImplLayoutVideoWindow();
235 return( mnFrameWnd
!= nullptr );
238 void Window::processGraphEvent()
240 mrPlayer
.processEvent();
243 void Window::updatePointer()
247 switch( mnPointerType
)
249 case awt::SystemPointer::CROSS
: pCursorName
= IDC_CROSS
; break;
250 case awt::SystemPointer::MOVE
: pCursorName
= IDC_SIZEALL
; break;
251 case awt::SystemPointer::WAIT
: pCursorName
= IDC_WAIT
; break;
254 pCursorName
= IDC_ARROW
;
258 SetCursor( LoadCursor( nullptr, pCursorName
) );
261 void SAL_CALL
Window::update( )
263 ::RedrawWindow( mnFrameWnd
, nullptr, nullptr, RDW_ALLCHILDREN
| RDW_INVALIDATE
| RDW_UPDATENOW
| RDW_ERASE
);
266 sal_Bool SAL_CALL
Window::setZoomLevel( media::ZoomLevel eZoomLevel
)
270 if( media::ZoomLevel_NOT_AVAILABLE
!= meZoomLevel
&&
271 media::ZoomLevel_NOT_AVAILABLE
!= eZoomLevel
)
273 if( eZoomLevel
!= meZoomLevel
)
275 meZoomLevel
= eZoomLevel
;
276 ImplLayoutVideoWindow();
285 media::ZoomLevel SAL_CALL
Window::getZoomLevel( )
290 void SAL_CALL
Window::setPointerType( sal_Int32 nPointerType
)
292 mnPointerType
= nPointerType
;
295 void SAL_CALL
Window::setPosSize( sal_Int32 X
, sal_Int32 Y
, sal_Int32 Width
, sal_Int32 Height
, sal_Int16
)
299 ::SetWindowPos( mnFrameWnd
, HWND_TOP
, X
, Y
, Width
, Height
, 0 );
300 ImplLayoutVideoWindow();
304 awt::Rectangle SAL_CALL
Window::getPosSize()
312 if( ::GetClientRect( mnFrameWnd
, &aWndRect
) )
314 aRet
.X
= aWndRect
.left
;
315 aRet
.Y
= aWndRect
.top
;
316 aRet
.Width
= aWndRect
.right
- aWndRect
.left
+ 1;
317 aRet
.Height
= aWndRect
.bottom
- aWndRect
.top
+ 1;
324 void SAL_CALL
Window::setVisible( sal_Bool bVisible
)
328 IVideoWindow
* pVideoWindow
= const_cast< IVideoWindow
* >( mrPlayer
.getVideoWindow() );
331 pVideoWindow
->put_Visible( bVisible
? OATRUE
: OAFALSE
);
333 ::ShowWindow( mnFrameWnd
, bVisible
? SW_SHOW
: SW_HIDE
);
337 void SAL_CALL
Window::setEnable( sal_Bool bEnable
)
340 ::EnableWindow( mnFrameWnd
, bEnable
);
343 void SAL_CALL
Window::setFocus( )
346 ::SetFocus( mnFrameWnd
);
349 void SAL_CALL
Window::addWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
351 std::unique_lock
g(maMutex
);
352 maWindowListeners
.addInterface( g
, xListener
);
355 void SAL_CALL
Window::removeWindowListener( const uno::Reference
< awt::XWindowListener
>& xListener
)
357 std::unique_lock
g(maMutex
);
358 maWindowListeners
.removeInterface( g
, xListener
);
361 void SAL_CALL
Window::addFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
363 std::unique_lock
g(maMutex
);
364 maFocusListeners
.addInterface( g
, xListener
);
367 void SAL_CALL
Window::removeFocusListener( const uno::Reference
< awt::XFocusListener
>& xListener
)
369 std::unique_lock
g(maMutex
);
370 maFocusListeners
.removeInterface( g
, xListener
);
373 void SAL_CALL
Window::addKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
375 std::unique_lock
g(maMutex
);
376 maKeyListeners
.addInterface( g
, xListener
);
379 void SAL_CALL
Window::removeKeyListener( const uno::Reference
< awt::XKeyListener
>& xListener
)
381 std::unique_lock
g(maMutex
);
382 maKeyListeners
.removeInterface( g
, xListener
);
385 void SAL_CALL
Window::addMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
387 std::unique_lock
g(maMutex
);
388 maMouseListeners
.addInterface( g
, xListener
);
391 void SAL_CALL
Window::removeMouseListener( const uno::Reference
< awt::XMouseListener
>& xListener
)
393 std::unique_lock
g(maMutex
);
394 maMouseListeners
.removeInterface( g
, xListener
);
397 void SAL_CALL
Window::addMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
399 std::unique_lock
g(maMutex
);
400 maMouseMotionListeners
.addInterface( g
, xListener
);
403 void SAL_CALL
Window::removeMouseMotionListener( const uno::Reference
< awt::XMouseMotionListener
>& xListener
)
405 std::unique_lock
g(maMutex
);
406 maMouseMotionListeners
.removeInterface( g
, xListener
);
409 void SAL_CALL
Window::addPaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
411 std::unique_lock
g(maMutex
);
412 maPaintListeners
.addInterface( g
, xListener
);
415 void SAL_CALL
Window::removePaintListener( const uno::Reference
< awt::XPaintListener
>& xListener
)
417 std::unique_lock
g(maMutex
);
418 maPaintListeners
.removeInterface( g
, xListener
);
421 void SAL_CALL
Window::dispose( )
425 void SAL_CALL
Window::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
427 std::unique_lock
g(maMutex
);
428 maEventListeners
.addInterface( g
, xListener
);
431 void SAL_CALL
Window::removeEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
433 std::unique_lock
g(maMutex
);
434 maEventListeners
.removeInterface( g
, xListener
);
437 void Window::fireMousePressedEvent( const css::awt::MouseEvent
& rEvt
)
439 std::unique_lock
g(maMutex
);
440 maMouseListeners
.notifyEach(g
, &awt::XMouseListener::mousePressed
, rEvt
);
443 void Window::fireMouseReleasedEvent( const css::awt::MouseEvent
& rEvt
)
445 std::unique_lock
g(maMutex
);
446 maMouseListeners
.notifyEach(g
, &awt::XMouseListener::mouseReleased
, rEvt
);
449 void Window::fireMouseMovedEvent( const css::awt::MouseEvent
& rEvt
)
451 std::unique_lock
g(maMutex
);
452 maMouseMotionListeners
.notifyEach(g
, &awt::XMouseMotionListener::mouseMoved
, rEvt
);
455 void Window::fireSetFocusEvent( const css::awt::FocusEvent
& rEvt
)
457 std::unique_lock
g(maMutex
);
458 maFocusListeners
.notifyEach(g
, &awt::XFocusListener::focusGained
, rEvt
);
461 OUString SAL_CALL
Window::getImplementationName( )
463 return AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME
;
466 sal_Bool SAL_CALL
Window::supportsService( const OUString
& ServiceName
)
468 return cppu::supportsService(this, ServiceName
);
471 uno::Sequence
< OUString
> SAL_CALL
Window::getSupportedServiceNames( )
473 return { AVMEDIA_WIN_WINDOW_SERVICENAME
};
476 } // namespace avmedia::win
479 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */