winamp/Src/Plugins/Library/ml_webdev/serviceHost.cpp

244 lines
5.8 KiB
C++

#include "main.h"
#include "./serviceHost.h"
#include "./wasabi.h"
#include "./resource.h"
#include "./external.h"
#include "./navigation.h"
#include "./commands.h"
#include "./serviceHelper.h"
#include <ifc_omservice.h>
#include <ifc_omserviceeditor.h>
#include <ifc_omservicecommand.h>
#include <browserView.h>
#include "../winamp/wa_ipc.h"
#include "../winamp/IWasabiDispatchable.h"
#include "../winamp/JSAPI_Info.h"
#include <strsafe.h>
#define IS_INVALIDISPATCH(__disp) (((IDispatch *)1) == (__disp) || NULL == (__disp))
static WebDevServiceHost *cachedInstance = NULL;
WebDevServiceHost::WebDevServiceHost()
: ref(1)
{
}
WebDevServiceHost::~WebDevServiceHost()
{
}
HRESULT WebDevServiceHost::CreateInstance(WebDevServiceHost **instance)
{
if (NULL == instance)
return E_POINTER;
*instance = new WebDevServiceHost();
if (NULL == instance) return E_OUTOFMEMORY;
return S_OK;
}
HRESULT WebDevServiceHost::GetCachedInstance(WebDevServiceHost **instance)
{
if (NULL == instance)
return E_POINTER;
if (NULL == cachedInstance)
{
HRESULT hr = CreateInstance(&cachedInstance);
if (FAILED(hr))
{
*instance = NULL;
return hr;
}
}
cachedInstance->AddRef();
*instance = cachedInstance;
return S_OK;
}
HRESULT WebDevServiceHost::ReleseCache()
{
if (NULL == cachedInstance)
return S_FALSE;
WebDevServiceHost *t = cachedInstance;
cachedInstance = NULL;
t->Release();
return S_OK;
}
size_t WebDevServiceHost::AddRef()
{
return InterlockedIncrement((LONG*)&ref);
}
size_t WebDevServiceHost::Release()
{
if (0 == ref)
return ref;
LONG r = InterlockedDecrement((LONG*)&ref);
if (0 == r)
delete(this);
return r;
}
int WebDevServiceHost::QueryInterface(GUID interface_guid, void **object)
{
if (NULL == object) return E_POINTER;
if (IsEqualIID(interface_guid, IFC_OmServiceHost))
*object = static_cast<ifc_omservicehost*>(this);
else if (IsEqualIID(interface_guid, IFC_OmServiceEvent))
*object = static_cast<ifc_omserviceevent*>(this);
else
{
*object = NULL;
return E_NOINTERFACE;
}
if (NULL == *object)
return E_UNEXPECTED;
AddRef();
return S_OK;
}
HRESULT WebDevServiceHost::GetExternal(ifc_omservice *service, IDispatch **ppDispatch)
{
if (NULL == ppDispatch)
return E_POINTER;
if (NULL != *ppDispatch)
{
// try to connect our external
IWasabiDispatchable *pWasabi;
if (SUCCEEDED((*ppDispatch)->QueryInterface(IID_IWasabiDispatchable, (void**)&pWasabi)))
{
JSAPI::ifc_info *pInfo;
if (SUCCEEDED(pWasabi->QueryDispatchable(JSAPI::IID_JSAPI_ifc_info, (Dispatchable**)&pInfo)))
{
ExternalDispatch *pExternal;
if (SUCCEEDED(ExternalDispatch::CreateInstance(&pExternal)))
{
pInfo->AddAPI(pExternal->GetName(), pExternal);
pExternal->Release();
}
pInfo->Release();
}
pWasabi->Release();
}
}
return S_OK;
}
HRESULT WebDevServiceHost::GetBasePath(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax)
{
if (NULL == pszBuffer)
return E_POINTER;
return StringCchCopy(pszBuffer, cchBufferMax, L".\\Plugins\\webDev");
}
HRESULT WebDevServiceHost::GetDefaultName(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax)
{
if (NULL == pszBuffer)
return E_POINTER;
if (NULL == service)
return E_INVALIDARG;
return StringCchPrintf(pszBuffer, cchBufferMax, L"wdService_{%010u}.ini", service->GetId());
}
HRESULT WebDevServiceHost::QueryCommandState(ifc_omservice *service, HWND hBrowser, const GUID *commandGroup, UINT commandId)
{
if (NULL == service || NULL == commandGroup)
return E_NOTIMPL;
if (IsEqualGUID(*commandGroup, CMDGROUP_ADDRESSBAR))
{
switch(commandId)
{
case ADDRESSCOMMAND_VISIBLE:
if (S_FALSE == ServiceHelper_IsSpecial(service))
return CMDSTATE_ENABLED;
return CMDSTATE_UNKNOWN;
case ADDRESSCOMMAND_READONLY:
if (S_FALSE == ServiceHelper_IsSpecial(service))
return CMDSTATE_DISABLED;
return CMDSTATE_ENABLED;
}
}
return E_NOTIMPL;
}
HRESULT WebDevServiceHost::ExecuteCommand(ifc_omservice *service, HWND hBrowser, const GUID *commandGroup, UINT commandId, ULONG_PTR commandArg)
{
return E_NOTIMPL;
}
HRESULT WebDevServiceHost::GetUrl(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax)
{
return E_NOTIMPL;
}
void WebDevServiceHost::ServiceChange(ifc_omservice *service, UINT nModified)
{
if (NULL == service) return;
Navigation *navigation;
if (SUCCEEDED(Plugin_GetNavigation(&navigation)))
{
navigation->UpdateService(service, nModified);
navigation->Release();
}
if ( 0 != (ifc_omserviceeditor::modifiedUrl & nModified))
{
Command_PostNavigateSvc(service, MAKEINTRESOURCE
(NAVIGATE_HOME), TRUE);
}
if (0 != (ifc_omserviceeditor::modifiedFlags & nModified))
{
ServiceHelper_RegisterPreAuthorized(service);
}
}
#define CBCLASS WebDevServiceHost
START_MULTIPATCH;
START_PATCH(MPIID_OMSVCHOST)
M_CB(MPIID_OMSVCHOST, ifc_omservicehost, ADDREF, AddRef);
M_CB(MPIID_OMSVCHOST, ifc_omservicehost, RELEASE, Release);
M_CB(MPIID_OMSVCHOST, ifc_omservicehost, QUERYINTERFACE, QueryInterface);
M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETEXTERNAL, GetExternal);
M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETBASEPATH, GetBasePath);
M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETDEFAULTNAME, GetDefaultName);
M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_QUERYCOMMANDSTATE, QueryCommandState);
M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_EXECUTECOMMAND, ExecuteCommand);
M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETURL, GetUrl);
NEXT_PATCH(MPIID_OMSVCEVENT)
M_CB(MPIID_OMSVCEVENT, ifc_omserviceevent, ADDREF, AddRef);
M_CB(MPIID_OMSVCEVENT, ifc_omserviceevent, RELEASE, Release);
M_CB(MPIID_OMSVCEVENT, ifc_omserviceevent, QUERYINTERFACE, QueryInterface);
M_VCB(MPIID_OMSVCEVENT, ifc_omserviceevent, API_SERVICECHANGE, ServiceChange);
END_PATCH
END_MULTIPATCH;
#undef CBCLASS