1 /*****************************************************************************
2 * vlccontrol.cpp: ActiveX control for VLC
3 *****************************************************************************
4 * Copyright (C) 2005 VideoLAN
6 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
24 #include "vlccontrol.h"
28 VLCControl::~VLCControl()
31 _p_typeinfo->Release();
34 HRESULT VLCControl::getTypeInfo(void)
37 if( NULL == _p_typeinfo )
41 HRESULT hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
44 hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl, &_p_typeinfo);
55 STDMETHODIMP VLCControl::GetTypeInfoCount(UINT* pctInfo)
60 if( SUCCEEDED(getTypeInfo()) )
68 STDMETHODIMP VLCControl::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
73 if( SUCCEEDED(getTypeInfo()) )
75 _p_typeinfo->AddRef();
76 *ppTInfo = _p_typeinfo;
83 STDMETHODIMP VLCControl::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
84 UINT cNames, LCID lcid, DISPID* rgDispID)
86 if( SUCCEEDED(getTypeInfo()) )
88 return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
93 STDMETHODIMP VLCControl::Invoke(DISPID dispIdMember, REFIID riid,
94 LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
95 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
97 if( SUCCEEDED(getTypeInfo()) )
99 return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
100 pVarResult, pExcepInfo, puArgErr);
105 STDMETHODIMP VLCControl::get_Value(VARIANT *pvarValue)
107 if( NULL == pvarValue )
110 V_VT(pvarValue) = VT_BOOL;
111 return get_Playing(&V_BOOL(pvarValue));
114 STDMETHODIMP VLCControl::put_Value(VARIANT pvarValue)
116 if( VT_BOOL != V_VT(&pvarValue) )
119 HRESULT hr = VariantChangeType(&boolValue, &pvarValue, 0, VT_BOOL);
122 hr = get_Playing(&V_BOOL(&pvarValue));
123 //VariantClear(&boolValue);
127 return get_Playing(&V_BOOL(&pvarValue));
130 STDMETHODIMP VLCControl::get_Visible(VARIANT_BOOL *isVisible)
132 if( NULL == isVisible )
135 *isVisible = _p_instance->getVisible();
140 STDMETHODIMP VLCControl::put_Visible(VARIANT_BOOL isVisible)
142 _p_instance->setVisible(isVisible != VARIANT_FALSE);
147 STDMETHODIMP VLCControl::play(void)
149 int i_vlc = _p_instance->getVLCObject();
153 _p_instance->fireOnPlayEvent();
159 STDMETHODIMP VLCControl::pause(void)
161 int i_vlc = _p_instance->getVLCObject();
165 _p_instance->fireOnPauseEvent();
171 STDMETHODIMP VLCControl::stop(void)
173 int i_vlc = _p_instance->getVLCObject();
177 _p_instance->fireOnStopEvent();
183 STDMETHODIMP VLCControl::get_Playing(VARIANT_BOOL *isPlaying)
185 if( NULL == isPlaying )
188 int i_vlc = _p_instance->getVLCObject();
191 *isPlaying = VLC_IsPlaying(i_vlc) ? VARIANT_TRUE : VARIANT_FALSE;
194 *isPlaying = VARIANT_FALSE;
198 STDMETHODIMP VLCControl::put_Playing(VARIANT_BOOL isPlaying)
200 int i_vlc = _p_instance->getVLCObject();
203 if( VARIANT_FALSE == isPlaying )
205 if( VLC_IsPlaying(i_vlc) )
210 if( ! VLC_IsPlaying(i_vlc) )
218 STDMETHODIMP VLCControl::get_Position(float *position)
220 if( NULL == position )
223 int i_vlc = _p_instance->getVLCObject();
226 *position = VLC_PositionGet(i_vlc);
233 STDMETHODIMP VLCControl::put_Position(float position)
235 int i_vlc = _p_instance->getVLCObject();
238 VLC_PositionSet(i_vlc, position);
244 STDMETHODIMP VLCControl::get_Time(int *seconds)
246 if( NULL == seconds )
249 int i_vlc = _p_instance->getVLCObject();
252 *seconds = VLC_TimeGet(i_vlc);
259 STDMETHODIMP VLCControl::put_Time(int seconds)
261 int i_vlc = _p_instance->getVLCObject();
264 VLC_TimeSet(i_vlc, seconds, VLC_FALSE);
270 STDMETHODIMP VLCControl::shuttle(int seconds)
272 int i_vlc = _p_instance->getVLCObject();
275 VLC_TimeSet(i_vlc, seconds, VLC_TRUE);
281 STDMETHODIMP VLCControl::fullscreen(void)
283 int i_vlc = _p_instance->getVLCObject();
286 VLC_FullScreen(i_vlc);
292 STDMETHODIMP VLCControl::get_Length(int *seconds)
294 if( NULL == seconds )
297 int i_vlc = _p_instance->getVLCObject();
300 *seconds = VLC_LengthGet(i_vlc);
307 STDMETHODIMP VLCControl::playFaster(void)
309 int i_vlc = _p_instance->getVLCObject();
312 VLC_SpeedFaster(i_vlc);
318 STDMETHODIMP VLCControl::playSlower(void)
320 int i_vlc = _p_instance->getVLCObject();
323 VLC_SpeedSlower(i_vlc);
329 STDMETHODIMP VLCControl::get_Volume(int *volume)
334 int i_vlc = _p_instance->getVLCObject();
337 *volume = VLC_VolumeGet(i_vlc);
344 STDMETHODIMP VLCControl::put_Volume(int volume)
346 int i_vlc = _p_instance->getVLCObject();
349 VLC_VolumeSet(i_vlc, volume);
355 STDMETHODIMP VLCControl::toggleMute(void)
357 int i_vlc = _p_instance->getVLCObject();
360 VLC_VolumeMute(i_vlc);
366 static void freeTargetOptions(char **cOptions, int cOptionCount)
369 for( long pos=0; pos<cOptionCount; ++pos )
371 char *cOption = cOptions[pos];
372 if( NULL != cOption )
377 if( NULL != cOptions )
381 static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount)
383 HRESULT hr = E_INVALIDARG;
384 if( VT_ERROR == V_VT(options) )
386 if( DISP_E_PARAMNOTFOUND == V_ERROR(options) )
388 // optional parameter not set
394 else if( (VT_EMPTY == V_VT(options)) || (VT_NULL == V_VT(options)) )
401 else if( VT_DISPATCH == V_VT(options) )
403 // collection parameter
405 V_VT(&colEnum) = VT_UNKNOWN;
406 hr = GetObjectProperty(V_DISPATCH(options), DISPID_NEWENUM, colEnum);
409 IEnumVARIANT *enumVar;
410 hr = V_UNKNOWN(&colEnum)->QueryInterface(IID_IEnumVARIANT, (LPVOID *)&enumVar);
417 *cOptions = (char **)malloc(capacity*sizeof(char *));
418 if( NULL != *cOptions )
420 ZeroMemory(*cOptions, sizeof(char *)*capacity);
421 while( SUCCEEDED(hr) && (S_OK == enumVar->Next(1, &option, NULL)) )
423 if( VT_BSTR == V_VT(&option) )
425 char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
426 (*cOptions)[pos] = cOption;
427 if( NULL != cOption )
430 if( pos == capacity )
432 char **moreOptions = (char **)realloc(*cOptions, (capacity+16)*sizeof(char *));
433 if( NULL != moreOptions )
435 ZeroMemory(moreOptions+capacity, sizeof(char *)*16);
437 *cOptions = moreOptions;
449 VariantClear(&option);
454 // free already processed elements
455 freeTargetOptions(*cOptions, *cOptionCount);
464 else if( V_ISARRAY(options) )
467 SAFEARRAY *array = V_ISBYREF(options) ? *V_ARRAYREF(options) : V_ARRAY(options);
469 if( SafeArrayGetDim(array) != 1 )
474 SafeArrayGetLBound(array, 1, &lBound);
475 SafeArrayGetUBound(array, 1, &uBound);
477 // have we got any options
478 if( uBound > lBound )
481 HRESULT hr = SafeArrayGetVartype(array, &vType);
487 // marshall options into an array of C strings
488 if( VT_VARIANT == vType )
490 *cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
491 if( NULL != options )
492 return E_OUTOFMEMORY;
494 for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
497 hr = SafeArrayGetElement(array, &pos, &option);
500 if( VT_BSTR == V_VT(&option) )
502 char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
503 (*cOptions)[pos-lBound] = cOption;
504 if( NULL == cOption )
509 VariantClear(&option);
513 else if( VT_BSTR == vType )
515 *cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
516 if( NULL != options )
517 return E_OUTOFMEMORY;
519 ZeroMemory(cOptions, sizeof(char *)*(uBound-lBound));
520 for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
523 hr = SafeArrayGetElement(array, &pos, &option);
526 char *cOption = CStrFromBSTR(codePage, option);
527 (*cOptions)[pos-lBound] = cOption;
528 if( NULL == cOption )
530 SysFreeString(option);
538 *cOptionCount = pos-lBound;
541 // free already processed elements
542 freeTargetOptions(*cOptions, *cOptionCount);
557 ** use VARIANT rather than a SAFEARRAY as argument type
558 ** for compatibility with some scripting language (JScript)
561 STDMETHODIMP VLCControl::addTarget( BSTR uri, VARIANT options, enum VLCPlaylistMode mode, int position)
563 if( 0 == SysStringLen(uri) )
566 HRESULT hr = E_UNEXPECTED;
568 int i_vlc = _p_instance->getVLCObject();
571 int codePage = _p_instance->getCodePage();
572 char *cUri = CStrFromBSTR(codePage, uri);
574 return E_OUTOFMEMORY;
579 if( FAILED(createTargetOptions(codePage, &options, &cOptions, &cOptionsCount)) )
582 VLC_AddTarget(i_vlc, cUri, (const char **)cOptions, cOptionsCount, mode, position);
585 freeTargetOptions(cOptions, cOptionsCount);
591 STDMETHODIMP VLCControl::get_PlaylistIndex(int *index)
596 int i_vlc = _p_instance->getVLCObject();
599 *index = VLC_PlaylistIndex(i_vlc);
606 STDMETHODIMP VLCControl::get_PlaylistCount(int *count)
608 int i_vlc = _p_instance->getVLCObject();
611 *count = VLC_PlaylistNumberOfItems(i_vlc);
617 STDMETHODIMP VLCControl::playlistNext(void)
619 int i_vlc = _p_instance->getVLCObject();
622 VLC_PlaylistNext(i_vlc);
628 STDMETHODIMP VLCControl::playlistPrev(void)
630 int i_vlc = _p_instance->getVLCObject();
633 VLC_PlaylistPrev(i_vlc);
639 STDMETHODIMP VLCControl::playlistClear(void)
641 int i_vlc = _p_instance->getVLCObject();
644 VLC_PlaylistClear(i_vlc);
650 STDMETHODIMP VLCControl::get_VersionInfo(BSTR *version)
652 if( NULL == version )
655 const char *versionStr = VLC_Version();
656 if( NULL != versionStr )
658 *version = BSTRFromCStr(_p_instance->getCodePage(), versionStr);
660 return NULL == *version ? E_OUTOFMEMORY : NOERROR;