1 /*
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Zan Dobersek <zandobersek@gmail.com>
4 * Copyright (C) 2009 Holger Hans Peter Freyther
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "config.h"
29 #include "PluginObject.h"
30
31 #include "npapi.h"
32 #include "npruntime.h"
33 #include "npfunctions.h"
34
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <stdlib.h>
39 #include <X11/Xlib.h>
40
41 extern "C" {
42 NPError NP_Initialize (NPNetscapeFuncs *aMozillaVTable, NPPluginFuncs *aPluginVTable);
43 NPError NP_Shutdown(void);
44 NPError NP_GetValue(void *future, NPPVariable variable, void *value);
45 char* NP_GetMIMEDescription(void);
46 }
47
48 static NPError
webkit_test_plugin_new_instance(NPMIMEType mimetype,NPP instance,uint16_t mode,int16_t argc,char * argn[],char * argv[],NPSavedData * savedData)49 webkit_test_plugin_new_instance(NPMIMEType mimetype,
50 NPP instance,
51 uint16_t mode,
52 int16_t argc,
53 char *argn[],
54 char *argv[],
55 NPSavedData *savedData)
56 {
57 if (browser->version >= 14) {
58 PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
59
60 for (int i = 0; i < argc; i++) {
61 if (strcasecmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
62 obj->onStreamLoad = strdup(argv[i]);
63 else if (strcasecmp(argn[i], "onStreamDestroy") == 0 && !obj->onStreamDestroy)
64 obj->onStreamDestroy = strdup(argv[i]);
65 else if (strcasecmp(argn[i], "onURLNotify") == 0 && !obj->onURLNotify)
66 obj->onURLNotify = strdup(argv[i]);
67 else if (strcasecmp(argn[i], "src") == 0 &&
68 strcasecmp(argv[i], "data:application/x-webkit-test-netscape,returnerrorfromnewstream") == 0)
69 obj->returnErrorFromNewStream = TRUE;
70 else if (strcasecmp(argn[i], "logfirstsetwindow") == 0)
71 obj->logSetWindow = TRUE;
72 else if (strcasecmp(argn[i], "testnpruntime") == 0)
73 testNPRuntime(instance);
74 else if (strcasecmp(argn[i], "logSrc") == 0) {
75 for (int i = 0; i < argc; i++)
76 if (strcasecmp(argn[i], "src") == 0)
77 pluginLog(instance, "src: %s", argv[i]);
78 }
79 }
80
81 instance->pdata = obj;
82 }
83
84 return NPERR_NO_ERROR;
85 }
86
87 static NPError
webkit_test_plugin_destroy_instance(NPP instance,NPSavedData ** save)88 webkit_test_plugin_destroy_instance(NPP instance, NPSavedData **save)
89 {
90 PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
91 if (obj) {
92 if (obj->onStreamLoad)
93 free(obj->onStreamLoad);
94
95 if (obj->onStreamDestroy)
96 free(obj->onStreamDestroy);
97
98 if (obj->onURLNotify)
99 free(obj->onURLNotify);
100
101 if (obj->logDestroy)
102 pluginLog(instance, "NPP_Destroy");
103
104 browser->releaseobject(&obj->header);
105 }
106
107 return NPERR_NO_ERROR;
108 }
109
110 static NPError
webkit_test_plugin_set_window(NPP instance,NPWindow * window)111 webkit_test_plugin_set_window(NPP instance, NPWindow *window)
112 {
113 PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
114
115 if (obj) {
116 if (obj->logSetWindow) {
117 pluginLog(instance, "NPP_SetWindow: %d %d", (int)window->width, (int)window->height);
118 obj->logSetWindow = false;
119 }
120 }
121
122 return NPERR_NO_ERROR;
123 }
124
executeScript(const PluginObject * obj,const char * script)125 static void executeScript(const PluginObject* obj, const char* script)
126 {
127 NPObject *windowScriptObject;
128 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
129
130 NPString npScript;
131 npScript.UTF8Characters = script;
132 npScript.UTF8Length = strlen(script);
133
134 NPVariant browserResult;
135 browser->evaluate(obj->npp, windowScriptObject, &npScript, &browserResult);
136 browser->releasevariantvalue(&browserResult);
137 }
138
139 static NPError
webkit_test_plugin_new_stream(NPP instance,NPMIMEType type,NPStream * stream,NPBool seekable,uint16 * stype)140 webkit_test_plugin_new_stream(NPP instance,
141 NPMIMEType type,
142 NPStream *stream,
143 NPBool seekable,
144 uint16* stype)
145 {
146 PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
147 obj->stream = stream;
148 *stype = NP_ASFILEONLY;
149
150 if (obj->returnErrorFromNewStream)
151 return NPERR_GENERIC_ERROR;
152
153 if (browser->version >= NPVERS_HAS_RESPONSE_HEADERS)
154 notifyStream(obj, stream->url, stream->headers);
155
156 if (obj->onStreamLoad)
157 executeScript(obj, obj->onStreamLoad);
158
159 return NPERR_NO_ERROR;
160 }
161
162 static NPError
webkit_test_plugin_destroy_stream(NPP instance,NPStream * stream,NPError reason)163 webkit_test_plugin_destroy_stream(NPP instance, NPStream *stream, NPError reason)
164 {
165 PluginObject* obj = (PluginObject*)instance->pdata;
166
167 if (obj->onStreamDestroy)
168 executeScript(obj, obj->onStreamDestroy);
169
170 return NPERR_NO_ERROR;
171 }
172
173 static void
webkit_test_plugin_stream_as_file(NPP instance,NPStream * stream,const char * fname)174 webkit_test_plugin_stream_as_file(NPP instance, NPStream *stream, const char* fname)
175 {
176 }
177
178 static int32
webkit_test_plugin_write_ready(NPP instance,NPStream * stream)179 webkit_test_plugin_write_ready(NPP instance, NPStream *stream)
180 {
181 return 0;
182 }
183
184 static int32
webkit_test_plugin_write(NPP instance,NPStream * stream,int32_t offset,int32_t len,void * buffer)185 webkit_test_plugin_write(NPP instance,
186 NPStream *stream,
187 int32_t offset,
188 int32_t len,
189 void *buffer)
190 {
191 return 0;
192 }
193
194 static void
webkit_test_plugin_print(NPP instance,NPPrint * platformPrint)195 webkit_test_plugin_print(NPP instance, NPPrint* platformPrint)
196 {
197 }
198
199 static int16_t
webkit_test_plugin_handle_event(NPP instance,void * event)200 webkit_test_plugin_handle_event(NPP instance, void* event)
201 {
202 PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
203 if (!obj->eventLogging)
204 return 0;
205
206 XEvent* evt = static_cast<XEvent*>(event);
207 pluginLog(instance, "event %d", evt->type);
208
209 return 0;
210 }
211
212 static void
webkit_test_plugin_url_notify(NPP instance,const char * url,NPReason reason,void * notifyData)213 webkit_test_plugin_url_notify(NPP instance, const char* url, NPReason reason, void* notifyData)
214 {
215 PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
216
217 if (obj->onURLNotify)
218 executeScript(obj, obj->onURLNotify);
219
220 handleCallback(obj, url, reason, notifyData);
221 }
222
223 static NPError
webkit_test_plugin_get_value(NPP instance,NPPVariable variable,void * value)224 webkit_test_plugin_get_value(NPP instance, NPPVariable variable, void *value)
225 {
226 NPError err = NPERR_NO_ERROR;
227
228 switch (variable) {
229 case NPPVpluginNameString:
230 *((char **)value) = const_cast<char*>("WebKit Test PlugIn");
231 break;
232 case NPPVpluginDescriptionString:
233 *((char **)value) = const_cast<char*>("Simple Netscape plug-in that handles test content for WebKit");
234 break;
235 case NPPVpluginNeedsXEmbed:
236 *((NPBool *)value) = TRUE;
237 break;
238 case NPPVpluginScriptableIID:
239 case NPPVpluginScriptableInstance:
240 case NPPVpluginScriptableNPObject:
241 err = NPERR_GENERIC_ERROR;
242 break;
243 default:
244 fprintf(stderr, "Unhandled variable\n");
245 err = NPERR_GENERIC_ERROR;
246 break;
247 }
248
249 if (variable == NPPVpluginScriptableNPObject) {
250 void **v = (void **)value;
251 PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
252 browser->retainobject((NPObject *)obj);
253 *v = obj;
254 err = NPERR_NO_ERROR;
255 }
256
257 return err;
258 }
259
260 static NPError
webkit_test_plugin_set_value(NPP instance,NPNVariable variable,void * value)261 webkit_test_plugin_set_value(NPP instance, NPNVariable variable, void *value)
262 {
263 return NPERR_NO_ERROR;
264 }
265
266 char *
NP_GetMIMEDescription(void)267 NP_GetMIMEDescription(void)
268 {
269 return const_cast<char*>("application/x-webkit-test-netscape:testnetscape:test netscape content");
270 }
271
272 NPError
NP_Initialize(NPNetscapeFuncs * aMozillaVTable,NPPluginFuncs * aPluginVTable)273 NP_Initialize (NPNetscapeFuncs *aMozillaVTable, NPPluginFuncs *aPluginVTable)
274 {
275 if (aMozillaVTable == NULL || aPluginVTable == NULL)
276 return NPERR_INVALID_FUNCTABLE_ERROR;
277
278 if ((aMozillaVTable->version >> 8) > NP_VERSION_MAJOR)
279 return NPERR_INCOMPATIBLE_VERSION_ERROR;
280
281 if (aPluginVTable->size < sizeof (NPPluginFuncs))
282 return NPERR_INVALID_FUNCTABLE_ERROR;
283
284 browser = aMozillaVTable;
285
286 aPluginVTable->size = sizeof (NPPluginFuncs);
287 aPluginVTable->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
288 aPluginVTable->newp = webkit_test_plugin_new_instance;
289 aPluginVTable->destroy = webkit_test_plugin_destroy_instance;
290 aPluginVTable->setwindow = webkit_test_plugin_set_window;
291 aPluginVTable->newstream = webkit_test_plugin_new_stream;
292 aPluginVTable->destroystream = webkit_test_plugin_destroy_stream;
293 aPluginVTable->asfile = webkit_test_plugin_stream_as_file;
294 aPluginVTable->writeready = webkit_test_plugin_write_ready;
295 aPluginVTable->write = webkit_test_plugin_write;
296 aPluginVTable->print = webkit_test_plugin_print;
297 aPluginVTable->event = webkit_test_plugin_handle_event;
298 aPluginVTable->urlnotify = webkit_test_plugin_url_notify;
299 aPluginVTable->javaClass = NULL;
300 aPluginVTable->getvalue = webkit_test_plugin_get_value;
301 aPluginVTable->setvalue = webkit_test_plugin_set_value;
302
303 return NPERR_NO_ERROR;
304 }
305
306 NPError
NP_Shutdown(void)307 NP_Shutdown(void)
308 {
309 return NPERR_NO_ERROR;
310 }
311
312 NPError
NP_GetValue(void * future,NPPVariable variable,void * value)313 NP_GetValue(void *future, NPPVariable variable, void *value)
314 {
315 return webkit_test_plugin_get_value(NULL, variable, value);
316 }
317