Updated core
[LibreOffice.git] / avmedia / source / win / window.cxx
blob0956cc1a500341c18ee1f639b85ee7bfd4001a1a
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 #if defined _MSC_VER
21 #pragma warning(push, 1)
22 #pragma warning(disable: 4917)
23 #endif
24 #include <objbase.h>
25 #include <strmif.h>
26 #include <control.h>
27 #define STRSAFE_NO_DEPRECATE
28 #include <dshow.h>
29 #if defined _MSC_VER
30 #pragma warning(pop)
31 #endif
32 #include <com/sun/star/awt/SystemPointer.hpp>
34 #include "window.hxx"
35 #include "player.hxx"
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;
48 if( pMutex == NULL )
50 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
52 if( pMutex == NULL )
54 static ::osl::Mutex aMutex;
55 pMutex = &aMutex;
59 return *pMutex;
62 LRESULT CALLBACK MediaPlayerWndProc( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
64 Window* pWindow = (Window*) ::GetWindowLong( hWnd, 0 );
65 bool bProcessed = true;
67 if( pWindow )
69 switch( nMsg )
71 case( WM_SETCURSOR ):
72 pWindow->updatePointer();
73 break;
75 case( WM_GRAPHNOTIFY ):
76 pWindow->processGraphEvent();
77 break;
79 case( WM_MOUSEMOVE ):
80 case( WM_LBUTTONDOWN ):
81 case( WM_MBUTTONDOWN ):
82 case( WM_RBUTTONDOWN ):
83 case( WM_LBUTTONUP ):
84 case( WM_MBUTTONUP ):
85 case( WM_RBUTTONUP ):
87 awt::MouseEvent aUNOEvt;
88 POINT aWinPoint;
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;
96 aUNOEvt.Buttons = 0;
97 aUNOEvt.X = aWinPoint.x;
98 aUNOEvt.Y = aWinPoint.y;
99 aUNOEvt.PopupTrigger = false;
101 // Modifiers
102 if( nPar1 & MK_SHIFT )
103 aUNOEvt.Modifiers |= awt::KeyModifier::SHIFT;
105 if( nPar1 & MK_CONTROL )
106 aUNOEvt.Modifiers |= awt::KeyModifier::MOD1;
108 // Buttons
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;
118 // event type
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();
140 break;
142 case( WM_SETFOCUS ):
144 const awt::FocusEvent aUNOEvt;
145 pWindow->fireSetFocusEvent( aUNOEvt );
147 break;
149 default:
150 bProcessed = false;
151 break;
154 else
155 bProcessed = false;
157 return( bProcessed ? 0 : DefWindowProc( hWnd, nMsg, nPar1, nPar2 ) );
160 WNDCLASS* lcl_getWndClass()
162 static WNDCLASS* s_pWndClass = NULL;
163 if ( !s_pWndClass )
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 );
177 return s_pWndClass;
180 Window::Window( const uno::Reference< lang::XMultiServiceFactory >& rxMgr, Player& rPlayer ) :
181 mxMgr( rxMgr ),
182 mrPlayer( rPlayer ),
183 meZoomLevel( media::ZoomLevel_NOT_AVAILABLE ),
184 mnParentWnd( 0 ),
185 mnFrameWnd( 0 ),
186 maListeners( maMutex ),
187 mnPointerType( awt::SystemPointer::ARROW )
189 ::osl::MutexGuard aGuard( ImplGetOwnStaticMutex() );
191 lcl_getWndClass();
194 Window::~Window()
196 if( mnFrameWnd )
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 )
213 bZoom = true;
215 else if( media::ZoomLevel_ZOOM_1_TO_4 == meZoomLevel )
217 aPrefSize.Width >>= 2;
218 aPrefSize.Height >>= 2;
219 bZoom = true;
221 else if( media::ZoomLevel_ZOOM_1_TO_2 == meZoomLevel )
223 aPrefSize.Width >>= 1;
224 aPrefSize.Height >>= 1;
225 bZoom = true;
227 else if( media::ZoomLevel_ZOOM_2_TO_1 == meZoomLevel )
229 aPrefSize.Width <<= 1;
230 aPrefSize.Height <<= 1;
231 bZoom = true;
233 else if( media::ZoomLevel_ZOOM_4_TO_1 == meZoomLevel )
235 aPrefSize.Width <<= 2;
236 aPrefSize.Height <<= 2;
237 bZoom = true;
239 else if( media::ZoomLevel_FIT_TO_WINDOW == meZoomLevel )
241 nWidth = nVideoW;
242 nHeight = nVideoH;
243 bDone = true;
246 if( bZoom )
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;
254 bDone = true;
258 if( !bDone )
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 );
266 else
267 nVideoH = (int)( nVideoW / fPrefWH );
269 nX = ( nW - nVideoW ) >> 1;
270 nY = ( nH - nVideoH ) >> 1;
271 nWidth = nVideoW;
272 nHeight = nVideoH;
274 else
275 nX = nY = nWidth = nHeight = 0;
278 IVideoWindow* pVideoWindow = const_cast< IVideoWindow* >( mrPlayer.getVideoWindow() );
280 if( pVideoWindow )
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;
293 sal_IntPtr nWnd;
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 );
316 if( mnFrameWnd )
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()
341 char* pCursorName;
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;
349 default:
350 pCursorName = IDC_ARROW;
351 break;
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();
377 bRet = true;
380 return bRet;
383 media::ZoomLevel SAL_CALL Window::getZoomLevel( )
384 throw (uno::RuntimeException)
386 return meZoomLevel;
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)
398 if( mnFrameWnd )
400 ::SetWindowPos( (HWND) mnFrameWnd, HWND_TOP, X, Y, Width, Height, 0 );
401 ImplLayoutVideoWindow();
405 awt::Rectangle SAL_CALL Window::getPosSize()
406 throw (uno::RuntimeException)
408 awt::Rectangle aRet;
410 if( mnFrameWnd )
412 ::RECT aWndRect;
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;
423 return aRet;
426 void SAL_CALL Window::setVisible( sal_Bool bVisible )
427 throw (uno::RuntimeException)
429 if( mnFrameWnd )
431 IVideoWindow* pVideoWindow = const_cast< IVideoWindow* >( mrPlayer.getVideoWindow() );
433 if( pVideoWindow )
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)
443 if( mnFrameWnd )
444 ::EnableWindow( (HWND) mnFrameWnd, bEnable );
447 void SAL_CALL Window::setFocus( )
448 throw (uno::RuntimeException)
450 if( mnFrameWnd )
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 ) );
547 if( pContainer )
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 ) );
560 if( pContainer )
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 ) );
573 if( pContainer )
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 ) );
586 if( pContainer )
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 ;
613 return aRet;
616 } // namespace win
617 } // namespace avmedia
619 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */