From 2e601a2947d494585956e21d3b6dab25d8201b2c Mon Sep 17 00:00:00 2001 From: "av%netscape.com" Date: Wed, 6 Mar 2002 03:55:03 +0000 Subject: [PATCH] Threaded plugin sample code, not part of the build git-svn-id: svn://10.0.0.236/trunk@115926 18797224-902f-48f8-a5cc-f745e15eee43 --- .../samples/npthread/windows/action.cpp | 125 ++++++++++ .../plugin/samples/npthread/windows/dbg.cpp | 15 ++ .../samples/npthread/windows/np_entry.cpp | 82 +++++++ .../samples/npthread/windows/npn_gate.cpp | 224 ++++++++++++++++++ .../samples/npthread/windows/npp_gate.cpp | 153 ++++++++++++ .../samples/npthread/windows/plugin.cpp | 197 +++++++++++++++ .../samples/npthread/windows/plugload.cpp | 117 +++++++++ .../samples/npthread/windows/thread.cpp | 167 +++++++++++++ 8 files changed, 1080 insertions(+) diff --git a/mozilla/modules/plugin/samples/npthread/windows/action.cpp b/mozilla/modules/plugin/samples/npthread/windows/action.cpp index 3983aaef5db..d6dd78c290b 100644 --- a/mozilla/modules/plugin/samples/npthread/windows/action.cpp +++ b/mozilla/modules/plugin/samples/npthread/windows/action.cpp @@ -34,3 +34,128 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + +#include "action.h" + +char * FormatAction(int aAction) +{ + static char string[64] = {'\0'}; + switch (aAction) { + case action_invalid: + strcpy(string, "invalid action"); + break; + case action_npn_version: + strcpy(string, "npn_version"); + break; + case action_npn_get_url_notify: + strcpy(string, "npn_get_url_notify"); + break; + case action_npn_get_url: + strcpy(string, "npn_get_url"); + break; + case action_npn_post_url_notify: + strcpy(string, "npn_post_url_notify"); + break; + case action_npn_post_url: + strcpy(string, "npn_post_url"); + break; + case action_npn_request_read: + strcpy(string, "npn_request_read"); + break; + case action_npn_new_stream: + strcpy(string, "npn_new_stream"); + break; + case action_npn_write: + strcpy(string, "npn_write"); + break; + case action_npn_destroy_stream: + strcpy(string, "npn_destroy_stream"); + break; + case action_npn_status: + strcpy(string, "npn_status"); + break; + case action_npn_user_agent: + strcpy(string, "npn_user_agent"); + break; + case action_npn_mem_alloc: + strcpy(string, "npn_mem_alloc"); + break; + case action_npn_mem_free: + strcpy(string, "npn_mem_free"); + break; + case action_npn_mem_flush: + strcpy(string, "npn_mem_flush"); + break; + case action_npn_reload_plugins: + strcpy(string, "npn_reload_plugins"); + break; + case action_npn_get_java_env: + strcpy(string, "npn_get_java_env"); + break; + case action_npn_get_java_peer: + strcpy(string, "npn_get_java_peer"); + break; + case action_npn_get_value: + strcpy(string, "npn_get_value"); + break; + case action_npn_set_value: + strcpy(string, "npn_set_value"); + break; + case action_npn_invalidate_rect: + strcpy(string, "npn_invalidate_rect"); + break; + case action_npn_invalidate_region: + strcpy(string, "npn_invalidate_region"); + break; + case action_npn_force_redraw: + strcpy(string, "npn_force_redraw"); + break; + + case action_npp_new: + strcpy(string, "npp_new"); + break; + case action_npp_destroy: + strcpy(string, "npp_destroy"); + break; + case action_npp_set_window: + strcpy(string, "npp_set_window"); + break; + case action_npp_new_stream: + strcpy(string, "npp_new_stream"); + break; + case action_npp_destroy_stream: + strcpy(string, "npp_destroy_stream"); + break; + case action_npp_stream_as_file: + strcpy(string, "npp_stream_as_file"); + break; + case action_npp_write_ready: + strcpy(string, "npp_write_ready"); + break; + case action_npp_write: + strcpy(string, "npp_write"); + break; + case action_npp_print: + strcpy(string, "npp_print"); + break; + case action_npp_handle_event: + strcpy(string, "npp_handle_event"); + break; + case action_npp_url_notify: + strcpy(string, "npp_url_notify"); + break; + case action_npp_get_java_class: + strcpy(string, "npp_get_java_class"); + break; + case action_npp_get_value: + strcpy(string, "npp_get_value"); + break; + case action_npp_set_value: + strcpy(string, "npp_set_value"); + break; + default: + strcpy(string, "Unknown action!"); + break; + } + return string; +} diff --git a/mozilla/modules/plugin/samples/npthread/windows/dbg.cpp b/mozilla/modules/plugin/samples/npthread/windows/dbg.cpp index 3983aaef5db..5cdce112425 100644 --- a/mozilla/modules/plugin/samples/npthread/windows/dbg.cpp +++ b/mozilla/modules/plugin/samples/npthread/windows/dbg.cpp @@ -34,3 +34,18 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + +#include + +#ifndef NTRACE +void __cdecl dbgOut(LPSTR format, ...) { + static char buf[1024]; + va_list va; + va_start(va, format); + wvsprintf(buf, format, va); + va_end(va); + lstrcat(buf, "\n"); + OutputDebugString(buf); +} +#endif // NDEBUG + diff --git a/mozilla/modules/plugin/samples/npthread/windows/np_entry.cpp b/mozilla/modules/plugin/samples/npthread/windows/np_entry.cpp index 3983aaef5db..8b9567a2389 100644 --- a/mozilla/modules/plugin/samples/npthread/windows/np_entry.cpp +++ b/mozilla/modules/plugin/samples/npthread/windows/np_entry.cpp @@ -34,3 +34,85 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + +#include "npapi.h" +#include "npupp.h" +#include "dbg.h" + +NPNetscapeFuncs NPNFuncs; + +NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* aPluginFuncs) +{ + dbgOut1("wrapper: NP_GetEntryPoints"); + + if(aPluginFuncs == NULL) + return NPERR_INVALID_FUNCTABLE_ERROR; + + if(aPluginFuncs->size < sizeof(NPPluginFuncs)) + return NPERR_INVALID_FUNCTABLE_ERROR; + + aPluginFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; + aPluginFuncs->newp = NPP_New; + aPluginFuncs->destroy = NPP_Destroy; + aPluginFuncs->setwindow = NPP_SetWindow; + aPluginFuncs->newstream = NPP_NewStream; + aPluginFuncs->destroystream = NPP_DestroyStream; + aPluginFuncs->asfile = NPP_StreamAsFile; + aPluginFuncs->writeready = NPP_WriteReady; + aPluginFuncs->write = NPP_Write; + aPluginFuncs->print = NPP_Print; + aPluginFuncs->event = NPP_HandleEvent; + aPluginFuncs->urlnotify = NPP_URLNotify; + aPluginFuncs->getvalue = NPP_GetValue; + aPluginFuncs->setvalue = NPP_SetValue; + aPluginFuncs->javaClass = NULL; + + return NPERR_NO_ERROR; +} + +NPError WINAPI NP_Initialize(NPNetscapeFuncs* aNetscapeFuncs) +{ + dbgOut1("wrapper: NP_Initalize"); + + if(aNetscapeFuncs == NULL) + return NPERR_INVALID_FUNCTABLE_ERROR; + + if(HIBYTE(aNetscapeFuncs->version) > NP_VERSION_MAJOR) + return NPERR_INCOMPATIBLE_VERSION_ERROR; + + if(aNetscapeFuncs->size < sizeof NPNetscapeFuncs) + return NPERR_INVALID_FUNCTABLE_ERROR; + + NPNFuncs.size = aNetscapeFuncs->size; + NPNFuncs.version = aNetscapeFuncs->version; + NPNFuncs.geturlnotify = aNetscapeFuncs->geturlnotify; + NPNFuncs.geturl = aNetscapeFuncs->geturl; + NPNFuncs.posturlnotify = aNetscapeFuncs->posturlnotify; + NPNFuncs.posturl = aNetscapeFuncs->posturl; + NPNFuncs.requestread = aNetscapeFuncs->requestread; + NPNFuncs.newstream = aNetscapeFuncs->newstream; + NPNFuncs.write = aNetscapeFuncs->write; + NPNFuncs.destroystream = aNetscapeFuncs->destroystream; + NPNFuncs.status = aNetscapeFuncs->status; + NPNFuncs.uagent = aNetscapeFuncs->uagent; + NPNFuncs.memalloc = aNetscapeFuncs->memalloc; + NPNFuncs.memfree = aNetscapeFuncs->memfree; + NPNFuncs.memflush = aNetscapeFuncs->memflush; + NPNFuncs.reloadplugins = aNetscapeFuncs->reloadplugins; + NPNFuncs.getJavaEnv = aNetscapeFuncs->getJavaEnv; + NPNFuncs.getJavaPeer = aNetscapeFuncs->getJavaPeer; + NPNFuncs.getvalue = aNetscapeFuncs->getvalue; + NPNFuncs.setvalue = aNetscapeFuncs->setvalue; + NPNFuncs.invalidaterect = aNetscapeFuncs->invalidaterect; + NPNFuncs.invalidateregion = aNetscapeFuncs->invalidateregion; + NPNFuncs.forceredraw = aNetscapeFuncs->forceredraw; + + return NPERR_NO_ERROR; +} + +NPError WINAPI NP_Shutdown() +{ + dbgOut1("wrapper:NP_Shutdown"); + + return NPERR_NO_ERROR; +} diff --git a/mozilla/modules/plugin/samples/npthread/windows/npn_gate.cpp b/mozilla/modules/plugin/samples/npthread/windows/npn_gate.cpp index 3983aaef5db..5239e92bde2 100644 --- a/mozilla/modules/plugin/samples/npthread/windows/npn_gate.cpp +++ b/mozilla/modules/plugin/samples/npthread/windows/npn_gate.cpp @@ -34,3 +34,227 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + +#include "npapi.h" +#include "npupp.h" +#include "dbg.h" + +extern NPNetscapeFuncs NPNFuncs; + +void NPN_Version(int* plugin_major, int* plugin_minor, int* netscape_major, int* netscape_minor) +{ + dbgOut1("wrapper: NPN_Version"); + + *plugin_major = NP_VERSION_MAJOR; + *plugin_minor = NP_VERSION_MINOR; + *netscape_major = HIBYTE(NPNFuncs.version); + *netscape_minor = LOBYTE(NPNFuncs.version); +} + +NPError NPN_GetURLNotify(NPP instance, const char *url, const char *target, void* notifyData) +{ + dbgOut1("wrapper: NPN_GetURLNotify"); + + int navMinorVers = NPNFuncs.version & 0xFF; + + NPError rv = NPERR_NO_ERROR; + + if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) + rv = NPNFuncs.geturlnotify(instance, url, target, notifyData); + else + rv = NPERR_INCOMPATIBLE_VERSION_ERROR; + + return rv; +} + +NPError NPN_GetURL(NPP instance, const char *url, const char *target) +{ + dbgOut1("wrapper: NPN_GetURL"); + + NPError rv = NPNFuncs.geturl(instance, url, target); + return rv; +} + +NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData) +{ + dbgOut1("wrapper: NPN_PostURLNotify"); + + int navMinorVers = NPNFuncs.version & 0xFF; + + NPError rv = NPERR_NO_ERROR; + + if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) + rv = NPNFuncs.posturlnotify(instance, url, window, len, buf, file, notifyData); + else + rv = NPERR_INCOMPATIBLE_VERSION_ERROR; + + return rv; +} + +NPError NPN_PostURL(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file) +{ + dbgOut1("wrapper: NPN_PostURL"); + + NPError rv = NPNFuncs.posturl(instance, url, window, len, buf, file); + return rv; +} + +NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) +{ + dbgOut1("wrapper: NPN_RequestRead"); + + NPError rv = NPNFuncs.requestread(stream, rangeList); + return rv; +} + +NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* target, NPStream** stream) +{ + dbgOut1("wrapper: NPN_NewStream"); + + int navMinorVersion = NPNFuncs.version & 0xFF; + + NPError rv = NPERR_NO_ERROR; + + if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) + rv = NPNFuncs.newstream(instance, type, target, stream); + else + rv = NPERR_INCOMPATIBLE_VERSION_ERROR; + + return rv; +} + +int32 NPN_Write(NPP instance, NPStream *stream, int32 len, void *buffer) +{ + dbgOut1("wrapper: NPN_Write"); + + int navMinorVersion = NPNFuncs.version & 0xFF; + + int32 rv = 0; + + if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) + rv = NPNFuncs.write(instance, stream, len, buffer); + else + rv = -1; + + return rv; +} + +NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason) +{ + dbgOut1("wrapper: NPN_DestroyStream"); + + int navMinorVersion = NPNFuncs.version & 0xFF; + + NPError rv = NPERR_NO_ERROR; + + if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) + rv = NPNFuncs.destroystream(instance, stream, reason); + else + rv = NPERR_INCOMPATIBLE_VERSION_ERROR; + + return rv; +} + +void NPN_Status(NPP instance, const char *message) +{ + dbgOut1("wrapper: NPN_Status"); + + NPNFuncs.status(instance, message); +} + +const char* NPN_UserAgent(NPP instance) +{ + dbgOut1("wrapper: NPN_UserAgent"); + + const char * rv = NULL; + rv = NPNFuncs.uagent(instance); + return rv; +} + +void* NPN_MemAlloc(uint32 size) +{ + //bgOut1("wrapper: NPN_MemAlloc"); + + void * rv = NULL; + rv = NPNFuncs.memalloc(size); + return rv; +} + +void NPN_MemFree(void* ptr) +{ + //dbgOut1("wrapper: NPN_MemFree"); + + NPNFuncs.memfree(ptr); +} + +uint32 NPN_MemFlush(uint32 size) +{ + dbgOut1("wrapper: NPN_MemFlush"); + + uint32 rv = NPNFuncs.memflush(size); + return rv; +} + +void NPN_ReloadPlugins(NPBool reloadPages) +{ + dbgOut1("wrapper: NPN_ReloadPlugins"); + + NPNFuncs.reloadplugins(reloadPages); +} + +JRIEnv* NPN_GetJavaEnv(void) +{ + dbgOut1("wrapper: NPN_GetJavaEnv"); + + JRIEnv * rv = NULL; + rv = NPNFuncs.getJavaEnv(); + return rv; +} + +jref NPN_GetJavaPeer(NPP instance) +{ + dbgOut1("wrapper: NPN_GetJavaPeer"); + + jref rv; + rv = NPNFuncs.getJavaPeer(instance); + return rv; +} + +NPError NPN_GetValue(NPP instance, NPNVariable variable, void *value) +{ + dbgOut1("wrapper: NPN_GetValue"); + + NPError rv = NPERR_NO_ERROR; + rv = NPNFuncs.getvalue(instance, variable, value); + return rv; +} + +NPError NPN_SetValue(NPP instance, NPPVariable variable, void *value) +{ + dbgOut1("wrapper: NPN_SetValue"); + + NPError rv = NPERR_NO_ERROR; + rv = NPNFuncs.setvalue(instance, variable, value); + return rv; +} + +void NPN_InvalidateRect(NPP instance, NPRect *invalidRect) +{ + dbgOut1("wrapper: NPN_InvalidateRect"); + + NPNFuncs.invalidaterect(instance, invalidRect); +} + +void NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion) +{ + dbgOut1("wrapper: NPN_InvalidateRegion"); + + NPNFuncs.invalidateregion(instance, invalidRegion); +} + +void NPN_ForceRedraw(NPP instance) +{ + dbgOut1("wrapper: ForceRedraw"); + + NPNFuncs.forceredraw(instance); +} diff --git a/mozilla/modules/plugin/samples/npthread/windows/npp_gate.cpp b/mozilla/modules/plugin/samples/npthread/windows/npp_gate.cpp index 3983aaef5db..f1a9731b7e1 100644 --- a/mozilla/modules/plugin/samples/npthread/windows/npp_gate.cpp +++ b/mozilla/modules/plugin/samples/npthread/windows/npp_gate.cpp @@ -34,3 +34,156 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + +#include "windows.h" + +#include "npupp.h" +#include "npapi.h" +#include "plugin.h" +#include "dbg.h" + +nsPluginThread * thePluginThread = NULL; + +jref NPP_GetJavaClass () +{ + dbgOut1("wrapper: NPP_GetJavaClass"); + jref rv = (jref)thePluginThread->callNPP(action_npp_get_java_class); + return NULL; +} + +NPError NPP_New(NPMIMEType aType, + NPP aInstance, + uint16 aMode, + int16 aArgc, + char* aArgn[], + char* aArgv[], + NPSavedData* aSaved) +{ + dbgOut1("wrapper: NPP_New"); + + NPError rv = NPERR_NO_ERROR; + + // lamely assuming there is only one embed tag on the page! + + // if it is first time in, we don't have it yet + // initiate a thread with plugin running in it + thePluginThread = new nsPluginThread((DWORD)aType); + + if (!thePluginThread) + return NPERR_GENERIC_ERROR; + + rv = (NPError)thePluginThread->callNPP(action_npp_new, + (DWORD)aType, + (DWORD)aInstance, + (DWORD)aMode, + (DWORD)aArgc, + (DWORD)aArgn, + (DWORD)aArgv, + (DWORD)aSaved); + + return rv; +} + +NPError NPP_Destroy (NPP aInstance, NPSavedData** aSave) +{ + dbgOut1("wrapper: NPP_Destroy"); + + if (!thePluginThread) + return NPERR_GENERIC_ERROR; + + NPError ret = (NPError)thePluginThread->callNPP(action_npp_destroy, (DWORD)aInstance, (DWORD)aSave); + + delete thePluginThread; + thePluginThread = NULL; + + return ret; +} + +NPError NPP_SetWindow (NPP aInstance, NPWindow* aNPWindow) +{ + dbgOut1("wrapper: NPP_SetWindow"); + + NPError rv = (NPError)thePluginThread->callNPP(action_npp_set_window, (DWORD)aInstance, (DWORD)aNPWindow); + return rv; +} + +NPError NPP_NewStream(NPP aInstance, + NPMIMEType aType, + NPStream* aStream, + NPBool aSeekable, + uint16* aStype) +{ + dbgOut1("wrapper: NPP_NewStream"); + + NPError rv = (NPError)thePluginThread->callNPP(action_npp_new_stream, (DWORD)aInstance, (DWORD)aType, (DWORD)aStream, (DWORD)aSeekable, (DWORD)aStype); + return rv; +} + +int32 NPP_WriteReady (NPP aInstance, NPStream *aStream) +{ + dbgOut1("wrapper: NPP_WriteReady"); + + int32 rv = (int32)thePluginThread->callNPP(action_npp_write_ready, (DWORD)aInstance, (DWORD)aStream); + return rv; +} + +int32 NPP_Write (NPP aInstance, NPStream *aStream, int32 aOffset, int32 len, void *aBuffer) +{ + dbgOut1("wrapper: NPP_Write"); + + int32 rv = (int32)thePluginThread->callNPP(action_npp_write, (DWORD)aInstance, (DWORD)aStream, (DWORD)aOffset, (DWORD)len, (DWORD)aBuffer); + return rv; +} + +NPError NPP_DestroyStream (NPP aInstance, NPStream *aStream, NPError aReason) +{ + dbgOut1("wrapper: NPP_DestroyStream"); + + NPError rv = (NPError)thePluginThread->callNPP(action_npp_destroy_stream, (DWORD)aInstance, (DWORD)aStream, (DWORD)aReason); + return rv; +} + +void NPP_StreamAsFile (NPP aInstance, NPStream* aStream, const char* aName) +{ + dbgOut1("wrapper: NPP_StreamAsFile"); + + thePluginThread->callNPP(action_npp_stream_as_file, (DWORD)aInstance, (DWORD)aStream, (DWORD)aName); +} + +void NPP_Print (NPP aInstance, NPPrint* aPrintInfo) +{ + dbgOut1("wrapper: NPP_Print"); + + thePluginThread->callNPP(action_npp_print, (DWORD)aInstance, (DWORD)aPrintInfo); +} + +void NPP_URLNotify(NPP aInstance, const char* aUrl, NPReason aReason, void* aNotifyData) +{ + dbgOut1("wrapper: NPP_URLNotify"); + + thePluginThread->callNPP(action_npp_url_notify, (DWORD)aInstance, (DWORD)aUrl, (DWORD)aReason, (DWORD)aNotifyData); +} + +NPError NPP_GetValue(NPP aInstance, NPPVariable aVariable, void *aValue) +{ + dbgOut1("wrapper: NPP_GetValue"); + + NPError rv = (NPError)thePluginThread->callNPP(action_npp_get_value, (DWORD)aInstance, (DWORD)aVariable, (DWORD)aValue); + return rv; +} + +NPError NPP_SetValue(NPP aInstance, NPNVariable aVariable, void *aValue) +{ + dbgOut1("wrapper: NPP_SetValue"); + + NPError rv = (NPError)thePluginThread->callNPP(action_npp_set_value, (DWORD)aInstance, (DWORD)aVariable, (DWORD)aValue); + return rv; +} + +int16 NPP_HandleEvent(NPP aInstance, void* aEvent) +{ + dbgOut1("wrapper: NPP_HandleEvent"); + + int16 rv = (int16)thePluginThread->callNPP(action_npp_handle_event, (DWORD)aInstance, (DWORD)aEvent); + return rv; +} diff --git a/mozilla/modules/plugin/samples/npthread/windows/plugin.cpp b/mozilla/modules/plugin/samples/npthread/windows/plugin.cpp index 3983aaef5db..70909a39077 100644 --- a/mozilla/modules/plugin/samples/npthread/windows/plugin.cpp +++ b/mozilla/modules/plugin/samples/npthread/windows/plugin.cpp @@ -34,3 +34,200 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + +#include "windows.h" + +#include "npupp.h" +#include "npapi.h" +#include "plugin.h" +#include "plugload.h" +#include "dbg.h" + +extern NPNetscapeFuncs NPNFuncs; +NPNetscapeFuncs wrapperNPNFuncs; +NPPluginFuncs pluginNPPFuncs; + +typedef NPError (__stdcall * NP_GETENTRYPOINTS)(NPPluginFuncs *); +typedef NPError (__stdcall * NP_INITIALIZE)(NPNetscapeFuncs *); +typedef NPError (__stdcall * NP_SHUTDOWN)(void); + +NP_SHUTDOWN plugin_NP_Shutdown = NULL; +HINSTANCE pluginLibrary = NULL; + +nsPluginThread::nsPluginThread(DWORD aP1) : CThread(), + mP1(aP1), + mP2(0), + mP3(0), + mP4(0), + mP5(0), + mP6(0), + mP7(0) +{ + dbgOut1("nsPluginThread::nsPluginThread"); + + open(this); +} + +nsPluginThread::~nsPluginThread() +{ + dbgOut1("nsPluginThread::~nsPluginThread"); + + close(this); +} + +BOOL nsPluginThread::init() +{ + dbgOut1("nsPluginThread::init"); + + // scan plugins dir for available plugins to see if we have anything + // for the given mimetype + pluginLibrary = LoadRealPlugin((NPMIMEType)mP1); + if(!pluginLibrary) + return FALSE; + + NP_GETENTRYPOINTS plugin_NP_GetEntryPoints = (NP_GETENTRYPOINTS)GetProcAddress(pluginLibrary, "NP_GetEntryPoints"); + if(!plugin_NP_GetEntryPoints) + return FALSE; + + NP_INITIALIZE plugin_NP_Initialize = (NP_INITIALIZE)GetProcAddress(pluginLibrary, "NP_Initialize"); + if(!plugin_NP_Initialize) + return FALSE; + + plugin_NP_Shutdown = (NP_SHUTDOWN)GetProcAddress(pluginLibrary, "NP_Shutdown"); + if(!plugin_NP_Shutdown) + return FALSE; + + // fill callbacks structs + memset(&pluginNPPFuncs, 0, sizeof(NPPluginFuncs)); + pluginNPPFuncs.size = sizeof(NPPluginFuncs); + + plugin_NP_GetEntryPoints(&pluginNPPFuncs); + + // inform the plugin about our entry point it should call + memset((void *)&wrapperNPNFuncs, 0, sizeof(wrapperNPNFuncs)); + wrapperNPNFuncs.size = sizeof(wrapperNPNFuncs); + wrapperNPNFuncs.version = NPNFuncs.version; + wrapperNPNFuncs.geturlnotify = NPN_GetURLNotify; + wrapperNPNFuncs.geturl = NPN_GetURL; + wrapperNPNFuncs.posturlnotify = NPN_PostURLNotify; + wrapperNPNFuncs.posturl = NPN_PostURL; + wrapperNPNFuncs.requestread = NPN_RequestRead; + wrapperNPNFuncs.newstream = NPN_NewStream; + wrapperNPNFuncs.write = NPN_Write; + wrapperNPNFuncs.destroystream = NPN_DestroyStream; + wrapperNPNFuncs.status = NPN_Status; + wrapperNPNFuncs.uagent = NPN_UserAgent; + wrapperNPNFuncs.memalloc = NPN_MemAlloc; + wrapperNPNFuncs.memfree = NPN_MemFree; + wrapperNPNFuncs.memflush = NPN_MemFlush; + wrapperNPNFuncs.reloadplugins = NPN_ReloadPlugins; + wrapperNPNFuncs.getJavaEnv = NPN_GetJavaEnv; + wrapperNPNFuncs.getJavaPeer = NPN_GetJavaPeer; + wrapperNPNFuncs.getvalue = NPN_GetValue; + wrapperNPNFuncs.setvalue = NPN_SetValue; + wrapperNPNFuncs.invalidaterect = NPN_InvalidateRect; + wrapperNPNFuncs.invalidateregion = NPN_InvalidateRegion; + wrapperNPNFuncs.forceredraw = NPN_ForceRedraw; + + plugin_NP_Initialize(&wrapperNPNFuncs); + + return TRUE; +} + +void nsPluginThread::shut() +{ + dbgOut1("nsPluginThread::shut"); + + if (!plugin_NP_Shutdown) + plugin_NP_Shutdown(); + + if (!pluginLibrary) + UnloadRealPlugin(pluginLibrary); +} + +// NPP_ call translator +DWORD nsPluginThread::callNPP(npapiAction aAction, DWORD aP1, DWORD aP2, + DWORD aP3, DWORD aP4, DWORD aP5, + DWORD aP6, DWORD aP7) +{ + // don't enter untill thread is ready + while (isBusy()) { + Sleep(0); + } + + mP1 = aP1; + mP2 = aP2; + mP3 = aP3; + mP4 = aP4; + mP5 = aP5; + mP6 = aP6; + mP7 = aP7; + + doAction(aAction); + + // don't return untill thread is ready + while (isBusy()) { + Sleep(0); + } + + return NPERR_NO_ERROR; +} +void nsPluginThread::dispatch() +{ + dbgOut2("nsPluginThread::dispatch: %s", FormatAction(mAction)); + + switch (mAction) { + case action_npp_new: + pluginNPPFuncs.newp((NPMIMEType)mP1, (NPP)mP2, (uint16)mP3, (int16)mP4, (char**)mP5, (char**)mP6, (NPSavedData*)mP7); + break; + case action_npp_destroy: + pluginNPPFuncs.destroy((NPP)mP1, (NPSavedData**)mP2); + break; + case action_npp_set_window: + pluginNPPFuncs.setwindow((NPP)mP1, (NPWindow*)mP2); + break; + case action_npp_new_stream: + pluginNPPFuncs.newstream((NPP)mP1, (NPMIMEType)mP2, (NPStream*)mP3, (NPBool)mP4, (uint16*)mP5); + break; + case action_npp_destroy_stream: + { + NPStream * stream = (NPStream *)mP2; + pluginNPPFuncs.destroystream((NPP)mP1, stream, (NPError)mP3); + break; + } + case action_npp_stream_as_file: + { + NPStream * stream = (NPStream *)mP2; + pluginNPPFuncs.asfile((NPP)mP1, stream, (char*)mP3); + break; + } + case action_npp_write_ready: + pluginNPPFuncs.writeready((NPP)mP1, (NPStream *)mP2); + break; + case action_npp_write: + pluginNPPFuncs.write((NPP)mP1, (NPStream *)mP2, (int32)mP3, (int32)mP4, (void *)mP5); + break; + case action_npp_print: + pluginNPPFuncs.print((NPP)mP1, (NPPrint*)mP2); + break; + case action_npp_handle_event: + pluginNPPFuncs.event((NPP)mP1, (void *)mP2); + break; + case action_npp_url_notify: + pluginNPPFuncs.urlnotify((NPP)mP1, (const char*)mP2, (NPReason)mP3, (void*)mP4); + break; + case action_npp_get_java_class: + //pluginNPPFuncs.javaClass; + break; + case action_npp_get_value: + pluginNPPFuncs.getvalue((NPP)mP1, (NPPVariable)mP2, (void *)mP3); + break; + case action_npp_set_value: + pluginNPPFuncs.setvalue((NPP)mP1, (NPNVariable)mP2, (void *)mP3); + break; + default: + dbgOut1("Unexpected action!"); + break; + } +} + diff --git a/mozilla/modules/plugin/samples/npthread/windows/plugload.cpp b/mozilla/modules/plugin/samples/npthread/windows/plugload.cpp index 3983aaef5db..ca45f47b4a3 100644 --- a/mozilla/modules/plugin/samples/npthread/windows/plugload.cpp +++ b/mozilla/modules/plugin/samples/npthread/windows/plugload.cpp @@ -34,3 +34,120 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + +#include "windows.h" + +DWORD GetPluginsDir(char * path, DWORD maxsize) +{ + if(!path) + return 0; + + path[0] = '\0'; + + DWORD res = GetModuleFileName(NULL, path, maxsize); + if(res == 0) + return 0; + + if(path[strlen(path) - 1] == '\\') + path[lstrlen(path) - 1] = '\0'; + + char *p = strrchr(path, '\\'); + + if(p) + *p = '\0'; + + strcat(path, "\\plugins"); + + res = strlen(path); + return res; +} + +HINSTANCE LoadRealPlugin(char * mimetype) +{ + if(!mimetype || !strlen(mimetype)) + return NULL; + + BOOL bDone = FALSE; + WIN32_FIND_DATA ffdataStruct; + + char szPath[_MAX_PATH]; + char szFileName[_MAX_PATH]; + + GetPluginsDir(szPath, _MAX_PATH); + + strcpy(szFileName, szPath); + strcat(szFileName, "\\00*"); + + HANDLE handle = FindFirstFile(szFileName, &ffdataStruct); + if(handle == INVALID_HANDLE_VALUE) { + FindClose(handle); + return NULL; + } + + DWORD versize = 0L; + DWORD zero = 0L; + char * verbuf = NULL; + + do { + strcpy(szFileName, szPath); + strcat(szFileName, "\\"); + strcat(szFileName, ffdataStruct.cFileName); + if(!(ffdataStruct. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + versize = GetFileVersionInfoSize(szFileName, &zero); + if (versize > 0) + verbuf = new char[versize]; + else + continue; + + if(!verbuf) + continue; + + GetFileVersionInfo(szFileName, NULL, versize, verbuf); + + char *mimetypes = NULL; + UINT len = 0; + + if(!VerQueryValue(verbuf, "\\StringFileInfo\\040904E4\\MIMEType", (void **)&mimetypes, &len) + || !mimetypes || !len) { + delete [] verbuf; + continue; + } + + // browse through a string of mimetypes + mimetypes[len] = '\0'; + char * type = mimetypes; + + BOOL more = TRUE; + while(more) { + char * p = strchr(type, '|'); + if(p) + *p = '\0'; + else + more = FALSE; + + if(0 == stricmp(mimetype, type)) { + // this is it! + delete [] verbuf; + FindClose(handle); + HINSTANCE hLib = LoadLibrary(szFileName); + return hLib; + } + + type = p; + type++; + } + + delete [] verbuf; + } + + } while(FindNextFile(handle, &ffdataStruct)); + + FindClose(handle); + return NULL; +} + +void UnloadRealPlugin(HINSTANCE hLib) +{ + if(!hLib) + FreeLibrary(hLib); +} diff --git a/mozilla/modules/plugin/samples/npthread/windows/thread.cpp b/mozilla/modules/plugin/samples/npthread/windows/thread.cpp index 3983aaef5db..6173df7836e 100644 --- a/mozilla/modules/plugin/samples/npthread/windows/thread.cpp +++ b/mozilla/modules/plugin/samples/npthread/windows/thread.cpp @@ -34,3 +34,170 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ + +#include +#include +#include + +#include "thread.h" +#include "dbg.h" + +static DWORD WINAPI ThreadFunction(void * lp) +{ + if (lp == NULL) + return 0L; + + CThread * thread = (CThread *)lp; + BOOL res = thread->init(); + thread->setInitEvent(); + + if(res) + thread->run(); + + thread->shut(); + DWORD ret; + GetExitCodeThread(thread->getHandle(), &ret); + thread->setShutEvent(); + return ret; +} + +CThread::CThread(DWORD aInitTimeOut, DWORD aShutTimeOut) : + mThread(NULL), + mID(0), + mState(ts_dead), + mEventThreadInitializationFinished(NULL), + mEventThreadShutdownFinished(NULL), + mInitTimeOut(aInitTimeOut), + mShutTimeOut(aShutTimeOut), + mEventDo(NULL), + mAction(0) +{ + dbgOut1("CThread::CThread"); +} + +CThread::~CThread() +{ + dbgOut1("CThread::~CThread"); +} + +BOOL CThread::open(CThread * aThread) +{ + dbgOut1("CThread::open"); + + mEventThreadInitializationFinished = CreateEvent(NULL, TRUE, FALSE, NULL); + mEventThreadShutdownFinished = CreateEvent(NULL, TRUE, FALSE, NULL); + mEventDo = CreateEvent(NULL, TRUE, FALSE, NULL); + + mThread = (HANDLE)::_beginthreadex(0, 1024, (UINT (__stdcall *)(void *))ThreadFunction, aThread, 0L, (UINT *)&mID); + + if(mThread == NULL) + return FALSE; + + SetThreadPriority(mThread, THREAD_PRIORITY_NORMAL); + + if(mEventThreadInitializationFinished != NULL) + WaitForSingleObject(mEventThreadInitializationFinished, mInitTimeOut); + + return TRUE; +} + +void CThread::close(CThread * aThread) +{ + switch (mState) { + case ts_dead: + break; + case ts_ready: + mState = ts_dead; + SetEvent(mEventDo); + if(mEventThreadShutdownFinished != NULL) + WaitForSingleObject(mEventThreadShutdownFinished, mShutTimeOut); + break; + case ts_busy: + { + aThread->shut(); + DWORD ret; + GetExitCodeThread(aThread->getHandle(), &ret); + TerminateThread(mThread, ret); + mState = ts_dead; + break; + } + default: + break; + } + + mThread = NULL; + CloseHandle(mEventThreadInitializationFinished); + CloseHandle(mEventThreadShutdownFinished); + CloseHandle(mEventDo); + dbgOut1("CThread::close"); +} + +BOOL CThread::setInitEvent() +{ + return SetEvent(mEventThreadInitializationFinished); +} + +BOOL CThread::setShutEvent() +{ + return SetEvent(mEventThreadShutdownFinished); +} + +BOOL CThread::isAlive() +{ + return (mThread != NULL); +} + +BOOL CThread::isBusy() +{ + return (mState == ts_busy); +} + +HANDLE CThread::getHandle() +{ + return mThread; +} + +void CThread::run() +{ + mState = ts_ready; + + while(mState != ts_dead) { + WaitForSingleObject(mEventDo, INFINITE); + //dbgOut2("CThread::run(): Do event signalled, %u", mState); + ResetEvent(mEventDo); + if(mState == ts_dead) + return; + mState = ts_busy; + dispatch(); + mState = ts_ready; + } + mState = ts_dead; +} + +BOOL CThread::tryAction(int aAction) +{ + if(mState != ts_ready) + return FALSE; + + mAction = aAction; + SetEvent(mEventDo); + + return TRUE; +} + +BOOL CThread::doAction(int aAction) +{ + while(mState != ts_ready) { + //dbgOut2("CThread::doAction %i -- waiting...", aAction); + if(mState == ts_dead) + return FALSE; + Sleep(0); + } + + mState = ts_busy; + mAction = aAction; + //dbgOut2("CThread::doAction -- about to signal %i", aAction); + SetEvent(mEventDo); + + return TRUE; +}