blob: b73e128e8713a629e66d3958b27f8baac31efc6d [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"
Grace Klobafbe47c02009-05-14 17:31:45 -070034#include "android_npapi.h"
35
36NPNetscapeFuncs* browser;
37#define EXPORT __attribute__((visibility("default")))
38
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040039NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
Grace Klobafbe47c02009-05-14 17:31:45 -070040 char* argn[], char* argv[], NPSavedData* saved);
41NPError NPP_Destroy(NPP instance, NPSavedData** save);
42NPError NPP_SetWindow(NPP instance, NPWindow* window);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040043NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
Grace Klobafbe47c02009-05-14 17:31:45 -070044 NPBool seekable, uint16* stype);
45NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
46int32 NPP_WriteReady(NPP instance, NPStream* stream);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040047int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
Grace Klobafbe47c02009-05-14 17:31:45 -070048 void* buffer);
49void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
50void NPP_Print(NPP instance, NPPrint* platformPrint);
51int16 NPP_HandleEvent(NPP instance, void* event);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040052void NPP_URLNotify(NPP instance, const char* URL, NPReason reason,
Grace Klobafbe47c02009-05-14 17:31:45 -070053 void* notifyData);
54NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
55NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
56
57extern "C" {
58EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env, void *application_context);
59EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value);
60EXPORT const char* NP_GetMIMEDescription(void);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040061EXPORT void NP_Shutdown(void);
Grace Klobafbe47c02009-05-14 17:31:45 -070062};
63
64ANPAudioTrackInterfaceV0 gSoundI;
Mike Reed224adad2009-06-10 10:24:01 -040065ANPBitmapInterfaceV0 gBitmapI;
Grace Klobafbe47c02009-05-14 17:31:45 -070066ANPCanvasInterfaceV0 gCanvasI;
67ANPLogInterfaceV0 gLogI;
68ANPPaintInterfaceV0 gPaintI;
69ANPPathInterfaceV0 gPathI;
70ANPTypefaceInterfaceV0 gTypefaceI;
Derek Sollenberger5b011e32009-06-22 11:39:40 -040071ANPWindowInterfaceV0 gWindowI;
Grace Klobafbe47c02009-05-14 17:31:45 -070072
73#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
Derek Sollenberger5b011e32009-06-22 11:39:40 -040074#define DEBUG_PLUGIN_EVENTS 0
Grace Klobafbe47c02009-05-14 17:31:45 -070075
76NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env, void *application_context)
77{
78 // Make sure we have a function table equal or larger than we are built against.
79 if (browserFuncs->size < sizeof(NPNetscapeFuncs)) {
80 return NPERR_GENERIC_ERROR;
81 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040082
Grace Klobafbe47c02009-05-14 17:31:45 -070083 // Copy the function table (structure)
84 browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs));
85 memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs));
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040086
Grace Klobafbe47c02009-05-14 17:31:45 -070087 // Build the plugin function table
88 pluginFuncs->version = 11;
89 pluginFuncs->size = sizeof(pluginFuncs);
90 pluginFuncs->newp = NPP_New;
91 pluginFuncs->destroy = NPP_Destroy;
92 pluginFuncs->setwindow = NPP_SetWindow;
93 pluginFuncs->newstream = NPP_NewStream;
94 pluginFuncs->destroystream = NPP_DestroyStream;
95 pluginFuncs->asfile = NPP_StreamAsFile;
96 pluginFuncs->writeready = NPP_WriteReady;
97 pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
98 pluginFuncs->print = NPP_Print;
99 pluginFuncs->event = NPP_HandleEvent;
100 pluginFuncs->urlnotify = NPP_URLNotify;
101 pluginFuncs->getvalue = NPP_GetValue;
102 pluginFuncs->setvalue = NPP_SetValue;
103
104 static const struct {
105 NPNVariable v;
106 uint32_t size;
107 ANPInterface* i;
108 } gPairs[] = {
Mike Reed224adad2009-06-10 10:24:01 -0400109 { kBitmapInterfaceV0_ANPGetValue, sizeof(gBitmapI), &gBitmapI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700110 { kCanvasInterfaceV0_ANPGetValue, sizeof(gCanvasI), &gCanvasI },
Mike Reed224adad2009-06-10 10:24:01 -0400111 { kLogInterfaceV0_ANPGetValue, sizeof(gLogI), &gLogI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700112 { kPaintInterfaceV0_ANPGetValue, sizeof(gPaintI), &gPaintI },
113 { kPathInterfaceV0_ANPGetValue, sizeof(gPathI), &gPathI },
114 { kTypefaceInterfaceV0_ANPGetValue, sizeof(gPaintI), &gTypefaceI },
115 { kAudioTrackInterfaceV0_ANPGetValue, sizeof(gSoundI), &gSoundI },
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400116 { kWindowInterfaceV0_ANPGetValue, sizeof(gWindowI), &gWindowI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700117 };
118 for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) {
119 gPairs[i].i->inSize = gPairs[i].size;
120 NPError err = browser->getvalue(NULL, gPairs[i].v, gPairs[i].i);
121 if (err) {
122 return err;
123 }
124 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400125
Grace Klobafbe47c02009-05-14 17:31:45 -0700126 return NPERR_NO_ERROR;
127}
128
129void NP_Shutdown(void)
130{
131
132}
133
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400134const char *NP_GetMIMEDescription(void)
Grace Klobafbe47c02009-05-14 17:31:45 -0700135{
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400136 return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
Grace Klobafbe47c02009-05-14 17:31:45 -0700137}
138
139NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
140 char* argn[], char* argv[], NPSavedData* saved)
141{
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400142
143 /* BEGIN: STANDARD PLUGIN FRAMEWORK */
Grace Klobafbe47c02009-05-14 17:31:45 -0700144 PluginObject *obj = NULL;
145
146 // Scripting functions appeared in NPAPI version 14
147 if (browser->version >= 14) {
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400148 instance->pdata = browser->createobject (instance, getPluginClass());
149 obj = static_cast<PluginObject*>(instance->pdata);
150 bzero(obj, sizeof(*obj));
Grace Klobafbe47c02009-05-14 17:31:45 -0700151 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400152 /* END: STANDARD PLUGIN FRAMEWORK */
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400153
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400154 // select the drawing model based on user input
Grace Klobafbe47c02009-05-14 17:31:45 -0700155 ANPDrawingModel model = kBitmap_ANPDrawingModel;
156
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400157 for (int i = 0; i < argc; i++) {
Grace Klobafbe47c02009-05-14 17:31:45 -0700158 if (!strcmp(argn[i], "DrawingModel")) {
159 if (!strcmp(argv[i], "Bitmap")) {
160 model = kBitmap_ANPDrawingModel;
161 }
162 if (!strcmp(argv[i], "Canvas")) {
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400163 //TODO support drawing on canvas instead of bitmap
Grace Klobafbe47c02009-05-14 17:31:45 -0700164 }
165 gLogI.log(instance, kDebug_ANPLogType, "------ %p DrawingModel is %d", instance, model);
166 break;
167 }
168 }
169
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400170 // comment this out to use the default model (bitmaps)
171 NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
Grace Klobafbe47c02009-05-14 17:31:45 -0700172 reinterpret_cast<void*>(model));
173 if (err) {
174 gLogI.log(instance, kError_ANPLogType, "request model %d err %d", model, err);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400175 return err;
Grace Klobafbe47c02009-05-14 17:31:45 -0700176 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400177
178 // select the pluginType
179 for (int i = 0; i < argc; i++) {
180 if (!strcmp(argn[i], "PluginType")) {
181 if (!strcmp(argv[i], "Animation")) {
182 obj->pluginType = kAnimation_PluginType;
183 obj->activePlugin = new BallAnimation(instance);
184 }
185 else if (!strcmp(argv[i], "Audio")) {
186 obj->pluginType = kAudio_PluginType;
Derek Sollenbergerf42e2f42009-06-26 11:42:46 -0400187 obj->activePlugin = new AudioPlugin(instance);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400188 }
189 else if (!strcmp(argv[i], "Background")) {
190 obj->pluginType = kBackground_PluginType;
191 obj->activePlugin = new BackgroundPlugin(instance);
192 }
193 gLogI.log(instance, kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
194 break;
195 }
196 }
197
198 // if no pluginType is specified then default to Animation
199 if (!obj->pluginType) {
200 obj->pluginType = kAnimation_PluginType;
201 obj->activePlugin = new BallAnimation(instance);
202 }
203
204 return NPERR_NO_ERROR;
Grace Klobafbe47c02009-05-14 17:31:45 -0700205}
206
207NPError NPP_Destroy(NPP instance, NPSavedData** save)
208{
209 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400210 delete obj->activePlugin;
Grace Klobafbe47c02009-05-14 17:31:45 -0700211
212 return NPERR_NO_ERROR;
213}
214
Grace Klobafbe47c02009-05-14 17:31:45 -0700215NPError NPP_SetWindow(NPP instance, NPWindow* window)
216{
217 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400218
Grace Klobafbe47c02009-05-14 17:31:45 -0700219 // Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
220 if (obj != NULL) {
221 obj->window = window;
222 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400223
Grace Klobafbe47c02009-05-14 17:31:45 -0700224 browser->invalidaterect(instance, NULL);
225
226 return NPERR_NO_ERROR;
227}
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400228
Grace Klobafbe47c02009-05-14 17:31:45 -0700229NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
230{
231 *stype = NP_ASFILEONLY;
232 return NPERR_NO_ERROR;
233}
234
235NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
236{
237 return NPERR_NO_ERROR;
238}
239
240int32 NPP_WriteReady(NPP instance, NPStream* stream)
241{
242 return 0;
243}
244
245int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
246{
247 return 0;
248}
249
250void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
251{
252}
253
254void NPP_Print(NPP instance, NPPrint* platformPrint)
255{
Grace Klobafbe47c02009-05-14 17:31:45 -0700256}
257
Grace Klobafbe47c02009-05-14 17:31:45 -0700258int16 NPP_HandleEvent(NPP instance, void* event)
259{
260 PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
261 const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
262
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400263#if DEBUG_PLUGIN_EVENTS
Grace Klobafbe47c02009-05-14 17:31:45 -0700264 switch (evt->eventType) {
265 case kDraw_ANPEventType:
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400266
267 if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
268
269 static ANPBitmapFormat currentFormat = -1;
270 if (evt->data.draw.data.bitmap.format != currentFormat) {
271 currentFormat = evt->data.draw.data.bitmap.format;
272 gLogI.log(instance, kDebug_ANPLogType, "---- %p Draw (bitmap)"
273 " clip=%d,%d,%d,%d format=%d", instance,
274 evt->data.draw.clip.left,
275 evt->data.draw.clip.top,
276 evt->data.draw.clip.right,
277 evt->data.draw.clip.bottom,
278 evt->data.draw.data.bitmap.format);
279 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700280 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400281 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700282
283 case kKey_ANPEventType:
284 gLogI.log(instance, kDebug_ANPLogType, "---- %p Key action=%d"
285 " code=%d vcode=%d unichar=%d repeat=%d mods=%x", instance,
286 evt->data.key.action,
287 evt->data.key.nativeCode,
288 evt->data.key.virtualCode,
289 evt->data.key.unichar,
290 evt->data.key.repeatCount,
291 evt->data.key.modifiers);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400292 break;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400293
294 case kLifecycle_ANPEventType:
295 gLogI.log(instance, kDebug_ANPLogType, "---- %p Lifecycle action=%d",
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400296 instance, evt->data.lifecycle.action);
Mike Reed1e7c3312009-05-26 16:37:45 -0400297 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700298
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400299 case kTouch_ANPEventType:
Grace Klobafbe47c02009-05-14 17:31:45 -0700300 gLogI.log(instance, kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
301 instance, evt->data.touch.action, evt->data.touch.x,
302 evt->data.touch.y);
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400303 break;
304
305 case kVisibleRect_ANPEventType:
306 gLogI.log(instance, kDebug_ANPLogType, "---- %p VisibleRect [%d %d %d %d]",
Derek Sollenbergerf42e2f42009-06-26 11:42:46 -0400307 instance, evt->data.visibleRect.rect.left, evt->data.visibleRect.rect.top,
308 evt->data.visibleRect.rect.right, evt->data.visibleRect.rect.bottom);
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400309 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700310
311 default:
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400312 gLogI.log(instance, kError_ANPLogType, "---- %p Unknown Event [%d]",
313 instance, evt->eventType);
Grace Klobafbe47c02009-05-14 17:31:45 -0700314 break;
315 }
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400316#endif
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400317
318 if(!obj->activePlugin) {
319 gLogI.log(instance, kError_ANPLogType, "the active plugin is null.");
320 return 0; // unknown or unhandled event
321 }
322 else {
323 return obj->activePlugin->handleEvent(evt);
324 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700325}
326
327void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
328{
329
330}
331
332EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) {
333
334 if (variable == NPPVpluginNameString) {
335 const char **str = (const char **)value;
336 *str = "Test Plugin";
337 return NPERR_NO_ERROR;
338 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400339
Grace Klobafbe47c02009-05-14 17:31:45 -0700340 if (variable == NPPVpluginDescriptionString) {
341 const char **str = (const char **)value;
342 *str = "Description of Test Plugin";
343 return NPERR_NO_ERROR;
344 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400345
Grace Klobafbe47c02009-05-14 17:31:45 -0700346 return NPERR_GENERIC_ERROR;
347}
348
349NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
350{
351 if (variable == NPPVpluginScriptableNPObject) {
352 void **v = (void **)value;
353 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400354
Grace Klobafbe47c02009-05-14 17:31:45 -0700355 if (obj)
356 browser->retainobject((NPObject*)obj);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400357
Grace Klobafbe47c02009-05-14 17:31:45 -0700358 *v = obj;
359 return NPERR_NO_ERROR;
360 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400361
Grace Klobafbe47c02009-05-14 17:31:45 -0700362 return NPERR_GENERIC_ERROR;
363}
364
365NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
366{
367 return NPERR_GENERIC_ERROR;
368}
369