Line data Source code
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 <config_features.h>
21 :
22 : #include <iostream>
23 : #include "mediawindow_impl.hxx"
24 : #include "mediaevent_impl.hxx"
25 : #include "mediamisc.hxx"
26 : #include "mediawindow.hrc"
27 : #include "helpids.hrc"
28 :
29 : #include <algorithm>
30 : #include <cmath>
31 :
32 : #include <comphelper/processfactory.hxx>
33 : #include <osl/mutex.hxx>
34 : #include <tools/urlobj.hxx>
35 : #include <unotools/securityoptions.hxx>
36 : #include <vcl/svapp.hxx>
37 :
38 : #include <com/sun/star/awt/SystemPointer.hpp>
39 : #include <com/sun/star/lang/XComponent.hpp>
40 : #include <com/sun/star/media/XManager.hpp>
41 : #include <vcl/sysdata.hxx>
42 : #include <vcl/opengl/OpenGLContext.hxx>
43 :
44 : using namespace ::com::sun::star;
45 :
46 : namespace avmedia { namespace priv {
47 :
48 0 : MediaWindowControl::MediaWindowControl(vcl::Window* pParent)
49 0 : : MediaControl(pParent, MEDIACONTROLSTYLE_MULTILINE)
50 : {
51 0 : }
52 :
53 0 : void MediaWindowControl::update()
54 : {
55 0 : MediaItem aItem;
56 :
57 0 : static_cast< MediaWindowImpl* >( GetParent() )->updateMediaItem( aItem );
58 0 : setState(aItem);
59 0 : }
60 :
61 0 : void MediaWindowControl::execute(const MediaItem& rItem)
62 : {
63 0 : static_cast<MediaWindowImpl*>(GetParent())->executeMediaItem(rItem);
64 0 : }
65 :
66 0 : MediaChildWindow::MediaChildWindow(vcl::Window* pParent)
67 0 : : SystemChildWindow(pParent, WB_CLIPCHILDREN)
68 : {
69 0 : }
70 :
71 : #if HAVE_FEATURE_GLTF
72 0 : MediaChildWindow::MediaChildWindow(vcl::Window* pParent, SystemWindowData* pData)
73 0 : : SystemChildWindow(pParent, WB_CLIPCHILDREN, pData)
74 : {
75 0 : }
76 : #endif
77 :
78 0 : void MediaChildWindow::MouseMove( const MouseEvent& rMEvt )
79 : {
80 0 : const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
81 0 : rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
82 :
83 0 : SystemChildWindow::MouseMove( rMEvt );
84 0 : GetParent()->MouseMove( aTransformedEvent );
85 0 : }
86 :
87 0 : void MediaChildWindow::MouseButtonDown( const MouseEvent& rMEvt )
88 : {
89 0 : const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
90 0 : rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
91 :
92 0 : SystemChildWindow::MouseButtonDown( rMEvt );
93 0 : GetParent()->MouseButtonDown( aTransformedEvent );
94 0 : }
95 :
96 0 : void MediaChildWindow::MouseButtonUp( const MouseEvent& rMEvt )
97 : {
98 0 : const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
99 0 : rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
100 :
101 0 : SystemChildWindow::MouseButtonUp( rMEvt );
102 0 : GetParent()->MouseButtonUp( aTransformedEvent );
103 0 : }
104 :
105 0 : void MediaChildWindow::KeyInput( const KeyEvent& rKEvt )
106 : {
107 0 : SystemChildWindow::KeyInput( rKEvt );
108 0 : GetParent()->KeyInput( rKEvt );
109 0 : }
110 :
111 0 : void MediaChildWindow::KeyUp( const KeyEvent& rKEvt )
112 : {
113 0 : SystemChildWindow::KeyUp( rKEvt );
114 0 : GetParent()->KeyUp( rKEvt );
115 0 : }
116 :
117 0 : void MediaChildWindow::Command( const CommandEvent& rCEvt )
118 : {
119 0 : const CommandEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rCEvt.GetMousePosPixel() ) ),
120 0 : rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetEventData() );
121 :
122 0 : SystemChildWindow::Command( rCEvt );
123 0 : GetParent()->Command( aTransformedEvent );
124 0 : }
125 :
126 0 : MediaWindowImpl::MediaWindowImpl(vcl::Window* pParent, MediaWindow* pMediaWindow, bool bInternalMediaControl)
127 : : Control(pParent)
128 : , DropTargetHelper(this)
129 : , DragSourceHelper(this)
130 : , mpMediaWindow(pMediaWindow)
131 : , mpEvents(nullptr)
132 : , mbEventTransparent(true)
133 : , mpMediaWindowControl(bInternalMediaControl ? VclPtr<MediaWindowControl>::Create(this) : nullptr)
134 : , mpEmptyBmpEx(nullptr)
135 0 : , mpAudioBmpEx(nullptr)
136 : {
137 0 : if (mpMediaWindowControl)
138 : {
139 0 : mpMediaWindowControl->SetSizePixel(mpMediaWindowControl->getMinSizePixel());
140 0 : mpMediaWindowControl->Show();
141 : }
142 0 : }
143 :
144 0 : MediaWindowImpl::~MediaWindowImpl()
145 : {
146 0 : disposeOnce();
147 0 : }
148 :
149 0 : void MediaWindowImpl::dispose()
150 : {
151 0 : if (mpEvents)
152 0 : mpEvents->cleanUp();
153 :
154 0 : if (mxPlayerWindow.is())
155 : {
156 0 : mxPlayerWindow->removeKeyListener( uno::Reference< awt::XKeyListener >( mxEventsIf, uno::UNO_QUERY ) );
157 0 : mxPlayerWindow->removeMouseListener( uno::Reference< awt::XMouseListener >( mxEventsIf, uno::UNO_QUERY ) );
158 0 : mxPlayerWindow->removeMouseMotionListener( uno::Reference< awt::XMouseMotionListener >( mxEventsIf, uno::UNO_QUERY ) );
159 :
160 0 : uno::Reference< lang::XComponent > xComponent( mxPlayerWindow, uno::UNO_QUERY );
161 0 : if (xComponent.is())
162 0 : xComponent->dispose();
163 :
164 0 : mxPlayerWindow.clear();
165 : }
166 :
167 0 : uno::Reference< lang::XComponent > xComponent( mxPlayer, uno::UNO_QUERY );
168 0 : if (xComponent.is()) // this stops the player
169 0 : xComponent->dispose();
170 :
171 0 : mxPlayer.clear();
172 :
173 0 : mpMediaWindow = NULL;
174 :
175 0 : delete mpEmptyBmpEx;
176 0 : mpEmptyBmpEx = NULL;
177 0 : delete mpAudioBmpEx;
178 0 : mpAudioBmpEx = NULL;
179 0 : mpMediaWindowControl.disposeAndClear();
180 0 : mpChildWindow.disposeAndClear();
181 :
182 0 : Control::dispose();
183 0 : }
184 :
185 1 : uno::Reference<media::XPlayer> MediaWindowImpl::createPlayer(const OUString& rURL, const OUString& rReferer, const OUString* pMimeType)
186 : {
187 1 : uno::Reference<media::XPlayer> xPlayer;
188 :
189 1 : if( rURL.isEmpty() )
190 0 : return xPlayer;
191 :
192 1 : if (SvtSecurityOptions().isUntrustedReferer(rReferer))
193 : {
194 0 : return xPlayer;
195 : }
196 2 : uno::Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext());
197 :
198 1 : if (!pMimeType || *pMimeType == AVMEDIA_MIMETYPE_COMMON)
199 : {
200 :
201 : static const char * aServiceManagers[] =
202 : {
203 : AVMEDIA_MANAGER_SERVICE_PREFERRED,
204 : AVMEDIA_MANAGER_SERVICE_NAME,
205 : // a fallback path just for gstreamer which has
206 : // two significant versions deployed at once ...
207 : #ifdef AVMEDIA_MANAGER_SERVICE_NAME_OLD
208 : AVMEDIA_MANAGER_SERVICE_NAME_OLD
209 : #endif
210 : // fallback to AVMedia framework on OS X
211 : #ifdef AVMEDIA_MANAGER_SERVICE_NAME_FALLBACK1
212 : AVMEDIA_MANAGER_SERVICE_NAME_FALLBACK1
213 : #endif
214 : };
215 :
216 0 : for (sal_uInt32 i = 0; !xPlayer.is() && i < SAL_N_ELEMENTS( aServiceManagers ); ++i)
217 : {
218 : const OUString aServiceName(aServiceManagers[i],
219 0 : strlen( aServiceManagers[i]),
220 0 : RTL_TEXTENCODING_ASCII_US);
221 :
222 0 : xPlayer = createPlayer(rURL, aServiceName, xContext);
223 0 : }
224 : }
225 : #if HAVE_FEATURE_GLTF
226 1 : else if ( *pMimeType == AVMEDIA_MIMETYPE_JSON )
227 : {
228 1 : xPlayer = createPlayer(rURL, AVMEDIA_OPENGL_MANAGER_SERVICE_NAME, xContext);
229 : }
230 : #endif
231 :
232 1 : return xPlayer;
233 : }
234 :
235 1 : uno::Reference< media::XPlayer > MediaWindowImpl::createPlayer(
236 : const OUString& rURL, const OUString& rManagerServName,
237 : uno::Reference< uno::XComponentContext > xContext)
238 : {
239 1 : uno::Reference< media::XPlayer > xPlayer;
240 : try
241 : {
242 : uno::Reference< media::XManager > xManager (
243 2 : xContext->getServiceManager()->createInstanceWithContext(rManagerServName, xContext),
244 1 : uno::UNO_QUERY );
245 1 : if( xManager.is() )
246 1 : xPlayer = uno::Reference< media::XPlayer >( xManager->createPlayer( rURL ), uno::UNO_QUERY );
247 : else
248 1 : SAL_WARN( "avmedia", "failed to create media player service " << rManagerServName );
249 0 : } catch ( const uno::Exception &e )
250 : {
251 : SAL_WARN( "avmedia", "couldn't create media player " << rManagerServName
252 : << ", exception '" << e.Message << '\'');
253 : }
254 1 : return xPlayer;
255 : }
256 :
257 0 : void MediaWindowImpl::setURL( const OUString& rURL,
258 : OUString const& rTempURL, OUString const& rReferer)
259 : {
260 0 : maReferer = rReferer;
261 0 : if( rURL != getURL() )
262 : {
263 0 : if( mxPlayer.is() )
264 0 : mxPlayer->stop();
265 :
266 0 : if( mxPlayerWindow.is() )
267 : {
268 0 : mxPlayerWindow->setVisible( false );
269 0 : mxPlayerWindow.clear();
270 : }
271 :
272 0 : mxPlayer.clear();
273 0 : mTempFileURL.clear();
274 :
275 0 : if (!rTempURL.isEmpty())
276 : {
277 0 : maFileURL = rURL;
278 0 : mTempFileURL = rTempURL;
279 : }
280 : else
281 : {
282 0 : INetURLObject aURL( rURL );
283 :
284 0 : if (aURL.GetProtocol() != INetProtocol::NotValid)
285 0 : maFileURL = aURL.GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS);
286 : else
287 0 : maFileURL = rURL;
288 : }
289 :
290 0 : mxPlayer = createPlayer((!mTempFileURL.isEmpty()) ? mTempFileURL : maFileURL, rReferer, &m_sMimeType );
291 0 : onURLChanged();
292 : }
293 0 : }
294 :
295 0 : const OUString& MediaWindowImpl::getURL() const
296 : {
297 0 : return maFileURL;
298 : }
299 :
300 0 : bool MediaWindowImpl::isValid() const
301 : {
302 0 : return( mxPlayer.is() );
303 : }
304 :
305 0 : Size MediaWindowImpl::getPreferredSize() const
306 : {
307 0 : Size aRet;
308 :
309 0 : if( mxPlayer.is() )
310 : {
311 0 : awt::Size aPrefSize( mxPlayer->getPreferredPlayerWindowSize() );
312 :
313 0 : aRet.Width() = aPrefSize.Width;
314 0 : aRet.Height() = aPrefSize.Height;
315 : }
316 :
317 0 : return aRet;
318 : }
319 :
320 0 : bool MediaWindowImpl::start()
321 : {
322 0 : return mxPlayer.is() && ( mxPlayer->start(), true );
323 : }
324 :
325 0 : void MediaWindowImpl::updateMediaItem( MediaItem& rItem ) const
326 : {
327 0 : if( isPlaying() )
328 0 : rItem.setState( MediaState::Play );
329 : else
330 0 : rItem.setState( ( 0.0 == getMediaTime() ) ? MediaState::Stop : MediaState::Pause );
331 :
332 0 : rItem.setDuration( getDuration() );
333 0 : rItem.setTime( getMediaTime() );
334 0 : rItem.setLoop( isPlaybackLoop() );
335 0 : rItem.setMute( isMute() );
336 0 : rItem.setVolumeDB( getVolumeDB() );
337 0 : rItem.setZoom( getZoom() );
338 0 : rItem.setURL( getURL(), mTempFileURL, maReferer );
339 0 : }
340 :
341 0 : void MediaWindowImpl::executeMediaItem( const MediaItem& rItem )
342 : {
343 0 : const AVMediaSetMask nMaskSet = rItem.getMaskSet();
344 :
345 : // set URL first
346 0 : if (nMaskSet & AVMediaSetMask::URL)
347 : {
348 0 : m_sMimeType = rItem.getMimeType();
349 0 : setURL(rItem.getURL(), rItem.getTempURL(), rItem.getReferer());
350 : }
351 :
352 : // set different states next
353 0 : if (nMaskSet & AVMediaSetMask::TIME)
354 0 : setMediaTime(std::min(rItem.getTime(), getDuration()));
355 :
356 0 : if (nMaskSet & AVMediaSetMask::LOOP)
357 0 : setPlaybackLoop(rItem.isLoop());
358 :
359 0 : if (nMaskSet & AVMediaSetMask::MUTE)
360 0 : setMute(rItem.isMute());
361 :
362 0 : if (nMaskSet & AVMediaSetMask::VOLUMEDB)
363 0 : setVolumeDB(rItem.getVolumeDB());
364 :
365 0 : if (nMaskSet & AVMediaSetMask::ZOOM)
366 0 : setZoom(rItem.getZoom());
367 :
368 : // set play state at last
369 0 : if (nMaskSet & AVMediaSetMask::STATE)
370 : {
371 0 : switch (rItem.getState())
372 : {
373 : case MediaState::Play:
374 : {
375 0 : if (!isPlaying())
376 0 : start();
377 : }
378 0 : break;
379 :
380 : case MediaState::Pause:
381 : {
382 0 : if (isPlaying())
383 0 : stop();
384 : }
385 0 : break;
386 :
387 : case MediaState::Stop:
388 : {
389 0 : if (isPlaying())
390 : {
391 0 : setMediaTime( 0.0 );
392 0 : stop();
393 0 : setMediaTime( 0.0 );
394 : }
395 : }
396 0 : break;
397 : }
398 : }
399 0 : }
400 :
401 0 : bool MediaWindowImpl::setZoom(css::media::ZoomLevel eLevel)
402 : {
403 0 : return mxPlayerWindow.is() && mxPlayerWindow->setZoomLevel( eLevel );
404 : }
405 :
406 0 : css::media::ZoomLevel MediaWindowImpl::getZoom() const
407 : {
408 0 : return( mxPlayerWindow.is() ? mxPlayerWindow->getZoomLevel() : media::ZoomLevel_NOT_AVAILABLE );
409 : }
410 :
411 0 : void MediaWindowImpl::stop()
412 : {
413 0 : if( mxPlayer.is() )
414 0 : mxPlayer->stop();
415 0 : }
416 :
417 0 : bool MediaWindowImpl::isPlaying() const
418 : {
419 0 : return( mxPlayer.is() && mxPlayer->isPlaying() );
420 : }
421 :
422 0 : double MediaWindowImpl::getDuration() const
423 : {
424 0 : return( mxPlayer.is() ? mxPlayer->getDuration() : 0.0 );
425 : }
426 :
427 0 : void MediaWindowImpl::setMediaTime( double fTime )
428 : {
429 0 : if( mxPlayer.is() )
430 0 : mxPlayer->setMediaTime( fTime );
431 0 : }
432 :
433 0 : double MediaWindowImpl::getMediaTime() const
434 : {
435 0 : return( mxPlayer.is() ? mxPlayer->getMediaTime() : 0.0 );
436 : }
437 :
438 0 : void MediaWindowImpl::setPlaybackLoop( bool bSet )
439 : {
440 0 : if( mxPlayer.is() )
441 0 : mxPlayer->setPlaybackLoop( bSet );
442 0 : }
443 :
444 0 : bool MediaWindowImpl::isPlaybackLoop() const
445 : {
446 0 : return mxPlayer.is() && mxPlayer->isPlaybackLoop();
447 : }
448 :
449 0 : void MediaWindowImpl::setMute( bool bSet )
450 : {
451 0 : if( mxPlayer.is() )
452 0 : mxPlayer->setMute( bSet );
453 0 : }
454 :
455 0 : bool MediaWindowImpl::isMute() const
456 : {
457 0 : return mxPlayer.is() && mxPlayer->isMute();
458 : }
459 :
460 0 : void MediaWindowImpl::setVolumeDB( sal_Int16 nVolumeDB )
461 : {
462 0 : if( mxPlayer.is() )
463 0 : mxPlayer->setVolumeDB( nVolumeDB );
464 0 : }
465 :
466 0 : sal_Int16 MediaWindowImpl::getVolumeDB() const
467 : {
468 0 : return (mxPlayer.is() ? mxPlayer->getVolumeDB() : 0);
469 : }
470 :
471 0 : void MediaWindowImpl::stopPlayingInternal(bool bStop)
472 : {
473 0 : if (isPlaying())
474 : {
475 0 : bStop ? mxPlayer->stop() : mxPlayer->start();
476 : }
477 0 : }
478 :
479 0 : void MediaWindowImpl::onURLChanged()
480 : {
481 0 : if (m_sMimeType == AVMEDIA_MIMETYPE_COMMON)
482 : {
483 0 : mpChildWindow.disposeAndClear();
484 0 : mpChildWindow.reset(VclPtr<MediaChildWindow>::Create(this));
485 : }
486 : #if HAVE_FEATURE_GLTF
487 0 : else if (m_sMimeType == AVMEDIA_MIMETYPE_JSON)
488 : {
489 0 : SystemWindowData aWinData = OpenGLContext::generateWinData(this, false);
490 0 : mpChildWindow.disposeAndClear();
491 0 : mpChildWindow.reset(VclPtr<MediaChildWindow>::Create(this,&aWinData));
492 0 : mbEventTransparent = false;
493 : }
494 : #endif
495 0 : if (!mpChildWindow)
496 0 : return;
497 0 : mpChildWindow->SetHelpId(HID_AVMEDIA_PLAYERWINDOW);
498 0 : mxEventsIf.set(static_cast<cppu::OWeakObject*>(mpEvents = new MediaEventListenersImpl(*mpChildWindow.get())));
499 :
500 0 : if (mxPlayer.is())
501 : {
502 0 : Resize();
503 0 : uno::Sequence<uno::Any> aArgs( 3 );
504 0 : uno::Reference<media::XPlayerWindow> xPlayerWindow;
505 0 : const Point aPoint;
506 0 : const Size aSize(mpChildWindow->GetSizePixel());
507 :
508 0 : aArgs[0] = uno::makeAny(mpChildWindow->GetParentWindowHandle());
509 0 : aArgs[1] = uno::makeAny(awt::Rectangle(aPoint.X(), aPoint.Y(), aSize.Width(), aSize.Height()));
510 0 : aArgs[2] = uno::makeAny(reinterpret_cast<sal_IntPtr>(mpChildWindow.get()));
511 :
512 : try
513 : {
514 0 : xPlayerWindow = mxPlayer->createPlayerWindow( aArgs );
515 : }
516 0 : catch( const uno::RuntimeException& )
517 : {
518 : // happens eg, on MacOSX where Java frames cannot be created from X11 window handles
519 : }
520 :
521 0 : mxPlayerWindow = xPlayerWindow;
522 :
523 0 : if( xPlayerWindow.is() )
524 : {
525 0 : xPlayerWindow->addKeyListener( uno::Reference< awt::XKeyListener >( mxEventsIf, uno::UNO_QUERY ) );
526 0 : xPlayerWindow->addMouseListener( uno::Reference< awt::XMouseListener >( mxEventsIf, uno::UNO_QUERY ) );
527 0 : xPlayerWindow->addMouseMotionListener( uno::Reference< awt::XMouseMotionListener >( mxEventsIf, uno::UNO_QUERY ) );
528 0 : xPlayerWindow->addFocusListener( uno::Reference< awt::XFocusListener >( mxEventsIf, uno::UNO_QUERY ) );
529 0 : }
530 : }
531 : else
532 0 : mxPlayerWindow.clear();
533 :
534 0 : if( mxPlayerWindow.is() )
535 0 : mpChildWindow->Show();
536 : else
537 0 : mpChildWindow->Hide();
538 :
539 0 : if( mpMediaWindowControl )
540 : {
541 0 : MediaItem aItem;
542 :
543 0 : updateMediaItem( aItem );
544 0 : mpMediaWindowControl->setState( aItem );
545 : }
546 : }
547 :
548 0 : void MediaWindowImpl::setPosSize(const Rectangle& rRect)
549 : {
550 0 : SetPosSizePixel(rRect.TopLeft(), rRect.GetSize());
551 0 : }
552 :
553 0 : void MediaWindowImpl::setPointer(const Pointer& rPointer)
554 : {
555 0 : SetPointer(rPointer);
556 :
557 0 : if (mpChildWindow)
558 0 : mpChildWindow->SetPointer(rPointer);
559 :
560 0 : if (mxPlayerWindow.is())
561 : {
562 : long nPointer;
563 :
564 0 : switch (rPointer.GetStyle())
565 : {
566 : case PointerStyle::Cross:
567 0 : nPointer = awt::SystemPointer::CROSS;
568 0 : break;
569 : case PointerStyle::Hand:
570 0 : nPointer = awt::SystemPointer::HAND;
571 0 : break;
572 : case PointerStyle::Move:
573 0 : nPointer = awt::SystemPointer::MOVE;
574 0 : break;
575 : case PointerStyle::Wait:
576 0 : nPointer = awt::SystemPointer::WAIT;
577 0 : break;
578 : default:
579 0 : nPointer = awt::SystemPointer::ARROW;
580 0 : break;
581 : }
582 :
583 0 : mxPlayerWindow->setPointerType(nPointer);
584 : }
585 0 : }
586 :
587 0 : void MediaWindowImpl::Resize()
588 : {
589 0 : const Size aCurSize(GetOutputSizePixel());
590 0 : const sal_Int32 nOffset(mpMediaWindowControl ? AVMEDIA_CONTROLOFFSET : 0);
591 :
592 0 : Size aPlayerWindowSize(aCurSize.Width() - (nOffset << 1),
593 0 : aCurSize.Height() - (nOffset << 1));
594 :
595 0 : if (mpMediaWindowControl)
596 : {
597 0 : const sal_Int32 nControlHeight = mpMediaWindowControl->GetSizePixel().Height();
598 0 : const sal_Int32 nControlY = ::std::max(aCurSize.Height() - nControlHeight - nOffset, 0L);
599 :
600 0 : aPlayerWindowSize.Height() = (nControlY - (nOffset << 1));
601 0 : mpMediaWindowControl->SetPosSizePixel(Point(nOffset, nControlY ), Size(aCurSize.Width() - (nOffset << 1), nControlHeight));
602 : }
603 0 : if (mpChildWindow)
604 0 : mpChildWindow->SetPosSizePixel(Point(0, 0), aPlayerWindowSize);
605 :
606 0 : if (mxPlayerWindow.is())
607 0 : mxPlayerWindow->setPosSize(0, 0, aPlayerWindowSize.Width(), aPlayerWindowSize.Height(), 0);
608 0 : }
609 :
610 0 : void MediaWindowImpl::StateChanged(StateChangedType eType)
611 : {
612 0 : if (mxPlayerWindow.is())
613 : {
614 : // stop playing when going disabled or hidden
615 0 : switch (eType)
616 : {
617 : case StateChangedType::Visible:
618 : {
619 0 : stopPlayingInternal(!IsVisible());
620 0 : mxPlayerWindow->setVisible(IsVisible());
621 : }
622 0 : break;
623 :
624 : case StateChangedType::Enable:
625 : {
626 0 : stopPlayingInternal(!IsEnabled());
627 0 : mxPlayerWindow->setEnable(IsEnabled());
628 : }
629 0 : break;
630 :
631 : default:
632 0 : break;
633 : }
634 : }
635 0 : }
636 :
637 0 : void MediaWindowImpl::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
638 : {
639 0 : if (mxPlayerWindow.is())
640 0 : mxPlayerWindow->update();
641 :
642 0 : BitmapEx* pLogo = NULL;
643 :
644 0 : if (!mxPlayer.is())
645 : {
646 0 : if (!mpEmptyBmpEx)
647 0 : mpEmptyBmpEx = new BitmapEx(AVMEDIA_RESID(AVMEDIA_BMP_EMPTYLOGO));
648 :
649 0 : pLogo = mpEmptyBmpEx;
650 : }
651 0 : else if (!mxPlayerWindow.is())
652 : {
653 0 : if (!mpAudioBmpEx)
654 0 : mpAudioBmpEx = new BitmapEx(AVMEDIA_RESID(AVMEDIA_BMP_AUDIOLOGO));
655 :
656 0 : pLogo = mpAudioBmpEx;
657 : }
658 :
659 0 : if (!mpChildWindow)
660 0 : return;
661 :
662 0 : const Point aBasePos(mpChildWindow->GetPosPixel());
663 0 : const Rectangle aVideoRect(aBasePos, mpChildWindow->GetSizePixel());
664 :
665 0 : if (pLogo && !pLogo->IsEmpty() && (aVideoRect.GetWidth() > 0) && (aVideoRect.GetHeight() > 0))
666 : {
667 0 : Size aLogoSize(pLogo->GetSizePixel());
668 0 : const Color aBackgroundColor(67, 67, 67);
669 :
670 0 : rRenderContext.SetLineColor(aBackgroundColor);
671 0 : rRenderContext.SetFillColor(aBackgroundColor);
672 0 : rRenderContext.DrawRect(aVideoRect);
673 :
674 0 : if ((aLogoSize.Width() > aVideoRect.GetWidth() || aLogoSize.Height() > aVideoRect.GetHeight() ) &&
675 0 : (aLogoSize.Height() > 0))
676 : {
677 0 : const double fLogoWH = double(aLogoSize.Width()) / aLogoSize.Height();
678 :
679 0 : if (fLogoWH < (double(aVideoRect.GetWidth()) / aVideoRect.GetHeight()))
680 : {
681 0 : aLogoSize.Width() = long(aVideoRect.GetHeight() * fLogoWH);
682 0 : aLogoSize.Height() = aVideoRect.GetHeight();
683 : }
684 : else
685 : {
686 0 : aLogoSize.Width() = aVideoRect.GetWidth();
687 0 : aLogoSize.Height()= long(aVideoRect.GetWidth() / fLogoWH);
688 : }
689 : }
690 :
691 0 : Point aPoint(aBasePos.X() + ((aVideoRect.GetWidth() - aLogoSize.Width()) >> 1),
692 0 : aBasePos.Y() + ((aVideoRect.GetHeight() - aLogoSize.Height()) >> 1));
693 :
694 0 : rRenderContext.DrawBitmapEx(aPoint, aLogoSize, *pLogo);
695 : }
696 : }
697 :
698 0 : void MediaWindowImpl::GetFocus()
699 : {
700 0 : }
701 :
702 0 : void MediaWindowImpl::MouseMove(const MouseEvent& rMEvt)
703 : {
704 0 : if (mpMediaWindow && mbEventTransparent)
705 0 : mpMediaWindow->MouseMove(rMEvt);
706 0 : }
707 :
708 0 : void MediaWindowImpl::MouseButtonDown(const MouseEvent& rMEvt)
709 : {
710 0 : if (mpMediaWindow && mbEventTransparent)
711 0 : mpMediaWindow->MouseButtonDown(rMEvt);
712 0 : }
713 :
714 0 : void MediaWindowImpl::MouseButtonUp(const MouseEvent& rMEvt)
715 : {
716 0 : if (mpMediaWindow && mbEventTransparent)
717 0 : mpMediaWindow->MouseButtonUp(rMEvt);
718 0 : }
719 :
720 0 : void MediaWindowImpl::KeyInput(const KeyEvent& rKEvt)
721 : {
722 0 : if (mpMediaWindow && mbEventTransparent)
723 0 : mpMediaWindow->KeyInput(rKEvt);
724 0 : }
725 :
726 0 : void MediaWindowImpl::KeyUp(const KeyEvent& rKEvt)
727 : {
728 0 : if (mpMediaWindow && mbEventTransparent)
729 0 : mpMediaWindow->KeyUp(rKEvt);
730 0 : }
731 :
732 0 : void MediaWindowImpl::Command(const CommandEvent& rCEvt)
733 : {
734 0 : if (mpMediaWindow && mbEventTransparent)
735 0 : mpMediaWindow->Command(rCEvt);
736 0 : }
737 :
738 0 : sal_Int8 MediaWindowImpl::AcceptDrop(const AcceptDropEvent& rEvt)
739 : {
740 0 : return (mpMediaWindow && mbEventTransparent ? mpMediaWindow->AcceptDrop(rEvt) : 0);
741 : }
742 :
743 0 : sal_Int8 MediaWindowImpl::ExecuteDrop(const ExecuteDropEvent& rEvt)
744 : {
745 0 : return (mpMediaWindow && mbEventTransparent ? mpMediaWindow->ExecuteDrop(rEvt) : 0);
746 : }
747 :
748 0 : void MediaWindowImpl::StartDrag(sal_Int8 nAction, const Point& rPosPixel)
749 : {
750 0 : if (mpMediaWindow && mbEventTransparent)
751 0 : mpMediaWindow->StartDrag(nAction, rPosPixel);
752 0 : }
753 :
754 : } // namespace priv
755 435 : } // namespace avmedia
756 :
757 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|