michael@0: /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* michael@0: * Copyright (c) 2004, Apple Computer, Inc. and The Mozilla Foundation. michael@0: * All rights reserved. michael@0: * michael@0: * Redistribution and use in source and binary forms, with or without michael@0: * modification, are permitted provided that the following conditions are michael@0: * met: michael@0: * michael@0: * 1. Redistributions of source code must retain the above copyright michael@0: * notice, this list of conditions and the following disclaimer. michael@0: * 2. Redistributions in binary form must reproduce the above copyright michael@0: * notice, this list of conditions and the following disclaimer in the michael@0: * documentation and/or other materials provided with the distribution. michael@0: * 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla michael@0: * Foundation ("Mozilla") nor the names of their contributors may be used michael@0: * to endorse or promote products derived from this software without michael@0: * specific prior written permission. michael@0: * michael@0: * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS michael@0: * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED michael@0: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A michael@0: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR michael@0: * THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED michael@0: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR michael@0: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF michael@0: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING michael@0: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS michael@0: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: * michael@0: */ michael@0: #ifndef _NP_RUNTIME_H_ michael@0: #define _NP_RUNTIME_H_ michael@0: michael@0: #ifdef __cplusplus michael@0: extern "C" { michael@0: #endif michael@0: michael@0: #include "nptypes.h" michael@0: michael@0: /* michael@0: This API is used to facilitate binding code written in C to script michael@0: objects. The API in this header does not assume the presence of a michael@0: user agent. That is, it can be used to bind C code to scripting michael@0: environments outside of the context of a user agent. michael@0: michael@0: However, the normal use of the this API is in the context of a michael@0: scripting environment running in a browser or other user agent. michael@0: In particular it is used to support the extended Netscape michael@0: script-ability API for plugins (NP-SAP). NP-SAP is an extension michael@0: of the Netscape plugin API. As such we have adopted the use of michael@0: the "NP" prefix for this API. michael@0: michael@0: The following NP{N|P}Variables were added to the Netscape plugin michael@0: API (in npapi.h): michael@0: michael@0: NPNVWindowNPObject michael@0: NPNVPluginElementNPObject michael@0: NPPVpluginScriptableNPObject michael@0: michael@0: These variables are exposed through NPN_GetValue() and michael@0: NPP_GetValue() (respectively) and are used to establish the michael@0: initial binding between the user agent and native code. The DOM michael@0: objects in the user agent can be examined and manipulated using michael@0: the NPN_ functions that operate on NPObjects described in this michael@0: header. michael@0: michael@0: To the extent possible the assumptions about the scripting michael@0: language used by the scripting environment have been minimized. michael@0: */ michael@0: michael@0: #define NP_BEGIN_MACRO do { michael@0: #define NP_END_MACRO } while (0) michael@0: michael@0: /* michael@0: Objects (non-primitive data) passed between 'C' and script is michael@0: always wrapped in an NPObject. The 'interface' of an NPObject is michael@0: described by an NPClass. michael@0: */ michael@0: typedef struct NPObject NPObject; michael@0: typedef struct NPClass NPClass; michael@0: michael@0: typedef char NPUTF8; michael@0: typedef struct _NPString { michael@0: const NPUTF8 *UTF8Characters; michael@0: uint32_t UTF8Length; michael@0: } NPString; michael@0: michael@0: typedef enum { michael@0: NPVariantType_Void, michael@0: NPVariantType_Null, michael@0: NPVariantType_Bool, michael@0: NPVariantType_Int32, michael@0: NPVariantType_Double, michael@0: NPVariantType_String, michael@0: NPVariantType_Object michael@0: } NPVariantType; michael@0: michael@0: typedef struct _NPVariant { michael@0: NPVariantType type; michael@0: union { michael@0: bool boolValue; michael@0: int32_t intValue; michael@0: double doubleValue; michael@0: NPString stringValue; michael@0: NPObject *objectValue; michael@0: } value; michael@0: } NPVariant; michael@0: michael@0: /* michael@0: NPN_ReleaseVariantValue is called on all 'out' parameters michael@0: references. Specifically it is to be called on variants that own michael@0: their value, as is the case with all non-const NPVariant* michael@0: arguments after a successful call to any methods (except this one) michael@0: in this API. michael@0: michael@0: After calling NPN_ReleaseVariantValue, the type of the variant michael@0: will be NPVariantType_Void. michael@0: */ michael@0: void NPN_ReleaseVariantValue(NPVariant *variant); michael@0: michael@0: #define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void) michael@0: #define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null) michael@0: #define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool) michael@0: #define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32) michael@0: #define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double) michael@0: #define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String) michael@0: #define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object) michael@0: michael@0: #define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue) michael@0: #define NPVARIANT_TO_INT32(_v) ((_v).value.intValue) michael@0: #define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue) michael@0: #define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue) michael@0: #define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue) michael@0: michael@0: #define VOID_TO_NPVARIANT(_v) \ michael@0: NP_BEGIN_MACRO \ michael@0: (_v).type = NPVariantType_Void; \ michael@0: (_v).value.objectValue = NULL; \ michael@0: NP_END_MACRO michael@0: michael@0: #define NULL_TO_NPVARIANT(_v) \ michael@0: NP_BEGIN_MACRO \ michael@0: (_v).type = NPVariantType_Null; \ michael@0: (_v).value.objectValue = NULL; \ michael@0: NP_END_MACRO michael@0: michael@0: #define BOOLEAN_TO_NPVARIANT(_val, _v) \ michael@0: NP_BEGIN_MACRO \ michael@0: (_v).type = NPVariantType_Bool; \ michael@0: (_v).value.boolValue = !!(_val); \ michael@0: NP_END_MACRO michael@0: michael@0: #define INT32_TO_NPVARIANT(_val, _v) \ michael@0: NP_BEGIN_MACRO \ michael@0: (_v).type = NPVariantType_Int32; \ michael@0: (_v).value.intValue = _val; \ michael@0: NP_END_MACRO michael@0: michael@0: #define DOUBLE_TO_NPVARIANT(_val, _v) \ michael@0: NP_BEGIN_MACRO \ michael@0: (_v).type = NPVariantType_Double; \ michael@0: (_v).value.doubleValue = _val; \ michael@0: NP_END_MACRO michael@0: michael@0: #define STRINGZ_TO_NPVARIANT(_val, _v) \ michael@0: NP_BEGIN_MACRO \ michael@0: (_v).type = NPVariantType_String; \ michael@0: NPString str = { _val, (uint32_t)(strlen(_val)) }; \ michael@0: (_v).value.stringValue = str; \ michael@0: NP_END_MACRO michael@0: michael@0: #define STRINGN_TO_NPVARIANT(_val, _len, _v) \ michael@0: NP_BEGIN_MACRO \ michael@0: (_v).type = NPVariantType_String; \ michael@0: NPString str = { _val, (uint32_t)(_len) }; \ michael@0: (_v).value.stringValue = str; \ michael@0: NP_END_MACRO michael@0: michael@0: #define OBJECT_TO_NPVARIANT(_val, _v) \ michael@0: NP_BEGIN_MACRO \ michael@0: (_v).type = NPVariantType_Object; \ michael@0: (_v).value.objectValue = _val; \ michael@0: NP_END_MACRO michael@0: michael@0: michael@0: /* michael@0: Type mappings (JavaScript types have been used for illustration michael@0: purposes): michael@0: michael@0: JavaScript to C (NPVariant with type:) michael@0: undefined NPVariantType_Void michael@0: null NPVariantType_Null michael@0: Boolean NPVariantType_Bool michael@0: Number NPVariantType_Double or NPVariantType_Int32 michael@0: String NPVariantType_String michael@0: Object NPVariantType_Object michael@0: michael@0: C (NPVariant with type:) to JavaScript michael@0: NPVariantType_Void undefined michael@0: NPVariantType_Null null michael@0: NPVariantType_Bool Boolean michael@0: NPVariantType_Int32 Number michael@0: NPVariantType_Double Number michael@0: NPVariantType_String String michael@0: NPVariantType_Object Object michael@0: */ michael@0: michael@0: typedef void *NPIdentifier; michael@0: michael@0: /* michael@0: NPObjects have methods and properties. Methods and properties are michael@0: identified with NPIdentifiers. These identifiers may be reflected michael@0: in script. NPIdentifiers can be either strings or integers, IOW, michael@0: methods and properties can be identified by either strings or michael@0: integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be michael@0: compared using ==. In case of any errors, the requested michael@0: NPIdentifier(s) will be NULL. NPIdentifier lifetime is controlled michael@0: by the browser. Plugins do not need to worry about memory management michael@0: with regards to NPIdentifiers. michael@0: */ michael@0: NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name); michael@0: void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, michael@0: NPIdentifier *identifiers); michael@0: NPIdentifier NPN_GetIntIdentifier(int32_t intid); michael@0: bool NPN_IdentifierIsString(NPIdentifier identifier); michael@0: michael@0: /* michael@0: The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed. michael@0: */ michael@0: NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier); michael@0: michael@0: /* michael@0: Get the integer represented by identifier. If identifier is not an michael@0: integer identifier, the behaviour is undefined. michael@0: */ michael@0: int32_t NPN_IntFromIdentifier(NPIdentifier identifier); michael@0: michael@0: /* michael@0: NPObject behavior is implemented using the following set of michael@0: callback functions. michael@0: michael@0: The NPVariant *result argument of these functions (where michael@0: applicable) should be released using NPN_ReleaseVariantValue(). michael@0: */ michael@0: typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass); michael@0: typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj); michael@0: typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj); michael@0: typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name); michael@0: typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name, michael@0: const NPVariant *args, uint32_t argCount, michael@0: NPVariant *result); michael@0: typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj, michael@0: const NPVariant *args, michael@0: uint32_t argCount, michael@0: NPVariant *result); michael@0: typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name); michael@0: typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name, michael@0: NPVariant *result); michael@0: typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name, michael@0: const NPVariant *value); michael@0: typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj, michael@0: NPIdentifier name); michael@0: typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value, michael@0: uint32_t *count); michael@0: typedef bool (*NPConstructFunctionPtr)(NPObject *npobj, michael@0: const NPVariant *args, michael@0: uint32_t argCount, michael@0: NPVariant *result); michael@0: michael@0: /* michael@0: NPObjects returned by create, retain, invoke, and getProperty pass michael@0: a reference count to the caller. That is, the callee adds a michael@0: reference count which passes to the caller. It is the caller's michael@0: responsibility to release the returned object. michael@0: michael@0: NPInvokeFunctionPtr function may return 0 to indicate a void michael@0: result. michael@0: michael@0: NPInvalidateFunctionPtr is called by the scripting environment michael@0: when the native code is shutdown. Any attempt to message a michael@0: NPObject instance after the invalidate callback has been michael@0: called will result in undefined behavior, even if the native code michael@0: is still retaining those NPObject instances. (The runtime michael@0: will typically return immediately, with 0 or NULL, from an michael@0: attempt to dispatch to a NPObject, but this behavior should not michael@0: be depended upon.) michael@0: michael@0: The NPEnumerationFunctionPtr function may pass an array of michael@0: NPIdentifiers back to the caller. The callee allocs the memory of michael@0: the array using NPN_MemAlloc(), and it's the caller's responsibility michael@0: to release it using NPN_MemFree(). michael@0: */ michael@0: struct NPClass michael@0: { michael@0: uint32_t structVersion; michael@0: NPAllocateFunctionPtr allocate; michael@0: NPDeallocateFunctionPtr deallocate; michael@0: NPInvalidateFunctionPtr invalidate; michael@0: NPHasMethodFunctionPtr hasMethod; michael@0: NPInvokeFunctionPtr invoke; michael@0: NPInvokeDefaultFunctionPtr invokeDefault; michael@0: NPHasPropertyFunctionPtr hasProperty; michael@0: NPGetPropertyFunctionPtr getProperty; michael@0: NPSetPropertyFunctionPtr setProperty; michael@0: NPRemovePropertyFunctionPtr removeProperty; michael@0: NPEnumerationFunctionPtr enumerate; michael@0: NPConstructFunctionPtr construct; michael@0: }; michael@0: michael@0: #define NP_CLASS_STRUCT_VERSION 3 michael@0: michael@0: #define NP_CLASS_STRUCT_VERSION_ENUM 2 michael@0: #define NP_CLASS_STRUCT_VERSION_CTOR 3 michael@0: michael@0: #define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass) \ michael@0: ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM) michael@0: michael@0: #define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass) \ michael@0: ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR) michael@0: michael@0: struct NPObject { michael@0: NPClass *_class; michael@0: uint32_t referenceCount; michael@0: /* michael@0: * Additional space may be allocated here by types of NPObjects michael@0: */ michael@0: }; michael@0: michael@0: /* michael@0: If the class has an allocate function, NPN_CreateObject invokes michael@0: that function, otherwise a NPObject is allocated and michael@0: returned. This method will initialize the referenceCount member of michael@0: the NPObject to 1. michael@0: */ michael@0: NPObject *NPN_CreateObject(NPP npp, NPClass *aClass); michael@0: michael@0: /* michael@0: Increment the NPObject's reference count. michael@0: */ michael@0: NPObject *NPN_RetainObject(NPObject *npobj); michael@0: michael@0: /* michael@0: Decremented the NPObject's reference count. If the reference michael@0: count goes to zero, the class's destroy function is invoke if michael@0: specified, otherwise the object is freed directly. michael@0: */ michael@0: void NPN_ReleaseObject(NPObject *npobj); michael@0: michael@0: /* michael@0: Functions to access script objects represented by NPObject. michael@0: michael@0: Calls to script objects are synchronous. If a function returns a michael@0: value, it will be supplied via the result NPVariant michael@0: argument. Successful calls will return true, false will be michael@0: returned in case of an error. michael@0: michael@0: Calls made from plugin code to script must be made from the thread michael@0: on which the plugin was initialized. michael@0: */ michael@0: michael@0: bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName, michael@0: const NPVariant *args, uint32_t argCount, NPVariant *result); michael@0: bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args, michael@0: uint32_t argCount, NPVariant *result); michael@0: bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script, michael@0: NPVariant *result); michael@0: bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, michael@0: NPVariant *result); michael@0: bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, michael@0: const NPVariant *value); michael@0: bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName); michael@0: bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName); michael@0: bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName); michael@0: bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier, michael@0: uint32_t *count); michael@0: bool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args, michael@0: uint32_t argCount, NPVariant *result); michael@0: michael@0: /* michael@0: NPN_SetException may be called to trigger a script exception upon michael@0: return from entry points into NPObjects. Typical usage: michael@0: michael@0: NPN_SetException (npobj, message); michael@0: */ michael@0: void NPN_SetException(NPObject *npobj, const NPUTF8 *message); michael@0: michael@0: #ifdef __cplusplus michael@0: } michael@0: #endif michael@0: michael@0: #endif