1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "mediawindow_impl.hxx"
25 #include "mediaevent_impl.hxx"
26 #include "mediamisc.hxx"
27 #include "mediawindow.hrc"
28 #include "helpids.hrc"
29
30 #include <algorithm>
31 #include <cmath>
32 #include <osl/mutex.hxx>
33 #include <tools/time.hxx>
34 #include <vcl/svapp.hxx>
35
36 #ifndef _COM_SUN_STAR_AWT_SYSTEMPOINTER_HDL_
37 #include <com/sun/star/awt/SystemPointer.hdl>
38 #endif
39 #ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HDL_
40 #include <com/sun/star/lang/XComponent.hdl>
41 #endif
42
43 #define AVMEDIA_TOOLBOXITEM_PREV 0x0001
44 #define AVMEDIA_TOOLBOXITEM_PLAY 0x0002
45 #define AVMEDIA_TOOLBOXITEM_PAUSE 0x0004
46 #define AVMEDIA_TOOLBOXITEM_STOP 0x0008
47 #define AVMEDIA_TOOLBOXITEM_NEXT 0x0010
48 #define AVMEDIA_TOOLBOXITEM_MUTE 0x0100
49
50 #define AVMEDIA_FFW_PLAYRATE 4
51
52 using namespace ::com::sun::star;
53
54 namespace avmedia { namespace priv {
55
56 // ----------------------
57 // - MediaWindowControl -
58 // ----------------------
59
MediaWindowControl(Window * pParent)60 MediaWindowControl::MediaWindowControl( Window* pParent ) :
61 MediaControl( pParent, MEDIACONTROLSTYLE_MULTILINE )
62 {
63 }
64
65 // ---------------------------------------------------------------------
66
~MediaWindowControl()67 MediaWindowControl::~MediaWindowControl()
68 {
69 }
70
71 // ---------------------------------------------------------------------
72
update()73 void MediaWindowControl::update()
74 {
75 MediaItem aItem;
76
77 static_cast< MediaWindowImpl* >( GetParent() )->updateMediaItem( aItem );
78 setState( aItem );
79 }
80
81 // ---------------------------------------------------------------------
82
execute(const MediaItem & rItem)83 void MediaWindowControl::execute( const MediaItem& rItem )
84 {
85 static_cast< MediaWindowImpl* >( GetParent() )->executeMediaItem( rItem );
86 }
87
88 // --------------------
89 // - MediaChildWindow -
90 // --------------------
91
MediaChildWindow(Window * pParent)92 MediaChildWindow::MediaChildWindow( Window* pParent ) :
93 SystemChildWindow( pParent, WB_CLIPCHILDREN )
94 {
95 }
96
97 // ---------------------------------------------------------------------
98
~MediaChildWindow()99 MediaChildWindow::~MediaChildWindow()
100 {
101 }
102
103 // ---------------------------------------------------------------------
104
MouseMove(const MouseEvent & rMEvt)105 void MediaChildWindow::MouseMove( const MouseEvent& rMEvt )
106 {
107 const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
108 rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
109
110 SystemChildWindow::MouseMove( rMEvt );
111 GetParent()->MouseMove( aTransformedEvent );
112 }
113
114 // ---------------------------------------------------------------------
115
MouseButtonDown(const MouseEvent & rMEvt)116 void MediaChildWindow::MouseButtonDown( const MouseEvent& rMEvt )
117 {
118 const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
119 rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
120
121 SystemChildWindow::MouseButtonDown( rMEvt );
122 GetParent()->MouseButtonDown( aTransformedEvent );
123 }
124
125 // ---------------------------------------------------------------------
126
MouseButtonUp(const MouseEvent & rMEvt)127 void MediaChildWindow::MouseButtonUp( const MouseEvent& rMEvt )
128 {
129 const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
130 rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
131
132 SystemChildWindow::MouseButtonUp( rMEvt );
133 GetParent()->MouseButtonUp( aTransformedEvent );
134 }
135
136 // ---------------------------------------------------------------------
137
KeyInput(const KeyEvent & rKEvt)138 void MediaChildWindow::KeyInput( const KeyEvent& rKEvt )
139 {
140 SystemChildWindow::KeyInput( rKEvt );
141 GetParent()->KeyInput( rKEvt );
142 }
143
144 // ---------------------------------------------------------------------
145
KeyUp(const KeyEvent & rKEvt)146 void MediaChildWindow::KeyUp( const KeyEvent& rKEvt )
147 {
148 SystemChildWindow::KeyUp( rKEvt );
149 GetParent()->KeyUp( rKEvt );
150 }
151
152 // ---------------------------------------------------------------------
153
Command(const CommandEvent & rCEvt)154 void MediaChildWindow::Command( const CommandEvent& rCEvt )
155 {
156 const CommandEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rCEvt.GetMousePosPixel() ) ),
157 rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetData() );
158
159 SystemChildWindow::Command( rCEvt );
160 GetParent()->Command( aTransformedEvent );
161 }
162
163 // ----------------------
164 // - MediaWindowImpl -
165 // ----------------------
166
MediaWindowImpl(Window * pParent,MediaWindow * pMediaWindow,bool bInternalMediaControl)167 MediaWindowImpl::MediaWindowImpl( Window* pParent, MediaWindow* pMediaWindow, bool bInternalMediaControl ) :
168 Control( pParent ),
169 MediaWindowBaseImpl( pMediaWindow ),
170 DropTargetHelper( this ),
171 DragSourceHelper( this ),
172 mxEventsIf( static_cast< ::cppu::OWeakObject* >( mpEvents = new MediaEventListenersImpl( maChildWindow ) ) ),
173 maChildWindow( this ),
174 mpMediaWindowControl( bInternalMediaControl ? new MediaWindowControl( this ) : NULL ),
175 mpEmptyBmpEx( NULL ),
176 mpAudioBmpEx( NULL )
177 {
178 maChildWindow.SetBackground( Color( COL_BLACK ) );
179 maChildWindow.SetHelpId( HID_AVMEDIA_PLAYERWINDOW );
180 maChildWindow.Hide();
181
182 if( mpMediaWindowControl )
183 {
184 mpMediaWindowControl->SetSizePixel( mpMediaWindowControl->getMinSizePixel() );
185 mpMediaWindowControl->Show();
186 }
187 }
188
189 // ---------------------------------------------------------------------
190
~MediaWindowImpl()191 MediaWindowImpl::~MediaWindowImpl()
192 {
193 delete mpEmptyBmpEx;
194 delete mpAudioBmpEx;
195 delete mpMediaWindowControl;
196 }
197
198 // ---------------------------------------------------------------------
199
cleanUp()200 void MediaWindowImpl::cleanUp()
201 {
202 uno::Reference< media::XPlayerWindow > xPlayerWindow( getPlayerWindow() );
203
204 mpEvents->cleanUp();
205
206 if( xPlayerWindow.is() )
207 {
208 xPlayerWindow->removeKeyListener( uno::Reference< awt::XKeyListener >( mxEventsIf, uno::UNO_QUERY ) );
209 xPlayerWindow->removeMouseListener( uno::Reference< awt::XMouseListener >( mxEventsIf, uno::UNO_QUERY ) );
210 xPlayerWindow->removeMouseMotionListener( uno::Reference< awt::XMouseMotionListener >( mxEventsIf, uno::UNO_QUERY ) );
211
212 uno::Reference< lang::XComponent > xComponent( xPlayerWindow, uno::UNO_QUERY );
213
214 if( xComponent.is() )
215 xComponent->dispose();
216
217 setPlayerWindow( NULL );
218 }
219
220 MediaWindowBaseImpl::cleanUp();
221 }
222
223 // ---------------------------------------------------------------------
224
onURLChanged()225 void MediaWindowImpl::onURLChanged()
226 {
227 if( getPlayer().is() )
228 {
229 uno::Reference< media::XPlayerWindow > xPlayerWindow;
230
231 const Point aPoint;
232 const Size aSize( maChildWindow.GetSizePixel() );
233 const sal_IntPtr nWndHandle = (sal_IntPtr) maChildWindow.GetParentWindowHandle( isMediaWindowJavaBased() );
234
235 try
236 {
237 if( nWndHandle != 0 )
238 {
239 uno::Sequence< uno::Any > aArgs( 3 );
240
241 aArgs[ 0 ] = uno::makeAny( nWndHandle );
242 aArgs[ 1 ] = uno::makeAny( awt::Rectangle( aPoint.X(), aPoint.Y(), aSize.Width(), aSize.Height() ) );
243 aArgs[ 2 ] = uno::makeAny( reinterpret_cast< sal_IntPtr >( &maChildWindow ) );
244
245 xPlayerWindow = getPlayer()->createPlayerWindow( aArgs );
246 }
247 }
248 catch( uno::RuntimeException )
249 {
250 // happens eg, on MacOSX where Java frames cannot be created from X11 window handles
251 }
252
253 setPlayerWindow( xPlayerWindow );
254
255 if( xPlayerWindow.is() )
256 {
257 xPlayerWindow->addKeyListener( uno::Reference< awt::XKeyListener >( mxEventsIf, uno::UNO_QUERY ) );
258 xPlayerWindow->addMouseListener( uno::Reference< awt::XMouseListener >( mxEventsIf, uno::UNO_QUERY ) );
259 xPlayerWindow->addMouseMotionListener( uno::Reference< awt::XMouseMotionListener >( mxEventsIf, uno::UNO_QUERY ) );
260 xPlayerWindow->addFocusListener( uno::Reference< awt::XFocusListener >( mxEventsIf, uno::UNO_QUERY ) );
261 }
262 }
263 else
264 setPlayerWindow( NULL );
265
266 if( getPlayerWindow().is() )
267 maChildWindow.Show();
268 else
269 maChildWindow.Hide();
270
271 if( mpMediaWindowControl )
272 {
273 MediaItem aItem;
274
275 updateMediaItem( aItem );
276 mpMediaWindowControl->setState( aItem );
277 }
278 }
279
280 // ---------------------------------------------------------------------
281
update()282 void MediaWindowImpl::update()
283 {
284 uno::Reference< media::XPlayerWindow > xPlayerWindow( getPlayerWindow() );
285
286 if( xPlayerWindow.is() )
287 xPlayerWindow->update();
288 }
289
290 // ---------------------------------------------------------------------
291
setPosSize(const Rectangle & rRect)292 void MediaWindowImpl::setPosSize( const Rectangle& rRect )
293 {
294 SetPosSizePixel( rRect.TopLeft(), rRect.GetSize() );
295 }
296
297 // ---------------------------------------------------------------------
298
setPointer(const Pointer & rPointer)299 void MediaWindowImpl::setPointer( const Pointer& rPointer )
300 {
301 uno::Reference< media::XPlayerWindow > xPlayerWindow( getPlayerWindow() );
302
303 SetPointer( rPointer );
304 maChildWindow.SetPointer( rPointer );
305
306 if( xPlayerWindow.is() )
307 {
308 long nPointer;
309
310 switch( rPointer.GetStyle() )
311 {
312 case( POINTER_CROSS ): nPointer = awt::SystemPointer::CROSS; break;
313 case( POINTER_HAND ): nPointer = awt::SystemPointer::HAND; break;
314 case( POINTER_MOVE ): nPointer = awt::SystemPointer::MOVE; break;
315 case( POINTER_WAIT ): nPointer = awt::SystemPointer::WAIT; break;
316
317 default: nPointer = awt::SystemPointer::ARROW; break;
318 }
319
320 xPlayerWindow->setPointerType( nPointer );
321 }
322 }
323
324 // ---------------------------------------------------------------------
325
getPointer() const326 const Pointer& MediaWindowImpl::getPointer() const
327 {
328 return GetPointer();
329 }
330
331 // ---------------------------------------------------------------------
332
hasInternalMediaControl() const333 bool MediaWindowImpl::hasInternalMediaControl() const
334 {
335 return( mpMediaWindowControl != NULL );
336 }
337
338 // ---------------------------------------------------------------------
339
Resize()340 void MediaWindowImpl::Resize()
341 {
342 uno::Reference< media::XPlayerWindow > xPlayerWindow( getPlayerWindow() );
343 const Size aCurSize( GetOutputSizePixel() );
344 const sal_Int32 nOffset( mpMediaWindowControl ? AVMEDIA_CONTROLOFFSET : 0 );
345 Size aPlayerWindowSize( aCurSize.Width() - ( nOffset << 1 ),
346 aCurSize.Height() - ( nOffset << 1 ) );
347
348 if( mpMediaWindowControl )
349 {
350 const sal_Int32 nControlHeight = mpMediaWindowControl->GetSizePixel().Height();
351 const sal_Int32 nControlY = ::std::max( aCurSize.Height() - nControlHeight - nOffset, 0L );
352
353 aPlayerWindowSize.Height() = ( nControlY - ( nOffset << 1 ) );
354 mpMediaWindowControl->SetPosSizePixel( Point( nOffset, nControlY ), Size( aCurSize.Width() - ( nOffset << 1 ), nControlHeight ) );
355 }
356
357 if( xPlayerWindow.is() )
358 xPlayerWindow->setPosSize( 0, 0, aPlayerWindowSize.Width(), aPlayerWindowSize.Height(), 0 );
359
360 maChildWindow.SetPosSizePixel( Point( nOffset, nOffset ), aPlayerWindowSize );
361 }
362
363 // ---------------------------------------------------------------------
364
StateChanged(StateChangedType eType)365 void MediaWindowImpl::StateChanged( StateChangedType eType )
366 {
367 uno::Reference< media::XPlayerWindow > xPlayerWindow( getPlayerWindow() );
368
369 if( xPlayerWindow.is() )
370 {
371 // stop playing when going disabled or hidden
372 switch( eType )
373 {
374 case STATE_CHANGE_VISIBLE:
375 {
376 stopPlayingInternal( !IsVisible() );
377 xPlayerWindow->setVisible( IsVisible() );
378 }
379 break;
380
381 case STATE_CHANGE_ENABLE:
382 {
383 stopPlayingInternal( !IsEnabled() );
384 xPlayerWindow->setEnable( IsEnabled() );
385 }
386 break;
387
388 default:
389 break;
390 }
391 }
392 }
393
394 // ---------------------------------------------------------------------
395
Paint(const Rectangle &)396 void MediaWindowImpl::Paint( const Rectangle& )
397 {
398 BitmapEx* pLogo = NULL;
399
400 if( !getPlayer().is() )
401 {
402 if( !mpEmptyBmpEx )
403 mpEmptyBmpEx = new BitmapEx( AVMEDIA_RESID( AVMEDIA_BMP_EMPTYLOGO ) );
404
405 pLogo = mpEmptyBmpEx;
406 }
407 else if( !getPlayerWindow().is() )
408 {
409 if( !mpAudioBmpEx )
410 mpAudioBmpEx = new BitmapEx( AVMEDIA_RESID( AVMEDIA_BMP_AUDIOLOGO ) );
411
412 pLogo = mpAudioBmpEx;
413 }
414
415 const Point aBasePos( maChildWindow.GetPosPixel() );
416 const Rectangle aVideoRect( aBasePos, maChildWindow.GetSizePixel() );
417
418 if( pLogo && !pLogo->IsEmpty() && ( aVideoRect.GetWidth() > 0 ) && ( aVideoRect.GetHeight() > 0 ) )
419 {
420 Size aLogoSize( pLogo->GetSizePixel() );
421 const Color aBackgroundColor( 67, 67, 67 );
422
423 SetLineColor( aBackgroundColor );
424 SetFillColor( aBackgroundColor );
425 DrawRect( aVideoRect );
426
427 if( ( aLogoSize.Width() > aVideoRect.GetWidth() || aLogoSize.Height() > aVideoRect.GetHeight() ) &&
428 ( aLogoSize.Height() > 0 ) )
429 {
430 const double fLogoWH = (double) aLogoSize.Width() / aLogoSize.Height();
431
432 if( fLogoWH < ( (double) aVideoRect.GetWidth() / aVideoRect.GetHeight() ) )
433 {
434 aLogoSize.Width() = (long) ( aVideoRect.GetHeight() * fLogoWH );
435 aLogoSize.Height()= aVideoRect.GetHeight();
436 }
437 else
438 {
439 aLogoSize.Width() = aVideoRect.GetWidth();
440 aLogoSize.Height()= (long) ( aVideoRect.GetWidth() / fLogoWH );
441 }
442 }
443
444 DrawBitmapEx( Point( aBasePos.X() + ( ( aVideoRect.GetWidth() - aLogoSize.Width() ) >> 1 ),
445 aBasePos.Y() + ( ( aVideoRect.GetHeight() - aLogoSize.Height() ) >> 1 ) ),
446 aLogoSize, *pLogo );
447 }
448 }
449
450 // ---------------------------------------------------------------------
451
GetFocus()452 void MediaWindowImpl::GetFocus()
453 {
454 }
455
456 // ---------------------------------------------------------------------
457
MouseMove(const MouseEvent & rMEvt)458 void MediaWindowImpl::MouseMove( const MouseEvent& rMEvt )
459 {
460 MediaWindow* pMediaWindow = getMediaWindow();
461
462 if( pMediaWindow )
463 pMediaWindow->MouseMove( rMEvt );
464 }
465
466 // ---------------------------------------------------------------------
467
MouseButtonDown(const MouseEvent & rMEvt)468 void MediaWindowImpl::MouseButtonDown( const MouseEvent& rMEvt )
469 {
470 MediaWindow* pMediaWindow = getMediaWindow();
471
472 if( pMediaWindow )
473 pMediaWindow->MouseButtonDown( rMEvt );
474 }
475
476 // ---------------------------------------------------------------------
477
MouseButtonUp(const MouseEvent & rMEvt)478 void MediaWindowImpl::MouseButtonUp( const MouseEvent& rMEvt )
479 {
480 MediaWindow* pMediaWindow = getMediaWindow();
481
482 if( pMediaWindow )
483 pMediaWindow->MouseButtonUp( rMEvt );
484 }
485
486 // ---------------------------------------------------------------------
487
KeyInput(const KeyEvent & rKEvt)488 void MediaWindowImpl::KeyInput( const KeyEvent& rKEvt )
489 {
490 MediaWindow* pMediaWindow = getMediaWindow();
491
492 if( pMediaWindow )
493 pMediaWindow->KeyInput( rKEvt );
494 }
495
496 // ---------------------------------------------------------------------
497
KeyUp(const KeyEvent & rKEvt)498 void MediaWindowImpl::KeyUp( const KeyEvent& rKEvt )
499 {
500 MediaWindow* pMediaWindow = getMediaWindow();
501
502 if( pMediaWindow )
503 pMediaWindow->KeyUp( rKEvt );
504 }
505
506 // ---------------------------------------------------------------------
507
Command(const CommandEvent & rCEvt)508 void MediaWindowImpl::Command( const CommandEvent& rCEvt )
509 {
510 MediaWindow* pMediaWindow = getMediaWindow();
511
512 if( pMediaWindow )
513 pMediaWindow->Command( rCEvt );
514 }
515
516 // ---------------------------------------------------------------------
517
AcceptDrop(const AcceptDropEvent & rEvt)518 sal_Int8 MediaWindowImpl::AcceptDrop( const AcceptDropEvent& rEvt )
519 {
520 MediaWindow* pMediaWindow = getMediaWindow();
521 return( pMediaWindow ? pMediaWindow->AcceptDrop( rEvt ) : 0 );
522 }
523
524 // ---------------------------------------------------------------------
525
ExecuteDrop(const ExecuteDropEvent & rEvt)526 sal_Int8 MediaWindowImpl::ExecuteDrop( const ExecuteDropEvent& rEvt )
527 {
528 MediaWindow* pMediaWindow = getMediaWindow();
529 return( pMediaWindow ? pMediaWindow->ExecuteDrop( rEvt ) : 0 );
530 }
531
532 // ---------------------------------------------------------------------
533
StartDrag(sal_Int8 nAction,const Point & rPosPixel)534 void MediaWindowImpl::StartDrag( sal_Int8 nAction, const Point& rPosPixel )
535 {
536 MediaWindow* pMediaWindow = getMediaWindow();
537
538 if( pMediaWindow )
539 pMediaWindow->StartDrag( nAction, rPosPixel );
540 }
541
542 } // namespace priv
543 } // namespace avmedia
544