1 /*****************************************************************************
\r
2 * vlccontrol.cpp: ActiveX control for VLC
\r
3 *****************************************************************************
\r
4 * Copyright (C) 2005 VideoLAN
\r
6 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
\r
8 * This program is free software; you can redistribute it and/or modify
\r
9 * it under the terms of the GNU General Public License as published by
\r
10 * the Free Software Foundation; either version 2 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU General Public License
\r
19 * along with this program; if not, write to the Free Software
\r
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
\r
21 *****************************************************************************/
\r
24 #include "vlccontrol.h"
\r
28 VLCControl::~VLCControl()
\r
31 _p_typeinfo->Release();
\r
34 HRESULT VLCControl::getTypeInfo(void)
\r
36 HRESULT hr = NOERROR;
\r
37 if( NULL == _p_typeinfo )
\r
39 ITypeLib *p_typelib;
\r
41 HRESULT hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
\r
44 hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl, &_p_typeinfo);
\r
49 p_typelib->Release();
\r
55 STDMETHODIMP VLCControl::GetTypeInfoCount(UINT* pctInfo)
\r
57 if( SUCCEEDED(getTypeInfo()) )
\r
65 STDMETHODIMP VLCControl::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
\r
67 if( NULL == ppTInfo )
\r
68 return E_INVALIDARG;
\r
70 if( SUCCEEDED(getTypeInfo()) )
\r
72 _p_typeinfo->AddRef();
\r
73 *ppTInfo = _p_typeinfo;
\r
80 STDMETHODIMP VLCControl::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
\r
81 UINT cNames, LCID lcid, DISPID* rgDispID)
\r
83 if( SUCCEEDED(getTypeInfo()) )
\r
85 return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
\r
90 STDMETHODIMP VLCControl::Invoke(DISPID dispIdMember, REFIID riid,
\r
91 LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
\r
92 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
\r
94 if( SUCCEEDED(getTypeInfo()) )
\r
96 return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
\r
97 pVarResult, pExcepInfo, puArgErr);
\r
102 STDMETHODIMP VLCControl::get_Value(VARIANT *pvarValue)
\r
104 if( NULL == pvarValue )
\r
105 return E_INVALIDARG;
\r
107 V_VT(pvarValue) = VT_BOOL;
\r
108 return get_Playing(&V_BOOL(pvarValue));
\r
111 STDMETHODIMP VLCControl::put_Value(VARIANT pvarValue)
\r
113 if( VT_BOOL != V_VT(&pvarValue) )
\r
116 HRESULT hr = VariantChangeType(&boolValue, &pvarValue, 0, VT_BOOL);
\r
117 if( SUCCEEDED(hr) )
\r
119 hr = get_Playing(&V_BOOL(&pvarValue));
\r
120 //VariantClear(&boolValue);
\r
124 return get_Playing(&V_BOOL(&pvarValue));
\r
127 STDMETHODIMP VLCControl::get_Visible(VARIANT_BOOL *isVisible)
\r
129 if( NULL == isVisible )
\r
130 return E_INVALIDARG;
\r
132 *isVisible = _p_instance->getVisible();
\r
137 STDMETHODIMP VLCControl::put_Visible(VARIANT_BOOL isVisible)
\r
139 _p_instance->setVisible(isVisible != VARIANT_FALSE);
\r
144 STDMETHODIMP VLCControl::play(void)
\r
146 int i_vlc = _p_instance->getVLCObject();
\r
150 _p_instance->fireOnPlayEvent();
\r
153 return E_UNEXPECTED;
\r
156 STDMETHODIMP VLCControl::pause(void)
\r
158 int i_vlc = _p_instance->getVLCObject();
\r
162 _p_instance->fireOnPauseEvent();
\r
165 return E_UNEXPECTED;
\r
168 STDMETHODIMP VLCControl::stop(void)
\r
170 int i_vlc = _p_instance->getVLCObject();
\r
174 _p_instance->fireOnStopEvent();
\r
177 return E_UNEXPECTED;
\r
180 STDMETHODIMP VLCControl::get_Playing(VARIANT_BOOL *isPlaying)
\r
182 if( NULL == isPlaying )
\r
183 return E_INVALIDARG;
\r
185 int i_vlc = _p_instance->getVLCObject();
\r
188 *isPlaying = VLC_IsPlaying(i_vlc) ? VARIANT_TRUE : VARIANT_FALSE;
\r
191 *isPlaying = VARIANT_FALSE;
\r
192 return E_UNEXPECTED;
\r
195 STDMETHODIMP VLCControl::put_Playing(VARIANT_BOOL isPlaying)
\r
197 int i_vlc = _p_instance->getVLCObject();
\r
200 if( VARIANT_FALSE == isPlaying )
\r
202 if( VLC_IsPlaying(i_vlc) )
\r
207 if( ! VLC_IsPlaying(i_vlc) )
\r
212 return E_UNEXPECTED;
\r
215 STDMETHODIMP VLCControl::get_Position(float *position)
\r
217 if( NULL == position )
\r
218 return E_INVALIDARG;
\r
220 int i_vlc = _p_instance->getVLCObject();
\r
223 *position = VLC_PositionGet(i_vlc);
\r
227 return E_UNEXPECTED;
\r
230 STDMETHODIMP VLCControl::put_Position(float position)
\r
232 int i_vlc = _p_instance->getVLCObject();
\r
235 VLC_PositionSet(i_vlc, position);
\r
238 return E_UNEXPECTED;
\r
241 STDMETHODIMP VLCControl::get_Time(int *seconds)
\r
243 if( NULL == seconds )
\r
244 return E_INVALIDARG;
\r
246 int i_vlc = _p_instance->getVLCObject();
\r
249 *seconds = VLC_TimeGet(i_vlc);
\r
253 return E_UNEXPECTED;
\r
256 STDMETHODIMP VLCControl::put_Time(int seconds)
\r
258 int i_vlc = _p_instance->getVLCObject();
\r
261 VLC_TimeSet(i_vlc, seconds, VLC_FALSE);
\r
264 return E_UNEXPECTED;
\r
267 STDMETHODIMP VLCControl::shuttle(int seconds)
\r
269 int i_vlc = _p_instance->getVLCObject();
\r
272 VLC_TimeSet(i_vlc, seconds, VLC_TRUE);
\r
275 return E_UNEXPECTED;
\r
278 STDMETHODIMP VLCControl::fullscreen(void)
\r
280 int i_vlc = _p_instance->getVLCObject();
\r
283 VLC_FullScreen(i_vlc);
\r
286 return E_UNEXPECTED;
\r
289 STDMETHODIMP VLCControl::get_Length(int *seconds)
\r
291 if( NULL == seconds )
\r
292 return E_INVALIDARG;
\r
294 int i_vlc = _p_instance->getVLCObject();
\r
297 *seconds = VLC_LengthGet(i_vlc);
\r
301 return E_UNEXPECTED;
\r
304 STDMETHODIMP VLCControl::playFaster(void)
\r
306 int i_vlc = _p_instance->getVLCObject();
\r
309 VLC_SpeedFaster(i_vlc);
\r
312 return E_UNEXPECTED;
\r
315 STDMETHODIMP VLCControl::playSlower(void)
\r
317 int i_vlc = _p_instance->getVLCObject();
\r
320 VLC_SpeedSlower(i_vlc);
\r
323 return E_UNEXPECTED;
\r
326 STDMETHODIMP VLCControl::get_Volume(int *volume)
\r
328 if( NULL == volume )
\r
329 return E_INVALIDARG;
\r
331 int i_vlc = _p_instance->getVLCObject();
\r
334 *volume = VLC_VolumeGet(i_vlc);
\r
338 return E_UNEXPECTED;
\r
341 STDMETHODIMP VLCControl::put_Volume(int volume)
\r
343 int i_vlc = _p_instance->getVLCObject();
\r
346 VLC_VolumeSet(i_vlc, volume);
\r
349 return E_UNEXPECTED;
\r
352 STDMETHODIMP VLCControl::toggleMute(void)
\r
354 int i_vlc = _p_instance->getVLCObject();
\r
357 VLC_VolumeMute(i_vlc);
\r
360 return E_UNEXPECTED;
\r
363 static void freeTargetOptions(char **cOptions, int cOptionCount)
\r
366 for( long pos=0; pos<cOptionCount; ++pos )
\r
368 char *cOption = cOptions[pos];
\r
369 if( NULL != cOption )
\r
374 if( NULL != cOptions )
\r
378 static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount)
\r
380 HRESULT hr = E_INVALIDARG;
\r
381 if( VT_ERROR == V_VT(options) )
\r
383 if( DISP_E_PARAMNOTFOUND == V_ERROR(options) )
\r
385 // optional parameter not set
\r
391 else if( (VT_EMPTY == V_VT(options)) || (VT_NULL == V_VT(options)) )
\r
398 else if( VT_DISPATCH == V_VT(options) )
\r
400 // collection parameter
\r
402 V_VT(&colEnum) = VT_UNKNOWN;
\r
403 hr = GetObjectProperty(V_DISPATCH(options), DISPID_NEWENUM, colEnum);
\r
404 if( SUCCEEDED(hr) )
\r
406 IEnumVARIANT *enumVar;
\r
407 hr = V_UNKNOWN(&colEnum)->QueryInterface(IID_IEnumVARIANT, (LPVOID *)&enumVar);
\r
408 if( SUCCEEDED(hr) )
\r
411 long capacity = 16;
\r
414 *cOptions = (char **)malloc(capacity*sizeof(char *));
\r
415 if( NULL != *cOptions )
\r
417 ZeroMemory(*cOptions, sizeof(char *)*capacity);
\r
418 while( SUCCEEDED(hr) && (S_OK == enumVar->Next(1, &option, NULL)) )
\r
420 if( VT_BSTR == V_VT(&option) )
\r
422 char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
\r
423 (*cOptions)[pos] = cOption;
\r
424 if( NULL != cOption )
\r
427 if( pos == capacity )
\r
429 char **moreOptions = (char **)realloc(*cOptions, (capacity+16)*sizeof(char *));
\r
430 if( NULL != moreOptions )
\r
432 ZeroMemory(moreOptions+capacity, sizeof(char *)*16);
\r
434 *cOptions = moreOptions;
\r
437 hr = E_OUTOFMEMORY;
\r
441 hr = E_OUTOFMEMORY;
\r
446 VariantClear(&option);
\r
448 *cOptionCount = pos;
\r
451 // free already processed elements
\r
452 freeTargetOptions(*cOptions, *cOptionCount);
\r
456 hr = E_OUTOFMEMORY;
\r
457 enumVar->Release();
\r
461 else if( V_ISARRAY(options) )
\r
464 SAFEARRAY *array = V_ISBYREF(options) ? *V_ARRAYREF(options) : V_ARRAY(options);
\r
466 if( SafeArrayGetDim(array) != 1 )
\r
467 return E_INVALIDARG;
\r
471 SafeArrayGetLBound(array, 1, &lBound);
\r
472 SafeArrayGetUBound(array, 1, &uBound);
\r
474 // have we got any options
\r
475 if( uBound > lBound )
\r
478 HRESULT hr = SafeArrayGetVartype(array, &vType);
\r
484 // marshall options into an array of C strings
\r
485 if( VT_VARIANT == vType )
\r
487 *cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
\r
488 if( NULL != options )
\r
489 return E_OUTOFMEMORY;
\r
491 for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
\r
494 hr = SafeArrayGetElement(array, &pos, &option);
\r
495 if( SUCCEEDED(hr) )
\r
497 if( VT_BSTR == V_VT(&option) )
\r
499 char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
\r
500 (*cOptions)[pos-lBound] = cOption;
\r
501 if( NULL == cOption )
\r
502 hr = E_OUTOFMEMORY;
\r
506 VariantClear(&option);
\r
510 else if( VT_BSTR == vType )
\r
512 *cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
\r
513 if( NULL != options )
\r
514 return E_OUTOFMEMORY;
\r
516 ZeroMemory(cOptions, sizeof(char *)*(uBound-lBound));
\r
517 for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
\r
520 hr = SafeArrayGetElement(array, &pos, &option);
\r
521 if( SUCCEEDED(hr) )
\r
523 char *cOption = CStrFromBSTR(codePage, option);
\r
524 (*cOptions)[pos-lBound] = cOption;
\r
525 if( NULL == cOption )
\r
526 hr = E_OUTOFMEMORY;
\r
527 SysFreeString(option);
\r
532 // unsupported type
\r
533 return E_INVALIDARG;
\r
535 *cOptionCount = pos-lBound;
\r
538 // free already processed elements
\r
539 freeTargetOptions(*cOptions, *cOptionCount);
\r
554 ** use VARIANT rather than a SAFEARRAY as argument type
\r
555 ** for compatibility with some scripting language (JScript)
\r
558 STDMETHODIMP VLCControl::addTarget( BSTR uri, VARIANT options, enum VLCPlaylistMode mode, int position)
\r
561 return E_INVALIDARG;
\r
563 HRESULT hr = E_UNEXPECTED;
\r
565 int i_vlc = _p_instance->getVLCObject();
\r
568 int codePage = _p_instance->getCodePage();
\r
569 char *cUri = CStrFromBSTR(codePage, uri);
\r
571 return E_OUTOFMEMORY;
\r
576 if( FAILED(createTargetOptions(codePage, &options, &cOptions, &cOptionsCount)) )
\r
577 return E_INVALIDARG;
\r
579 VLC_AddTarget(i_vlc, cUri, (const char **)cOptions, cOptionsCount, mode, position);
\r
582 freeTargetOptions(cOptions, cOptionsCount);
\r
588 STDMETHODIMP VLCControl::get_PlaylistIndex(int *index)
\r
590 if( NULL == index )
\r
591 return E_INVALIDARG;
\r
593 int i_vlc = _p_instance->getVLCObject();
\r
596 *index = VLC_PlaylistIndex(i_vlc);
\r
600 return E_UNEXPECTED;
\r
603 STDMETHODIMP VLCControl::get_PlaylistCount(int *count)
\r
605 int i_vlc = _p_instance->getVLCObject();
\r
608 *count = VLC_PlaylistNumberOfItems(i_vlc);
\r
611 return E_UNEXPECTED;
\r
614 STDMETHODIMP VLCControl::playlistNext(void)
\r
616 int i_vlc = _p_instance->getVLCObject();
\r
619 VLC_PlaylistNext(i_vlc);
\r
622 return E_UNEXPECTED;
\r
625 STDMETHODIMP VLCControl::playlistPrev(void)
\r
627 int i_vlc = _p_instance->getVLCObject();
\r
630 VLC_PlaylistPrev(i_vlc);
\r
633 return E_UNEXPECTED;
\r
636 STDMETHODIMP VLCControl::playlistClear(void)
\r
638 int i_vlc = _p_instance->getVLCObject();
\r
641 VLC_PlaylistClear(i_vlc);
\r
644 return E_UNEXPECTED;
\r
647 STDMETHODIMP VLCControl::get_VersionInfo(BSTR *version)
\r
649 if( NULL == version )
\r
650 return E_INVALIDARG;
\r
652 const char *versionStr = VLC_Version();
\r
653 if( NULL != versionStr )
\r
655 *version = BSTRFromCStr(_p_instance->getCodePage(), versionStr);
\r
657 return NULL == *version ? E_OUTOFMEMORY : NOERROR;
\r