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(&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 if( _p_instance->isInPlaceActive() )
\r
133 *isVisible = _p_instance->isVisible() ? VARIANT_TRUE : VARIANT_FALSE;
\r
135 *isVisible = VARIANT_FALSE;
\r
140 STDMETHODIMP VLCControl::put_Visible(VARIANT_BOOL isVisible)
\r
142 if( _p_instance->isInPlaceActive() )
\r
143 _p_instance->setVisible(isVisible != VARIANT_FALSE);
\r
145 _p_instance->setShowDisplay(isVisible != VARIANT_FALSE);
\r
150 STDMETHODIMP VLCControl::play(void)
\r
152 int i_vlc = _p_instance->getVLCObject();
\r
156 _p_instance->fireOnPlayEvent();
\r
159 return E_UNEXPECTED;
\r
162 STDMETHODIMP VLCControl::pause(void)
\r
164 int i_vlc = _p_instance->getVLCObject();
\r
168 _p_instance->fireOnPauseEvent();
\r
171 return E_UNEXPECTED;
\r
174 STDMETHODIMP VLCControl::stop(void)
\r
176 int i_vlc = _p_instance->getVLCObject();
\r
180 _p_instance->fireOnStopEvent();
\r
183 return E_UNEXPECTED;
\r
186 STDMETHODIMP VLCControl::get_Playing(VARIANT_BOOL *isPlaying)
\r
188 if( NULL == isPlaying )
\r
189 return E_INVALIDARG;
\r
191 int i_vlc = _p_instance->getVLCObject();
\r
194 *isPlaying = VLC_IsPlaying(i_vlc) ? VARIANT_TRUE : VARIANT_FALSE;
\r
197 *isPlaying = VARIANT_FALSE;
\r
198 return E_UNEXPECTED;
\r
201 STDMETHODIMP VLCControl::put_Playing(VARIANT_BOOL isPlaying)
\r
203 int i_vlc = _p_instance->getVLCObject();
\r
206 if( VARIANT_FALSE == isPlaying )
\r
208 if( VLC_IsPlaying(i_vlc) )
\r
213 if( ! VLC_IsPlaying(i_vlc) )
\r
218 return E_UNEXPECTED;
\r
221 STDMETHODIMP VLCControl::get_Position(float *position)
\r
223 if( NULL == position )
\r
224 return E_INVALIDARG;
\r
226 int i_vlc = _p_instance->getVLCObject();
\r
229 *position = VLC_PositionGet(i_vlc);
\r
233 return E_UNEXPECTED;
\r
236 STDMETHODIMP VLCControl::put_Position(float position)
\r
238 int i_vlc = _p_instance->getVLCObject();
\r
241 VLC_PositionSet(i_vlc, position);
\r
244 return E_UNEXPECTED;
\r
247 STDMETHODIMP VLCControl::get_Time(int *seconds)
\r
249 if( NULL == seconds )
\r
250 return E_INVALIDARG;
\r
252 int i_vlc = _p_instance->getVLCObject();
\r
255 *seconds = VLC_TimeGet(i_vlc);
\r
259 return E_UNEXPECTED;
\r
262 STDMETHODIMP VLCControl::put_Time(int seconds)
\r
264 int i_vlc = _p_instance->getVLCObject();
\r
267 VLC_TimeSet(i_vlc, seconds, VLC_FALSE);
\r
270 return E_UNEXPECTED;
\r
273 STDMETHODIMP VLCControl::shuttle(int seconds)
\r
275 int i_vlc = _p_instance->getVLCObject();
\r
278 VLC_TimeSet(i_vlc, seconds, VLC_TRUE);
\r
281 return E_UNEXPECTED;
\r
284 STDMETHODIMP VLCControl::fullscreen(void)
\r
286 int i_vlc = _p_instance->getVLCObject();
\r
289 VLC_FullScreen(i_vlc);
\r
292 return E_UNEXPECTED;
\r
295 STDMETHODIMP VLCControl::get_Length(int *seconds)
\r
297 if( NULL == seconds )
\r
298 return E_INVALIDARG;
\r
300 int i_vlc = _p_instance->getVLCObject();
\r
303 *seconds = VLC_LengthGet(i_vlc);
\r
307 return E_UNEXPECTED;
\r
310 STDMETHODIMP VLCControl::playFaster(void)
\r
312 int i_vlc = _p_instance->getVLCObject();
\r
315 VLC_SpeedFaster(i_vlc);
\r
318 return E_UNEXPECTED;
\r
321 STDMETHODIMP VLCControl::playSlower(void)
\r
323 int i_vlc = _p_instance->getVLCObject();
\r
326 VLC_SpeedSlower(i_vlc);
\r
329 return E_UNEXPECTED;
\r
332 STDMETHODIMP VLCControl::get_Volume(int *volume)
\r
334 if( NULL == volume )
\r
335 return E_INVALIDARG;
\r
337 int i_vlc = _p_instance->getVLCObject();
\r
340 *volume = VLC_VolumeGet(i_vlc);
\r
344 return E_UNEXPECTED;
\r
347 STDMETHODIMP VLCControl::put_Volume(int volume)
\r
349 int i_vlc = _p_instance->getVLCObject();
\r
352 VLC_VolumeSet(i_vlc, volume);
\r
355 return E_UNEXPECTED;
\r
358 STDMETHODIMP VLCControl::toggleMute(void)
\r
360 int i_vlc = _p_instance->getVLCObject();
\r
363 VLC_VolumeMute(i_vlc);
\r
366 return E_UNEXPECTED;
\r
369 static void freeTargetOptions(char **cOptions, int cOptionCount)
\r
372 for( long pos=0; pos<cOptionCount; ++pos )
\r
374 char *cOption = cOptions[pos];
\r
375 if( NULL != cOption )
\r
380 if( NULL != cOptions )
\r
384 static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount)
\r
386 HRESULT hr = E_INVALIDARG;
\r
387 if( VT_ERROR == V_VT(options) )
\r
389 if( DISP_E_PARAMNOTFOUND == V_ERROR(options) )
\r
391 // optional parameter not set
\r
397 else if( (VT_EMPTY == V_VT(options)) || (VT_NULL == V_VT(options)) )
\r
404 else if( VT_DISPATCH == V_VT(options) )
\r
406 // collection parameter
\r
408 V_VT(&colEnum) = VT_UNKNOWN;
\r
409 hr = GetObjectProperty(V_DISPATCH(options), DISPID_NEWENUM, colEnum);
\r
410 if( SUCCEEDED(hr) )
\r
412 IEnumVARIANT *enumVar;
\r
413 hr = V_UNKNOWN(&colEnum)->QueryInterface(IID_IEnumVARIANT, (LPVOID *)&enumVar);
\r
414 if( SUCCEEDED(hr) )
\r
417 long capacity = 16;
\r
420 *cOptions = (char **)malloc(capacity*sizeof(char *));
\r
421 if( NULL != *cOptions )
\r
423 ZeroMemory(*cOptions, sizeof(char *)*capacity);
\r
424 while( SUCCEEDED(hr) && (S_OK == enumVar->Next(1, &option, NULL)) )
\r
426 if( VT_BSTR == V_VT(&option) )
\r
428 char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
\r
429 (*cOptions)[pos] = cOption;
\r
430 if( NULL != cOption )
\r
433 if( pos == capacity )
\r
435 char **moreOptions = (char **)realloc(*cOptions, (capacity+16)*sizeof(char *));
\r
436 if( NULL != moreOptions )
\r
438 ZeroMemory(moreOptions+capacity, sizeof(char *)*16);
\r
440 *cOptions = moreOptions;
\r
443 hr = E_OUTOFMEMORY;
\r
447 hr = E_OUTOFMEMORY;
\r
452 VariantClear(&option);
\r
454 *cOptionCount = pos;
\r
457 // free already processed elements
\r
458 freeTargetOptions(*cOptions, *cOptionCount);
\r
462 hr = E_OUTOFMEMORY;
\r
463 enumVar->Release();
\r
467 else if( V_ISARRAY(options) )
\r
470 SAFEARRAY *array = V_ISBYREF(options) ? *V_ARRAYREF(options) : V_ARRAY(options);
\r
472 if( SafeArrayGetDim(array) != 1 )
\r
473 return E_INVALIDARG;
\r
477 SafeArrayGetLBound(array, 1, &lBound);
\r
478 SafeArrayGetUBound(array, 1, &uBound);
\r
480 // have we got any options
\r
481 if( uBound > lBound )
\r
484 HRESULT hr = SafeArrayGetVartype(array, &vType);
\r
490 // marshall options into an array of C strings
\r
491 if( VT_VARIANT == vType )
\r
493 *cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
\r
494 if( NULL != options )
\r
495 return E_OUTOFMEMORY;
\r
497 for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
\r
500 hr = SafeArrayGetElement(array, &pos, &option);
\r
501 if( SUCCEEDED(hr) )
\r
503 if( VT_BSTR == V_VT(&option) )
\r
505 char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
\r
506 (*cOptions)[pos-lBound] = cOption;
\r
507 if( NULL == cOption )
\r
508 hr = E_OUTOFMEMORY;
\r
512 VariantClear(&option);
\r
516 else if( VT_BSTR == vType )
\r
518 *cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
\r
519 if( NULL != options )
\r
520 return E_OUTOFMEMORY;
\r
522 ZeroMemory(cOptions, sizeof(char *)*(uBound-lBound));
\r
523 for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
\r
526 hr = SafeArrayGetElement(array, &pos, &option);
\r
527 if( SUCCEEDED(hr) )
\r
529 char *cOption = CStrFromBSTR(codePage, option);
\r
530 (*cOptions)[pos-lBound] = cOption;
\r
531 if( NULL == cOption )
\r
532 hr = E_OUTOFMEMORY;
\r
533 SysFreeString(option);
\r
538 // unsupported type
\r
539 return E_INVALIDARG;
\r
541 *cOptionCount = pos-lBound;
\r
544 // free already processed elements
\r
545 freeTargetOptions(*cOptions, *cOptionCount);
\r
560 ** use VARIANT rather than a SAFEARRAY as argument type
\r
561 ** for compatibility with some scripting language (JScript)
\r
564 STDMETHODIMP VLCControl::addTarget( BSTR uri, VARIANT options, enum VLCPlaylistMode mode, int position)
\r
567 return E_INVALIDARG;
\r
569 HRESULT hr = E_UNEXPECTED;
\r
571 int i_vlc = _p_instance->getVLCObject();
\r
574 int codePage = _p_instance->getCodePage();
\r
575 char *cUri = CStrFromBSTR(codePage, uri);
\r
577 return E_OUTOFMEMORY;
\r
582 if( FAILED(createTargetOptions(codePage, &options, &cOptions, &cOptionsCount)) )
\r
583 return E_INVALIDARG;
\r
585 VLC_AddTarget(i_vlc, cUri, (const char **)cOptions, cOptionsCount, mode, position);
\r
588 freeTargetOptions(cOptions, cOptionsCount);
\r
594 STDMETHODIMP VLCControl::get_PlaylistIndex(int *index)
\r
596 if( NULL == index )
\r
597 return E_INVALIDARG;
\r
599 int i_vlc = _p_instance->getVLCObject();
\r
602 *index = VLC_PlaylistIndex(i_vlc);
\r
606 return E_UNEXPECTED;
\r
609 STDMETHODIMP VLCControl::get_PlaylistCount(int *count)
\r
611 int i_vlc = _p_instance->getVLCObject();
\r
614 *count = VLC_PlaylistNumberOfItems(i_vlc);
\r
617 return E_UNEXPECTED;
\r
620 STDMETHODIMP VLCControl::playlistNext(void)
\r
622 int i_vlc = _p_instance->getVLCObject();
\r
625 VLC_PlaylistNext(i_vlc);
\r
628 return E_UNEXPECTED;
\r
631 STDMETHODIMP VLCControl::playlistPrev(void)
\r
633 int i_vlc = _p_instance->getVLCObject();
\r
636 VLC_PlaylistPrev(i_vlc);
\r
639 return E_UNEXPECTED;
\r
642 STDMETHODIMP VLCControl::playlistClear(void)
\r
644 int i_vlc = _p_instance->getVLCObject();
\r
647 VLC_PlaylistClear(i_vlc);
\r
650 return E_UNEXPECTED;
\r
653 STDMETHODIMP VLCControl::get_VersionInfo(BSTR *version)
\r
655 if( NULL == version )
\r
656 return E_INVALIDARG;
\r
658 const char *versionStr = VLC_Version();
\r
659 if( NULL != versionStr )
\r
661 *version = BSTRFromCStr(_p_instance->getCodePage(), versionStr);
\r
663 return NULL == *version ? E_OUTOFMEMORY : NOERROR;
\r