]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/mediactrl.cpp
mouse-capture fix
[wxWidgets.git] / src / mac / carbon / mediactrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: mac/carbon/mediactrl.cpp
3 // Purpose: Built-in Media Backends for Mac
4 // Author: Ryan Norton <wxprojects@comcast.net>
5 // Modified by:
6 // Created: 11/07/04
7 // RCS-ID: $Id$
8 // Copyright: (c) 2004-2005 Ryan Norton, portions (c) 2004 Kevin Olliver
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 //===========================================================================
13 // DECLARATIONS
14 //===========================================================================
15
16 //---------------------------------------------------------------------------
17 // Pre-compiled header stuff
18 //---------------------------------------------------------------------------
19
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "mediactrl.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 //---------------------------------------------------------------------------
32 // Includes
33 //---------------------------------------------------------------------------
34 #include "wx/mediactrl.h"
35
36 //---------------------------------------------------------------------------
37 // Compilation guard
38 //---------------------------------------------------------------------------
39 #if wxUSE_MEDIACTRL
40
41 //---------------------------------------------------------------------------
42 // Whether or not to use OSX 10.2's CreateMovieControl for native QuickTime
43 // control - i.e. native positioning and event handling etc..
44 //---------------------------------------------------------------------------
45 #ifndef wxUSE_CREATEMOVIECONTROL
46 # if defined( __WXMAC_OSX__ ) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2 )
47 # define wxUSE_CREATEMOVIECONTROL 1
48 # else
49 # define wxUSE_CREATEMOVIECONTROL 0
50 # endif
51 #endif
52
53 //===========================================================================
54 // BACKEND DECLARATIONS
55 //===========================================================================
56
57 //---------------------------------------------------------------------------
58 //
59 // wxQTMediaBackend
60 //
61 //---------------------------------------------------------------------------
62
63 //---------------------------------------------------------------------------
64 // QT Includes
65 //---------------------------------------------------------------------------
66 //uma is for wxMacFSSpec
67 #include "wx/mac/uma.h"
68 #include "wx/timer.h"
69 #ifndef __DARWIN__
70 #include <Movies.h>
71 #include <Gestalt.h>
72 #include <QuickTimeComponents.h> //Standard QT stuff
73 #else
74 #include <QuickTime/QuickTimeComponents.h>
75 #endif
76
77 //Determines whether version 4 of QT is installed (Pretty much for classic only)
78 Boolean _wxIsQuickTime4Installed (void)
79 {
80 short error;
81 long result;
82
83 error = Gestalt (gestaltQuickTime, &result);
84 return (error == noErr) && (((result >> 16) & 0xffff) >= 0x0400);
85 }
86
87 class WXDLLIMPEXP_MEDIA wxQTMediaBackend : public wxMediaBackend
88 {
89 public:
90
91 wxQTMediaBackend();
92 ~wxQTMediaBackend();
93
94 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
95 wxWindowID id,
96 const wxPoint& pos,
97 const wxSize& size,
98 long style,
99 const wxValidator& validator,
100 const wxString& name);
101
102 virtual bool Play();
103 virtual bool Pause();
104 virtual bool Stop();
105
106 virtual bool Load(const wxString& fileName);
107 virtual bool Load(const wxURI& location);
108
109 virtual wxMediaState GetState();
110
111 virtual bool SetPosition(wxLongLong where);
112 virtual wxLongLong GetPosition();
113 virtual wxLongLong GetDuration();
114
115 virtual void Move(int x, int y, int w, int h);
116 wxSize GetVideoSize() const;
117
118 virtual double GetPlaybackRate();
119 virtual bool SetPlaybackRate(double dRate);
120
121 virtual double GetVolume();
122 virtual bool SetVolume(double);
123
124 void Cleanup();
125 void FinishLoad();
126
127 wxSize m_bestSize; //Original movie size
128 #ifdef __WXMAC_OSX__
129 struct MovieType** m_movie; //QT Movie handle/instance
130 #else
131 Movie m_movie ;
132 #endif
133 wxControl* m_ctrl; //Parent control
134 bool m_bVideo; //Whether or not we have video
135 class _wxQTTimer* m_timer; //Timer for streaming the movie
136
137 DECLARE_DYNAMIC_CLASS(wxQTMediaBackend)
138 };
139
140
141 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
142 //
143 // wxQTMediaBackend
144 //
145 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
146
147 IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend);
148
149 //Time between timer calls
150 #define MOVIE_DELAY 100
151
152 // --------------------------------------------------------------------------
153 // wxQTTimer - Handle Asyncronous Playing
154 // --------------------------------------------------------------------------
155 class _wxQTTimer : public wxTimer
156 {
157 public:
158 _wxQTTimer(Movie movie, wxQTMediaBackend* parent) :
159 m_movie(movie), m_bPaused(false), m_parent(parent)
160 {
161 }
162
163 ~_wxQTTimer()
164 {
165 }
166
167 bool GetPaused() {return m_bPaused;}
168 void SetPaused(bool bPaused) {m_bPaused = bPaused;}
169
170 //-----------------------------------------------------------------------
171 // _wxQTTimer::Notify
172 //
173 // 1) Checks to see if the movie is done, and if not continues
174 // streaming the movie
175 // 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of
176 // the movie.
177 //-----------------------------------------------------------------------
178 void Notify()
179 {
180 if (!m_bPaused)
181 {
182 if(!IsMovieDone(m_movie))
183 MoviesTask(m_movie, MOVIE_DELAY);
184 else
185 {
186 wxMediaEvent theEvent(wxEVT_MEDIA_STOP,
187 m_parent->m_ctrl->GetId());
188 m_parent->m_ctrl->ProcessEvent(theEvent);
189
190 if(theEvent.IsAllowed())
191 {
192 Stop();
193 m_parent->Stop();
194 wxASSERT(::GetMoviesError() == noErr);
195
196 //send the event to our child
197 wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED,
198 m_parent->m_ctrl->GetId());
199 m_parent->m_ctrl->ProcessEvent(theEvent);
200 }
201 }
202 }
203 }
204
205 protected:
206 Movie m_movie; //Our movie instance
207 bool m_bPaused; //Whether we are paused or not
208 wxQTMediaBackend* m_parent; //Backend pointer
209 };
210
211 //---------------------------------------------------------------------------
212 // wxQTMediaBackend Constructor
213 //
214 // Sets m_timer to NULL signifying we havn't loaded anything yet
215 //---------------------------------------------------------------------------
216 wxQTMediaBackend::wxQTMediaBackend() : m_timer(NULL)
217 {
218 }
219
220 //---------------------------------------------------------------------------
221 // wxQTMediaBackend Destructor
222 //
223 // 1) Cleans up the QuickTime movie instance
224 // 2) Decrements the QuickTime reference counter - if this reaches
225 // 0, QuickTime shuts down
226 // 3) Decrements the QuickTime Windows Media Layer reference counter -
227 // if this reaches 0, QuickTime shuts down the Windows Media Layer
228 //---------------------------------------------------------------------------
229 wxQTMediaBackend::~wxQTMediaBackend()
230 {
231 if(m_timer)
232 Cleanup();
233
234 //Note that ExitMovies() is not necessary...
235 ExitMovies();
236 }
237
238 //---------------------------------------------------------------------------
239 // wxQTMediaBackend::CreateControl
240 //
241 // 1) Intializes QuickTime
242 // 2) Creates the control window
243 //---------------------------------------------------------------------------
244 bool wxQTMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
245 wxWindowID id,
246 const wxPoint& pos,
247 const wxSize& size,
248 long style,
249 const wxValidator& validator,
250 const wxString& name)
251 {
252 //Don't bother in Native control mode
253 #if defined( __WXMAC__ ) && TARGET_API_MAC_OSX && ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2 )
254 if (!_wxIsQuickTime4Installed())
255 return false;
256 #endif
257
258 EnterMovies();
259
260 //
261 // Create window
262 // By default wxWindow(s) is created with a border -
263 // so we need to get rid of those
264 //
265 // Since we don't have a child window like most other
266 // backends, we don't need wxCLIP_CHILDREN
267 //
268 if ( !
269
270 #if wxUSE_CREATEMOVIECONTROL
271 ctrl->wxWindow::Create(parent, id, pos, size,
272 wxWindow::MacRemoveBordersFromStyle(style),
273 name)
274 #else
275 ctrl->wxControl::Create(parent, id, pos, size,
276 wxWindow::MacRemoveBordersFromStyle(style),
277 validator, name)
278 #endif
279 )
280 return false;
281
282 #if wxUSE_VALIDATORS
283 ctrl->SetValidator(validator);
284 #endif
285
286 m_ctrl = ctrl;
287 return true;
288 }
289
290 //---------------------------------------------------------------------------
291 // wxQTMediaBackend::Load (file version)
292 //
293 // 1) Get an FSSpec from the Windows path name
294 // 2) Open the movie
295 // 3) Obtain the movie instance from the movie resource
296 // 4) Close the movie resource
297 // 5) Finish loading
298 //---------------------------------------------------------------------------
299 bool wxQTMediaBackend::Load(const wxString& fileName)
300 {
301 if(m_timer)
302 Cleanup();
303
304 OSErr err = noErr;
305 short movieResFile;
306 FSSpec sfFile;
307
308 //FIXME:wxMacFilename2FSSpec crashes on empty string -
309 //does it crash on other strings too and should this
310 //"fix" be put in the carbon wxSound?
311 if (fileName.empty())
312 return false;
313
314 wxMacFilename2FSSpec( fileName , &sfFile );
315
316 if (OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr)
317 return false;
318
319 short movieResID = 0;
320 Str255 movieName;
321
322 err = NewMovieFromFile (
323 &m_movie,
324 movieResFile,
325 &movieResID,
326 movieName,
327 newMovieActive,
328 NULL); //wasChanged
329
330 CloseMovieFile (movieResFile);
331
332 if (err != noErr)
333 return false;
334
335 FinishLoad();
336
337 return ::GetMoviesError() == noErr;
338 }
339
340 //---------------------------------------------------------------------------
341 // wxQTMediaBackend::Load (URL Version)
342 //
343 // 1) Build an escaped URI from location
344 // 2) Create a handle to store the URI string
345 // 3) Put the URI string inside the handle
346 // 4) Make a QuickTime URL data ref from the handle with the URI in it
347 // 5) Clean up the URI string handle
348 // 6) Do some prerolling
349 // 7) Finish Loading
350 //---------------------------------------------------------------------------
351 bool wxQTMediaBackend::Load(const wxURI& location)
352 {
353 if(m_timer)
354 Cleanup();
355
356 wxString theURI = location.BuildURI();
357
358 OSErr err = noErr;
359
360 Handle theHandle = NewHandleClear(theURI.length() + 1);
361 wxASSERT(theHandle);
362
363 BlockMove(theURI.mb_str(), *theHandle, theURI.length() + 1);
364
365 //create the movie from the handle that refers to the URI
366 err = NewMovieFromDataRef(&m_movie, newMovieActive,
367 NULL, theHandle,
368 URLDataHandlerSubType);
369
370 DisposeHandle(theHandle);
371
372 if (err != noErr)
373 return false;
374
375 //preroll movie for streaming
376 //TODO:Async this using threads?
377 TimeValue timeNow;
378 Fixed playRate;
379 timeNow = GetMovieTime(m_movie, NULL);
380 playRate = GetMoviePreferredRate(m_movie);
381 PrePrerollMovie(m_movie, timeNow, playRate, NULL, NULL);
382 PrerollMovie(m_movie, timeNow, playRate);
383 SetMovieRate(m_movie, playRate);
384
385 FinishLoad();
386
387 return ::GetMoviesError() == noErr;
388 }
389
390 //---------------------------------------------------------------------------
391 // wxQTMediaBackend::FinishLoad
392 //
393 // 1) Create the movie timer
394 // 2) Get real size of movie for GetBestSize/sizers
395 // 3) See if there is video in the movie, and if so then either
396 // SetMovieGWorld if < 10.2 or use Native CreateMovieControl
397 // 4) Set the movie time scale to something usable so that seeking
398 // etc. will work correctly
399 // 5) Refresh parent window
400 //---------------------------------------------------------------------------
401 void wxQTMediaBackend::FinishLoad()
402 {
403 m_timer = new _wxQTTimer(m_movie, (wxQTMediaBackend*) this);
404 wxASSERT(m_timer);
405
406 //get the real size of the movie
407 Rect outRect;
408 ::GetMovieNaturalBoundsRect (m_movie, &outRect);
409 wxASSERT(::GetMoviesError() == noErr);
410
411 m_bestSize.x = outRect.right - outRect.left;
412 m_bestSize.y = outRect.bottom - outRect.top;
413
414 //reparent movie/*AudioMediaCharacteristic*/
415 if(GetMovieIndTrackType(m_movie, 1,
416 VisualMediaCharacteristic,
417 movieTrackCharacteristic |
418 movieTrackEnabledOnly) != NULL)
419 {
420 #if wxUSE_CREATEMOVIECONTROL
421 //
422 //Native CreateMovieControl QT control (Thanks to Kevin Olliver's
423 //wxQTMovie for some of this).
424 //
425 #define GetControlPeer(whatever) ctrl->m_peer
426 wxMediaCtrl* ctrl = (wxMediaCtrl*) m_ctrl;
427 Rect bounds = wxMacGetBoundsForControl(m_ctrl,
428 m_ctrl->GetPosition(),
429 m_ctrl->GetSize());
430
431 //Dispose of old control for new one
432 if (GetControlPeer(m_ctrl) && GetControlPeer(m_ctrl)->Ok() )
433 GetControlPeer(m_ctrl)->Dispose();
434
435 //Options-
436 //kMovieControlOptionXXX
437 //HideController - hide the movie controller
438 //LocateTopLeft - movie is pinned to top left rather than centered in the control
439 //EnableEditing - Allows programmatic editing and dragn'drop
440 //HandleEditingHI- Installs event stuff for edit menu - forces EnableEditing also
441 //SetKeysEnabled - Allows keyboard input
442 //ManuallyIdled - app handles movie idling rather than internal timer event loop
443 ::CreateMovieControl(
444 (WindowRef)
445 ctrl->MacGetTopLevelWindowRef(), //parent
446 &bounds, //control bounds
447 m_movie, //movie handle
448 kMovieControlOptionHideController
449 | kMovieControlOptionLocateTopLeft
450 | kMovieControlOptionSetKeysEnabled
451 // | kMovieControlOptionManuallyIdled
452 , //flags
453 ctrl->m_peer->GetControlRefAddr() );
454
455 ::EmbedControl(ctrl->m_peer->GetControlRef(), (ControlRef)ctrl->GetParent()->GetHandle());
456 #else
457 //
458 //"Emulation"
459 //
460 SetMovieGWorld(m_movie,
461 (CGrafPtr)
462 GetWindowPort(
463 (WindowRef)
464 m_ctrl->MacGetTopLevelWindowRef()
465 ),
466 nil);
467 #endif
468 }
469
470 //we want millisecond precision
471 ::SetMovieTimeScale(m_movie, 1000);
472 wxASSERT(::GetMoviesError() == noErr);
473
474 //
475 //Here, if the parent of the control has a sizer - we
476 //tell it to recalculate the size of this control since
477 //the user opened a separate media file
478 //
479 m_ctrl->InvalidateBestSize();
480 m_ctrl->GetParent()->Layout();
481 m_ctrl->GetParent()->Refresh();
482 m_ctrl->GetParent()->Update();
483
484 //send loaded event
485 wxMediaEvent theEvent(wxEVT_MEDIA_LOADED,
486 m_ctrl->GetId());
487 m_ctrl->AddPendingEvent(theEvent);
488 }
489
490 //---------------------------------------------------------------------------
491 // wxQTMediaBackend::Play
492 //
493 // 1) Start the QT movie
494 // 2) Start the movie loading timer
495 //---------------------------------------------------------------------------
496 bool wxQTMediaBackend::Play()
497 {
498 ::StartMovie(m_movie);
499 m_timer->SetPaused(false);
500 m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
501 return ::GetMoviesError() == noErr;
502 }
503
504 //---------------------------------------------------------------------------
505 // wxQTMediaBackend::Pause
506 //
507 // 1) Stop the movie
508 // 2) Stop the movie timer
509 //---------------------------------------------------------------------------
510 bool wxQTMediaBackend::Pause()
511 {
512 ::StopMovie(m_movie);
513 m_timer->SetPaused(true);
514 m_timer->Stop();
515 return ::GetMoviesError() == noErr;
516 }
517
518 //---------------------------------------------------------------------------
519 // wxQTMediaBackend::Stop
520 //
521 // 1) Stop the movie
522 // 2) Stop the movie timer
523 // 3) Seek to the beginning of the movie
524 //---------------------------------------------------------------------------
525 bool wxQTMediaBackend::Stop()
526 {
527 m_timer->SetPaused(false);
528 m_timer->Stop();
529
530 ::StopMovie(m_movie);
531 if(::GetMoviesError() != noErr)
532 return false;
533
534 ::GoToBeginningOfMovie(m_movie);
535 return ::GetMoviesError() == noErr;
536 }
537
538 //---------------------------------------------------------------------------
539 // wxQTMediaBackend::GetPlaybackRate
540 //
541 // 1) Get the movie playback rate from ::GetMovieRate
542 //---------------------------------------------------------------------------
543 double wxQTMediaBackend::GetPlaybackRate()
544 {
545 return ( ((double)::GetMovieRate(m_movie)) / 0x10000);
546 }
547
548 //---------------------------------------------------------------------------
549 // wxQTMediaBackend::SetPlaybackRate
550 //
551 // 1) Convert dRate to Fixed and Set the movie rate through SetMovieRate
552 //---------------------------------------------------------------------------
553 bool wxQTMediaBackend::SetPlaybackRate(double dRate)
554 {
555 ::SetMovieRate(m_movie, (Fixed) (dRate * 0x10000));
556 return ::GetMoviesError() == noErr;
557 }
558
559 //---------------------------------------------------------------------------
560 // wxQTMediaBackend::SetPosition
561 //
562 // 1) Create a time record struct (TimeRecord) with appropriate values
563 // 2) Pass struct to SetMovieTime
564 //---------------------------------------------------------------------------
565 bool wxQTMediaBackend::SetPosition(wxLongLong where)
566 {
567 TimeRecord theTimeRecord;
568 memset(&theTimeRecord, 0, sizeof(TimeRecord));
569 theTimeRecord.value.lo = where.GetValue();
570 theTimeRecord.scale = ::GetMovieTimeScale(m_movie);
571 theTimeRecord.base = ::GetMovieTimeBase(m_movie);
572 ::SetMovieTime(m_movie, &theTimeRecord);
573
574 if (::GetMoviesError() != noErr)
575 return false;
576
577 return true;
578 }
579
580 //---------------------------------------------------------------------------
581 // wxQTMediaBackend::GetPosition
582 //
583 // Calls GetMovieTime
584 //---------------------------------------------------------------------------
585 wxLongLong wxQTMediaBackend::GetPosition()
586 {
587 return ::GetMovieTime(m_movie, NULL);
588 }
589
590 //---------------------------------------------------------------------------
591 // wxQTMediaBackend::GetVolume
592 //
593 // Gets the volume through GetMovieVolume - which returns a 16 bit short -
594 //
595 // +--------+--------+
596 // + (1) + (2) +
597 // +--------+--------+
598 //
599 // (1) first 8 bits are value before decimal
600 // (2) second 8 bits are value after decimal
601 //
602 // Volume ranges from -1.0 (gain but no sound), 0 (no sound and no gain) to
603 // 1 (full gain and sound)
604 //---------------------------------------------------------------------------
605 double wxQTMediaBackend::GetVolume()
606 {
607 short sVolume = GetMovieVolume(m_movie);
608
609 if(sVolume & (128 << 8)) //negative - no sound
610 return 0.0;
611
612 return (sVolume & (127 << 8)) ? 1.0 : ((double)(sVolume & 255)) / 255.0;
613 }
614
615 //---------------------------------------------------------------------------
616 // wxQTMediaBackend::SetVolume
617 //
618 // Sets the volume through SetMovieVolume - which takes a 16 bit short -
619 //
620 // +--------+--------+
621 // + (1) + (2) +
622 // +--------+--------+
623 //
624 // (1) first 8 bits are value before decimal
625 // (2) second 8 bits are value after decimal
626 //
627 // Volume ranges from -1.0 (gain but no sound), 0 (no sound and no gain) to
628 // 1 (full gain and sound)
629 //---------------------------------------------------------------------------
630 bool wxQTMediaBackend::SetVolume(double dVolume)
631 {
632 short sVolume = (short) (dVolume >= .9999 ? 1 << 8 : (dVolume * 255) );
633 SetMovieVolume(m_movie, sVolume);
634 return true;
635 }
636
637 //---------------------------------------------------------------------------
638 // wxQTMediaBackend::GetDuration
639 //
640 // Calls GetMovieDuration
641 //---------------------------------------------------------------------------
642 wxLongLong wxQTMediaBackend::GetDuration()
643 {
644 return ::GetMovieDuration(m_movie);
645 }
646
647 //---------------------------------------------------------------------------
648 // wxQTMediaBackend::GetState
649 //
650 // Determines the current state - the timer keeps track of whether or not
651 // we are paused or stopped (if the timer is running we are playing)
652 //---------------------------------------------------------------------------
653 wxMediaState wxQTMediaBackend::GetState()
654 {
655 if ( !m_timer || (m_timer->IsRunning() == false &&
656 m_timer->GetPaused() == false) )
657 return wxMEDIASTATE_STOPPED;
658
659 if( m_timer->IsRunning() )
660 return wxMEDIASTATE_PLAYING;
661 else
662 return wxMEDIASTATE_PAUSED;
663 }
664
665 //---------------------------------------------------------------------------
666 // wxQTMediaBackend::Cleanup
667 //
668 // Diposes of the movie timer, Control if native, and stops and disposes
669 // of the QT movie
670 //---------------------------------------------------------------------------
671 void wxQTMediaBackend::Cleanup()
672 {
673 delete m_timer;
674 m_timer = NULL;
675
676 #if wxUSE_CREATEMOVIECONTROL
677 DisposeControl(((wxMediaCtrl*)m_ctrl)->m_peer->GetControlRef());
678 #endif
679
680 StopMovie(m_movie);
681 DisposeMovie(m_movie);
682 }
683
684 //---------------------------------------------------------------------------
685 // wxQTMediaBackend::GetVideoSize
686 //
687 // Returns the actual size of the QT movie
688 //---------------------------------------------------------------------------
689 wxSize wxQTMediaBackend::GetVideoSize() const
690 {
691 return m_bestSize;
692 }
693
694 //---------------------------------------------------------------------------
695 // wxQTMediaBackend::Move
696 //
697 // We need to do this even when using native qt control because
698 // CreateMovieControl is broken in this regard...
699 //---------------------------------------------------------------------------
700 void wxQTMediaBackend::Move(int x, int y, int w, int h)
701 {
702 #if !wxUSE_CREATEMOVIECONTROL
703 if(m_timer)
704 {
705 if ( m_ctrl )
706 {
707 m_ctrl->GetParent()->MacWindowToRootWindow(&x, &y);
708 }
709
710 Rect theRect = {y, x, y+h, x+w};
711
712 ::SetMovieBox(m_movie, &theRect);
713 wxASSERT(::GetMoviesError() == noErr);
714 }
715 #else
716 if(m_timer && m_ctrl)
717 {
718 m_ctrl->GetParent()->MacWindowToRootWindow(&x, &y);
719
720 ::MoveControl( (ControlRef) m_ctrl->GetHandle(), x, y );
721 m_ctrl->GetParent()->Refresh();
722 m_ctrl->GetParent()->Update();
723 }
724 #endif
725 }
726
727
728 //in source file that contains stuff you don't directly use
729 #include "wx/html/forcelnk.h"
730 FORCE_LINK_ME(basewxmediabackends);
731
732 #endif //wxUSE_MEDIACTRL