X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=activex%2Fvlccontrol.cpp;h=d9793bf30a87f384bcbe5b56d4aebd6305b1a953;hb=c1d8196e177c6b7d44d0ba84d09d121e5d4072b3;hp=4edaefb4f7412a2fc3c6142ccf3873f1d4791422;hpb=19313bbfdececacf005acccfb1da9d02a90084b9;p=vlc diff --git a/activex/vlccontrol.cpp b/activex/vlccontrol.cpp index 4edaefb4f7..d9793bf30a 100644 --- a/activex/vlccontrol.cpp +++ b/activex/vlccontrol.cpp @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #include "plugin.h" @@ -40,7 +40,7 @@ HRESULT VLCControl::getTypeInfo(void) { ITypeLib *p_typelib; - HRESULT hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib); + hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib); if( SUCCEEDED(hr) ) { hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCControl, &_p_typeinfo); @@ -76,13 +76,13 @@ STDMETHODIMP VLCControl::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo { _p_typeinfo->AddRef(); *ppTInfo = _p_typeinfo; - return NO_ERROR; + return NOERROR; } *ppTInfo = NULL; return E_NOTIMPL; }; -STDMETHODIMP VLCControl::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, +STDMETHODIMP VLCControl::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispID) { if( SUCCEEDED(getTypeInfo()) ) @@ -113,7 +113,7 @@ STDMETHODIMP VLCControl::get_Visible(VARIANT_BOOL *isVisible) return NOERROR; }; - + STDMETHODIMP VLCControl::put_Visible(VARIANT_BOOL isVisible) { _p_instance->setVisible(isVisible != VARIANT_FALSE); @@ -123,201 +123,227 @@ STDMETHODIMP VLCControl::put_Visible(VARIANT_BOOL isVisible) STDMETHODIMP VLCControl::play(void) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) { VLC_Play(i_vlc); _p_instance->fireOnPlayEvent(); - return NOERROR; } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::pause(void) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) { VLC_Pause(i_vlc); _p_instance->fireOnPauseEvent(); - return NOERROR; } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::stop(void) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) { VLC_Stop(i_vlc); _p_instance->fireOnStopEvent(); - return NOERROR; } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::get_Playing(VARIANT_BOOL *isPlaying) { if( NULL == isPlaying ) return E_POINTER; - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + HRESULT result = NOERROR; + if( _p_instance->isRunning() ) { - *isPlaying = VLC_IsPlaying(i_vlc) ? VARIANT_TRUE : VARIANT_FALSE; - return NOERROR; + int i_vlc; + result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) + { + *isPlaying = VLC_IsPlaying(i_vlc) ? VARIANT_TRUE : VARIANT_FALSE; + return NOERROR; + } } *isPlaying = VARIANT_FALSE; - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::get_Position(float *position) { if( NULL == position ) return E_POINTER; - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + HRESULT result = E_UNEXPECTED; + if( _p_instance->isRunning() ) { - *position = VLC_PositionGet(i_vlc); - return NOERROR; + int i_vlc; + result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) + { + *position = VLC_PositionGet(i_vlc); + return NOERROR; + } } *position = 0.0f; - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::put_Position(float position) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + HRESULT result = E_UNEXPECTED; + if( _p_instance->isRunning() ) { - VLC_PositionSet(i_vlc, position); - return NOERROR; + int i_vlc; + result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) + { + VLC_PositionSet(i_vlc, position); + } } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::get_Time(int *seconds) { if( NULL == seconds ) return E_POINTER; - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + HRESULT result = NOERROR; + if( _p_instance->isRunning() ) { - *seconds = VLC_TimeGet(i_vlc); - return NOERROR; + int i_vlc; + result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) + { + *seconds = VLC_TimeGet(i_vlc); + } } - *seconds = 0; - return E_UNEXPECTED; + else + *seconds = _p_instance->getTime(); + + return result; }; - + STDMETHODIMP VLCControl::put_Time(int seconds) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) - { - VLC_TimeSet(i_vlc, seconds, VLC_FALSE); - return NOERROR; - } - return E_UNEXPECTED; + _p_instance->setTime(seconds); + + return NOERROR; }; - + STDMETHODIMP VLCControl::shuttle(int seconds) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + HRESULT result = E_UNEXPECTED; + if( _p_instance->isRunning() ) { - VLC_TimeSet(i_vlc, seconds, VLC_TRUE); - return NOERROR; + int i_vlc; + result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) + { + VLC_TimeSet(i_vlc, seconds, VLC_TRUE); + } } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::fullscreen(void) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + HRESULT result = E_UNEXPECTED; + if( _p_instance->isRunning() ) { - VLC_FullScreen(i_vlc); - return NOERROR; + int i_vlc; + result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) + { + VLC_FullScreen(i_vlc); + } } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::get_Length(int *seconds) { if( NULL == seconds ) return E_POINTER; - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + HRESULT result = NOERROR; + if( _p_instance->isRunning() ) { - *seconds = VLC_LengthGet(i_vlc); - return NOERROR; + int i_vlc; + result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) + { + *seconds = VLC_LengthGet(i_vlc); + return NOERROR; + } } *seconds = 0; - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::playFaster(void) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + HRESULT result = E_UNEXPECTED; + if( _p_instance->isRunning() ) { - VLC_SpeedFaster(i_vlc); - return NOERROR; + int i_vlc; + result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) + { + VLC_SpeedFaster(i_vlc); + } } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::playSlower(void) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + HRESULT result = E_UNEXPECTED; + if( _p_instance->isRunning() ) { - VLC_SpeedSlower(i_vlc); - return NOERROR; + int i_vlc; + result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) + { + VLC_SpeedSlower(i_vlc); + } } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::get_Volume(int *volume) { if( NULL == volume ) return E_POINTER; - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) - { - *volume = VLC_VolumeGet(i_vlc); - return NOERROR; - } - *volume = 0; - return E_UNEXPECTED; + *volume = _p_instance->getVolume(); + return NOERROR; }; - + STDMETHODIMP VLCControl::put_Volume(int volume) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) - { - VLC_VolumeSet(i_vlc, volume); - return NOERROR; - } - return E_UNEXPECTED; + _p_instance->setVolume(volume); + return NOERROR; }; - + STDMETHODIMP VLCControl::toggleMute(void) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) { VLC_VolumeMute(i_vlc); - return NOERROR; } - return E_UNEXPECTED; + return result; }; STDMETHODIMP VLCControl::setVariable(BSTR name, VARIANT value) @@ -325,18 +351,18 @@ STDMETHODIMP VLCControl::setVariable(BSTR name, VARIANT value) if( 0 == SysStringLen(name) ) return E_INVALIDARG; - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT hr = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(hr) ) { int codePage = _p_instance->getCodePage(); char *psz_varname = CStrFromBSTR(codePage, name); if( NULL == psz_varname ) return E_OUTOFMEMORY; - HRESULT hr = E_INVALIDARG; int i_type; vlc_value_t val; - + if( VLC_SUCCESS == VLC_VariableType(i_vlc, psz_varname, &i_type) ) { VARIANT arg; @@ -345,20 +371,20 @@ STDMETHODIMP VLCControl::setVariable(BSTR name, VARIANT value) switch( i_type ) { case VLC_VAR_BOOL: - hr = VariantChangeType(&value, &arg, 0, VT_BOOL); + hr = VariantChangeType(&arg, &value, 0, VT_BOOL); if( SUCCEEDED(hr) ) val.b_bool = (VARIANT_TRUE == V_BOOL(&arg)) ? VLC_TRUE : VLC_FALSE; break; case VLC_VAR_INTEGER: case VLC_VAR_HOTKEY: - hr = VariantChangeType(&value, &arg, 0, VT_I4); + hr = VariantChangeType(&arg, &value, 0, VT_I4); if( SUCCEEDED(hr) ) val.i_int = V_I4(&arg); break; case VLC_VAR_FLOAT: - hr = VariantChangeType(&value, &arg, 0, VT_R4); + hr = VariantChangeType(&arg, &value, 0, VT_R4); if( SUCCEEDED(hr) ) val.f_float = V_R4(&arg); break; @@ -368,9 +394,10 @@ STDMETHODIMP VLCControl::setVariable(BSTR name, VARIANT value) case VLC_VAR_FILE: case VLC_VAR_DIRECTORY: case VLC_VAR_VARIABLE: - hr = VariantChangeType(&value, &arg, 0, VT_BSTR); + hr = VariantChangeType(&arg, &value, 0, VT_BSTR); if( SUCCEEDED(hr) ) { + i_type = VLC_VAR_STRING; val.psz_string = CStrFromBSTR(codePage, V_BSTR(&arg)); VariantClear(&arg); } @@ -378,7 +405,7 @@ STDMETHODIMP VLCControl::setVariable(BSTR name, VARIANT value) case VLC_VAR_TIME: // use a double value to represent time (base is expressed in seconds) - hr = VariantChangeType(&value, &arg, 0, VT_R8); + hr = VariantChangeType(&arg, &value, 0, VT_R8); if( SUCCEEDED(hr) ) val.i_time = (signed __int64)(V_R8(&arg)*1000000.0); break; @@ -388,7 +415,7 @@ STDMETHODIMP VLCControl::setVariable(BSTR name, VARIANT value) } } else { - // no defined type, defaults to VARIANT type + // no defined type, use type in VARIANT hr = NO_ERROR; switch( V_VT(&value) ) { @@ -425,29 +452,30 @@ STDMETHODIMP VLCControl::setVariable(BSTR name, VARIANT value) CoTaskMemFree(val.psz_string); } CoTaskMemFree(psz_varname); - - return hr; } - return E_UNEXPECTED; + return hr; }; STDMETHODIMP VLCControl::getVariable( BSTR name, VARIANT *value) { - if( 0 == SysStringLen(name) ) - return E_INVALIDARG; - if( NULL == value ) return E_POINTER; - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + VariantInit(value); + + if( 0 == SysStringLen(name) ) + return E_INVALIDARG; + + int i_vlc; + HRESULT hr = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(hr) ) { - int codePage = _p_instance->getCodePage(); + UINT codePage = _p_instance->getCodePage(); char *psz_varname = CStrFromBSTR(codePage, name); if( NULL == psz_varname ) return E_OUTOFMEMORY; - HRESULT hr = E_INVALIDARG; + hr = E_INVALIDARG; vlc_value_t val; int i_type; @@ -481,7 +509,8 @@ STDMETHODIMP VLCControl::getVariable( BSTR name, VARIANT *value) case VLC_VAR_VARIABLE: V_VT(value) = VT_BSTR; V_BSTR(value) = BSTRFromCStr(codePage, val.psz_string); - CoTaskMemFree(val.psz_string); + if( NULL != val.psz_string) + free(val.psz_string); break; case VLC_VAR_TIME: @@ -497,12 +526,12 @@ STDMETHODIMP VLCControl::getVariable( BSTR name, VARIANT *value) CoTaskMemFree(psz_varname); return hr; } - return E_UNEXPECTED; + return hr; }; -static void freeTargetOptions(char **cOptions, int cOptionCount) +void VLCControl::FreeTargetOptions(char **cOptions, int cOptionCount) { - // clean up + // clean up if( NULL != cOptions ) { for( int pos=0; pos 0 ) + { + hr = E_OUTOFMEMORY; + char *s = CStrFromBSTR(codePage, bstr); + char *val = s; + if( val ) + { + long capacity = 16; + char **options = (char **)CoTaskMemAlloc(capacity*sizeof(char *)); + if( options ) + { + int nOptions = 0; + + char *end = val + strlen(val); + while( val < end ) + { + // skip leading blanks + while( (val < end) + && ((*val == ' ' ) || (*val == '\t')) ) + ++val; + + char *start = val; + // skip till we get a blank character + while( (val < end) + && (*val != ' ' ) + && (*val != '\t') ) + { + char c = *(val++); + if( ('\'' == c) || ('"' == c) ) + { + // skip till end of string + while( (val < end) && (*(val++) != c ) ); + } + } + + if( val > start ) + { + if( nOptions == capacity ) + { + capacity += 16; + char **moreOptions = (char **)CoTaskMemRealloc(options, capacity*sizeof(char*)); + if( ! moreOptions ) + { + /* failed to allocate more memory */ + CoTaskMemFree(s); + /* return what we got so far */ + *cOptionCount = nOptions; + *cOptions = options; + return NOERROR; + } + options = moreOptions; + } + *(val++) = '\0'; + options[nOptions] = (char *)CoTaskMemAlloc(val-start); + if( options[nOptions] ) + { + memcpy(options[nOptions], start, val-start); + ++nOptions; + } + else + { + /* failed to allocate memory */ + CoTaskMemFree(s); + /* return what we got so far */ + *cOptionCount = nOptions; + *cOptions = options; + return NOERROR; + } + } + else + // must be end of string + break; + } + *cOptionCount = nOptions; + *cOptions = options; + hr = NOERROR; + } + CoTaskMemFree(s); + } + } + return hr; +} + +HRESULT VLCControl::CreateTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount) { HRESULT hr = E_INVALIDARG; if( VT_ERROR == V_VT(options) ) @@ -539,7 +654,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti } else if( VT_DISPATCH == V_VT(options) ) { - // collection parameter + // if object is a collection, retrieve enumerator VARIANT colEnum; V_VT(&colEnum) = VT_UNKNOWN; hr = GetObjectProperty(V_DISPATCH(options), DISPID_NEWENUM, colEnum); @@ -592,7 +707,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti if( FAILED(hr) ) { // free already processed elements - freeTargetOptions(*cOptions, *cOptionCount); + FreeTargetOptions(*cOptions, *cOptionCount); } } else @@ -601,6 +716,18 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti enumVar->Release(); } } + else + { + // coerce object into a string and parse it + VARIANT v_name; + VariantInit(&v_name); + hr = VariantChangeType(&v_name, options, 0, VT_BSTR); + if( SUCCEEDED(hr) ) + { + hr = parseStringOptions(codePage, V_BSTR(&v_name), cOptions, cOptionCount); + VariantClear(&v_name); + } + } } else if( V_ISARRAY(options) ) { @@ -616,7 +743,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti SafeArrayGetUBound(array, 1, &uBound); // have we got any options - if( uBound > lBound ) + if( uBound >= lBound ) { VARTYPE vType; hr = SafeArrayGetVartype(array, &vType); @@ -628,18 +755,18 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti // marshall options into an array of C strings if( VT_VARIANT == vType ) { - *cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound)); + *cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound+1)); if( NULL == *cOptions ) return E_OUTOFMEMORY; - ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound)); - for(pos=lBound; SUCCEEDED(hr) && (posgetVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT hr = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(hr) ) { char *cUri = CStrFromBSTR(CP_UTF8, uri); if( NULL == cUri ) @@ -722,7 +864,7 @@ STDMETHODIMP VLCControl::addTarget( BSTR uri, VARIANT options, enum VLCPlaylistM int cOptionsCount; char **cOptions; - if( FAILED(createTargetOptions(CP_UTF8, &options, &cOptions, &cOptionsCount)) ) + if( FAILED(CreateTargetOptions(CP_UTF8, &options, &cOptions, &cOptionsCount)) ) return E_INVALIDARG; if( VLC_SUCCESS <= VLC_AddTarget(i_vlc, cUri, (const char **)cOptions, cOptionsCount, mode, position) ) @@ -738,72 +880,77 @@ STDMETHODIMP VLCControl::addTarget( BSTR uri, VARIANT options, enum VLCPlaylistM _p_instance->fireOnStopEvent(); } - freeTargetOptions(cOptions, cOptionsCount); + FreeTargetOptions(cOptions, cOptionsCount); CoTaskMemFree(cUri); } return hr; }; - + STDMETHODIMP VLCControl::get_PlaylistIndex(int *index) { if( NULL == index ) return E_POINTER; - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) { *index = VLC_PlaylistIndex(i_vlc); return NOERROR; } *index = 0; - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::get_PlaylistCount(int *count) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) { *count = VLC_PlaylistNumberOfItems(i_vlc); return NOERROR; } *count = 0; - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::playlistNext(void) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) { VLC_PlaylistNext(i_vlc); return NOERROR; } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::playlistPrev(void) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) { VLC_PlaylistPrev(i_vlc); return NOERROR; } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::playlistClear(void) { - int i_vlc = _p_instance->getVLCObject(); - if( i_vlc ) + int i_vlc; + HRESULT result = _p_instance->getVLCObject(&i_vlc); + if( SUCCEEDED(result) ) { VLC_PlaylistClear(i_vlc); return NOERROR; } - return E_UNEXPECTED; + return result; }; - + STDMETHODIMP VLCControl::get_VersionInfo(BSTR *version) { if( NULL == version ) @@ -812,14 +959,14 @@ STDMETHODIMP VLCControl::get_VersionInfo(BSTR *version) const char *versionStr = VLC_Version(); if( NULL != versionStr ) { - *version = BSTRFromCStr(_p_instance->getCodePage(), versionStr); - + *version = BSTRFromCStr(CP_UTF8, versionStr); + return NULL == *version ? E_OUTOFMEMORY : NOERROR; } *version = NULL; return E_FAIL; }; - + STDMETHODIMP VLCControl::get_MRL(BSTR *mrl) { if( NULL == mrl ) @@ -866,4 +1013,3 @@ STDMETHODIMP VLCControl::put_AutoLoop(VARIANT_BOOL autoloop) _p_instance->setAutoLoop((VARIANT_FALSE != autoloop) ? TRUE: FALSE); return S_OK; }; -