1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 #include "nptypes.h"
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 \
75   }                  \
76   while (0)
77 
78 /*
79     Objects (non-primitive data) passed between 'C' and script is
80     always wrapped in an NPObject.  The 'interface' of an NPObject is
81     described by an NPClass.
82 */
83 typedef struct NPObject NPObject;
84 typedef struct NPClass NPClass;
85 
86 typedef char NPUTF8;
87 typedef struct _NPString {
88   const NPUTF8* UTF8Characters;
89   uint32_t UTF8Length;
90 } NPString;
91 
92 typedef enum {
93   NPVariantType_Void,
94   NPVariantType_Null,
95   NPVariantType_Bool,
96   NPVariantType_Int32,
97   NPVariantType_Double,
98   NPVariantType_String,
99   NPVariantType_Object
100 } NPVariantType;
101 
102 typedef struct _NPVariant {
103   NPVariantType type;
104   union {
105     bool boolValue;
106     int32_t intValue;
107     double doubleValue;
108     NPString stringValue;
109     NPObject* objectValue;
110   } value;
111 } NPVariant;
112 
113 /*
114     NPN_ReleaseVariantValue is called on all 'out' parameters
115     references.  Specifically it is to be called on variants that own
116     their value, as is the case with all non-const NPVariant*
117     arguments after a successful call to any methods (except this one)
118     in this API.
119 
120     After calling NPN_ReleaseVariantValue, the type of the variant
121     will be NPVariantType_Void.
122 */
123 void NPN_ReleaseVariantValue(NPVariant* variant);
124 
125 #define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void)
126 #define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null)
127 #define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool)
128 #define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32)
129 #define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double)
130 #define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String)
131 #define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object)
132 
133 #define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue)
134 #define NPVARIANT_TO_INT32(_v) ((_v).value.intValue)
135 #define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue)
136 #define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue)
137 #define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue)
138 
139 #define VOID_TO_NPVARIANT(_v)                   \
140   NP_BEGIN_MACRO(_v).type = NPVariantType_Void; \
141   (_v).value.objectValue = NULL;                \
142   NP_END_MACRO
143 
144 #define NULL_TO_NPVARIANT(_v)                   \
145   NP_BEGIN_MACRO(_v).type = NPVariantType_Null; \
146   (_v).value.objectValue = NULL;                \
147   NP_END_MACRO
148 
149 #define BOOLEAN_TO_NPVARIANT(_val, _v)          \
150   NP_BEGIN_MACRO(_v).type = NPVariantType_Bool; \
151   (_v).value.boolValue = !!(_val);              \
152   NP_END_MACRO
153 
154 #define INT32_TO_NPVARIANT(_val, _v)             \
155   NP_BEGIN_MACRO(_v).type = NPVariantType_Int32; \
156   (_v).value.intValue = _val;                    \
157   NP_END_MACRO
158 
159 #define DOUBLE_TO_NPVARIANT(_val, _v)             \
160   NP_BEGIN_MACRO(_v).type = NPVariantType_Double; \
161   (_v).value.doubleValue = _val;                  \
162   NP_END_MACRO
163 
164 #define STRINGZ_TO_NPVARIANT(_val, _v)             \
165   NP_BEGIN_MACRO(_v).type = NPVariantType_String;  \
166   NPString str = {_val, (uint32_t)(strlen(_val))}; \
167   (_v).value.stringValue = str;                    \
168   NP_END_MACRO
169 
170 #define STRINGN_TO_NPVARIANT(_val, _len, _v)      \
171   NP_BEGIN_MACRO(_v).type = NPVariantType_String; \
172   NPString str = {_val, (uint32_t)(_len)};        \
173   (_v).value.stringValue = str;                   \
174   NP_END_MACRO
175 
176 #define OBJECT_TO_NPVARIANT(_val, _v)             \
177   NP_BEGIN_MACRO(_v).type = NPVariantType_Object; \
178   (_v).value.objectValue = _val;                  \
179   NP_END_MACRO
180 
181 /*
182   Type mappings (JavaScript types have been used for illustration
183     purposes):
184 
185   JavaScript       to             C (NPVariant with type:)
186   undefined                       NPVariantType_Void
187   null                            NPVariantType_Null
188   Boolean                         NPVariantType_Bool
189   Number                          NPVariantType_Double or NPVariantType_Int32
190   String                          NPVariantType_String
191   Object                          NPVariantType_Object
192 
193   C (NPVariant with type:)   to   JavaScript
194   NPVariantType_Void              undefined
195   NPVariantType_Null              null
196   NPVariantType_Bool              Boolean
197   NPVariantType_Int32             Number
198   NPVariantType_Double            Number
199   NPVariantType_String            String
200   NPVariantType_Object            Object
201 */
202 
203 typedef void* NPIdentifier;
204 
205 /*
206     NPObjects have methods and properties.  Methods and properties are
207     identified with NPIdentifiers.  These identifiers may be reflected
208     in script.  NPIdentifiers can be either strings or integers, IOW,
209     methods and properties can be identified by either strings or
210     integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be
211     compared using ==.  In case of any errors, the requested
212     NPIdentifier(s) will be NULL. NPIdentifier lifetime is controlled
213     by the browser. Plugins do not need to worry about memory management
214     with regards to NPIdentifiers.
215 */
216 NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name);
217 void NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount,
218                               NPIdentifier* identifiers);
219 NPIdentifier NPN_GetIntIdentifier(int32_t intid);
220 bool NPN_IdentifierIsString(NPIdentifier identifier);
221 
222 /*
223     The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed.
224 */
225 NPUTF8* NPN_UTF8FromIdentifier(NPIdentifier identifier);
226 
227 /*
228     Get the integer represented by identifier. If identifier is not an
229     integer identifier, the behaviour is undefined.
230 */
231 int32_t NPN_IntFromIdentifier(NPIdentifier identifier);
232 
233 /*
234     NPObject behavior is implemented using the following set of
235     callback functions.
236 
237     The NPVariant *result argument of these functions (where
238     applicable) should be released using NPN_ReleaseVariantValue().
239 */
240 typedef NPObject* (*NPAllocateFunctionPtr)(NPP npp, NPClass* aClass);
241 typedef void (*NPDeallocateFunctionPtr)(NPObject* npobj);
242 typedef void (*NPInvalidateFunctionPtr)(NPObject* npobj);
243 typedef bool (*NPHasMethodFunctionPtr)(NPObject* npobj, NPIdentifier name);
244 typedef bool (*NPInvokeFunctionPtr)(NPObject* npobj, NPIdentifier name,
245                                     const NPVariant* args, uint32_t argCount,
246                                     NPVariant* result);
247 typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject* npobj,
248                                            const NPVariant* args,
249                                            uint32_t argCount,
250                                            NPVariant* result);
251 typedef bool (*NPHasPropertyFunctionPtr)(NPObject* npobj, NPIdentifier name);
252 typedef bool (*NPGetPropertyFunctionPtr)(NPObject* npobj, NPIdentifier name,
253                                          NPVariant* result);
254 typedef bool (*NPSetPropertyFunctionPtr)(NPObject* npobj, NPIdentifier name,
255                                          const NPVariant* value);
256 typedef bool (*NPRemovePropertyFunctionPtr)(NPObject* npobj, NPIdentifier name);
257 typedef bool (*NPEnumerationFunctionPtr)(NPObject* npobj, NPIdentifier** value,
258                                          uint32_t* count);
259 typedef bool (*NPConstructFunctionPtr)(NPObject* npobj, const NPVariant* args,
260                                        uint32_t argCount, NPVariant* result);
261 
262 /*
263     NPObjects returned by create, retain, invoke, and getProperty pass
264     a reference count to the caller.  That is, the callee adds a
265     reference count which passes to the caller.  It is the caller's
266     responsibility to release the returned object.
267 
268     NPInvokeFunctionPtr function may return 0 to indicate a void
269     result.
270 
271     NPInvalidateFunctionPtr is called by the scripting environment
272     when the native code is shutdown.  Any attempt to message a
273     NPObject instance after the invalidate callback has been
274     called will result in undefined behavior, even if the native code
275     is still retaining those NPObject instances.  (The runtime
276     will typically return immediately, with 0 or NULL, from an
277     attempt to dispatch to a NPObject, but this behavior should not
278     be depended upon.)
279 
280     The NPEnumerationFunctionPtr function may pass an array of
281     NPIdentifiers back to the caller. The callee allocs the memory of
282     the array using NPN_MemAlloc(), and it's the caller's responsibility
283     to release it using NPN_MemFree().
284 */
285 struct NPClass {
286   uint32_t structVersion;
287   NPAllocateFunctionPtr allocate;
288   NPDeallocateFunctionPtr deallocate;
289   NPInvalidateFunctionPtr invalidate;
290   NPHasMethodFunctionPtr hasMethod;
291   NPInvokeFunctionPtr invoke;
292   NPInvokeDefaultFunctionPtr invokeDefault;
293   NPHasPropertyFunctionPtr hasProperty;
294   NPGetPropertyFunctionPtr getProperty;
295   NPSetPropertyFunctionPtr setProperty;
296   NPRemovePropertyFunctionPtr removeProperty;
297   NPEnumerationFunctionPtr enumerate;
298   NPConstructFunctionPtr construct;
299 };
300 
301 #define NP_CLASS_STRUCT_VERSION 3
302 
303 #define NP_CLASS_STRUCT_VERSION_ENUM 2
304 #define NP_CLASS_STRUCT_VERSION_CTOR 3
305 
306 #define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass) \
307   ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM)
308 
309 #define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass) \
310   ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR)
311 
312 struct NPObject {
313   NPClass* _class;
314   uint32_t referenceCount;
315   /*
316    * Additional space may be allocated here by types of NPObjects
317    */
318 };
319 
320 /*
321     If the class has an allocate function, NPN_CreateObject invokes
322     that function, otherwise a NPObject is allocated and
323     returned. This method will initialize the referenceCount member of
324     the NPObject to 1.
325 */
326 NPObject* NPN_CreateObject(NPP npp, NPClass* aClass);
327 
328 /*
329     Increment the NPObject's reference count.
330 */
331 NPObject* NPN_RetainObject(NPObject* npobj);
332 
333 /*
334     Decremented the NPObject's reference count.  If the reference
335     count goes to zero, the class's destroy function is invoke if
336     specified, otherwise the object is freed directly.
337 */
338 void NPN_ReleaseObject(NPObject* npobj);
339 
340 /*
341     Functions to access script objects represented by NPObject.
342 
343     Calls to script objects are synchronous.  If a function returns a
344     value, it will be supplied via the result NPVariant
345     argument. Successful calls will return true, false will be
346     returned in case of an error.
347 
348     Calls made from plugin code to script must be made from the thread
349     on which the plugin was initialized.
350 */
351 
352 bool NPN_Invoke(NPP npp, NPObject* npobj, NPIdentifier methodName,
353                 const NPVariant* args, uint32_t argCount, NPVariant* result);
354 bool NPN_InvokeDefault(NPP npp, NPObject* npobj, const NPVariant* args,
355                        uint32_t argCount, NPVariant* result);
356 bool NPN_Evaluate(NPP npp, NPObject* npobj, NPString* script,
357                   NPVariant* result);
358 bool NPN_GetProperty(NPP npp, NPObject* npobj, NPIdentifier propertyName,
359                      NPVariant* result);
360 bool NPN_SetProperty(NPP npp, NPObject* npobj, NPIdentifier propertyName,
361                      const NPVariant* value);
362 bool NPN_RemoveProperty(NPP npp, NPObject* npobj, NPIdentifier propertyName);
363 bool NPN_HasProperty(NPP npp, NPObject* npobj, NPIdentifier propertyName);
364 bool NPN_HasMethod(NPP npp, NPObject* npobj, NPIdentifier methodName);
365 bool NPN_Enumerate(NPP npp, NPObject* npobj, NPIdentifier** identifier,
366                    uint32_t* count);
367 bool NPN_Construct(NPP npp, NPObject* npobj, const NPVariant* args,
368                    uint32_t argCount, NPVariant* result);
369 
370 /*
371     NPN_SetException may be called to trigger a script exception upon
372     return from entry points into NPObjects.  Typical usage:
373 
374     NPN_SetException (npobj, message);
375 */
376 void NPN_SetException(NPObject* npobj, const NPUTF8* message);
377 
378 #ifdef __cplusplus
379 }
380 #endif
381 
382 #endif
383