]> git.saurik.com Git - wxWidgets.git/blame - src/common/mediactrlcmn.cpp
return correct error message if NSLinkModule() fails; fixed flagrant buffer overflow
[wxWidgets.git] / src / common / mediactrlcmn.cpp
CommitLineData
ff4aedc5
RN
1/////////////////////////////////////////////////////////////////////////////
2// Name: common/mediactrl.cpp
3// Purpose: wxMediaCtrl common code
4// Author: Ryan Norton <wxprojects@comcast.net>
5// Modified by:
6// Created: 11/07/04
7// RCS-ID: $Id$
8// Copyright: (c) Ryan Norton
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12//===========================================================================
13// Definitions
14//===========================================================================
15
16//---------------------------------------------------------------------------
17// Pre-compiled header stuff
18//---------------------------------------------------------------------------
19
ff4aedc5
RN
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23#pragma hdrstop
24#endif
25
26//---------------------------------------------------------------------------
27// Includes
28//---------------------------------------------------------------------------
29#include "wx/mediactrl.h"
30#include "wx/hash.h"
31
32//---------------------------------------------------------------------------
33// Compilation guard
34//---------------------------------------------------------------------------
35#if wxUSE_MEDIACTRL
36
37//===========================================================================
38//
39// Implementation
226ec5a7 40//
ff4aedc5
RN
41//===========================================================================
42
43//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
44// RTTI and Event implementations
45//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46
47IMPLEMENT_CLASS(wxMediaCtrl, wxControl);
48IMPLEMENT_CLASS(wxMediaBackend, wxObject);
49IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent);
c220a8ec 50DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED);
c5191fbd 51DEFINE_EVENT_TYPE(wxEVT_MEDIA_LOADED);
c220a8ec 52DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP);
ff4aedc5
RN
53
54//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
55//
56// wxMediaCtrl
57//
58//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
59
38647faa
WS
60//---------------------------------------------------------------------------
61// wxMediaBackend Destructor
62//
63// This is here because the DARWIN gcc compiler badly screwed up and
64// needs the destructor implementation in the source
65//---------------------------------------------------------------------------
66wxMediaBackend::~wxMediaBackend()
67{
68}
69
ff4aedc5
RN
70//---------------------------------------------------------------------------
71// wxMediaCtrl::Create (file version)
72// wxMediaCtrl::Create (URL version)
73//
74// Searches for a backend that is installed on the system (backends
75// starting with lower characters in the alphabet are given priority),
76// and creates the control from it
226ec5a7 77//
ff4aedc5
RN
78// This searches by searching the global RTTI hashtable, class by class,
79// attempting to call CreateControl on each one found that is a derivative
9180b535 80// of wxMediaBackend - if it succeeded Create returns true, otherwise
ff4aedc5
RN
81// it keeps iterating through the hashmap.
82//---------------------------------------------------------------------------
83bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
84 const wxString& fileName,
226ec5a7 85 const wxPoint& pos,
ff4aedc5 86 const wxSize& size,
226ec5a7 87 long style,
ff4aedc5
RN
88 const wxString& szBackend,
89 const wxValidator& validator,
90 const wxString& name)
91{
92 if(!szBackend.empty())
93 {
38647faa
WS
94 wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
95
96 if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
97 pos, size, style, validator, name))
ff4aedc5
RN
98 {
99 m_imp = NULL;
100 return false;
101 }
102
103 if (!fileName.empty())
104 {
4ac61319 105 if (!Load(fileName))
ff4aedc5
RN
106 {
107 delete m_imp;
108 m_imp = NULL;
109 return false;
110 }
111 }
112
4ac61319 113 SetBestFittingSize(size);
ff4aedc5
RN
114 return true;
115 }
116 else
117 {
118 wxClassInfo::sm_classTable->BeginFind();
119
f8fe8a9e 120 wxClassInfo* classInfo;
ff4aedc5 121
f8fe8a9e 122 while((classInfo = NextBackend()) != NULL)
ff4aedc5
RN
123 {
124 if(!DoCreate(classInfo, parent, id,
125 pos, size, style, validator, name))
226ec5a7 126 continue;
ff4aedc5
RN
127
128 if (!fileName.empty())
129 {
4ac61319
RN
130 if (Load(fileName))
131 {
132 SetBestFittingSize(size);
ff4aedc5 133 return true;
4ac61319 134 }
ff4aedc5
RN
135 else
136 delete m_imp;
137 }
138 else
4ac61319
RN
139 {
140 SetBestFittingSize(size);
ff4aedc5 141 return true;
4ac61319 142 }
ff4aedc5
RN
143 }
144
145 m_imp = NULL;
146 return false;
147 }
148}
149
150bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
38647faa
WS
151 const wxURI& location,
152 const wxPoint& pos,
153 const wxSize& size,
154 long style,
155 const wxString& szBackend,
156 const wxValidator& validator,
157 const wxString& name)
ff4aedc5
RN
158{
159 if(!szBackend.empty())
160 {
38647faa
WS
161 wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
162 if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
163 pos, size, style, validator, name))
ff4aedc5
RN
164 {
165 m_imp = NULL;
166 return false;
167 }
168
4ac61319 169 if (!Load(location))
ff4aedc5
RN
170 {
171 delete m_imp;
172 m_imp = NULL;
173 return false;
174 }
175
4ac61319 176 SetBestFittingSize(size);
ff4aedc5
RN
177 return true;
178 }
179 else
180 {
181 wxClassInfo::sm_classTable->BeginFind();
182
f8fe8a9e 183 wxClassInfo* classInfo;
ff4aedc5 184
f8fe8a9e 185 while((classInfo = NextBackend()) != NULL)
ff4aedc5
RN
186 {
187 if(!DoCreate(classInfo, parent, id,
188 pos, size, style, validator, name))
226ec5a7 189 continue;
ff4aedc5 190
4ac61319
RN
191 if (Load(location))
192 {
193 SetBestFittingSize(size);
ff4aedc5 194 return true;
4ac61319 195 }
ff4aedc5
RN
196 else
197 delete m_imp;
ff4aedc5
RN
198 }
199
200 m_imp = NULL;
201 return false;
202 }
203}
204
205//---------------------------------------------------------------------------
206// wxMediaCtrl::DoCreate
207//
208// Attempts to create the control from a backend
209//---------------------------------------------------------------------------
210bool wxMediaCtrl::DoCreate(wxClassInfo* classInfo,
211 wxWindow* parent, wxWindowID id,
226ec5a7 212 const wxPoint& pos,
ff4aedc5 213 const wxSize& size,
226ec5a7 214 long style,
ff4aedc5
RN
215 const wxValidator& validator,
216 const wxString& name)
217{
218 m_imp = (wxMediaBackend*)classInfo->CreateObject();
226ec5a7 219
ff4aedc5
RN
220 if( m_imp->CreateControl(this, parent, id, pos, size,
221 style, validator, name) )
222 {
ff4aedc5
RN
223 return true;
224 }
226ec5a7 225
ff4aedc5
RN
226 delete m_imp;
227 return false;
228}
229
230//---------------------------------------------------------------------------
231// wxMediaCtrl::NextBackend
232//
233//
234// Search through the RTTI hashmap one at a
235// time, attempting to create each derivative
236// of wxMediaBackend
226ec5a7 237//
ff4aedc5 238//
43e8916f 239// STL isn't compatible with and will have a compilation error
ff4aedc5
RN
240// on a wxNode, however, wxHashTable::compatibility_iterator is
241// incompatible with the old 2.4 stable version - but since
242// we're in 2.5 only we don't need to worry about this
243// static
244//---------------------------------------------------------------------------
245wxClassInfo* wxMediaCtrl::NextBackend()
246{
247 wxHashTable::compatibility_iterator
248 node = wxClassInfo::sm_classTable->Next();
249 while (node)
250 {
251 wxClassInfo* classInfo = (wxClassInfo *)node->GetData();
252 if ( classInfo->IsKindOf(CLASSINFO(wxMediaBackend)) &&
253 classInfo != CLASSINFO(wxMediaBackend) )
254 {
255 return classInfo;
256 }
257 node = wxClassInfo::sm_classTable->Next();
258 }
259
260 //
261 // Nope - couldn't successfully find one... fail
262 //
263 return NULL;
264}
265
266
267//---------------------------------------------------------------------------
268// wxMediaCtrl Destructor
269//
270// Free up the backend if it exists
271//---------------------------------------------------------------------------
272wxMediaCtrl::~wxMediaCtrl()
273{
274 if (m_imp)
275 delete m_imp;
276}
277
278//---------------------------------------------------------------------------
279// wxMediaCtrl::Load (file version)
280// wxMediaCtrl::Load (URL version)
c5191fbd
VZ
281// wxMediaCtrl::Load (URL & Proxy version)
282// wxMediaCtrl::Load (wxInputStream version)
ff4aedc5
RN
283//
284// Here we call load of the backend - keeping
285// track of whether it was successful or not - which
286// will determine which later method calls work
287//---------------------------------------------------------------------------
288bool wxMediaCtrl::Load(const wxString& fileName)
289{
290 if(m_imp)
291 return (m_bLoaded = m_imp->Load(fileName));
292 return false;
293}
294
295bool wxMediaCtrl::Load(const wxURI& location)
296{
297 if(m_imp)
298 return (m_bLoaded = m_imp->Load(location));
299 return false;
300}
301
c5191fbd
VZ
302bool wxMediaCtrl::Load(const wxURI& location, const wxURI& proxy)
303{
304 if(m_imp)
305 return (m_bLoaded = m_imp->Load(location, proxy));
306 return false;
307}
308
ff4aedc5
RN
309//---------------------------------------------------------------------------
310// wxMediaCtrl::Play
311// wxMediaCtrl::Pause
312// wxMediaCtrl::Stop
313// wxMediaCtrl::GetPlaybackRate
314// wxMediaCtrl::SetPlaybackRate
9180b535
RN
315// wxMediaCtrl::Seek --> SetPosition
316// wxMediaCtrl::Tell --> GetPosition
317// wxMediaCtrl::Length --> GetDuration
ff4aedc5
RN
318// wxMediaCtrl::GetState
319// wxMediaCtrl::DoGetBestSize
6f8c67e7
JS
320// wxMediaCtrl::SetVolume
321// wxMediaCtrl::GetVolume
c5191fbd
VZ
322// wxMediaCtrl::ShowInterface
323// wxMediaCtrl::GetDownloadProgress
324// wxMediaCtrl::GetDownloadTotal
226ec5a7 325//
ff4aedc5
RN
326// 1) Check to see whether the backend exists and is loading
327// 2) Call the backend's version of the method, returning success
328// if the backend's version succeeds
329//---------------------------------------------------------------------------
330bool wxMediaCtrl::Play()
331{
332 if(m_imp && m_bLoaded)
333 return m_imp->Play();
334 return 0;
335}
336
337bool wxMediaCtrl::Pause()
338{
339 if(m_imp && m_bLoaded)
340 return m_imp->Pause();
341 return 0;
342}
343
344bool wxMediaCtrl::Stop()
345{
346 if(m_imp && m_bLoaded)
347 return m_imp->Stop();
348 return 0;
349}
350
351double wxMediaCtrl::GetPlaybackRate()
352{
353 if(m_imp && m_bLoaded)
354 return m_imp->GetPlaybackRate();
355 return 0;
356}
357
358bool wxMediaCtrl::SetPlaybackRate(double dRate)
359{
360 if(m_imp && m_bLoaded)
361 return m_imp->SetPlaybackRate(dRate);
362 return false;
363}
364
9180b535 365wxFileOffset wxMediaCtrl::Seek(wxFileOffset where, wxSeekMode mode)
ff4aedc5 366{
9180b535
RN
367 wxFileOffset offset;
368
369 switch (mode)
370 {
371 case wxFromStart:
372 offset = where;
373 break;
374 case wxFromEnd:
375 offset = Length() - where;
376 break;
377// case wxFromCurrent:
378 default:
379 offset = Tell() + where;
380 break;
381 }
382
383 if(m_imp && m_bLoaded && m_imp->SetPosition(offset))
384 return offset;
385 return wxInvalidOffset;
ff4aedc5
RN
386}
387
9180b535 388wxFileOffset wxMediaCtrl::Tell()
ff4aedc5
RN
389{
390 if(m_imp && m_bLoaded)
9180b535
RN
391 return (wxFileOffset) m_imp->GetPosition().ToLong();
392 return wxInvalidOffset;
ff4aedc5
RN
393}
394
9180b535 395wxFileOffset wxMediaCtrl::Length()
ff4aedc5
RN
396{
397 if(m_imp && m_bLoaded)
9180b535
RN
398 return (wxFileOffset) m_imp->GetDuration().ToLong();
399 return wxInvalidOffset;
ff4aedc5
RN
400}
401
402wxMediaState wxMediaCtrl::GetState()
403{
404 if(m_imp && m_bLoaded)
405 return m_imp->GetState();
406 return wxMEDIASTATE_STOPPED;
407}
408
409wxSize wxMediaCtrl::DoGetBestSize() const
410{
411 if(m_imp)
412 return m_imp->GetVideoSize();
c47addef 413 return wxSize(0,0);
ff4aedc5
RN
414}
415
6f8c67e7
JS
416double wxMediaCtrl::GetVolume()
417{
418 if(m_imp && m_bLoaded)
419 return m_imp->GetVolume();
420 return 0.0;
421}
422
423bool wxMediaCtrl::SetVolume(double dVolume)
424{
425 if(m_imp && m_bLoaded)
426 return m_imp->SetVolume(dVolume);
427 return false;
428}
429
c5191fbd
VZ
430bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
431{
432 if(m_imp)
433 return m_imp->ShowPlayerControls(flags);
434 return false;
435}
436
437wxFileOffset wxMediaCtrl::GetDownloadProgress()
438{
439 if(m_imp && m_bLoaded)
440 return (wxFileOffset) m_imp->GetDownloadProgress().ToLong();
441 return wxInvalidOffset;
442}
443
444wxFileOffset wxMediaCtrl::GetDownloadTotal()
445{
446 if(m_imp && m_bLoaded)
447 return (wxFileOffset) m_imp->GetDownloadTotal().ToLong();
448 return wxInvalidOffset;
449}
450
ff4aedc5
RN
451//---------------------------------------------------------------------------
452// wxMediaCtrl::DoMoveWindow
226ec5a7 453//
ff4aedc5
RN
454// 1) Call parent's version so that our control's window moves where
455// it's supposed to
456// 2) If the backend exists and is loaded, move the video
457// of the media to where our control's window is now located
458//---------------------------------------------------------------------------
459void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h)
460{
461 wxControl::DoMoveWindow(x,y,w,h);
462
463 if(m_imp)
464 m_imp->Move(x, y, w, h);
465}
466
bf354396
VZ
467//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
468//
469// wxMediaBackendCommonBase
470//
471//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
472
473void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
474{
475 // our best size changed after opening a new file
476 m_ctrl->InvalidateBestSize();
477 m_ctrl->SetSize(m_ctrl->GetSize());
478
479 // if the parent of the control has a sizer ask it to refresh our size
480 wxWindow * const parent = m_ctrl->GetParent();
481 if ( parent->GetSizer() )
482 {
483 m_ctrl->GetParent()->Layout();
484 m_ctrl->GetParent()->Refresh();
485 m_ctrl->GetParent()->Update();
486 }
487}
488
489void wxMediaBackendCommonBase::NotifyMovieLoaded()
490{
491 NotifyMovieSizeChanged();
492
493 // notify about movie being fully loaded
494 QueueEvent(wxEVT_MEDIA_LOADED);
495}
496
497bool wxMediaBackendCommonBase::SendStopEvent()
498{
499 wxMediaEvent theEvent(wxEVT_MEDIA_STOP, m_ctrl->GetId());
500
501 return !m_ctrl->ProcessEvent(theEvent) || theEvent.IsAllowed();
502}
503
504void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType)
505{
506 wxMediaEvent theEvent(evtType, m_ctrl->GetId());
507 m_ctrl->AddPendingEvent(theEvent);
508}
509
02250fa1 510#include "wx/html/forcelnk.h"
ff4aedc5
RN
511FORCE_LINK(basewxmediabackends);
512
513//---------------------------------------------------------------------------
514// End of compilation guard and of file
515//---------------------------------------------------------------------------
516#endif //wxUSE_MEDIACTRL
517
518