1/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * Copyright (c) 2004, Apple Computer, Inc. and The Mozilla Foundation.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla
16 * Foundation ("Mozilla") nor the names of their contributors may be used
17 * to endorse or promote products derived from this software without
18 * specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS
21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR
24 * THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33#ifndef _NP_RUNTIME_H_
34#define _NP_RUNTIME_H_
35
36#include "npapi.h"
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42/*
43    This API is used to facilitate binding code written in C to script
44    objects.  The API in this header does not assume the presence of a
45    user agent.  That is, it can be used to bind C code to scripting
46    environments outside of the context of a user agent.
47
48    However, the normal use of the this API is in the context of a
49    scripting environment running in a browser or other user agent.
50    In particular it is used to support the extended Netscape
51    script-ability API for plugins (NP-SAP).  NP-SAP is an extension
52    of the Netscape plugin API.  As such we have adopted the use of
53    the "NP" prefix for this API.
54
55    The following NP{N|P}Variables were added to the Netscape plugin
56    API (in npapi.h):
57
58    NPNVWindowNPObject
59    NPNVPluginElementNPObject
60    NPPVpluginScriptableNPObject
61
62    These variables are exposed through NPN_GetValue() and
63    NPP_GetValue() (respectively) and are used to establish the
64    initial binding between the user agent and native code.  The DOM
65    objects in the user agent can be examined and manipulated using
66    the NPN_ functions that operate on NPObjects described in this
67    header.
68
69    To the extent possible the assumptions about the scripting
70    language used by the scripting environment have been minimized.
71*/
72
73#define NP_BEGIN_MACRO  do {
74#define NP_END_MACRO    } while (0)
75
76/*
77    Objects (non-primitive data) passed between 'C' and script is
78    always wrapped in an NPObject.  The 'interface' of an NPObject is
79    described by an NPClass.
80*/
81typedef struct NPObject NPObject;
82typedef struct NPClass NPClass;
83
84typedef char NPUTF8;
85typedef struct _NPString {
86    const NPUTF8 *UTF8Characters;
87    uint32_t UTF8Length;
88} NPString;
89
90typedef enum {
91    NPVariantType_Void,
92    NPVariantType_Null,
93    NPVariantType_Bool,
94    NPVariantType_Int32,
95    NPVariantType_Double,
96    NPVariantType_String,
97    NPVariantType_Object
98} NPVariantType;
99
100typedef struct _NPVariant {
101    NPVariantType type;
102    union {
103        bool boolValue;
104        int32_t intValue;
105        double doubleValue;
106        NPString stringValue;
107        NPObject *objectValue;
108    } value;
109} NPVariant;
110
111/*
112    NPN_ReleaseVariantValue is called on all 'out' parameters
113    references.  Specifically it is to be called on variants that own
114    their value, as is the case with all non-const NPVariant*
115    arguments after a successful call to any methods (except this one)
116    in this API.
117
118    After calling NPN_ReleaseVariantValue, the type of the variant
119    will be NPVariantType_Void.
120*/
121void NPN_ReleaseVariantValue(NPVariant *variant);
122
123#define NPVARIANT_IS_VOID(_v)    ((_v).type == NPVariantType_Void)
124#define NPVARIANT_IS_NULL(_v)    ((_v).type == NPVariantType_Null)
125#define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool)
126#define NPVARIANT_IS_INT32(_v)   ((_v).type == NPVariantType_Int32)
127#define NPVARIANT_IS_DOUBLE(_v)  ((_v).type == NPVariantType_Double)
128#define NPVARIANT_IS_STRING(_v)  ((_v).type == NPVariantType_String)
129#define NPVARIANT_IS_OBJECT(_v)  ((_v).type == NPVariantType_Object)
130
131#define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue)
132#define NPVARIANT_TO_INT32(_v)   ((_v).value.intValue)
133#define NPVARIANT_TO_DOUBLE(_v)  ((_v).value.doubleValue)
134#define NPVARIANT_TO_STRING(_v)  ((_v).value.stringValue)
135#define NPVARIANT_TO_OBJECT(_v)  ((_v).value.objectValue)
136
137#define VOID_TO_NPVARIANT(_v)                                                 \
138NP_BEGIN_MACRO                                                                \
139    (_v).type = NPVariantType_Void;                                           \
140    (_v).value.objectValue = NULL;                                            \
141NP_END_MACRO
142
143#define NULL_TO_NPVARIANT(_v)                                                 \
144NP_BEGIN_MACRO                                                                \
145    (_v).type = NPVariantType_Null;                                           \
146    (_v).value.objectValue = NULL;                                            \
147NP_END_MACRO
148
149#define BOOLEAN_TO_NPVARIANT(_val, _v)                                        \
150NP_BEGIN_MACRO                                                                \
151    (_v).type = NPVariantType_Bool;                                           \
152    (_v).value.boolValue = !!(_val);                                          \
153NP_END_MACRO
154
155#define INT32_TO_NPVARIANT(_val, _v)                                          \
156NP_BEGIN_MACRO                                                                \
157    (_v).type = NPVariantType_Int32;                                          \
158    (_v).value.intValue = _val;                                               \
159NP_END_MACRO
160
161#define DOUBLE_TO_NPVARIANT(_val, _v)                                         \
162NP_BEGIN_MACRO                                                                \
163    (_v).type = NPVariantType_Double;                                         \
164    (_v).value.doubleValue = _val;                                            \
165NP_END_MACRO
166
167#define STRINGZ_TO_NPVARIANT(_val, _v)                                        \
168NP_BEGIN_MACRO                                                                \
169    (_v).type = NPVariantType_String;                                         \
170    NPString str = { _val, uint32_t(strlen(_val)) };                          \
171    (_v).value.stringValue = str;                                             \
172NP_END_MACRO
173
174#define STRINGN_TO_NPVARIANT(_val, _len, _v)                                  \
175NP_BEGIN_MACRO                                                                \
176    (_v).type = NPVariantType_String;                                         \
177    NPString str = { _val, uint32_t(_len) };                                  \
178    (_v).value.stringValue = str;                                             \
179NP_END_MACRO
180
181#define OBJECT_TO_NPVARIANT(_val, _v)                                         \
182NP_BEGIN_MACRO                                                                \
183    (_v).type = NPVariantType_Object;                                         \
184    (_v).value.objectValue = _val;                                            \
185NP_END_MACRO
186
187
188/*
189  Type mappings (JavaScript types have been used for illustration
190    purposes):
191
192  JavaScript       to             C (NPVariant with type:)
193  undefined                       NPVariantType_Void
194  null                            NPVariantType_Null
195  Boolean                         NPVariantType_Bool
196  Number                          NPVariantType_Double or NPVariantType_Int32
197  String                          NPVariantType_String
198  Object                          NPVariantType_Object
199
200  C (NPVariant with type:)   to   JavaScript
201  NPVariantType_Void              undefined
202  NPVariantType_Null              null
203  NPVariantType_Bool              Boolean
204  NPVariantType_Int32             Number
205  NPVariantType_Double            Number
206  NPVariantType_String            String
207  NPVariantType_Object            Object
208*/
209
210typedef void *NPIdentifier;
211
212/*
213    NPObjects have methods and properties.  Methods and properties are
214    identified with NPIdentifiers.  These identifiers may be reflected
215    in script.  NPIdentifiers can be either strings or integers, IOW,
216    methods and properties can be identified by either strings or
217    integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be
218    compared using ==.  In case of any errors, the requested
219    NPIdentifier(s) will be NULL. NPIdentifier lifetime is controlled
220    by the browser. Plugins do not need to worry about memory management
221    with regards to NPIdentifiers.
222*/
223NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name);
224void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount,
225                              NPIdentifier *identifiers);
226NPIdentifier NPN_GetIntIdentifier(int32_t intid);
227bool NPN_IdentifierIsString(NPIdentifier identifier);
228
229/*
230    The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed.
231*/
232NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier);
233
234/*
235    Get the integer represented by identifier. If identifier is not an
236    integer identifier, the behaviour is undefined.
237*/
238int32_t NPN_IntFromIdentifier(NPIdentifier identifier);
239
240/*
241    NPObject behavior is implemented using the following set of
242    callback functions.
243
244    The NPVariant *result argument of these functions (where
245    applicable) should be released using NPN_ReleaseVariantValue().
246*/
247typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass);
248typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj);
249typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj);
250typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name);
251typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name,
252                                    const NPVariant *args, uint32_t argCount,
253                                    NPVariant *result);
254typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj,
255                                           const NPVariant *args,
256                                           uint32_t argCount,
257                                           NPVariant *result);
258typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name);
259typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
260                                         NPVariant *result);
261typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
262                                         const NPVariant *value);
263typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj,
264                                            NPIdentifier name);
265typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value,
266                                         uint32_t *count);
267typedef bool (*NPConstructFunctionPtr)(NPObject *npobj,
268                                       const NPVariant *args,
269                                       uint32_t argCount,
270                                       NPVariant *result);
271
272/*
273    NPObjects returned by create, retain, invoke, and getProperty pass
274    a reference count to the caller.  That is, the callee adds a
275    reference count which passes to the caller.  It is the caller's
276    responsibility to release the returned object.
277
278    NPInvokeFunctionPtr function may return 0 to indicate a void
279    result.
280
281    NPInvalidateFunctionPtr is called by the scripting environment
282    when the native code is shutdown.  Any attempt to message a
283    NPObject instance after the invalidate callback has been
284    called will result in undefined behavior, even if the native code
285    is still retaining those NPObject instances.  (The runtime
286    will typically return immediately, with 0 or NULL, from an attempt
287    to dispatch to a NPObject, but this behavior should not be
288    depended upon.)
289
290    The NPEnumerationFunctionPtr function may pass an array of
291    NPIdentifiers back to the caller. The callee allocs the memory of
292    the array using NPN_MemAlloc(), and it's the caller's responsibility
293    to release it using NPN_MemFree().
294*/
295struct NPClass
296{
297    uint32_t structVersion;
298    NPAllocateFunctionPtr allocate;
299    NPDeallocateFunctionPtr deallocate;
300    NPInvalidateFunctionPtr invalidate;
301    NPHasMethodFunctionPtr hasMethod;
302    NPInvokeFunctionPtr invoke;
303    NPInvokeDefaultFunctionPtr invokeDefault;
304    NPHasPropertyFunctionPtr hasProperty;
305    NPGetPropertyFunctionPtr getProperty;
306    NPSetPropertyFunctionPtr setProperty;
307    NPRemovePropertyFunctionPtr removeProperty;
308    NPEnumerationFunctionPtr enumerate;
309    NPConstructFunctionPtr construct;
310};
311
312#define NP_CLASS_STRUCT_VERSION      3
313
314#define NP_CLASS_STRUCT_VERSION_ENUM 2
315#define NP_CLASS_STRUCT_VERSION_CTOR 3
316
317#define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass)   \
318        ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM)
319
320#define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass)   \
321        ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR)
322
323struct NPObject {
324    NPClass *_class;
325    uint32_t referenceCount;
326    /*
327     * Additional space may be allocated here by types of NPObjects
328     */
329};
330
331/*
332    If the class has an allocate function, NPN_CreateObject invokes
333    that function, otherwise a NPObject is allocated and
334    returned. This method will initialize the referenceCount member of
335    the NPObject to 1.
336*/
337NPObject *NPN_CreateObject(NPP npp, NPClass *aClass);
338
339/*
340    Increment the NPObject's reference count.
341*/
342NPObject *NPN_RetainObject(NPObject *npobj);
343
344/*
345    Decremented the NPObject's reference count.  If the reference
346    count goes to zero, the class's destroy function is invoke if
347    specified, otherwise the object is freed directly.
348*/
349void NPN_ReleaseObject(NPObject *npobj);
350
351/*
352    Functions to access script objects represented by NPObject.
353
354    Calls to script objects are synchronous.  If a function returns a
355    value, it will be supplied via the result NPVariant
356    argument. Successful calls will return true, false will be
357    returned in case of an error.
358
359    Calls made from plugin code to script must be made from the thread
360    on which the plugin was initialized.
361*/
362
363bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName,
364                const NPVariant *args, uint32_t argCount, NPVariant *result);
365bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args,
366                       uint32_t argCount, NPVariant *result);
367bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script,
368                  NPVariant *result);
369bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
370                     NPVariant *result);
371bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
372                     const NPVariant *value);
373bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
374bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
375bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName);
376bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier,
377                   uint32_t *count);
378bool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args,
379                   uint32_t argCount, NPVariant *result);
380
381/*
382    NPN_SetException may be called to trigger a script exception upon
383    return from entry points into NPObjects.  Typical usage:
384
385    NPN_SetException (npobj, message);
386*/
387void NPN_SetException(NPObject *npobj, const NPUTF8 *message);
388
389#ifdef __cplusplus
390}
391#endif
392
393#endif
394