LibreOffice Module avmedia (master) 1
window.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <objbase.h>
21#include <strmif.h>
22#include <control.h>
23#include <dshow.h>
24
25#include <com/sun/star/awt/SystemPointer.hpp>
27
28#include "window.hxx"
29#include "player.hxx"
30
31constexpr OUStringLiteral AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME = u"com.sun.star.comp.avmedia.Window_DirectX";
32constexpr OUStringLiteral AVMEDIA_WIN_WINDOW_SERVICENAME = u"com.sun.star.media.Window_DirectX";
33
34using namespace ::com::sun::star;
35
36namespace avmedia::win {
37
38static LRESULT CALLBACK MediaPlayerWndProc( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
39{
40 Window* pWindow = reinterpret_cast<Window*>(GetWindowLongPtrW( hWnd, 0 ));
41 bool bProcessed = true;
42
43 if( pWindow )
44 {
45 switch( nMsg )
46 {
47 case WM_SETCURSOR:
48 pWindow->updatePointer();
49 break;
50
51 case WM_GRAPHNOTIFY:
52 pWindow->processGraphEvent();
53 break;
54
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;
64
65 case WM_SETFOCUS:
66 {
67 const awt::FocusEvent aUNOEvt;
68 pWindow->fireSetFocusEvent( aUNOEvt );
69 }
70 break;
71
72 default:
73 bProcessed = false;
74 break;
75 }
76 }
77 else
78 bProcessed = false;
79
80 return( bProcessed ? 0 : DefWindowProcW( hWnd, nMsg, nPar1, nPar2 ) );
81}
82
83static WNDCLASSW* lcl_getWndClass()
84{
85 WNDCLASSW* s_pWndClass = new WNDCLASSW;
86
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 );
94
95 RegisterClassW( s_pWndClass );
96
97 return s_pWndClass;
98}
99
101 meZoomLevel( media::ZoomLevel_NOT_AVAILABLE ),
102 mrPlayer( rPlayer ),
103 mnFrameWnd( nullptr ),
104 mnParentWnd( nullptr ),
105 mnPointerType( awt::SystemPointer::ARROW )
106{
107}
108
110{
111 if( mnFrameWnd )
112 ::DestroyWindow( mnFrameWnd );
113}
114
116{
117 if( media::ZoomLevel_NOT_AVAILABLE != meZoomLevel )
118 {
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;
125
126 if( media::ZoomLevel_ORIGINAL == meZoomLevel )
127 {
128 bZoom = true;
129 }
130 else if( media::ZoomLevel_ZOOM_1_TO_4 == meZoomLevel )
131 {
132 aPrefSize.Width >>= 2;
133 aPrefSize.Height >>= 2;
134 bZoom = true;
135 }
136 else if( media::ZoomLevel_ZOOM_1_TO_2 == meZoomLevel )
137 {
138 aPrefSize.Width >>= 1;
139 aPrefSize.Height >>= 1;
140 bZoom = true;
141 }
142 else if( media::ZoomLevel_ZOOM_2_TO_1 == meZoomLevel )
143 {
144 aPrefSize.Width <<= 1;
145 aPrefSize.Height <<= 1;
146 bZoom = true;
147 }
148 else if( media::ZoomLevel_ZOOM_4_TO_1 == meZoomLevel )
149 {
150 aPrefSize.Width <<= 2;
151 aPrefSize.Height <<= 2;
152 bZoom = true;
153 }
154 else if( media::ZoomLevel_FIT_TO_WINDOW == meZoomLevel )
155 {
156 nWidth = nVideoW;
157 nHeight = nVideoH;
158 bDone = true;
159 }
160
161 if( bZoom )
162 {
163 if( ( aPrefSize.Width <= nVideoW ) && ( aPrefSize.Height <= nVideoH ) )
164 {
165 nX = ( nVideoW - aPrefSize.Width ) >> 1;
166 nY = ( nVideoH - aPrefSize.Height ) >> 1;
167 nWidth = aPrefSize.Width;
168 nHeight = aPrefSize.Height;
169 bDone = true;
170 }
171 }
172
173 if( !bDone )
174 {
175 if( aPrefSize.Width > 0 && aPrefSize.Height > 0 && nVideoW > 0 && nVideoH > 0 )
176 {
177 double fPrefWH = static_cast<double>(aPrefSize.Width) / aPrefSize.Height;
178
179 if( fPrefWH < ( static_cast<double>(nVideoW) / nVideoH ) )
180 nVideoW = static_cast<int>( nVideoH * fPrefWH );
181 else
182 nVideoH = static_cast<int>( nVideoW / fPrefWH );
183
184 nX = ( nW - nVideoW ) >> 1;
185 nY = ( nH - nVideoH ) >> 1;
186 nWidth = nVideoW;
187 nHeight = nVideoH;
188 }
189 else
190 nX = nY = nWidth = nHeight = 0;
191 }
192
193 IVideoWindow* pVideoWindow = const_cast< IVideoWindow* >( mrPlayer.getVideoWindow() );
194
195 if( pVideoWindow )
196 pVideoWindow->SetWindowPosition( nX, nY, nWidth, nHeight );
197 }
198}
199
200bool Window::create( const uno::Sequence< uno::Any >& rArguments )
201{
202 IVideoWindow* pVideoWindow = const_cast< IVideoWindow* >( mrPlayer.getVideoWindow() );
203 static WNDCLASSW* mpWndClass = lcl_getWndClass();
204
205 if( !mnFrameWnd && pVideoWindow && mpWndClass )
206 {
207 awt::Rectangle aRect;
208 sal_IntPtr nWnd;
209
210 rArguments[ 0 ] >>= nWnd;
211 rArguments[ 1 ] >>= aRect;
212
213 mnParentWnd = reinterpret_cast<HWND>(nWnd);
214
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 );
219
220 if( mnFrameWnd )
221 {
222 SetWindowLongPtrW( mnFrameWnd, 0, reinterpret_cast<LONG_PTR>(this) );
223
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 );
227
229
230 meZoomLevel = media::ZoomLevel_FIT_TO_WINDOW;
232 }
233 }
234
235 return( mnFrameWnd != nullptr );
236}
237
239{
241}
242
244{
245 LPCTSTR pCursorName;
246
247 switch( mnPointerType )
248 {
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;
252
253 default:
254 pCursorName = IDC_ARROW;
255 break;
256 }
257
258 SetCursor( LoadCursor( nullptr, pCursorName ) );
259}
260
261void SAL_CALL Window::update( )
262{
263 ::RedrawWindow( mnFrameWnd, nullptr, nullptr, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE );
264}
265
266sal_Bool SAL_CALL Window::setZoomLevel( media::ZoomLevel eZoomLevel )
267{
268 bool bRet = false;
269
270 if( media::ZoomLevel_NOT_AVAILABLE != meZoomLevel &&
271 media::ZoomLevel_NOT_AVAILABLE != eZoomLevel )
272 {
273 if( eZoomLevel != meZoomLevel )
274 {
275 meZoomLevel = eZoomLevel;
277 }
278
279 bRet = true;
280 }
281
282 return bRet;
283}
284
285media::ZoomLevel SAL_CALL Window::getZoomLevel( )
286{
287 return meZoomLevel;
288}
289
290void SAL_CALL Window::setPointerType( sal_Int32 nPointerType )
291{
292 mnPointerType = nPointerType;
293}
294
295void SAL_CALL Window::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 )
296{
297 if( mnFrameWnd )
298 {
299 ::SetWindowPos( mnFrameWnd, HWND_TOP, X, Y, Width, Height, 0 );
301 }
302}
303
304awt::Rectangle SAL_CALL Window::getPosSize()
305{
306 awt::Rectangle aRet;
307
308 if( mnFrameWnd )
309 {
310 ::RECT aWndRect;
311
312 if( ::GetClientRect( mnFrameWnd, &aWndRect ) )
313 {
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;
318 }
319 }
320
321 return aRet;
322}
323
324void SAL_CALL Window::setVisible( sal_Bool bVisible )
325{
326 if( mnFrameWnd )
327 {
328 IVideoWindow* pVideoWindow = const_cast< IVideoWindow* >( mrPlayer.getVideoWindow() );
329
330 if( pVideoWindow )
331 pVideoWindow->put_Visible( bVisible ? OATRUE : OAFALSE );
332
333 ::ShowWindow( mnFrameWnd, bVisible ? SW_SHOW : SW_HIDE );
334 }
335}
336
337void SAL_CALL Window::setEnable( sal_Bool bEnable )
338{
339 if( mnFrameWnd )
340 ::EnableWindow( mnFrameWnd, bEnable );
341}
342
343void SAL_CALL Window::setFocus( )
344{
345 if( mnFrameWnd )
346 ::SetFocus( mnFrameWnd );
347}
348
349void SAL_CALL Window::addWindowListener( const uno::Reference< awt::XWindowListener >& xListener )
350{
351 std::unique_lock g(maMutex);
352 maWindowListeners.addInterface( g, xListener );
353}
354
355void SAL_CALL Window::removeWindowListener( const uno::Reference< awt::XWindowListener >& xListener )
356{
357 std::unique_lock g(maMutex);
358 maWindowListeners.removeInterface( g, xListener );
359}
360
361void SAL_CALL Window::addFocusListener( const uno::Reference< awt::XFocusListener >& xListener )
362{
363 std::unique_lock g(maMutex);
364 maFocusListeners.addInterface( g, xListener );
365}
366
367void SAL_CALL Window::removeFocusListener( const uno::Reference< awt::XFocusListener >& xListener )
368{
369 std::unique_lock g(maMutex);
370 maFocusListeners.removeInterface( g, xListener );
371}
372
373void SAL_CALL Window::addKeyListener( const uno::Reference< awt::XKeyListener >& xListener )
374{
375 std::unique_lock g(maMutex);
376 maKeyListeners.addInterface( g, xListener );
377}
378
379void SAL_CALL Window::removeKeyListener( const uno::Reference< awt::XKeyListener >& xListener )
380{
381 std::unique_lock g(maMutex);
382 maKeyListeners.removeInterface( g, xListener );
383}
384
385void SAL_CALL Window::addMouseListener( const uno::Reference< awt::XMouseListener >& xListener )
386{
387 std::unique_lock g(maMutex);
388 maMouseListeners.addInterface( g, xListener );
389}
390
391void SAL_CALL Window::removeMouseListener( const uno::Reference< awt::XMouseListener >& xListener )
392{
393 std::unique_lock g(maMutex);
394 maMouseListeners.removeInterface( g, xListener );
395}
396
397void SAL_CALL Window::addMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& xListener )
398{
399 std::unique_lock g(maMutex);
400 maMouseMotionListeners.addInterface( g, xListener );
401}
402
403void SAL_CALL Window::removeMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& xListener )
404{
405 std::unique_lock g(maMutex);
407}
408
409void SAL_CALL Window::addPaintListener( const uno::Reference< awt::XPaintListener >& xListener )
410{
411 std::unique_lock g(maMutex);
412 maPaintListeners.addInterface( g, xListener );
413}
414
415void SAL_CALL Window::removePaintListener( const uno::Reference< awt::XPaintListener >& xListener )
416{
417 std::unique_lock g(maMutex);
418 maPaintListeners.removeInterface( g, xListener );
419}
420
421void SAL_CALL Window::dispose( )
422{
423}
424
425void SAL_CALL Window::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
426{
427 std::unique_lock g(maMutex);
428 maEventListeners.addInterface( g, xListener );
429}
430
431void SAL_CALL Window::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
432{
433 std::unique_lock g(maMutex);
434 maEventListeners.removeInterface( g, xListener );
435}
436
437void Window::fireMousePressedEvent( const css::awt::MouseEvent& rEvt )
438{
439 std::unique_lock g(maMutex);
440 maMouseListeners.notifyEach(g, &awt::XMouseListener::mousePressed, rEvt);
441}
442
443void Window::fireMouseReleasedEvent( const css::awt::MouseEvent& rEvt )
444{
445 std::unique_lock g(maMutex);
446 maMouseListeners.notifyEach(g, &awt::XMouseListener::mouseReleased, rEvt);
447}
448
449void Window::fireMouseMovedEvent( const css::awt::MouseEvent& rEvt )
450{
451 std::unique_lock g(maMutex);
452 maMouseMotionListeners.notifyEach(g, &awt::XMouseMotionListener::mouseMoved, rEvt);
453}
454
455void Window::fireSetFocusEvent( const css::awt::FocusEvent& rEvt )
456{
457 std::unique_lock g(maMutex);
458 maFocusListeners.notifyEach(g, &awt::XFocusListener::focusGained, rEvt);
459}
460
462{
464}
465
466sal_Bool SAL_CALL Window::supportsService( const OUString& ServiceName )
467{
469}
470
471uno::Sequence< OUString > SAL_CALL Window::getSupportedServiceNames( )
472{
474}
475
476} // namespace avmedia::win
477
478
479/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void setNotifyWnd(HWND nNotifyWnd)
Definition: player.cxx:144
const IVideoWindow * getVideoWindow() const
Definition: player.cxx:138
virtual css::awt::Size SAL_CALL getPreferredPlayerWindowSize() override
Definition: player.cxx:340
virtual void SAL_CALL addPaintListener(const css::uno::Reference< css::awt::XPaintListener > &xListener) override
virtual void SAL_CALL setEnable(sal_Bool Enable) override
Definition: window.cxx:337
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
void fireMouseReleasedEvent(const css::awt::MouseEvent &rEvt)
Definition: window.cxx:443
virtual void SAL_CALL dispose() override
Definition: window.cxx:421
virtual css::media::ZoomLevel SAL_CALL getZoomLevel() override
Definition: window.cxx:285
virtual void SAL_CALL removeKeyListener(const css::uno::Reference< css::awt::XKeyListener > &xListener) override
virtual css::awt::Rectangle SAL_CALL getPosSize() override
Definition: window.cxx:304
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: window.cxx:471
virtual void SAL_CALL removeWindowListener(const css::uno::Reference< css::awt::XWindowListener > &xListener) override
virtual void SAL_CALL addFocusListener(const css::uno::Reference< css::awt::XFocusListener > &xListener) override
comphelper::OInterfaceContainerHelper4< css::awt::XMouseMotionListener > maMouseMotionListeners
Definition: win/window.hxx:104
virtual void SAL_CALL addMouseMotionListener(const css::uno::Reference< css::awt::XMouseMotionListener > &xListener) override
virtual void SAL_CALL setFocus() override
Definition: window.cxx:343
void fireSetFocusEvent(const css::awt::FocusEvent &rEvt)
Definition: window.cxx:455
css::media::ZoomLevel meZoomLevel
Definition: win/window.hxx:107
virtual void SAL_CALL addWindowListener(const css::uno::Reference< css::awt::XWindowListener > &xListener) override
virtual void SAL_CALL setPointerType(sal_Int32 nPointerType) override
Definition: window.cxx:290
void ImplLayoutVideoWindow()
Definition: window.cxx:115
HWND getParentWnd() const
Definition: win/window.hxx:95
comphelper::OInterfaceContainerHelper4< css::awt::XMouseListener > maMouseListeners
Definition: win/window.hxx:103
virtual sal_Bool SAL_CALL setZoomLevel(css::media::ZoomLevel ZoomLevel) override
comphelper::OInterfaceContainerHelper4< css::awt::XKeyListener > maKeyListeners
Definition: win/window.hxx:102
bool create(const css::uno::Sequence< css::uno::Any > &aArguments)
Definition: window.cxx:200
virtual void SAL_CALL removeMouseMotionListener(const css::uno::Reference< css::awt::XMouseMotionListener > &xListener) override
~Window() override
Definition: window.cxx:109
Window(Player &rPlayer)
Definition: window.cxx:100
comphelper::OInterfaceContainerHelper4< css::awt::XPaintListener > maPaintListeners
Definition: win/window.hxx:105
virtual void SAL_CALL addKeyListener(const css::uno::Reference< css::awt::XKeyListener > &xListener) override
virtual void SAL_CALL removeFocusListener(const css::uno::Reference< css::awt::XFocusListener > &xListener) override
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: window.cxx:466
virtual void SAL_CALL addMouseListener(const css::uno::Reference< css::awt::XMouseListener > &xListener) override
virtual void SAL_CALL setPosSize(sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags) override
Definition: window.cxx:295
virtual OUString SAL_CALL getImplementationName() override
Definition: window.cxx:461
virtual void SAL_CALL removePaintListener(const css::uno::Reference< css::awt::XPaintListener > &xListener) override
void fireMouseMovedEvent(const css::awt::MouseEvent &rEvt)
Definition: window.cxx:449
virtual void SAL_CALL removeMouseListener(const css::uno::Reference< css::awt::XMouseListener > &xListener) override
virtual void SAL_CALL update() override
Definition: window.cxx:261
comphelper::OInterfaceContainerHelper4< css::awt::XWindowListener > maWindowListeners
Definition: win/window.hxx:100
comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > maEventListeners
Definition: win/window.hxx:106
void fireMousePressedEvent(const css::awt::MouseEvent &rEvt)
Definition: window.cxx:437
virtual void SAL_CALL setVisible(sal_Bool Visible) override
Definition: window.cxx:324
void processGraphEvent()
Definition: window.cxx:238
comphelper::OInterfaceContainerHelper4< css::awt::XFocusListener > maFocusListeners
Definition: win/window.hxx:101
sal_Int32 addInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
void notifyEach(std::unique_lock< std::mutex > &rGuard, void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event) const
sal_Int32 removeInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
float u
ARROW
#define WM_GRAPHNOTIFY
Definition: gstcommon.hxx:41
static WNDCLASSW * lcl_getWndClass()
Definition: window.cxx:83
static LRESULT CALLBACK MediaPlayerWndProc(HWND hWnd, UINT nMsg, WPARAM nPar1, LPARAM nPar2)
Definition: window.cxx:38
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
#define CALLBACK
#define Y
bool bVisible
unsigned char sal_Bool
constexpr OUStringLiteral AVMEDIA_WIN_WINDOW_SERVICENAME
Definition: window.cxx:32
constexpr OUStringLiteral AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME
Definition: window.cxx:31