| /* ***** BEGIN LICENSE BLOCK ***** | |
| * Version: NPL 1.1/GPL 2.0/LGPL 2.1 | |
| * | |
| * The contents of this file are subject to the Netscape Public License | |
| * Version 1.1 (the "License"); you may not use this file except in | |
| * compliance with the License. You may obtain a copy of the License at | |
| * http://www.mozilla.org/NPL/ | |
| * | |
| * Software distributed under the License is distributed on an "AS IS" basis, | |
| * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
| * for the specific language governing rights and limitations under the | |
| * License. | |
| * | |
| * The Original Code is mozilla.org code. | |
| * | |
| * The Initial Developer of the Original Code is | |
| * Netscape Communications Corporation. | |
| * Portions created by the Initial Developer are Copyright (C) 1998 | |
| * the Initial Developer. All Rights Reserved. | |
| * | |
| * Contributor(s): | |
| * | |
| * Alternatively, the contents of this file may be used under the terms of | |
| * either the GNU General Public License Version 2 or later (the "GPL"), or | |
| * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), | |
| * in which case the provisions of the GPL or the LGPL are applicable instead | |
| * of those above. If you wish to allow use of your version of this file only | |
| * under the terms of either the GPL or the LGPL, and not to allow others to | |
| * use your version of this file under the terms of the NPL, indicate your | |
| * decision by deleting the provisions above and replace them with the notice | |
| * and other provisions required by the GPL or the LGPL. If you do not delete | |
| * the provisions above, a recipient may use your version of this file under | |
| * the terms of any one of the NPL, the GPL or the LGPL. | |
| * | |
| * ***** END LICENSE BLOCK ***** */ | |
| //////////////////////////////////////////////////////////// | |
| // | |
| // Implementation of Netscape entry points (NPN_*), which are the functions | |
| // the plugin calls to talk to the browser. | |
| // | |
| #include "Debug.h" | |
| // Sun's cstring doesn't declare memcpy | |
| #include <string.h> | |
| //#include <cstring> | |
| #include "mozincludes.h" | |
| //#include "gears/base/common/base_class.h" | |
| //#include "gears/base/common/thread_locals.h" | |
| //#include "gears/base/npapi/module.h" | |
| #ifndef HIBYTE | |
| #define HIBYTE(x) ((((uint32)(x)) & 0xff00) >> 8) | |
| #endif | |
| #ifndef LOBYTE | |
| #define LOBYTE(W) ((W) & 0xFF) | |
| #endif | |
| static NPNetscapeFuncs npn_funcs; | |
| void SetNPNFuncs(NPNetscapeFuncs* npnFuncs) { | |
| // Since we can't rely on the pointer remaining valid, we need to | |
| // copy the function pointers. | |
| int size = sizeof(NPNetscapeFuncs); | |
| if (size > npnFuncs->size) { | |
| Debug::log(Debug::Warning) << "*** Warning: NPNetscapeFuncs supplied by " | |
| "browser is smaller than expected: " << npnFuncs->size << " vs " << size | |
| << Debug::flush; | |
| size = npnFuncs->size; | |
| } | |
| memcpy(&npn_funcs, npnFuncs, size); | |
| } | |
| const NPNetscapeFuncs &GetNPNFuncs() { | |
| return npn_funcs; | |
| } | |
| void NPN_Version(int* plugin_major, int* plugin_minor, | |
| int* netscape_major, int* netscape_minor) | |
| { | |
| const NPNetscapeFuncs &funcs = GetNPNFuncs(); | |
| *plugin_major = NP_VERSION_MAJOR; | |
| *plugin_minor = NP_VERSION_MINOR; | |
| *netscape_major = HIBYTE(funcs.version); | |
| *netscape_minor = LOBYTE(funcs.version); | |
| } | |
| NPError NPN_GetURLNotify(NPP instance, const char *url, const char *target, | |
| void* notifyData) | |
| { | |
| const NPNetscapeFuncs &funcs = GetNPNFuncs(); | |
| int navMinorVers = funcs.version & 0xFF; | |
| NPError rv = NPERR_NO_ERROR; | |
| if (navMinorVers >= NPVERS_HAS_NOTIFICATION) | |
| rv = funcs.geturlnotify(instance, url, target, notifyData); | |
| else | |
| rv = NPERR_INCOMPATIBLE_VERSION_ERROR; | |
| return rv; | |
| } | |
| NPError NPN_GetURL(NPP instance, const char *url, const char *target) | |
| { | |
| NPError rv = GetNPNFuncs().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) | |
| { | |
| const NPNetscapeFuncs &funcs = GetNPNFuncs(); | |
| int navMinorVers = funcs.version & 0xFF; | |
| NPError rv = NPERR_NO_ERROR; | |
| if (navMinorVers >= NPVERS_HAS_NOTIFICATION) { | |
| rv = funcs.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) | |
| { | |
| NPError rv = GetNPNFuncs().posturl(instance, url, window, len, buf, file); | |
| return rv; | |
| } | |
| NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) | |
| { | |
| NPError rv = GetNPNFuncs().requestread(stream, rangeList); | |
| return rv; | |
| } | |
| NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* target, | |
| NPStream** stream) | |
| { | |
| const NPNetscapeFuncs &funcs = GetNPNFuncs(); | |
| int navMinorVersion = funcs.version & 0xFF; | |
| NPError rv = NPERR_NO_ERROR; | |
| if ( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) | |
| rv = funcs.newstream(instance, type, target, stream); | |
| else | |
| rv = NPERR_INCOMPATIBLE_VERSION_ERROR; | |
| return rv; | |
| } | |
| int32 NPN_Write(NPP instance, NPStream *stream, int32 len, void *buffer) | |
| { | |
| const NPNetscapeFuncs &funcs = GetNPNFuncs(); | |
| int navMinorVersion = funcs.version & 0xFF; | |
| int32 rv = 0; | |
| if ( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) | |
| rv = funcs.write(instance, stream, len, buffer); | |
| else | |
| rv = -1; | |
| return rv; | |
| } | |
| NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason) | |
| { | |
| const NPNetscapeFuncs &funcs = GetNPNFuncs(); | |
| int navMinorVersion = funcs.version & 0xFF; | |
| NPError rv = NPERR_NO_ERROR; | |
| if ( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) | |
| rv = funcs.destroystream(instance, stream, reason); | |
| else | |
| rv = NPERR_INCOMPATIBLE_VERSION_ERROR; | |
| return rv; | |
| } | |
| void NPN_Status(NPP instance, const char *message) | |
| { | |
| GetNPNFuncs().status(instance, message); | |
| } | |
| const char* NPN_UserAgent(NPP instance) | |
| { | |
| const char * rv = NULL; | |
| rv = GetNPNFuncs().uagent(instance); | |
| return rv; | |
| } | |
| void* NPN_MemAlloc(uint32 size) | |
| { | |
| void * rv = NULL; | |
| rv = GetNPNFuncs().memalloc(size); | |
| return rv; | |
| } | |
| void NPN_MemFree(void* ptr) | |
| { | |
| GetNPNFuncs().memfree(ptr); | |
| } | |
| uint32 NPN_MemFlush(uint32 size) | |
| { | |
| uint32 rv = GetNPNFuncs().memflush(size); | |
| return rv; | |
| } | |
| void NPN_ReloadPlugins(NPBool reloadPages) | |
| { | |
| GetNPNFuncs().reloadplugins(reloadPages); | |
| } | |
| NPError NPN_GetValue(NPP instance, NPNVariable variable, void *value) | |
| { | |
| NPError rv = GetNPNFuncs().getvalue(instance, variable, value); | |
| return rv; | |
| } | |
| NPError NPN_SetValue(NPP instance, NPPVariable variable, void *value) | |
| { | |
| NPError rv = GetNPNFuncs().setvalue(instance, variable, value); | |
| return rv; | |
| } | |
| void NPN_InvalidateRect(NPP instance, NPRect *invalidRect) | |
| { | |
| GetNPNFuncs().invalidaterect(instance, invalidRect); | |
| } | |
| void NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion) | |
| { | |
| GetNPNFuncs().invalidateregion(instance, invalidRegion); | |
| } | |
| void NPN_ForceRedraw(NPP instance) | |
| { | |
| GetNPNFuncs().forceredraw(instance); | |
| } | |
| NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name) | |
| { | |
| return GetNPNFuncs().getstringidentifier(name); | |
| } | |
| void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, | |
| NPIdentifier *identifiers) | |
| { | |
| return GetNPNFuncs().getstringidentifiers(names, nameCount, identifiers); | |
| } | |
| NPIdentifier NPN_GetIntIdentifier(int32_t intid) | |
| { | |
| return GetNPNFuncs().getintidentifier(intid); | |
| } | |
| bool NPN_IdentifierIsString(NPIdentifier identifier) | |
| { | |
| return GetNPNFuncs().identifierisstring(identifier); | |
| } | |
| NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier) | |
| { | |
| return GetNPNFuncs().utf8fromidentifier(identifier); | |
| } | |
| // On WebKit under OSX, the intfromidentifier field of the structure isn't | |
| // filled in (see WebNetscapePluginPackage.m#526 in WebKit source tree). | |
| // At this time this function isn't called from our code, so for now comment it | |
| // out. | |
| // | |
| int32_t NPN_IntFromIdentifier(NPIdentifier identifier) | |
| { | |
| return GetNPNFuncs().intfromidentifier(identifier); | |
| } | |
| NPObject *NPN_CreateObject(NPP npp, NPClass *aClass) | |
| { | |
| return GetNPNFuncs().createobject(npp, aClass); | |
| } | |
| NPObject *NPN_RetainObject(NPObject *obj) | |
| { | |
| return GetNPNFuncs().retainobject(obj); | |
| } | |
| void NPN_ReleaseObject(NPObject *obj) | |
| { | |
| return GetNPNFuncs().releaseobject(obj); | |
| } | |
| bool NPN_Invoke(NPP npp, NPObject* obj, NPIdentifier methodName, | |
| const NPVariant *args, uint32_t argCount, NPVariant *result) | |
| { | |
| return GetNPNFuncs().invoke(npp, obj, methodName, args, argCount, result); | |
| } | |
| bool NPN_InvokeDefault(NPP npp, NPObject* obj, const NPVariant *args, | |
| uint32_t argCount, NPVariant *result) | |
| { | |
| return GetNPNFuncs().invokeDefault(npp, obj, args, argCount, result); | |
| } | |
| bool NPN_Evaluate(NPP npp, NPObject* obj, NPString *script, | |
| NPVariant *result) | |
| { | |
| return GetNPNFuncs().evaluate(npp, obj, script, result); | |
| } | |
| bool NPN_GetProperty(NPP npp, NPObject* obj, NPIdentifier propertyName, | |
| NPVariant *result) | |
| { | |
| // Workaround for bug in WebKit: GetProperty() fails when attempting to | |
| // read a null value from an array, however it fills in the variant structure | |
| // correctly. | |
| // The workaround is to chek if GetProprety() touches the variant structure, | |
| // if so, we assume it succeeded. | |
| #ifdef BROWSER_WEBKIT | |
| result->type = static_cast<NPVariantType>(-1); | |
| bool ret = GetNPNFuncs().getproperty(npp, obj, propertyName, result); | |
| if (result->type != -1 && !ret) { | |
| ret = true; | |
| } | |
| return ret; | |
| #else | |
| return GetNPNFuncs().getproperty(npp, obj, propertyName, result); | |
| #endif | |
| } | |
| bool NPN_SetProperty(NPP npp, NPObject* obj, NPIdentifier propertyName, | |
| const NPVariant *value) | |
| { | |
| return GetNPNFuncs().setproperty(npp, obj, propertyName, value); | |
| } | |
| bool NPN_RemoveProperty(NPP npp, NPObject* obj, NPIdentifier propertyName) | |
| { | |
| return GetNPNFuncs().removeproperty(npp, obj, propertyName); | |
| } | |
| #ifdef BROWSER_WEBKIT | |
| // This field of NPN functions isn't filled in by WebKit on OSX. | |
| #else | |
| bool NPN_HasProperty(NPP npp, NPObject* obj, NPIdentifier propertyName) | |
| { | |
| return GetNPNFuncs().hasproperty(npp, obj, propertyName); | |
| } | |
| #endif | |
| #ifdef BROWSER_WEBKIT | |
| // This field of NPN functions isn't filled in by WebKit on OSX. | |
| #else | |
| bool NPN_HasMethod(NPP npp, NPObject* obj, NPIdentifier methodName) | |
| { | |
| return GetNPNFuncs().hasmethod(npp, obj, methodName); | |
| } | |
| #endif | |
| void NPN_ReleaseVariantValue(NPVariant *variant) | |
| { | |
| GetNPNFuncs().releasevariantvalue(variant); | |
| } | |
| #ifdef BROWSER_WEBKIT | |
| // This function is buggy in WebKit, see | |
| // http://bugs.webkit.org/show_bug.cgi?id=16829 | |
| #else | |
| void NPN_SetException(NPObject* obj, const NPUTF8 *message) | |
| { | |
| GetNPNFuncs().setexception(obj, message); | |
| } | |
| #endif |