blob: 7e7d04258cc8fa4f47f0ce95af34b3f48198efa5 [file] [log] [blame]
Grace Klobafbe47c02009-05-14 17:31:45 -07001/*
2 * Copyright 2008, The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <stdlib.h>
27#include <string.h>
28#include <stdio.h>
29#include "main.h"
30#include "PluginObject.h"
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040031#include "AnimationPlugin.h"
Derek Sollenbergerf42e2f42009-06-26 11:42:46 -040032#include "AudioPlugin.h"
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040033#include "BackgroundPlugin.h"
Derek Sollenbergerdb398a72009-06-29 13:53:04 -040034#include "FormPlugin.h"
Derek Sollenbergerc0f26572009-07-16 11:38:02 -040035#include "SurfacePlugin.h"
Grace Klobafbe47c02009-05-14 17:31:45 -070036#include "android_npapi.h"
37
38NPNetscapeFuncs* browser;
39#define EXPORT __attribute__((visibility("default")))
40
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040041NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
Grace Klobafbe47c02009-05-14 17:31:45 -070042 char* argn[], char* argv[], NPSavedData* saved);
43NPError NPP_Destroy(NPP instance, NPSavedData** save);
44NPError NPP_SetWindow(NPP instance, NPWindow* window);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040045NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
Grace Klobafbe47c02009-05-14 17:31:45 -070046 NPBool seekable, uint16* stype);
47NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
48int32 NPP_WriteReady(NPP instance, NPStream* stream);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040049int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
Grace Klobafbe47c02009-05-14 17:31:45 -070050 void* buffer);
51void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
52void NPP_Print(NPP instance, NPPrint* platformPrint);
53int16 NPP_HandleEvent(NPP instance, void* event);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040054void NPP_URLNotify(NPP instance, const char* URL, NPReason reason,
Grace Klobafbe47c02009-05-14 17:31:45 -070055 void* notifyData);
56NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
57NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
58
59extern "C" {
60EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env, void *application_context);
61EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value);
62EXPORT const char* NP_GetMIMEDescription(void);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040063EXPORT void NP_Shutdown(void);
Grace Klobafbe47c02009-05-14 17:31:45 -070064};
65
66ANPAudioTrackInterfaceV0 gSoundI;
Mike Reed224adad2009-06-10 10:24:01 -040067ANPBitmapInterfaceV0 gBitmapI;
Grace Klobafbe47c02009-05-14 17:31:45 -070068ANPCanvasInterfaceV0 gCanvasI;
69ANPLogInterfaceV0 gLogI;
70ANPPaintInterfaceV0 gPaintI;
71ANPPathInterfaceV0 gPathI;
Derek Sollenbergerc0f26572009-07-16 11:38:02 -040072ANPSurfaceInterfaceV0 gSurfaceI;
Grace Klobafbe47c02009-05-14 17:31:45 -070073ANPTypefaceInterfaceV0 gTypefaceI;
Derek Sollenberger5b011e32009-06-22 11:39:40 -040074ANPWindowInterfaceV0 gWindowI;
Grace Klobafbe47c02009-05-14 17:31:45 -070075
76#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
Derek Sollenberger5b011e32009-06-22 11:39:40 -040077#define DEBUG_PLUGIN_EVENTS 0
Grace Klobafbe47c02009-05-14 17:31:45 -070078
79NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env, void *application_context)
80{
81 // Make sure we have a function table equal or larger than we are built against.
82 if (browserFuncs->size < sizeof(NPNetscapeFuncs)) {
83 return NPERR_GENERIC_ERROR;
84 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040085
Grace Klobafbe47c02009-05-14 17:31:45 -070086 // Copy the function table (structure)
87 browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs));
88 memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs));
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040089
Grace Klobafbe47c02009-05-14 17:31:45 -070090 // Build the plugin function table
91 pluginFuncs->version = 11;
92 pluginFuncs->size = sizeof(pluginFuncs);
93 pluginFuncs->newp = NPP_New;
94 pluginFuncs->destroy = NPP_Destroy;
95 pluginFuncs->setwindow = NPP_SetWindow;
96 pluginFuncs->newstream = NPP_NewStream;
97 pluginFuncs->destroystream = NPP_DestroyStream;
98 pluginFuncs->asfile = NPP_StreamAsFile;
99 pluginFuncs->writeready = NPP_WriteReady;
100 pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
101 pluginFuncs->print = NPP_Print;
102 pluginFuncs->event = NPP_HandleEvent;
103 pluginFuncs->urlnotify = NPP_URLNotify;
104 pluginFuncs->getvalue = NPP_GetValue;
105 pluginFuncs->setvalue = NPP_SetValue;
106
107 static const struct {
108 NPNVariable v;
109 uint32_t size;
110 ANPInterface* i;
111 } gPairs[] = {
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400112 { kAudioTrackInterfaceV0_ANPGetValue, sizeof(gSoundI), &gSoundI },
Mike Reed224adad2009-06-10 10:24:01 -0400113 { kBitmapInterfaceV0_ANPGetValue, sizeof(gBitmapI), &gBitmapI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700114 { kCanvasInterfaceV0_ANPGetValue, sizeof(gCanvasI), &gCanvasI },
Mike Reed224adad2009-06-10 10:24:01 -0400115 { kLogInterfaceV0_ANPGetValue, sizeof(gLogI), &gLogI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700116 { kPaintInterfaceV0_ANPGetValue, sizeof(gPaintI), &gPaintI },
117 { kPathInterfaceV0_ANPGetValue, sizeof(gPathI), &gPathI },
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400118 { kSurfaceInterfaceV0_ANPGetValue, sizeof(gSurfaceI), &gSurfaceI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700119 { kTypefaceInterfaceV0_ANPGetValue, sizeof(gPaintI), &gTypefaceI },
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400120 { kWindowInterfaceV0_ANPGetValue, sizeof(gWindowI), &gWindowI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700121 };
122 for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) {
123 gPairs[i].i->inSize = gPairs[i].size;
124 NPError err = browser->getvalue(NULL, gPairs[i].v, gPairs[i].i);
125 if (err) {
126 return err;
127 }
128 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400129
Grace Klobafbe47c02009-05-14 17:31:45 -0700130 return NPERR_NO_ERROR;
131}
132
133void NP_Shutdown(void)
134{
135
136}
137
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400138const char *NP_GetMIMEDescription(void)
Grace Klobafbe47c02009-05-14 17:31:45 -0700139{
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400140 return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
Grace Klobafbe47c02009-05-14 17:31:45 -0700141}
142
143NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
144 char* argn[], char* argv[], NPSavedData* saved)
145{
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400146
147 /* BEGIN: STANDARD PLUGIN FRAMEWORK */
Grace Klobafbe47c02009-05-14 17:31:45 -0700148 PluginObject *obj = NULL;
149
150 // Scripting functions appeared in NPAPI version 14
151 if (browser->version >= 14) {
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400152 instance->pdata = browser->createobject (instance, getPluginClass());
153 obj = static_cast<PluginObject*>(instance->pdata);
154 bzero(obj, sizeof(*obj));
Grace Klobafbe47c02009-05-14 17:31:45 -0700155 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400156 /* END: STANDARD PLUGIN FRAMEWORK */
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400157
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400158 // select the pluginType
159 for (int i = 0; i < argc; i++) {
160 if (!strcmp(argn[i], "PluginType")) {
161 if (!strcmp(argv[i], "Animation")) {
162 obj->pluginType = kAnimation_PluginType;
163 obj->activePlugin = new BallAnimation(instance);
164 }
165 else if (!strcmp(argv[i], "Audio")) {
166 obj->pluginType = kAudio_PluginType;
Derek Sollenbergerf42e2f42009-06-26 11:42:46 -0400167 obj->activePlugin = new AudioPlugin(instance);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400168 }
169 else if (!strcmp(argv[i], "Background")) {
170 obj->pluginType = kBackground_PluginType;
171 obj->activePlugin = new BackgroundPlugin(instance);
172 }
Derek Sollenbergerdb398a72009-06-29 13:53:04 -0400173 else if (!strcmp(argv[i], "Form")) {
174 obj->pluginType = kForm_PluginType;
175 obj->activePlugin = new FormPlugin(instance);
176 }
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400177 else if (!strcmp(argv[i], "RGBA_Surface")) {
178 obj->pluginType = kSurface_PluginType;
179 obj->activePlugin = new SurfacePlugin(instance, kRGBA_ANPSurfaceType);
180 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400181 gLogI.log(instance, kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
182 break;
183 }
184 }
185
186 // if no pluginType is specified then default to Animation
187 if (!obj->pluginType) {
188 obj->pluginType = kAnimation_PluginType;
189 obj->activePlugin = new BallAnimation(instance);
190 }
191
Derek Sollenberger21f39912009-07-09 09:19:39 -0400192 // select the drawing model based on user input
193 ANPDrawingModel model = kBitmap_ANPDrawingModel;
194
195 for (int i = 0; i < argc; i++) {
196 if (!strcmp(argn[i], "DrawingModel")) {
197 if (!strcmp(argv[i], "Bitmap")) {
198 model = kBitmap_ANPDrawingModel;
199 }
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400200 else if (!strcmp(argv[i], "Surface")) {
201 model = kSurface_ANPDrawingModel;
Derek Sollenberger21f39912009-07-09 09:19:39 -0400202 }
203 gLogI.log(instance, kDebug_ANPLogType, "------ %p DrawingModel is %d", instance, model);
204 break;
205 }
206 }
207
208 // check to ensure the pluginType supports the model
209 if (!obj->activePlugin->supportsDrawingModel(model)) {
210 gLogI.log(instance, kError_ANPLogType, "------ %p Unsupported DrawingModel (%d)", instance, model);
211 return NPERR_GENERIC_ERROR;
212 }
213
214 // notify the plugin API of the drawing model we wish to use
215 NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
216 reinterpret_cast<void*>(model));
217 if (err) {
218 gLogI.log(instance, kError_ANPLogType, "request model %d err %d", model, err);
219 return err;
220 }
221
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400222 return NPERR_NO_ERROR;
Grace Klobafbe47c02009-05-14 17:31:45 -0700223}
224
225NPError NPP_Destroy(NPP instance, NPSavedData** save)
226{
227 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400228 delete obj->activePlugin;
Grace Klobafbe47c02009-05-14 17:31:45 -0700229
230 return NPERR_NO_ERROR;
231}
232
Grace Klobafbe47c02009-05-14 17:31:45 -0700233NPError NPP_SetWindow(NPP instance, NPWindow* window)
234{
235 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400236
Grace Klobafbe47c02009-05-14 17:31:45 -0700237 // Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
238 if (obj != NULL) {
239 obj->window = window;
240 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400241
Grace Klobafbe47c02009-05-14 17:31:45 -0700242 browser->invalidaterect(instance, NULL);
243
244 return NPERR_NO_ERROR;
245}
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400246
Grace Klobafbe47c02009-05-14 17:31:45 -0700247NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
248{
249 *stype = NP_ASFILEONLY;
250 return NPERR_NO_ERROR;
251}
252
253NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
254{
255 return NPERR_NO_ERROR;
256}
257
258int32 NPP_WriteReady(NPP instance, NPStream* stream)
259{
260 return 0;
261}
262
263int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
264{
265 return 0;
266}
267
268void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
269{
270}
271
272void NPP_Print(NPP instance, NPPrint* platformPrint)
273{
Grace Klobafbe47c02009-05-14 17:31:45 -0700274}
275
Grace Klobafbe47c02009-05-14 17:31:45 -0700276int16 NPP_HandleEvent(NPP instance, void* event)
277{
278 PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
279 const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
280
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400281#if DEBUG_PLUGIN_EVENTS
Grace Klobafbe47c02009-05-14 17:31:45 -0700282 switch (evt->eventType) {
283 case kDraw_ANPEventType:
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400284
285 if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
286
287 static ANPBitmapFormat currentFormat = -1;
288 if (evt->data.draw.data.bitmap.format != currentFormat) {
289 currentFormat = evt->data.draw.data.bitmap.format;
290 gLogI.log(instance, kDebug_ANPLogType, "---- %p Draw (bitmap)"
291 " clip=%d,%d,%d,%d format=%d", instance,
292 evt->data.draw.clip.left,
293 evt->data.draw.clip.top,
294 evt->data.draw.clip.right,
295 evt->data.draw.clip.bottom,
296 evt->data.draw.data.bitmap.format);
297 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700298 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400299 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700300
301 case kKey_ANPEventType:
302 gLogI.log(instance, kDebug_ANPLogType, "---- %p Key action=%d"
303 " code=%d vcode=%d unichar=%d repeat=%d mods=%x", instance,
304 evt->data.key.action,
305 evt->data.key.nativeCode,
306 evt->data.key.virtualCode,
307 evt->data.key.unichar,
308 evt->data.key.repeatCount,
309 evt->data.key.modifiers);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400310 break;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400311
312 case kLifecycle_ANPEventType:
313 gLogI.log(instance, kDebug_ANPLogType, "---- %p Lifecycle action=%d",
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400314 instance, evt->data.lifecycle.action);
Mike Reed1e7c3312009-05-26 16:37:45 -0400315 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700316
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400317 case kTouch_ANPEventType:
Grace Klobafbe47c02009-05-14 17:31:45 -0700318 gLogI.log(instance, kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
319 instance, evt->data.touch.action, evt->data.touch.x,
320 evt->data.touch.y);
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400321 break;
322
Derek Sollenbergerdb398a72009-06-29 13:53:04 -0400323 case kMouse_ANPEventType:
324 gLogI.log(instance, kDebug_ANPLogType, "---- %p Mouse action=%d [%d %d]",
325 instance, evt->data.mouse.action, evt->data.mouse.x,
326 evt->data.mouse.y);
327 break;
328
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400329 case kVisibleRect_ANPEventType:
330 gLogI.log(instance, kDebug_ANPLogType, "---- %p VisibleRect [%d %d %d %d]",
Derek Sollenbergerf42e2f42009-06-26 11:42:46 -0400331 instance, evt->data.visibleRect.rect.left, evt->data.visibleRect.rect.top,
332 evt->data.visibleRect.rect.right, evt->data.visibleRect.rect.bottom);
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400333 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700334
335 default:
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400336 gLogI.log(instance, kError_ANPLogType, "---- %p Unknown Event [%d]",
337 instance, evt->eventType);
Grace Klobafbe47c02009-05-14 17:31:45 -0700338 break;
339 }
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400340#endif
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400341
342 if(!obj->activePlugin) {
343 gLogI.log(instance, kError_ANPLogType, "the active plugin is null.");
344 return 0; // unknown or unhandled event
345 }
346 else {
347 return obj->activePlugin->handleEvent(evt);
348 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700349}
350
351void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
352{
353
354}
355
356EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) {
357
358 if (variable == NPPVpluginNameString) {
359 const char **str = (const char **)value;
360 *str = "Test Plugin";
361 return NPERR_NO_ERROR;
362 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400363
Grace Klobafbe47c02009-05-14 17:31:45 -0700364 if (variable == NPPVpluginDescriptionString) {
365 const char **str = (const char **)value;
366 *str = "Description of Test Plugin";
367 return NPERR_NO_ERROR;
368 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400369
Grace Klobafbe47c02009-05-14 17:31:45 -0700370 return NPERR_GENERIC_ERROR;
371}
372
373NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
374{
375 if (variable == NPPVpluginScriptableNPObject) {
376 void **v = (void **)value;
377 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400378
Grace Klobafbe47c02009-05-14 17:31:45 -0700379 if (obj)
380 browser->retainobject((NPObject*)obj);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400381
Grace Klobafbe47c02009-05-14 17:31:45 -0700382 *v = obj;
383 return NPERR_NO_ERROR;
384 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400385
Grace Klobafbe47c02009-05-14 17:31:45 -0700386 return NPERR_GENERIC_ERROR;
387}
388
389NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
390{
391 return NPERR_GENERIC_ERROR;
392}
393