]> git.sesse.net Git - vlc/blobdiff - activex/vlccontrol.cpp
* ctrl_*.cpp : mouse scrolling behavior change
[vlc] / activex / vlccontrol.cpp
index 89320207a7d382297d93ae3a1fd415f7ee7a0c12..3ae440fc237bb106f75bad2d0a8fda650868aa24 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * vlccontrol.cpp: ActiveX control for VLC
  *****************************************************************************
- * Copyright (C) 2005 VideoLAN
+ * Copyright (C) 2005 the VideoLAN team
  *
  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
  *
@@ -126,6 +126,26 @@ STDMETHODIMP VLCControl::play(void)
     int i_vlc = _p_instance->getVLCObject();
     if( i_vlc )
     {
+        if( ! _p_instance->isInPlaceActive() )
+        {
+            /*
+            ** object has not yet been activated. try doing it by ourself
+            ** if parent container is known
+            */
+            LPOLEOBJECT p_oleobject;
+            if( SUCCEEDED(QueryInterface(IID_IOleObject, (LPVOID *)&p_oleobject)) )
+            {
+                LPOLECLIENTSITE p_clientsite;
+                if( SUCCEEDED(p_oleobject->GetClientSite(&p_clientsite)
+                    && (NULL != p_clientsite)) )
+                {
+                    p_oleobject->DoVerb(OLEIVERB_INPLACEACTIVATE,
+                            NULL, p_clientsite, 0, NULL, NULL);
+                    p_clientsite->Release();
+                }
+                p_oleobject->Release();
+            }
+        }
         VLC_Play(i_vlc);
         _p_instance->fireOnPlayEvent();
         return NOERROR;
@@ -355,15 +375,13 @@ STDMETHODIMP VLCControl::setVariable( BSTR name, VARIANT value)
 
         HRESULT hr = E_INVALIDARG;
         int i_type;
+        vlc_value_t val;
+        
         if( VLC_SUCCESS == VLC_VariableType(i_vlc, psz_varname, &i_type) )
         {
             VARIANT arg;
             VariantInit(&arg);
 
-            vlc_value_t val;
-
-            hr = DISP_E_TYPEMISMATCH;
-
             switch( i_type )
             {
                 case VLC_VAR_BOOL:
@@ -373,6 +391,7 @@ STDMETHODIMP VLCControl::setVariable( BSTR name, VARIANT value)
                     break;
 
                 case VLC_VAR_INTEGER:
+                case VLC_VAR_HOTKEY:
                     hr = VariantChangeType(&value, &arg, 0, VT_I4);
                     if( SUCCEEDED(hr) )
                         val.i_int = V_I4(&arg);
@@ -385,22 +404,67 @@ STDMETHODIMP VLCControl::setVariable( BSTR name, VARIANT value)
                     break;
 
                 case VLC_VAR_STRING:
+                case VLC_VAR_MODULE:
+                case VLC_VAR_FILE:
+                case VLC_VAR_DIRECTORY:
+                case VLC_VAR_VARIABLE:
                     hr = VariantChangeType(&value, &arg, 0, VT_BSTR);
                     if( SUCCEEDED(hr) )
+                    {
                         val.psz_string = CStrFromBSTR(codePage, V_BSTR(&arg));
+                        VariantClear(&arg);
+                    }
                     break;
-            }
-            if( SUCCEEDED(hr) )
-            {
-                VariantClear(&arg);
 
-                hr = (VLC_SUCCESS == VLC_VariableSet(i_vlc, psz_varname, val)) ? NOERROR : E_FAIL;
+                case VLC_VAR_TIME:
+                    // use a double value to represent time (base is expressed in seconds)
+                    hr = VariantChangeType(&value, &arg, 0, VT_R8);
+                    if( SUCCEEDED(hr) )
+                        val.i_time = (signed __int64)(V_R8(&arg)*1000000.0);
+                    break;
 
-                if( (VLC_VAR_STRING == i_type) && (NULL != val.psz_string) )
-                    free(val.psz_string);
+                default:
+                    hr = DISP_E_TYPEMISMATCH;
+            }
+        }
+        else {
+            // no defined type, defaults to VARIANT type
+            hr = NO_ERROR;
+            switch( V_VT(&value) )
+            {
+                case VT_BOOL:
+                    val.b_bool = (VARIANT_TRUE == V_BOOL(&value)) ? VLC_TRUE : VLC_FALSE;
+                    i_type = VLC_VAR_BOOL;
+                    break;
+                case VT_I4:
+                    val.i_int = V_I4(&value);
+                    i_type = VLC_VAR_INTEGER;
+                    break;
+                case VT_R4:
+                    val.f_float = V_R4(&value);
+                    i_type = VLC_VAR_FLOAT;
+                    break;
+                case VT_BSTR:
+                    val.psz_string = CStrFromBSTR(codePage, V_BSTR(&value));
+                    i_type = VLC_VAR_STRING;
+                    break;
+                case VT_R8:
+                    // use a double value to represent time (base is expressed in seconds)
+                    val.i_time = (signed __int64)(V_R8(&value)*1000000.0);
+                    i_type = VLC_VAR_TIME;
+                    break;
+                default:
+                    hr = DISP_E_TYPEMISMATCH;
             }
         }
-        free(psz_varname);
+        if( SUCCEEDED(hr) )
+        {
+            hr = (VLC_SUCCESS == VLC_VariableSet(i_vlc, psz_varname, val)) ? NOERROR : E_FAIL;
+
+            if( (VLC_VAR_STRING == i_type) && (NULL != val.psz_string) )
+                CoTaskMemFree(val.psz_string);
+        }
+        CoTaskMemFree(psz_varname);
 
         return hr;
     }
