Commit 7194c2f6 authored by Damien Fouilleul's avatar Damien Fouilleul

- activex: multiple bugfix backports from trunk

parent 2ca06f95
......@@ -29,6 +29,7 @@
#include <windows.h>
#include <shlwapi.h>
#include <tchar.h>
#include <guiddef.h>
using namespace std;
......@@ -80,10 +81,10 @@ STDAPI DllCanUnloadNow(VOID)
return (0 == i_class_ref) ? S_OK: S_FALSE;
};
static inline HKEY keyCreate(HKEY parentKey, LPCSTR keyName)
static inline HKEY keyCreate(HKEY parentKey, LPCTSTR keyName)
{
HKEY childKey;
if( ERROR_SUCCESS == RegCreateKeyExA(parentKey, keyName, 0, NULL,
if( ERROR_SUCCESS == RegCreateKeyEx(parentKey, keyName, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &childKey, NULL) )
{
return childKey;
......@@ -91,24 +92,24 @@ static inline HKEY keyCreate(HKEY parentKey, LPCSTR keyName)
return NULL;
};
static inline HKEY keySet(HKEY hKey, LPCSTR valueName, const void *s, size_t len)
static inline HKEY keySet(HKEY hKey, LPCTSTR valueName, const void *s, size_t len, DWORD dwType = REG_SZ)
{
if( NULL != hKey )
{
RegSetValueExA(hKey, valueName, 0, REG_SZ,
RegSetValueEx(hKey, valueName, 0, dwType,
(const BYTE*)s, len);
}
return hKey;
};
static inline HKEY keySetDef(HKEY hKey, const void *s, size_t len)
static inline HKEY keySetDef(HKEY hKey, const void *s, size_t len, DWORD dwType = REG_SZ)
{
return keySet(hKey, NULL, s, len);
return keySet(hKey, NULL, s, len, dwType);
};
static inline HKEY keySetDef(HKEY hKey, LPCSTR s)
static inline HKEY keySetDef(HKEY hKey, LPCTSTR s)
{
return keySetDef(hKey, s, strlen(s)+1);
return keySetDef(hKey, s, sizeof(TCHAR)*(_tcslen(s)+1), REG_SZ);
};
static inline HKEY keyClose(HKEY hKey)
......@@ -120,25 +121,23 @@ static inline HKEY keyClose(HKEY hKey)
return NULL;
};
static HRESULT UnregisterProgID(REFCLSID rclsid, unsigned int version)
static void UnregisterProgID(REFCLSID rclsid, unsigned int version)
{
LPCSTR psz_CLSID = CStrFromGUID(rclsid);
OLECHAR szCLSID[GUID_STRLEN];
if( NULL == psz_CLSID )
return E_OUTOFMEMORY;
StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);
char progId[sizeof(PROGID_STR)+16];
sprintf(progId, "%s.%u", PROGID_STR, version);
TCHAR progId[sizeof(PROGID_STR)+16];
_stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);
SHDeleteKeyA(HKEY_CLASSES_ROOT, progId);
SHDeleteKey(HKEY_CLASSES_ROOT, progId);
HKEY hClsIDKey;
if( ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_WRITE, &hClsIDKey) )
if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_WRITE, &hClsIDKey) )
{
SHDeleteKey(hClsIDKey, psz_CLSID);
SHDeleteKey(hClsIDKey, szCLSID);
RegCloseKey(hClsIDKey);
}
CoTaskMemFree((void *)psz_CLSID);
};
STDAPI DllUnregisterServer(VOID)
......@@ -173,20 +172,19 @@ STDAPI DllUnregisterServer(VOID)
return S_OK;
};
static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int version, BOOL isDefault, const char *path, size_t pathLen)
static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int version, BOOL isDefault, LPCTSTR path, size_t pathLen)
{
char progId[sizeof(PROGID_STR)+16];
sprintf(progId, "%s.%u", PROGID_STR, version);
TCHAR progId[sizeof(PROGID_STR)+16];
_stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);
char description[sizeof(DESCRIPTION)+16];
sprintf(description, "%s v%u", DESCRIPTION, version);
TCHAR description[sizeof(DESCRIPTION)+16];
_stprintf(description, TEXT("%s v%u"), TEXT(DESCRIPTION), version);
HKEY hClassKey;
{
LPCSTR psz_CLSID = CStrFromGUID(rclsid);
OLECHAR szCLSID[GUID_STRLEN];
if( NULL == psz_CLSID )
return E_OUTOFMEMORY;
StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);
HKEY hProgKey = keyCreate(HKEY_CLASSES_ROOT, progId);
if( NULL != hProgKey )
......@@ -194,9 +192,9 @@ static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int versi
// default key value
keySetDef(hProgKey, description);
keyClose(keySetDef(keyCreate(hProgKey, "CLSID"),
psz_CLSID,
GUID_STRLEN));
keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
szCLSID,
sizeof(szCLSID)));
//hSubKey = keyClose(keyCreate(hBaseKey, "Insertable"));
......@@ -204,22 +202,21 @@ static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int versi
}
if( isDefault )
{
hProgKey = keyCreate(HKEY_CLASSES_ROOT, PROGID_STR);
hProgKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
if( NULL != hProgKey )
{
// default key value
keySetDef(hProgKey, description);
keyClose(keySetDef(keyCreate(hProgKey, "CLSID"),
psz_CLSID,
GUID_STRLEN));
keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
szCLSID,
sizeof(szCLSID)));
keyClose(keySetDef(keyCreate(hProgKey, "CurVer"),
keyClose(keySetDef(keyCreate(hProgKey, TEXT("CurVer")),
progId));
}
}
hClassKey = keyCreate(hParent, psz_CLSID);
CoTaskMemFree((void *)psz_CLSID);
hClassKey = keyCreate(hParent, szCLSID);
}
if( NULL != hClassKey )
{
......@@ -227,45 +224,45 @@ static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int versi
keySetDef(hClassKey, description);
// Control key value
keyClose(keyCreate(hClassKey, "Control"));
keyClose(keyCreate(hClassKey, TEXT("Control")));
// Insertable key value
//keyClose(keyCreate(hClassKey, "Insertable"));
//keyClose(keyCreate(hClassKey, TEXT("Insertable")));
// ToolboxBitmap32 key value
{
char iconPath[pathLen+3];
memcpy(iconPath, path, pathLen);
strcpy(iconPath+pathLen, ",1");
TCHAR iconPath[pathLen+3];
memcpy(iconPath, path, sizeof(TCHAR)*pathLen);
_tcscpy(iconPath+pathLen, TEXT(",1"));
keyClose(keySetDef(keyCreate(hClassKey,
"ToolboxBitmap32"),
TEXT("ToolboxBitmap32")),
iconPath, sizeof(iconPath)));
}
#ifdef BUILD_LOCALSERVER
// LocalServer32 key value
keyClose(keySetDef(keyCreate(hClassKey,
"LocalServer32", path, pathLen+1)));
TEXT("LocalServer32"), path, sizeof(TCHAR)*(pathLen+1))));
#else
// InprocServer32 key value
{
HKEY hSubKey = keySetDef(keyCreate(hClassKey,
"InprocServer32"),
path, pathLen+1);
TEXT("InprocServer32")),
path, sizeof(TCHAR)*(pathLen+1));
keySet(hSubKey,
"ThreadingModel",
THREADING_MODEL, sizeof(THREADING_MODEL));
TEXT("ThreadingModel"),
TEXT(THREADING_MODEL), sizeof(TEXT(THREADING_MODEL)));
keyClose(hSubKey);
}
#endif
// MiscStatus key value
keyClose(keySetDef(keyCreate(hClassKey,
"MiscStatus\\1"),
MISC_STATUS, sizeof(MISC_STATUS)));
TEXT("MiscStatus\\1")),
TEXT(MISC_STATUS), sizeof(TEXT(MISC_STATUS))));
// Programmable key value
keyClose(keyCreate(hClassKey, "Programmable"));
keyClose(keyCreate(hClassKey, TEXT("Programmable")));
// ProgID key value
keyClose(keySetDef(keyCreate(hClassKey,
......@@ -274,23 +271,23 @@ static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int versi
// VersionIndependentProgID key value
keyClose(keySetDef(keyCreate(hClassKey,
"VersionIndependentProgID"),
PROGID_STR, sizeof(PROGID_STR)));
TEXT("VersionIndependentProgID")),
TEXT(PROGID_STR), sizeof(TEXT(PROGID_STR))));
// Version key value
keyClose(keySetDef(keyCreate(hClassKey,
"Version"),
"1.0"));
TEXT("Version")),
TEXT("1.0")));
// TypeLib key value
LPCSTR psz_LIBID = CStrFromGUID(LIBID_AXVLC);
if( NULL != psz_LIBID )
{
OLECHAR szLIBID[GUID_STRLEN];
StringFromGUID2(LIBID_AXVLC, szLIBID, GUID_STRLEN);
keyClose(keySetDef(keyCreate(hClassKey,
"TypeLib"),
psz_LIBID, GUID_STRLEN));
CoTaskMemFree((void *)psz_LIBID);
}
TEXT("TypeLib")),
szLIBID, sizeof(szLIBID)));
RegCloseKey(hClassKey);
}
return S_OK;
......@@ -300,14 +297,14 @@ STDAPI DllRegisterServer(VOID)
{
DllUnregisterServer();
char DllPath[MAX_PATH];
DWORD DllPathLen=GetModuleFileNameA(h_instance, DllPath, sizeof(DllPath)) ;
TCHAR DllPath[MAX_PATH];
DWORD DllPathLen=GetModuleFileName(h_instance, DllPath, MAX_PATH) ;
if( 0 == DllPathLen )
return E_UNEXPECTED;
HKEY hBaseKey;
if( ERROR_SUCCESS != RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_CREATE_SUB_KEY, &hBaseKey) )
if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_CREATE_SUB_KEY, &hBaseKey) )
return SELFREG_E_CLASS;
RegisterClassID(hBaseKey, CLSID_VLCPlugin, 1, FALSE, DllPath, DllPathLen);
......@@ -334,34 +331,19 @@ STDAPI DllRegisterServer(VOID)
pcr->Release();
}
// register type lib into the registry
ITypeLib *typeLib;
#ifdef BUILD_LOCALSERVER
// replace .exe by .tlb
strcpy(DllPath+DllPathLen-4, ".tlb");
_tcscpy(DllPath+DllPathLen-4, TEXT(".tlb"));
#endif
#ifndef OLE2ANSI
size_t typeLibPathLen = MultiByteToWideChar(CP_ACP, 0, DllPath, -1, NULL, 0);
if( typeLibPathLen > 0 )
{
LPOLESTR typeLibPath = (LPOLESTR)CoTaskMemAlloc(typeLibPathLen*sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, 0, DllPath, DllPathLen, typeLibPath, typeLibPathLen);
if( FAILED(LoadTypeLibEx(typeLibPath, REGKIND_REGISTER, &typeLib)) )
#ifndef BUILD_LOCALSERVER
return SELFREG_E_TYPELIB;
typeLib->Release();
#endif
CoTaskMemFree((void *)typeLibPath);
}
#else
if( FAILED(LoadTypeLibEx((LPOLESTR)DllPath, REGKIND_REGISTER, &typeLib)) )
return SELFREG_E_TYPELIB;
// register type lib into the registry
ITypeLib *typeLib;
HRESULT result = LoadTypeLibEx(DllPath, REGKIND_REGISTER, &typeLib);
if( SUCCEEDED(result) )
typeLib->Release();
#endif
return S_OK;
return result;
};
#ifdef BUILD_LOCALSERVER
......
......@@ -565,38 +565,52 @@ HRESULT VLCPlugin::getVLC(libvlc_instance_t** pp_libvlc)
char *ppsz_argv[32] = { "vlc" };
int ppsz_argc = 1;
char p_progpath[MAX_PATH];
{
TCHAR w_progpath[MAX_PATH];
DWORD len = GetModuleFileName(DllGetModule(), w_progpath, MAX_PATH);
if( len > 0 )
{
len = WideCharToMultiByte(CP_UTF8, 0, w_progpath, len, p_progpath,
sizeof(p_progpath)-1, NULL, NULL);
if( len > 0 )
{
p_progpath[len] = '\0';
ppsz_argv[0] = p_progpath;
}
}
}
ppsz_argv[ppsz_argc++] = "-vv";
HKEY h_key;
DWORD i_type, i_data = MAX_PATH + 1;
char p_data[MAX_PATH + 1];
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\VideoLAN\\VLC",
char p_pluginpath[MAX_PATH];
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("Software\\VideoLAN\\VLC"),
0, KEY_READ, &h_key ) == ERROR_SUCCESS )
{
if( RegQueryValueEx( h_key, "InstallDir", 0, &i_type,
(LPBYTE)p_data, &i_data ) == ERROR_SUCCESS )
DWORD i_type, i_data = MAX_PATH;
TCHAR w_pluginpath[MAX_PATH];
if( RegQueryValueEx( h_key, TEXT("InstallDir"), 0, &i_type,
(LPBYTE)w_pluginpath, &i_data ) == ERROR_SUCCESS )
{
if( i_type == REG_SZ )
{
strcat( p_data, "\\plugins" );
if( WideCharToMultiByte(CP_UTF8, 0, w_pluginpath, -1, p_pluginpath,
sizeof(p_pluginpath)-sizeof("\\plugins")+1, NULL, NULL) )
{
strcat( p_pluginpath, "\\plugins" );
ppsz_argv[ppsz_argc++] = "--plugin-path";
ppsz_argv[ppsz_argc++] = p_data;
ppsz_argv[ppsz_argc++] = p_pluginpath;
}
}
RegCloseKey( h_key );
}
char p_path[MAX_PATH+1];
DWORD len = GetModuleFileNameA(DllGetModule(), p_path, sizeof(p_path));
if( len > 0 )
{
p_path[len] = '\0';
ppsz_argv[0] = p_path;
RegCloseKey( h_key );
}
// make sure plugin isn't affected with VLC single instance mode
ppsz_argv[ppsz_argc++] = "--no-one-instance";
/* common settings */
ppsz_argv[ppsz_argc++] = "-vv";
ppsz_argv[ppsz_argc++] = "--no-stats";
ppsz_argv[ppsz_argc++] = "--intf";
ppsz_argv[ppsz_argc++] = "dummy";
......@@ -822,7 +836,7 @@ HRESULT VLCPlugin::onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprc
** properly clipped.
*/
_inplacewnd = CreateWindow(_p_class->getInPlaceWndClassName(),
"VLC Plugin In-Place Window",
TEXT("VLC Plugin In-Place Window"),
WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
clipRect.left,
clipRect.top,
......@@ -846,7 +860,7 @@ HRESULT VLCPlugin::onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprc
** is always correct relative to the viewport bounds
*/
_videownd = CreateWindow(_p_class->getVideoWndClassName(),
"VLC Plugin Video Window",
TEXT("VLC Plugin Video Window"),
WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE,
posRect.left,
posRect.top,
......@@ -947,6 +961,26 @@ void VLCPlugin::setVolume(int volume)
}
};
void VLCPlugin::setTime(int seconds)
{
if( seconds < 0 )
seconds = 0;
if( seconds != _i_time )
{
setStartTime(_i_time);
if( isRunning() )
{
libvlc_input_t *p_input = libvlc_playlist_get_input(_p_libvlc, NULL);
if( NULL != p_input )
{
libvlc_input_set_time(p_input, _i_time, NULL);
libvlc_input_free(p_input);
}
}
}
};
void VLCPlugin::setFocus(BOOL fFocus)
{
if( fFocus )
......
......@@ -51,8 +51,8 @@ public:
REFCLSID getClassID(void) { return (REFCLSID)_classid; };
LPCSTR getInPlaceWndClassName(void) const { return TEXT("VLC Plugin In-Place"); };
LPCSTR getVideoWndClassName(void) const { return TEXT("VLC Plugin Video"); };
LPCTSTR getInPlaceWndClassName(void) const { return TEXT("VLC Plugin In-Place"); };
LPCTSTR getVideoWndClassName(void) const { return TEXT("VLC Plugin Video"); };
HINSTANCE getHInstance(void) const { return _hinstance; };
LPPICTURE getInPlacePict(void) const
{ if( NULL != _inplace_picture) _inplace_picture->AddRef(); return _inplace_picture; };
......@@ -127,6 +127,9 @@ public:
};
inline int getStartTime(void) { return _i_time; };
void setTime(int time);
int getTime(void) { return _i_time; };
void setBaseURL(BSTR url)
{
SysFreeString(_bstr_baseurl);
......
......@@ -77,28 +77,6 @@ BSTR BSTRFromCStr(UINT codePage, LPCSTR s)
return NULL;
};
char *CStrFromGUID(REFGUID clsid)
{
LPOLESTR oleStr;
if( FAILED(StringFromIID(clsid, &oleStr)) )
return NULL;
#ifdef OLE2ANSI
return (LPCSTR)oleStr;
#else
char *pct_CLSID = NULL;
size_t len = WideCharToMultiByte(CP_ACP, 0, oleStr, -1, NULL, 0, NULL, NULL);
if( len > 0 )
{
pct_CLSID = (char *)CoTaskMemAlloc(len);
WideCharToMultiByte(CP_ACP, 0, oleStr, -1, pct_CLSID, len, NULL, NULL);
}
CoTaskMemFree(oleStr);
return pct_CLSID;
#endif
};
/*
** properties
*/
......
......@@ -32,8 +32,6 @@ extern char *CStrFromWSTR(UINT codePage, LPCWSTR wstr, UINT len);
extern char *CStrFromBSTR(UINT codePage, BSTR bstr);
extern BSTR BSTRFromCStr(UINT codePage, LPCSTR s);
extern char *CStrFromGUID(REFGUID clsid);
// properties
extern HRESULT GetObjectProperty(LPUNKNOWN object, DISPID dispID, VARIANT& v);
......@@ -48,7 +46,7 @@ extern LPWSTR CombineURL(LPCWSTR baseUrl, LPCWSTR url);
/**************************************************************************************************/
/* this function object is used to dereference the iterator into a value */
template <class T, class Iterator>
template <typename T, class Iterator>
struct VLCDereference
{
T operator()(const Iterator& i) const
......@@ -57,7 +55,7 @@ struct VLCDereference
};
};
template<REFIID EnumeratorIID, class Enumerator, class T, class Iterator, typename Dereference = VLCDereference<T, Iterator> >
template<REFIID EnumeratorIID, class Enumerator, typename T, class Iterator, typename Dereference = VLCDereference<T, Iterator> >
class VLCEnumIterator : public Enumerator
{
......
......@@ -228,31 +228,16 @@ STDMETHODIMP VLCControl::get_Time(int *seconds)
}
}
else
*seconds = _p_instance->getStartTime();
*seconds = _p_instance->getTime();
return result;
};
STDMETHODIMP VLCControl::put_Time(int seconds)
{
if( seconds < 0 )
seconds = 0;
_p_instance->setTime(seconds);
HRESULT result = NOERROR;
if( _p_instance->isRunning() )
{
int i_vlc;
result = _p_instance->getVLCObject(&i_vlc);
if( SUCCEEDED(result) )
{
VLC_TimeSet(i_vlc, seconds, VLC_FALSE);
}
}
else if( seconds != _p_instance->getStartTime() )
{
_p_instance->setStartTime(seconds);
}
return result;
return NOERROR;
};
STDMETHODIMP VLCControl::shuttle(int seconds)
......@@ -561,6 +546,92 @@ void VLCControl::FreeTargetOptions(char **cOptions, int cOptionCount)
}
};
static HRESULT parseStringOptions(int codePage, BSTR bstr, char*** cOptions, int *cOptionCount)
{
HRESULT hr = E_INVALIDARG;
if( SysStringLen(bstr) > 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;
......@@ -583,7 +654,7 @@ HRESULT VLCControl::CreateTargetOptions(int codePage, VARIANT *options, char ***
}
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);
......@@ -645,6 +716,18 @@ HRESULT VLCControl::CreateTargetOptions(int codePage, VARIANT *options, char ***
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) )
{
......@@ -741,6 +824,22 @@ HRESULT VLCControl::CreateTargetOptions(int codePage, VARIANT *options, char ***
return NOERROR;
}
}
else if( VT_UNKNOWN == V_VT(options) )
{
// 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( VT_BSTR == V_VT(options) )
{
hr = parseStringOptions(codePage, V_BSTR(options), cOptions, cOptionCount);
}
return hr;
};
......@@ -861,6 +960,7 @@ STDMETHODIMP VLCControl::get_VersionInfo(BSTR *version)
if( NULL != versionStr )
{
*version = BSTRFromCStr(CP_UTF8, versionStr);
return NULL == *version ? E_OUTOFMEMORY : NOERROR;
}
*version = NULL;
......
......@@ -190,7 +190,8 @@ STDMETHODIMP VLCAudio::put_volume(long volume)
libvlc_audio_set_volume(p_libvlc, volume, &ex);
if( libvlc_exception_raised(&ex) )
{
_p_instance->setErrorInfo(IID_IVLCAudio, libvlc_exception_get_message(&ex));
_p_instance->setErrorInfo(IID_IVLCAudio,
libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
......@@ -216,7 +217,8 @@ STDMETHODIMP VLCAudio::get_track(long* track)
libvlc_input_free(p_input);
if( libvlc_exception_raised(&ex) )
{
_p_instance->setErrorInfo(IID_IVLCAudio, libvlc_exception_get_message(&ex));
_p_instance->setErrorInfo(IID_IVLCAudio,
libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
......@@ -239,7 +241,8 @@ STDMETHODIMP VLCAudio::put_track(long track)
libvlc_input_free(p_input);
if( libvlc_exception_raised(&ex) )
{
_p_instance->setErrorInfo(IID_IVLCAudio, libvlc_exception_get_message(&ex));
_p_instance->setErrorInfo(IID_IVLCAudio,
libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
......@@ -297,7 +300,7 @@ STDMETHODIMP VLCAudio::put_channel(long channel)
STDMETHODIMP VLCAudio::toggleMute()
{
libvlc_instance_t* p_libvlc = NULL;
libvlc_instance_t* p_libvlc;
HRESULT hr = _p_instance->getVLC(&p_libvlc);
if( SUCCEEDED(hr) )
{
......@@ -855,6 +858,89 @@ STDMETHODIMP VLCLog::put_verbosity(long verbosity)
/*******************************************************************************/
/* STL forward iterator used by VLCEnumIterator class to implement IEnumVARIANT */
class VLCMessageSTLIterator
{
public:
VLCMessageSTLIterator(IVLCMessageIterator* iter) : iter(iter), msg(NULL)
{
// get first message
operator++();
};
VLCMessageSTLIterator(const VLCMessageSTLIterator& other)
{
iter = other.iter;
if( iter )
iter->AddRef();
msg = other.msg;
if( msg )
msg->AddRef();
};
virtual ~VLCMessageSTLIterator()
{
if( msg )
msg->Release();
if( iter )
iter->Release();
};
// we only need prefix ++ operator
VLCMessageSTLIterator& operator++()
{
VARIANT_BOOL hasNext = VARIANT_FALSE;
if( iter )
{
iter->get_hasNext(&hasNext);
if( msg )
{
msg->Release();
msg = NULL;
}
if( VARIANT_TRUE == hasNext ) {
iter->next(&msg);
}
}
return *this;
};
VARIANT operator*() const
{
VARIANT v;
VariantInit(&v);
if( msg )
{
if( SUCCEEDED(msg->QueryInterface(IID_IDispatch, (LPVOID*)&V_DISPATCH(&v))) )
{
V_VT(&v) = VT_DISPATCH;
}
}
return v;
};
bool operator==(const VLCMessageSTLIterator& other) const
{
return msg == other.msg;
};
bool operator!=(const VLCMessageSTLIterator& other) const
{
return msg != other.msg;
};
private:
IVLCMessageIterator* iter;
IVLCMessage* msg;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////
VLCMessages::~VLCMessages()
{
if( _p_typeinfo )
......@@ -937,9 +1023,16 @@ STDMETHODIMP VLCMessages::get__NewEnum(LPUNKNOWN* _NewEnum)
if( NULL == _NewEnum )
return E_POINTER;
// TODO
*_NewEnum = NULL;
return E_NOTIMPL;
IVLCMessageIterator* iter = NULL;
iterator(&iter);
*_NewEnum= new VLCEnumIterator<IID_IEnumVARIANT,
IEnumVARIANT,
VARIANT,
VLCMessageSTLIterator>
(VLCMessageSTLIterator(iter), VLCMessageSTLIterator(NULL));
return *_NewEnum ? S_OK : E_OUTOFMEMORY;
};
STDMETHODIMP VLCMessages::clear()
......@@ -2100,16 +2193,17 @@ STDMETHODIMP VLCVideo::put_aspectRatio(BSTR aspect)
HRESULT hr = _p_instance->getVLC(&p_libvlc);
if( SUCCEEDED(hr) )
{
char *psz_aspect = NULL;
libvlc_exception_t ex;
libvlc_exception_init(&ex);
libvlc_input_t *p_input = libvlc_playlist_get_input(p_libvlc, &ex);
if( ! libvlc_exception_raised(&ex) )
{
psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
char *psz_aspect = CStrFromBSTR(CP_UTF8, aspect);
if( NULL == psz_aspect )
{
return E_OUTOFMEMORY;
}
libvlc_video_set_aspect_ratio(p_input, psz_aspect, &ex);
......
......@@ -5080,7 +5080,7 @@ then
fi
AC_LANG_PUSH(C++)
AC_CHECK_HEADERS(ole2.h olectl.h,
[ VLC_ADD_CPPFLAGS([activex],[-D_MIDL_USE_GUIDDEF_])
[ VLC_ADD_CPPFLAGS([activex],[-DUNICODE -D_UNICODE -D_MIDL_USE_GUIDDEF_])
VLC_ADD_CXXFLAGS([activex],[-fno-exceptions])
VLC_ADD_LDFLAGS([activex],[-lole32 -loleaut32 -luuid -lshlwapi])
AC_CHECK_HEADERS(objsafe.h,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment