зеркало из https://github.com/mozilla/pjs.git
NOT PART OF BUILD. Moved streaming off onto another thread to make UI responsive. First cut impl of NPN_GetValue.
This commit is contained in:
Родитель
3b4a5dd337
Коммит
502a6d6e59
|
@ -77,9 +77,7 @@ Still to do
|
|||
===========
|
||||
|
||||
* Only hosts windowed plugins.
|
||||
* Untested on Win98/95/Me.
|
||||
* Doesn't work for the Adobe Acrobat plugin yet.
|
||||
* Streaming data blocks the UI because it's running on the same thread.
|
||||
Should be moved to another thread.
|
||||
* No progress indication to show when there is network activity
|
||||
* Plugins cannot create writeable streams.
|
||||
* Package pluginhostctrl.dll into a CAB file automatic installation in IE.
|
||||
|
|
|
@ -43,8 +43,10 @@
|
|||
static NPError
|
||||
_OpenURL(NPP npp, const char *szURL, const char *szTarget, void *pNotifyData, const char *pPostData, uint32 len, NPBool isFile)
|
||||
{
|
||||
if(!npp)
|
||||
if (!npp)
|
||||
{
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
}
|
||||
|
||||
nsPluginHostCtrl *pCtrl = (nsPluginHostCtrl *) npp->ndata;
|
||||
ATLASSERT(pCtrl);
|
||||
|
@ -134,8 +136,10 @@ NPN_PostURL(NPP npp,
|
|||
NPError NP_EXPORT
|
||||
NPN_NewStream(NPP npp, NPMIMEType type, const char* window, NPStream* *result)
|
||||
{
|
||||
if(!npp)
|
||||
if (!npp)
|
||||
{
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
}
|
||||
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
@ -145,8 +149,10 @@ NPN_NewStream(NPP npp, NPMIMEType type, const char* window, NPStream* *result)
|
|||
int32 NP_EXPORT
|
||||
NPN_Write(NPP npp, NPStream *pstream, int32 len, void *buffer)
|
||||
{
|
||||
if(!npp)
|
||||
if (!npp)
|
||||
{
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
}
|
||||
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
@ -156,8 +162,10 @@ NPN_Write(NPP npp, NPStream *pstream, int32 len, void *buffer)
|
|||
NPError NP_EXPORT
|
||||
NPN_DestroyStream(NPP npp, NPStream *pstream, NPError reason)
|
||||
{
|
||||
if(!npp)
|
||||
if (!npp)
|
||||
{
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
}
|
||||
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
@ -167,8 +175,11 @@ NPN_DestroyStream(NPP npp, NPStream *pstream, NPError reason)
|
|||
void NP_EXPORT
|
||||
NPN_Status(NPP npp, const char *message)
|
||||
{
|
||||
if(!npp)
|
||||
if (!npp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// TODO status message
|
||||
}
|
||||
|
||||
|
||||
|
@ -184,8 +195,10 @@ NPN_MemAlloc (uint32 size)
|
|||
void NP_EXPORT
|
||||
NPN_MemFree (void *ptr)
|
||||
{
|
||||
if(ptr)
|
||||
if (ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,8 +221,12 @@ NPN_ReloadPlugins(NPBool reloadPages)
|
|||
void NP_EXPORT
|
||||
NPN_InvalidateRect(NPP npp, NPRect *invalidRect)
|
||||
{
|
||||
if(!npp)
|
||||
if (!npp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO - windowless plugins
|
||||
}
|
||||
|
||||
|
||||
|
@ -217,8 +234,11 @@ NPN_InvalidateRect(NPP npp, NPRect *invalidRect)
|
|||
void NP_EXPORT
|
||||
NPN_InvalidateRegion(NPP npp, NPRegion invalidRegion)
|
||||
{
|
||||
if(!npp)
|
||||
if (!npp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// TODO - windowless plugins
|
||||
}
|
||||
|
||||
|
||||
|
@ -226,18 +246,67 @@ NPN_InvalidateRegion(NPP npp, NPRegion invalidRegion)
|
|||
void NP_EXPORT
|
||||
NPN_ForceRedraw(NPP npp)
|
||||
{
|
||||
if(!npp)
|
||||
if (!npp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// TODO - windowless plugins
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
NPError NP_EXPORT
|
||||
NPN_GetValue(NPP npp, NPNVariable variable, void *result)
|
||||
{
|
||||
if(!npp)
|
||||
if (!npp)
|
||||
{
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
}
|
||||
|
||||
return NPERR_GENERIC_ERROR;
|
||||
if (!result)
|
||||
{
|
||||
return NPERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
nsPluginHostCtrl *pCtrl = (nsPluginHostCtrl *) npp->ndata;
|
||||
ATLASSERT(pCtrl);
|
||||
|
||||
CComPtr<IWebBrowserApp> cpBrowser;
|
||||
pCtrl->GetWebBrowserApp(&cpBrowser);
|
||||
|
||||
// Test the variable
|
||||
if (variable == NPNVnetscapeWindow)
|
||||
{
|
||||
*((HWND *) result) = pCtrl->m_wndPlugin.m_hWnd;
|
||||
}
|
||||
else if (variable == NPNVjavascriptEnabledBool)
|
||||
{
|
||||
// TODO
|
||||
*((NPBool *) result) = TRUE;
|
||||
}
|
||||
else if (variable == NPNVasdEnabledBool) // Smart update
|
||||
{
|
||||
*((NPBool *) result) = FALSE;
|
||||
}
|
||||
else if (variable == NPNVisOfflineBool)
|
||||
{
|
||||
*((NPBool *) result) = FALSE;
|
||||
if (cpBrowser)
|
||||
{
|
||||
CComQIPtr<IWebBrowser2> cpBrowser2 = cpBrowser;
|
||||
if (cpBrowser2)
|
||||
{
|
||||
VARIANT_BOOL bOffline = VARIANT_FALSE;
|
||||
cpBrowser2->get_Offline(&bOffline);
|
||||
*((NPBool *) result) = (bOffline == VARIANT_TRUE) ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
@ -245,8 +314,14 @@ NPN_GetValue(NPP npp, NPNVariable variable, void *result)
|
|||
NPError NP_EXPORT
|
||||
NPN_SetValue(NPP npp, NPPVariable variable, void *result)
|
||||
{
|
||||
if(!npp)
|
||||
if (!npp)
|
||||
{
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
}
|
||||
|
||||
// TODO windowless
|
||||
// NPPVpluginWindowBool
|
||||
// NPPVpluginTransparentBool
|
||||
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
@ -256,8 +331,10 @@ NPN_SetValue(NPP npp, NPPVariable variable, void *result)
|
|||
NPError NP_EXPORT
|
||||
NPN_RequestRead(NPStream *pstream, NPByteRange *rangeList)
|
||||
{
|
||||
if(!pstream || !rangeList || !pstream->ndata)
|
||||
if (!pstream || !rangeList || !pstream->ndata)
|
||||
{
|
||||
return NPERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
|
|
@ -797,25 +797,9 @@ HRESULT nsPluginHostCtrl::SizeToFitPluginInstance()
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT nsPluginHostCtrl::OpenURLStream(const TCHAR *szURL, void *pNotifyData, const void *pPostData, unsigned long nDataLength)
|
||||
HRESULT nsPluginHostCtrl::OpenURLStream(const TCHAR *szURL, void *pNotifyData, const void *pPostData, unsigned long nPostDataLength)
|
||||
{
|
||||
// Create a callback object and open a stream to feed data out to it
|
||||
CComObject<nsURLDataCallback> *pCallback = NULL;
|
||||
CComObject<nsURLDataCallback>::CreateInstance(&pCallback);
|
||||
if (!pCallback)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
pCallback->SetOwner(this);
|
||||
pCallback->SetNotifyData(pNotifyData);
|
||||
if (pPostData)
|
||||
{
|
||||
pCallback->SetPostData(pPostData, nDataLength);
|
||||
}
|
||||
|
||||
URLOpenStream(NULL, szURL, 0, pCallback);
|
||||
|
||||
nsURLDataCallback::OpenURL(this, szURL, pNotifyData, pPostData, nPostDataLength);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -213,7 +213,6 @@ protected:
|
|||
|
||||
LoadedPluginInfo *m_pLoadedPlugin;
|
||||
|
||||
nsPluginWnd m_wndPlugin;
|
||||
NPWindow m_NPWindow;
|
||||
|
||||
static NPNetscapeFuncs g_NPNFuncs;
|
||||
|
@ -227,6 +226,7 @@ public:
|
|||
NPP_t m_NPP;
|
||||
BOOL m_bPluginIsAlive;
|
||||
BOOL m_bCreatePluginFromStreamData;
|
||||
nsPluginWnd m_wndPlugin;
|
||||
|
||||
// Struct holding pointers to the functions within the plugin
|
||||
NPPluginFuncs m_NPPFuncs;
|
||||
|
|
|
@ -34,10 +34,13 @@
|
|||
*/
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <process.h>
|
||||
|
||||
#include "Pluginhostctrl.h"
|
||||
#include "nsPluginHostCtrl.h"
|
||||
#include "nsURLDataCallback.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsURLDataCallback
|
||||
|
||||
|
@ -55,12 +58,9 @@ nsURLDataCallback::nsURLDataCallback() :
|
|||
|
||||
nsURLDataCallback::~nsURLDataCallback()
|
||||
{
|
||||
if (m_hPostData)
|
||||
GlobalFree(m_hPostData);
|
||||
if (m_szURL)
|
||||
free(m_szURL);
|
||||
if (m_szContentType)
|
||||
free(m_szContentType);
|
||||
SetPostData(NULL, 0);
|
||||
SetURL(NULL);
|
||||
SetContentType(NULL);
|
||||
}
|
||||
|
||||
void nsURLDataCallback::SetPostData(const void *pData, unsigned long nSize)
|
||||
|
@ -70,6 +70,7 @@ void nsURLDataCallback::SetPostData(const void *pData, unsigned long nSize)
|
|||
if (m_hPostData)
|
||||
{
|
||||
GlobalFree(m_hPostData);
|
||||
m_hPostData = NULL;
|
||||
}
|
||||
if (pData)
|
||||
{
|
||||
|
@ -84,6 +85,174 @@ void nsURLDataCallback::SetPostData(const void *pData, unsigned long nSize)
|
|||
}
|
||||
}
|
||||
|
||||
HRESULT nsURLDataCallback::OpenURL(nsPluginHostCtrl *pOwner, const TCHAR *szURL, void *pNotifyData, const void *pPostData, unsigned long nPostDataSize)
|
||||
{
|
||||
// Create the callback object
|
||||
CComObject<nsURLDataCallback> *pCallback = NULL;
|
||||
CComObject<nsURLDataCallback>::CreateInstance(&pCallback);
|
||||
if (!pCallback)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
pCallback->AddRef();
|
||||
|
||||
// Initialise it
|
||||
pCallback->SetOwner(pOwner);
|
||||
pCallback->SetNotifyData(pNotifyData);
|
||||
if (pPostData && nPostDataSize > 0)
|
||||
{
|
||||
pCallback->SetPostData(pPostData, nPostDataSize);
|
||||
}
|
||||
|
||||
USES_CONVERSION;
|
||||
pCallback->SetURL(T2CA(szURL));
|
||||
|
||||
// Create an object window on this thread that will be sent messages when
|
||||
// something happens on the worker thread.
|
||||
RECT rcPos = {0, 0, 10, 10};
|
||||
pCallback->Create(HWND_DESKTOP, rcPos);
|
||||
|
||||
// Start the worker thread
|
||||
_beginthread(StreamThread, 0, pCallback);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void __cdecl nsURLDataCallback::StreamThread(void *pData)
|
||||
{
|
||||
HRESULT hr = CoInitialize(NULL);
|
||||
ATLASSERT(SUCCEEDED(hr));
|
||||
|
||||
CComObject<nsURLDataCallback> *pThis = (CComObject<nsURLDataCallback> *) pData;
|
||||
|
||||
// Open the URL
|
||||
hr = URLOpenStream(NULL, pThis->m_szURL, 0, static_cast<IBindStatusCallback*>(pThis));
|
||||
ATLASSERT(SUCCEEDED(hr));
|
||||
|
||||
// Pump messages until WM_QUIT arrives
|
||||
BOOL bQuit = FALSE;
|
||||
while (!bQuit)
|
||||
{
|
||||
MSG msg;
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
|
||||
{
|
||||
if (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
bQuit = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
_endthread();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Windows message handlers
|
||||
|
||||
LRESULT nsURLDataCallback::OnNPPNewStream(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
_NewStreamData *pNewStreamData = (_NewStreamData *) lParam;
|
||||
|
||||
// Notify the plugin that a new stream has been created
|
||||
if (m_pOwner->m_NPPFuncs.newstream)
|
||||
{
|
||||
NPError npres = m_pOwner->m_NPPFuncs.newstream(
|
||||
pNewStreamData->npp,
|
||||
pNewStreamData->contenttype,
|
||||
pNewStreamData->stream,
|
||||
pNewStreamData->seekable,
|
||||
pNewStreamData->stype);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT nsURLDataCallback::OnNPPDestroyStream(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
_DestroyStreamData *pDestroyStreamData = (_DestroyStreamData *) lParam;
|
||||
|
||||
// Notify the plugin that the stream has been closed
|
||||
if (m_pOwner->m_NPPFuncs.destroystream)
|
||||
{
|
||||
m_pOwner->m_NPPFuncs.destroystream(
|
||||
pDestroyStreamData->npp,
|
||||
pDestroyStreamData->stream,
|
||||
pDestroyStreamData->reason);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT nsURLDataCallback::OnNPPURLNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
_UrlNotifyData *pUrlNotifyData = (_UrlNotifyData *) lParam;
|
||||
|
||||
// Notify the plugin that the url has loaded
|
||||
if (m_pNotifyData && m_pOwner->m_NPPFuncs.urlnotify)
|
||||
{
|
||||
m_pOwner->m_NPPFuncs.urlnotify(
|
||||
pUrlNotifyData->npp,
|
||||
pUrlNotifyData->url,
|
||||
pUrlNotifyData->reason,
|
||||
pUrlNotifyData->notifydata);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT nsURLDataCallback::OnNPPWriteReady(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
_WriteReadyData *pWriteReadyData = (_WriteReadyData *) lParam;
|
||||
if (m_pOwner->m_NPPFuncs.writeready)
|
||||
{
|
||||
pWriteReadyData->result = m_pOwner->m_NPPFuncs.writeready(
|
||||
pWriteReadyData->npp,
|
||||
pWriteReadyData->stream);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT nsURLDataCallback::OnNPPWrite(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
_WriteData *pWriteData = (_WriteData *) lParam;
|
||||
if (m_pOwner->m_NPPFuncs.write)
|
||||
{
|
||||
m_pOwner->m_NPPFuncs.write(
|
||||
pWriteData->npp,
|
||||
pWriteData->stream,
|
||||
pWriteData->offset,
|
||||
pWriteData->len,
|
||||
pWriteData->buffer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT nsURLDataCallback::OnClassCreatePluginInstance(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
// Test whether the plugin for this content type exists or not and if not,
|
||||
// create it right now.
|
||||
if (!m_pOwner->m_bPluginIsAlive &&
|
||||
m_pOwner->m_bCreatePluginFromStreamData)
|
||||
{
|
||||
if (FAILED(m_pOwner->LoadPluginByContentType(A2CT(m_szContentType))) ||
|
||||
FAILED(m_pOwner->CreatePluginInstance()))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT nsURLDataCallback::OnClassCleanup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
DestroyWindow();
|
||||
Release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// IBindStatusCallback implementation
|
||||
|
||||
|
@ -119,18 +288,14 @@ HRESULT STDMETHODCALLTYPE nsURLDataCallback::OnProgress(
|
|||
case BINDSTATUS_REDIRECTING:
|
||||
{
|
||||
USES_CONVERSION;
|
||||
if (m_szURL)
|
||||
free(m_szURL);
|
||||
m_szURL = strdup(W2A(szStatusText));
|
||||
SetURL(W2A(szStatusText));
|
||||
}
|
||||
break;
|
||||
|
||||
case BINDSTATUS_MIMETYPEAVAILABLE:
|
||||
{
|
||||
USES_CONVERSION;
|
||||
if (m_szContentType)
|
||||
free(m_szContentType);
|
||||
m_szContentType = strdup(W2A(szStatusText));
|
||||
SetContentType(W2A(szStatusText));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -147,27 +312,26 @@ HRESULT STDMETHODCALLTYPE nsURLDataCallback::OnStopBinding(
|
|||
NPReason reason = SUCCEEDED(hresult) ? NPRES_DONE : NPRES_NETWORK_ERR;
|
||||
|
||||
// Notify the plugin that the stream has been closed
|
||||
if (m_pOwner->m_NPPFuncs.destroystream)
|
||||
{
|
||||
m_pOwner->m_NPPFuncs.destroystream(
|
||||
&m_pOwner->m_NPP,
|
||||
&m_NPStream,
|
||||
reason);
|
||||
}
|
||||
_DestroyStreamData destroyStreamData;
|
||||
destroyStreamData.npp = &m_pOwner->m_NPP;
|
||||
destroyStreamData.stream = &m_NPStream;
|
||||
destroyStreamData.reason = reason;
|
||||
SendMessage(WM_NPP_DESTROYSTREAM, 0, (LPARAM) &destroyStreamData);
|
||||
|
||||
if (m_pNotifyData && m_pOwner->m_NPPFuncs.urlnotify)
|
||||
{
|
||||
// Notify the plugin that the url has loaded
|
||||
m_pOwner->m_NPPFuncs.urlnotify(
|
||||
&m_pOwner->m_NPP,
|
||||
m_szURL,
|
||||
reason,
|
||||
m_pNotifyData);
|
||||
}
|
||||
// Notify the plugin that the url has loaded
|
||||
_UrlNotifyData urlNotifyData;
|
||||
urlNotifyData.npp = &m_pOwner->m_NPP;
|
||||
urlNotifyData.url = m_szURL;
|
||||
urlNotifyData.reason = reason;
|
||||
urlNotifyData.notifydata = m_pNotifyData;
|
||||
SendMessage(WM_NPP_URLNOTIFY, 0, (LPARAM) &urlNotifyData);
|
||||
}
|
||||
|
||||
m_cpBinding.Release();
|
||||
|
||||
SendMessage(WM_CLASS_CLEANUP);
|
||||
PostQuitMessage(0);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -175,13 +339,23 @@ HRESULT STDMETHODCALLTYPE nsURLDataCallback::OnStopBinding(
|
|||
/* [out] */ DWORD __RPC_FAR *grfBINDF,
|
||||
/* [unique][out][in] */ BINDINFO __RPC_FAR *pbindinfo)
|
||||
{
|
||||
*grfBINDF = BINDF_ASYNCHRONOUS;
|
||||
*grfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE |
|
||||
BINDF_GETNEWESTVERSION;
|
||||
|
||||
ULONG cbSize = pbindinfo->cbSize;
|
||||
memset(pbindinfo, 0, cbSize); // zero out structure
|
||||
pbindinfo->cbSize = cbSize;
|
||||
if (m_hPostData)
|
||||
{
|
||||
pbindinfo->dwBindVerb = BINDVERB_POST;
|
||||
pbindinfo->stgmedData.tymed = TYMED_HGLOBAL;
|
||||
pbindinfo->stgmedData.hGlobal = m_hPostData;
|
||||
}
|
||||
else
|
||||
{
|
||||
pbindinfo->dwBindVerb = BINDVERB_GET;
|
||||
}
|
||||
|
||||
return S_OK ;
|
||||
}
|
||||
|
||||
|
@ -208,15 +382,10 @@ HRESULT STDMETHODCALLTYPE nsURLDataCallback::OnStopBinding(
|
|||
|
||||
// Test if there is a plugin yet. If not try and create one for this
|
||||
// kind of content.
|
||||
if (!m_pOwner->m_bPluginIsAlive &&
|
||||
m_pOwner->m_bCreatePluginFromStreamData)
|
||||
if (SendMessage(WM_CLASS_CREATEPLUGININSTANCE))
|
||||
{
|
||||
if (FAILED(m_pOwner->LoadPluginByContentType(A2CT(m_szContentType))) ||
|
||||
FAILED(m_pOwner->CreatePluginInstance()))
|
||||
{
|
||||
m_cpBinding->Abort();
|
||||
return S_OK;
|
||||
}
|
||||
m_cpBinding->Abort();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Tell the plugin that there is a new stream of data
|
||||
|
@ -225,27 +394,25 @@ HRESULT STDMETHODCALLTYPE nsURLDataCallback::OnStopBinding(
|
|||
m_NPStream.lastmodified = 0;
|
||||
m_NPStream.notifyData = m_pNotifyData;
|
||||
|
||||
if (m_pOwner->m_NPPFuncs.newstream)
|
||||
{
|
||||
uint16 stype = NP_NORMAL;
|
||||
NPError npres = m_pOwner->m_NPPFuncs.newstream(
|
||||
&m_pOwner->m_NPP,
|
||||
m_szContentType,
|
||||
&m_NPStream,
|
||||
FALSE,
|
||||
&stype);
|
||||
}
|
||||
uint16 stype = NP_NORMAL;
|
||||
_NewStreamData newStreamData;
|
||||
newStreamData.npp = &m_pOwner->m_NPP;
|
||||
newStreamData.contenttype = m_szContentType;
|
||||
newStreamData.stream = &m_NPStream;
|
||||
newStreamData.seekable = FALSE;
|
||||
newStreamData.stype = &stype;
|
||||
SendMessage(WM_NPP_NEWSTREAM, 0, (LPARAM) &newStreamData);
|
||||
}
|
||||
if (!m_pOwner->m_bPluginIsAlive)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ATLTRACE(_T("Data for stream %s (%d bytes)\n"), m_szURL, dwSize);
|
||||
ATLTRACE(_T("Data for stream %s (%d bytes available)\n"), m_szURL, dwSize);
|
||||
|
||||
// Feed the stream data into the plugin
|
||||
HRESULT hr;
|
||||
char bData[8192];
|
||||
char bData[16384];
|
||||
while (m_nDataPos < dwSize)
|
||||
{
|
||||
ULONG nBytesToRead = dwSize - m_nDataPos;
|
||||
|
@ -257,28 +424,27 @@ HRESULT STDMETHODCALLTYPE nsURLDataCallback::OnStopBinding(
|
|||
}
|
||||
|
||||
// How many bytes can the plugin cope with?
|
||||
if (m_pOwner->m_NPPFuncs.writeready)
|
||||
_WriteReadyData writeReadyData;
|
||||
writeReadyData.npp = &m_pOwner->m_NPP;
|
||||
writeReadyData.stream = &m_NPStream;
|
||||
writeReadyData.result = nBytesToRead;
|
||||
SendMessage(WM_NPP_WRITEREADY, 0, (LPARAM) &writeReadyData);
|
||||
if (nBytesToRead > writeReadyData.result)
|
||||
{
|
||||
int32 nPluginMaxBytes = m_pOwner->m_NPPFuncs.writeready(
|
||||
&m_pOwner->m_NPP,
|
||||
&m_NPStream);
|
||||
if (nBytesToRead > nPluginMaxBytes)
|
||||
{
|
||||
nBytesToRead = nPluginMaxBytes;
|
||||
}
|
||||
nBytesToRead = writeReadyData.result;
|
||||
}
|
||||
|
||||
// Read 'n' feed
|
||||
ATLTRACE(_T(" Reading %d bytes\n"), (int) nBytesToRead);
|
||||
hr = pstgmed->pstm->Read(&bData, nBytesToRead, &nBytesRead);
|
||||
if (m_pOwner->m_NPPFuncs.write)
|
||||
{
|
||||
m_pOwner->m_NPPFuncs.write(
|
||||
&m_pOwner->m_NPP,
|
||||
&m_NPStream,
|
||||
m_nDataPos,
|
||||
nBytesRead,
|
||||
bData);
|
||||
}
|
||||
|
||||
_WriteData writeData;
|
||||
writeData.npp = &m_pOwner->m_NPP;
|
||||
writeData.stream = &m_NPStream;
|
||||
writeData.offset = m_nDataPos;
|
||||
writeData.len = nBytesRead;
|
||||
writeData.buffer = bData;
|
||||
SendMessage(WM_NPP_WRITE, 0, (LPARAM) &writeData);
|
||||
|
||||
m_nDataPos += nBytesRead;
|
||||
}
|
||||
|
|
|
@ -41,10 +41,60 @@
|
|||
|
||||
class nsPluginHostCtrl;
|
||||
|
||||
#define WM_NPP_NEWSTREAM WM_USER
|
||||
#define WM_NPP_DESTROYSTREAM WM_USER + 1
|
||||
#define WM_NPP_URLNOTIFY WM_USER + 2
|
||||
#define WM_NPP_WRITEREADY WM_USER + 3
|
||||
#define WM_NPP_WRITE WM_USER + 4
|
||||
|
||||
#define WM_CLASS_CLEANUP WM_USER + 10
|
||||
#define WM_CLASS_CREATEPLUGININSTANCE WM_USER + 11
|
||||
|
||||
struct _DestroyStreamData
|
||||
{
|
||||
NPP npp;
|
||||
NPStream *stream;
|
||||
NPReason reason;
|
||||
};
|
||||
|
||||
struct _UrlNotifyData
|
||||
{
|
||||
NPP npp;
|
||||
char *url;
|
||||
NPReason reason;
|
||||
void *notifydata;
|
||||
};
|
||||
|
||||
struct _NewStreamData
|
||||
{
|
||||
NPP npp;
|
||||
char *contenttype;
|
||||
NPStream *stream;
|
||||
NPBool seekable;
|
||||
uint16 *stype;
|
||||
};
|
||||
|
||||
struct _WriteReadyData
|
||||
{
|
||||
NPP npp;
|
||||
NPStream *stream;
|
||||
int32 result;
|
||||
};
|
||||
|
||||
struct _WriteData
|
||||
{
|
||||
NPP npp;
|
||||
NPStream *stream;
|
||||
int32 offset;
|
||||
int32 len;
|
||||
void* buffer;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsURLDataCallback
|
||||
class ATL_NO_VTABLE nsURLDataCallback :
|
||||
public CComObjectRootEx<CComSingleThreadModel>,
|
||||
public CComObjectRootEx<CComMultiThreadModel>,
|
||||
public CWindowImpl<nsURLDataCallback, CWindow, CNullTraits>,
|
||||
public CComCoClass<nsURLDataCallback, &CLSID_NULL>,
|
||||
public IBindStatusCallback
|
||||
{
|
||||
|
@ -57,6 +107,27 @@ BEGIN_COM_MAP(nsURLDataCallback)
|
|||
COM_INTERFACE_ENTRY(IBindStatusCallback)
|
||||
END_COM_MAP()
|
||||
|
||||
DECLARE_WND_CLASS(_T("MozStreamWindow"))
|
||||
|
||||
BEGIN_MSG_MAP(nsURLDataCallback)
|
||||
MESSAGE_HANDLER(WM_NPP_NEWSTREAM, OnNPPNewStream)
|
||||
MESSAGE_HANDLER(WM_NPP_DESTROYSTREAM, OnNPPDestroyStream)
|
||||
MESSAGE_HANDLER(WM_NPP_URLNOTIFY, OnNPPURLNotify)
|
||||
MESSAGE_HANDLER(WM_NPP_WRITEREADY, OnNPPWriteReady)
|
||||
MESSAGE_HANDLER(WM_NPP_WRITE, OnNPPWrite)
|
||||
MESSAGE_HANDLER(WM_CLASS_CLEANUP, OnClassCleanup)
|
||||
MESSAGE_HANDLER(WM_CLASS_CREATEPLUGININSTANCE, OnClassCreatePluginInstance)
|
||||
END_MSG_MAP()
|
||||
|
||||
LRESULT OnNPPNewStream(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnNPPDestroyStream(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnNPPURLNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnNPPWriteReady(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnNPPWrite(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
|
||||
LRESULT OnClassCreatePluginInstance(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnClassCleanup(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
|
||||
protected:
|
||||
virtual ~nsURLDataCallback();
|
||||
|
||||
|
@ -73,10 +144,24 @@ protected:
|
|||
|
||||
CComPtr<IBinding> m_cpBinding;
|
||||
|
||||
public:
|
||||
void SetURL(const char *szURL)
|
||||
{
|
||||
if (m_szURL) { free(m_szURL); m_szURL = NULL; }
|
||||
if (szURL) { m_szURL = strdup(szURL); }
|
||||
}
|
||||
void SetContentType(const char *szContentType)
|
||||
{
|
||||
if (m_szContentType) { free(m_szContentType); m_szContentType = NULL; }
|
||||
if (szContentType) { m_szContentType = strdup(szContentType); }
|
||||
}
|
||||
void SetPostData(const void *pData, unsigned long nSize);
|
||||
void SetOwner(nsPluginHostCtrl *pOwner) { m_pOwner = pOwner; }
|
||||
void SetNotifyData(void *pNotifyData) { m_pNotifyData = pNotifyData; }
|
||||
|
||||
static void __cdecl StreamThread(void *pThis);
|
||||
|
||||
public:
|
||||
static HRESULT OpenURL(nsPluginHostCtrl *pOwner, const TCHAR *szURL, void *pNotifyData, const void *pData, unsigned long nSize);
|
||||
|
||||
// IBindStatusCallback
|
||||
public:
|
||||
|
|
Загрузка…
Ссылка в новой задаче