@@ -440,6 +504,7 @@ STDMETHODIMP VLCControl::getVariable( BSTR name, VARIANT *value)
                     break;
 
                 case VLC_VAR_INTEGER:
+                case VLC_VAR_HOTKEY:
                     V_VT(value) = VT_I4;
                     V_I4(value) = val.i_int;
                     break;
@@ -450,15 +515,26 @@ STDMETHODIMP VLCControl::getVariable( BSTR name, VARIANT *value)
                     break;
 
                 case VLC_VAR_STRING:
+                case VLC_VAR_MODULE:
+                case VLC_VAR_FILE:
+                case VLC_VAR_DIRECTORY:
+                case VLC_VAR_VARIABLE:
                     V_VT(value) = VT_BSTR;
                     V_BSTR(value) = BSTRFromCStr(codePage, val.psz_string);
-                    free(val.psz_string);
+                    CoTaskMemFree(val.psz_string);
                     break;
+
+                case VLC_VAR_TIME:
+                    // use a double value to represent time (base is expressed in seconds)
+                    V_VT(value) = VT_R8;
+                    V_R8(value) = ((double)val.i_time)/1000000.0;
+                    break;
+
                 default:
                     hr = DISP_E_TYPEMISMATCH;
             }
         }
-        free(psz_varname);
+        CoTaskMemFree(psz_varname);
         return hr;
     }
     return E_UNEXPECTED;
@@ -467,16 +543,18 @@ STDMETHODIMP VLCControl::getVariable( BSTR name, VARIANT *value)
 static void freeTargetOptions(char **cOptions, int cOptionCount)
 {
     // clean up 
-    for( long pos=0; pos<cOptionCount; ++pos )
+    if( NULL != cOptions )
     {
-        char *cOption = cOptions[pos];
-        if( NULL != cOption )
-            free(cOption);
-        else
-            break;
+        for( int pos=0; pos<cOptionCount; ++pos )
+        {
+            char *cOption = cOptions[pos];
+            if( NULL != cOption )
+                CoTaskMemFree(cOption);
+            else
+                break;
+        }
+        CoTaskMemFree(cOptions);
     }
-    if( NULL != cOptions )
-        free(cOptions);
 };
 
 static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount)
@@ -515,7 +593,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
                 long capacity = 16;
                 VARIANT option;
 
