bump product version to 6.3.0.0.beta1
[LibreOffice.git] / avmedia / source / win / window.cxx
blob44dfb7b239acf3b268576eb74fd0e171630424b5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <objbase.h>
21 #include <strmif.h>
22 #include <control.h>
23 #include <dshow.h>
25 #include <com/sun/star/awt/SystemPointer.hpp>
26 #include <cppuhelper/supportsservice.hxx>
28 #include "window.hxx"
29 #include "player.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;
43 if( pWindow )
45 switch( nMsg )
47 case WM_SETCURSOR:
48 pWindow->updatePointer();
49 break;
51 case WM_GRAPHNOTIFY:
52 pWindow->processGraphEvent();
53 break;
55 case WM_MOUSEMOVE:
56 case WM_LBUTTONDOWN:
57 case WM_MBUTTONDOWN:
58 case WM_RBUTTONDOWN:
59 case WM_LBUTTONUP:
60 case WM_MBUTTONUP:
61 case WM_RBUTTONUP:
62 PostMessage(pWindow->getParentWnd(), nMsg, nPar1, nPar2);
63 break;
65 case WM_SETFOCUS:
67 const awt::FocusEvent aUNOEvt;
68 pWindow->fireSetFocusEvent( aUNOEvt );
70 break;
72 default:
73 bProcessed = false;
74 break;
77 else
78 bProcessed = false;
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 );
97 return s_pWndClass;
100 Window::Window( const uno::Reference< lang::XMultiServiceFactory >& rxMgr, Player& rPlayer ) :
101 mxMgr( rxMgr ),
102 maListeners( maMutex ),
103 meZoomLevel( media::ZoomLevel_NOT_AVAILABLE ),
104 mrPlayer( rPlayer ),
105 mnFrameWnd( nullptr ),
106 mnParentWnd( nullptr ),
107 mnPointerType( awt::SystemPointer::ARROW )
111 Window::~Window()
113 if( mnFrameWnd )
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 )
130 bZoom = true;
132 else if( media::ZoomLevel_ZOOM_1_TO_4 == meZoomLevel )
134 aPrefSize.Width >>= 2;
135 aPrefSize.Height >>= 2;
136 bZoom = true;
138 else if( media::ZoomLevel_ZOOM_1_TO_2 == meZoomLevel )
140 aPrefSize.Width >>= 1;
141 aPrefSize.Height >>= 1;
142 bZoom = true;
144 else if( media::ZoomLevel_ZOOM_2_TO_1 == meZoomLevel )
146 aPrefSize.Width <<= 1;
147 aPrefSize.Height <<= 1;
148 bZoom = true;
150 else if( media::ZoomLevel_ZOOM_4_TO_1 == meZoomLevel )
152 aPrefSize.Width <<= 2;
153 aPrefSize.Height <<= 2;
154 bZoom = true;
156 else if( media::ZoomLevel_FIT_TO_WINDOW == meZoomLevel )
158 nWidth = nVideoW;
159 nHeight = nVideoH;
160 bDone = true;
163 if( bZoom )
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;
171 bDone = true;
175 if( !bDone )
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 );
183 else
184 nVideoH = static_cast<int>( nVideoW / fPrefWH );
186 nX = ( nW - nVideoW ) >> 1;
187 nY = ( nH - nVideoH ) >> 1;
188 nWidth = nVideoW;
189 nHeight = nVideoH;
191 else
192 nX = nY = nWidth = nHeight = 0;
195 IVideoWindow* pVideoWindow = const_cast< IVideoWindow* >( mrPlayer.getVideoWindow() );
197 if( pVideoWindow )
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;
210 sal_IntPtr nWnd;
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 );
222 if( mnFrameWnd )
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()
247 LPCTSTR pCursorName;
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;
255 default:
256 pCursorName = IDC_ARROW;
257 break;
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();
281 bRet = true;
284 return bRet;
287 media::ZoomLevel SAL_CALL Window::getZoomLevel( )
289 return meZoomLevel;
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 )
299 if( mnFrameWnd )
301 ::SetWindowPos( mnFrameWnd, HWND_TOP, X, Y, Width, Height, 0 );
302 ImplLayoutVideoWindow();
306 awt::Rectangle SAL_CALL Window::getPosSize()
308 awt::Rectangle aRet;
310 if( mnFrameWnd )
312 ::RECT aWndRect;
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;
323 return aRet;
326 void SAL_CALL Window::setVisible( sal_Bool bVisible )
328 if( mnFrameWnd )
330 IVideoWindow* pVideoWindow = const_cast< IVideoWindow* >( mrPlayer.getVideoWindow() );
332 if( pVideoWindow )
333 pVideoWindow->put_Visible( bVisible ? OATRUE : OAFALSE );
335 ::ShowWindow( mnFrameWnd, bVisible ? SW_SHOW : SW_HIDE );
339 void SAL_CALL Window::setEnable( sal_Bool bEnable )
341 if( mnFrameWnd )
342 ::EnableWindow( mnFrameWnd, bEnable );
345 void SAL_CALL Window::setFocus( )
347 if( mnFrameWnd )
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());
429 if( pContainer )
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());
442 if( pContainer )
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());
455 if( pContainer )
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());
468 if( pContainer )
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 };
492 } // namespace win
493 } // namespace avmedia
495 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */