aboutsummaryrefslogtreecommitdiff
path: root/Src/Winamp/JSAPI_CallbackParameters.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Winamp/JSAPI_CallbackParameters.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Winamp/JSAPI_CallbackParameters.cpp')
-rw-r--r--Src/Winamp/JSAPI_CallbackParameters.cpp384
1 files changed, 384 insertions, 0 deletions
diff --git a/Src/Winamp/JSAPI_CallbackParameters.cpp b/Src/Winamp/JSAPI_CallbackParameters.cpp
new file mode 100644
index 00000000..281159da
--- /dev/null
+++ b/Src/Winamp/JSAPI_CallbackParameters.cpp
@@ -0,0 +1,384 @@
+#include "JSAPI_CallbackParameters.h"
+#include "JSAPI.h"
+
+JSAPI::CallbackParameters::CallbackParameters()
+{
+ refCount = 1;
+}
+
+JSAPI::CallbackParameters::~CallbackParameters()
+{
+ //for (size_t p=0;p!=params.size();p++)
+ //{
+ // ParameterList::value_type &property = params.at(p);
+ // // some types need to be specifically destroyed or released
+ // switch(property.second.vt)
+ // {
+ // case VT_DISPATCH: // add a reference if it's an IDispatch
+ // property.second.pdispVal->Release();
+ // break;
+ // case VT_BSTR: // re-allocate
+ // SysFreeString(property.second.bstrVal);
+ // break;
+ // }
+ //}
+ for (auto &param : params)
+ {
+ // some types need to be specifically destroyed or released
+ switch(param.second.vt)
+ {
+ case VT_DISPATCH: // add a reference if it's an IDispatch
+ param.second.pdispVal->Release();
+ break;
+ case VT_BSTR: // re-allocate
+ SysFreeString(param.second.bstrVal);
+ break;
+ }
+ }
+}
+
+HRESULT JSAPI::CallbackParameters::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
+{
+ bool unknowns = false;
+ for (unsigned int i = 0;i != cNames;i++)
+ {
+ rgdispid[i] = DISPID_UNKNOWN;
+ const wchar_t *propertyName = rgszNames[i];
+
+ bool found=false;
+ //for (size_t p=0;p!=params.size();p++)
+ size_t p = 0;
+ for(auto it = params.begin(); it != params.end(); it++, p++)
+ {
+ //ParameterList::value_type &property = params.at(p);
+ if (!wcscmp(it->first.c_str(), propertyName))
+ {
+ found=true;
+ rgdispid[i] = (DISPID)p;
+ break;
+ }
+ }
+ if (!found)
+ unknowns=true;
+ }
+
+ if (unknowns)
+ return DISP_E_UNKNOWNNAME;
+ else
+ return S_OK;
+}
+
+HRESULT JSAPI::CallbackParameters::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
+{
+ JSAPI_VERIFY_PARAMCOUNT(pdispparams, 0);
+ size_t index = (size_t)dispid;
+ if (index>=params.size())
+ return DISP_E_MEMBERNOTFOUND;
+ if (wFlags & DISPATCH_PROPERTYGET)
+ {
+ if (pvarResult)
+ {
+ //ParameterList::value_type &property = params.at(index);
+ auto it = params.begin();
+ while (index--)
+ {
+ it++;
+ }
+
+ *pvarResult = it->second;
+ // do any type-specific allocations that are necessary
+ switch(pvarResult->vt)
+ {
+ case VT_DISPATCH: // add a reference if it's an IDispatch
+ pvarResult->pdispVal->AddRef();
+ break;
+ case VT_BSTR: // re-allocate
+ pvarResult->bstrVal = SysAllocString(pvarResult->bstrVal);
+ break;
+ }
+ }
+ return S_OK;
+ }
+ else
+ return DISP_E_MEMBERNOTFOUND;
+}
+
+
+HRESULT JSAPI::CallbackParameters::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT JSAPI::CallbackParameters::GetTypeInfoCount(unsigned int FAR * pctinfo)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP JSAPI::CallbackParameters::QueryInterface(REFIID riid, PVOID *ppvObject)
+{
+ if (!ppvObject)
+ return E_POINTER;
+
+ else if (IsEqualIID(riid, IID_IDispatch))
+ *ppvObject = (IDispatch *)this;
+ else if (IsEqualIID(riid, IID_IUnknown))
+ *ppvObject = this;
+ else if (IsEqualIID(riid, IID_IDispatchEx))
+ *ppvObject = (IDispatchEx *)this;
+ else
+ {
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ }
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG JSAPI::CallbackParameters::AddRef(void)
+{
+ return InterlockedIncrement(&refCount);
+}
+
+
+ULONG JSAPI::CallbackParameters::Release(void)
+{
+ LONG lRef = InterlockedDecrement(&refCount);
+ if (lRef == 0) delete this;
+ return lRef;
+}
+
+HRESULT JSAPI::CallbackParameters::GetDispID(BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+ //for (size_t p=0;p!=params.size();p++)
+ //{
+ // ParameterList::value_type &property = params.at(p);
+ // if (!wcscmp(property.first.c_str(), bstrName))
+ // {
+ // *pid= (DISPID)p;
+ // return S_OK;
+ // }
+ //}
+ size_t p = 0;
+ for (auto it = params.begin(); it != params.end(); it++, p++)
+ {
+ if (!wcscmp(it->first.c_str(), bstrName))
+ {
+ *pid = (DISPID)p;
+ return S_OK;
+ }
+ }
+
+ return DISP_E_MEMBERNOTFOUND;
+}
+
+HRESULT JSAPI::CallbackParameters::InvokeEx(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+ JSAPI_VERIFY_PARAMCOUNT(pdp, 0);
+ size_t index = (size_t)id;
+ if (index>=params.size())
+ return DISP_E_MEMBERNOTFOUND;
+ if (wFlags & DISPATCH_PROPERTYGET)
+ {
+ if (pvarRes)
+ {
+ //ParameterList::value_type &property = params.at(index);
+ auto it = params.begin();
+ while (index--)
+ {
+ it++;
+ }
+
+ *pvarRes = it->second;
+ // do any type-specific allocations that are necessary
+ switch(pvarRes->vt)
+ {
+ case VT_DISPATCH: // add a reference if it's an IDispatch
+ pvarRes->pdispVal->AddRef();
+ break;
+ case VT_BSTR: // re-allocate
+ pvarRes->bstrVal = SysAllocString(pvarRes->bstrVal);
+ break;
+ }
+ }
+ return S_OK;
+ }
+ else
+ return DISP_E_MEMBERNOTFOUND;
+
+}
+
+HRESULT JSAPI::CallbackParameters::DeleteMemberByName(BSTR bstrName, DWORD grfdex)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT JSAPI::CallbackParameters::DeleteMemberByDispID(DISPID id)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT JSAPI::CallbackParameters::GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT JSAPI::CallbackParameters::GetMemberName(DISPID id, BSTR *pbstrName)
+{
+ if (id >= 0 && (size_t)id < params.size())
+ {
+ auto it = params.begin();
+ while (id--)
+ {
+ it++;
+ }
+ *pbstrName = SysAllocString(it->first.c_str());
+ return S_OK;
+ }
+ return E_NOTIMPL;
+}
+
+HRESULT JSAPI::CallbackParameters::GetNextDispID(DWORD grfdex, DISPID id, DISPID *pid)
+{
+ if (grfdex == fdexEnumDefault)
+ {
+ if (id == DISPID_UNKNOWN)
+ {
+ if (params.size() == 0)
+ return S_FALSE;
+ else
+ {
+ *pid = 0;
+ return S_OK;
+ }
+ }
+ else
+ {
+ size_t index = id+1;
+ if (index >= params.size())
+ {
+ return S_FALSE;
+ }
+ else
+ {
+ *pid = (DISPID)index;
+ return S_OK;
+ }
+
+ }
+ }
+
+ return E_NOTIMPL;
+}
+
+HRESULT JSAPI::CallbackParameters::GetNameSpaceParent(IUnknown **ppunk)
+{
+ return E_NOTIMPL;
+}
+
+void JSAPI::CallbackParameters::AddProperty(const wchar_t *name, const VARIANT &property)
+{
+ params[name]=property;
+}
+
+void JSAPI::CallbackParameters::AddString(const wchar_t *name, const wchar_t *value)
+{
+ VARIANT bstrVar;
+ V_VT(&bstrVar) = VT_BSTR;
+ V_BSTR(&bstrVar) = SysAllocString(value);
+ AddProperty(name, bstrVar);
+}
+
+void JSAPI::CallbackParameters::AddDispatch(const wchar_t *name, IDispatch *disp)
+{
+ VARIANT dispVar;
+ V_VT(&dispVar) = VT_DISPATCH;
+ V_DISPATCH(&dispVar) = disp;
+ disp->AddRef();
+ AddProperty(name, dispVar);
+}
+
+void JSAPI::CallbackParameters::AddLong(const wchar_t *name, LONG value)
+{
+ VARIANT i4Var;
+ V_VT(&i4Var) = VT_I4;
+ V_I4(&i4Var) = value;
+ AddProperty(name, i4Var);
+}
+
+void JSAPI::CallbackParameters::AddBoolean(const wchar_t *name, bool value)
+{
+ VARIANT boolVar;
+ V_VT(&boolVar) = VT_BOOL;
+ V_BOOL(&boolVar) = value?VARIANT_TRUE:VARIANT_FALSE;
+ AddProperty(name, boolVar);
+}
+
+size_t JSAPI::CallbackParameters::AddPropertyIndirect(const JSAPI::CallbackParameters::PropertyTemplate *entries, size_t count)
+{
+ if (NULL == entries) return 0;
+
+ size_t inserted = 0;
+ VARIANT val;
+
+ for (size_t i = 0; i < count; i++)
+ {
+ const PropertyTemplate *ppt = &entries[i];
+ if (NULL == ppt->name)
+ continue;
+
+ switch(ppt->type)
+ {
+ case typeBool:
+ V_VT(&val) = VT_BOOL;
+ V_BOOL(&val) = (FALSE != ((BOOL)ppt->value)) ? VARIANT_TRUE : VARIANT_FALSE;
+ break;
+ case typeString:
+ V_VT(&val) = VT_BSTR;
+ V_BSTR(&val) = SysAllocString((LPCWSTR)ppt->value);
+ break;
+ case typeLong:
+ V_VT(&val) = VT_I4;
+ V_I4(&val) = (ULONG)ppt->value;
+ break;
+ case typeDispatch:
+ V_VT(&val) = VT_DISPATCH;
+ V_DISPATCH(&val) = (IDispatch*)ppt->value;
+ if (NULL != val.pdispVal)
+ val.pdispVal->AddRef();
+ break;
+ default:
+ continue;
+ break;
+ }
+ AddProperty(ppt->name, val);
+ inserted++;
+ }
+
+ return inserted;
+}
+
+/* ---------------------------------------------------------------------------- */
+HRESULT JSAPI::InvokeEvent(JSAPI::CallbackParameters *parameters, IDispatch *invokee)
+{
+ unsigned int ret;
+ DISPPARAMS params;
+ VARIANTARG arguments[1];
+
+ VariantInit(&arguments[0]);
+ V_VT(&arguments[0]) = VT_DISPATCH;
+ V_DISPATCH(&arguments[0]) = parameters;
+ parameters->AddRef();
+
+ params.cArgs = 1;
+ params.cNamedArgs = 0;
+ params.rgdispidNamedArgs = NULL;
+ params.rgvarg = arguments;
+
+ HRESULT hr = invokee->Invoke(0, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, 0, 0, &ret);
+
+ VariantClear(&arguments[0]);
+
+ return hr;
+}
+