-                *cOptions = (char **)malloc(capacity*sizeof(char *));
+                *cOptions = (char **)CoTaskMemAlloc(capacity*sizeof(char *));
                 if( NULL != *cOptions )
                 {
                     ZeroMemory(*cOptions, sizeof(char *)*capacity);
@@ -530,7 +608,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
                                 ++pos;
                                 if( pos == capacity )
                                 {
-                                    char **moreOptions = (char **)realloc(*cOptions, (capacity+16)*sizeof(char *));
+                                    char **moreOptions = (char **)CoTaskMemRealloc(*cOptions, (capacity+16)*sizeof(char *));
                                     if( NULL != moreOptions )
                                     {
                                         ZeroMemory(moreOptions+capacity, sizeof(char *)*16);
@@ -542,7 +620,8 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
                                 }
                             }
                             else
-                                hr = E_OUTOFMEMORY;
+                                hr = ( SysStringLen(V_BSTR(&option)) > 0 ) ?
+                                    E_OUTOFMEMORY : E_INVALIDARG;
                         }
                         else
                             hr = E_INVALIDARG;
@@ -558,6 +637,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
                 }
                 else
                     hr = E_OUTOFMEMORY;
+
                 enumVar->Release();
             }
         }
@@ -579,7 +659,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
         if( uBound > lBound )
         {
             VARTYPE vType;
-            HRESULT hr = SafeArrayGetVartype(array, &vType);
+            hr = SafeArrayGetVartype(array, &vType);
             if( FAILED(hr) )
                 return hr;
 
@@ -588,10 +668,11 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
             // marshall options into an array of C strings
             if( VT_VARIANT == vType )
             {
-                *cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
-                if( NULL != options )
+                *cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound));
+                if( NULL == *cOptions )
                     return E_OUTOFMEMORY;
 
+                ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound));
                 for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
                 {
                     VARIANT option;
@@ -603,7 +684,8 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
                             char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
                             (*cOptions)[pos-lBound] = cOption;
                             if( NULL == cOption )
-                                hr = E_OUTOFMEMORY;
+                                hr = ( SysStringLen(V_BSTR(&option)) > 0 ) ?
+                                    E_OUTOFMEMORY : E_INVALIDARG;
                         }
                         else
                             hr = E_INVALIDARG;
@@ -613,28 +695,32 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
             }
             else if( VT_BSTR == vType )
             {
-                *cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
-                if( NULL != options )
+                *cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound));
+                if( NULL == *cOptions )
                     return E_OUTOFMEMORY;
 
-                ZeroMemory(cOptions, sizeof(char *)*(uBound-lBound));
-                for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
+                ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound));
+                for(pos=lBound; (pos<uBound) && SUCCEEDED(hr); ++pos )
                 {
                     BSTR option;
                     hr = SafeArrayGetElement(array, &pos, &option);
                     if( SUCCEEDED(hr) )
                     {
                         char *cOption = CStrFromBSTR(codePage, option);
+
                         (*cOptions)[pos-lBound] = cOption;
                         if( NULL == cOption )
-                            hr = E_OUTOFMEMORY;
+                            hr = ( SysStringLen(option) > 0 ) ?
+                                E_OUTOFMEMORY : E_INVALIDARG;
                         SysFreeString(option);
                     }
                 }
             }
-            else
+            else 
+            {
                 // unsupported type
                 return E_INVALIDARG;
+            }
 
             *cOptionCount = pos-lBound;
             if( FAILED(hr) )
@@ -694,7 +780,7 @@ STDMETHODIMP VLCControl::addTarget( BSTR uri, VARIANT options, enum VLCPlaylistM
         }
 
         freeTargetOptions(cOptions, cOptionsCount);
-        free(cUri);
+        CoTaskMemFree(cUri);
     }
     return hr;
 };
@@ -722,6 +808,7 @@ STDMETHODIMP VLCControl::get_PlaylistCount(int *count)
         *count = VLC_PlaylistNumberOfItems(i_vlc);
         return NOERROR;
     }
+    *count = 0;
     return E_UNEXPECTED;
 };