2009-06-30 Xan Lopez <xlopez@igalia.com>
[WebKit-https.git] / WebKitTools / DumpRenderTree / gtk / TestNetscapePlugin / TestNetscapePlugin.cpp
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 static void log(NPP instance, const char* format, ...)
42 {
43     va_list args;
44     va_start(args, format);
45     char message[2048] = "PLUGIN: ";
46     vsprintf(message + strlen(message), format, args);
47     va_end(args);
48
49     NPObject* windowObject = 0;
50     NPError error = browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
51     if (error != NPERR_NO_ERROR) {
52         fprintf(stderr, "Failed to retrieve window object while logging: %s\n", message);
53         return;
54     }
55
56     NPVariant consoleVariant;
57     if (!browser->getproperty(instance, windowObject, browser->getstringidentifier("console"), &consoleVariant)) {
58         fprintf(stderr, "Failed to retrieve console object while logging: %s\n", message);
59         browser->releaseobject(windowObject);
60         return;
61     }
62
63     NPObject* consoleObject = NPVARIANT_TO_OBJECT(consoleVariant);
64
65     NPVariant messageVariant;
66     STRINGZ_TO_NPVARIANT(message, messageVariant);
67
68     NPVariant result;
69     if (!browser->invoke(instance, consoleObject, browser->getstringidentifier("log"), &messageVariant, 1, &result)) {
70         fprintf(stderr, "Failed to invoke console.log while logging: %s\n", message);
71         browser->releaseobject(consoleObject);
72         browser->releaseobject(windowObject);
73         return;
74     }
75
76     browser->releasevariantvalue(&result);
77     browser->releaseobject(consoleObject);
78     browser->releaseobject(windowObject);
79 }
80
81 extern "C" {
82     NPError NP_Initialize (NPNetscapeFuncs *aMozillaVTable, NPPluginFuncs *aPluginVTable);
83     NPError NP_Shutdown(void);
84     NPError NP_GetValue(void *future, NPPVariable variable, void *value);
85     char* NP_GetMIMEDescription(void);
86 }
87
88 static NPError
89 webkit_test_plugin_new_instance(NPMIMEType mimetype,
90                                 NPP instance,
91                                 uint16_t mode,
92                                 int16_t argc,
93                                 char *argn[],
94                                 char *argv[],
95                                 NPSavedData *savedData)
96 {
97     if (browser->version >= 14) {
98         PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
99
100         for (int i = 0; i < argc; i++) {
101             if (strcasecmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
102                 obj->onStreamLoad = strdup(argv[i]);
103             else if (strcasecmp(argn[i], "onStreamDestroy") == 0 && !obj->onStreamDestroy)
104                 obj->onStreamDestroy = strdup(argv[i]);
105             else if (strcasecmp(argn[i], "onURLNotify") == 0 && !obj->onURLNotify)
106                 obj->onURLNotify = strdup(argv[i]);
107             else if (strcasecmp(argn[i], "src") == 0 &&
108                      strcasecmp(argv[i], "data:application/x-webkit-test-netscape,returnerrorfromnewstream") == 0)
109                 obj->returnErrorFromNewStream = TRUE;
110             else if (strcasecmp(argn[i], "logfirstsetwindow") == 0)
111                 obj->logSetWindow = TRUE;
112             else if (strcasecmp(argn[i], "testnpruntime") == 0)
113                 testNPRuntime(instance);
114             else if (strcasecmp(argn[i], "logSrc") == 0) {
115                 for (int i = 0; i < argc; i++)
116                     if (strcasecmp(argn[i], "src") == 0)
117                         log(instance, "src: %s", argv[i]);
118             }
119         }
120
121         instance->pdata = obj;
122     }
123
124     return NPERR_NO_ERROR;
125 }
126
127 static NPError
128 webkit_test_plugin_destroy_instance(NPP instance, NPSavedData **save)
129 {
130     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
131     if (obj) {
132         if (obj->onStreamLoad)
133             free(obj->onStreamLoad);
134
135         if (obj->onStreamDestroy)
136             free(obj->onStreamDestroy);
137
138         if (obj->onURLNotify)
139             free(obj->onURLNotify);
140
141         if (obj->logDestroy)
142             log(instance, "NPP_Destroy");
143
144         browser->releaseobject(&obj->header);
145     }
146
147     return NPERR_NO_ERROR;
148 }
149
150 static NPError
151 webkit_test_plugin_set_window(NPP instance, NPWindow *window)
152 {
153     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
154
155     if (obj) {
156         if (obj->logSetWindow) {
157             log(instance, "NPP_SetWindow: %d %d", (int)window->width, (int)window->height);
158             obj->logSetWindow = false;
159         }
160     }
161
162     return NPERR_NO_ERROR;
163 }
164
165 static void executeScript(const PluginObject* obj, const char* script)
166 {
167     NPObject *windowScriptObject;
168     browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
169
170     NPString npScript;
171     npScript.UTF8Characters = script;
172     npScript.UTF8Length = strlen(script);
173
174     NPVariant browserResult;
175     browser->evaluate(obj->npp, windowScriptObject, &npScript, &browserResult);
176     browser->releasevariantvalue(&browserResult);
177 }
178
179 static NPError
180 webkit_test_plugin_new_stream(NPP instance,
181                               NPMIMEType type,
182                               NPStream *stream,
183                               NPBool seekable,
184                               uint16* stype)
185 {
186     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
187     obj->stream = stream;
188     *stype = NP_ASFILEONLY;
189
190     if (obj->returnErrorFromNewStream)
191         return NPERR_GENERIC_ERROR;
192
193     if (browser->version >= NPVERS_HAS_RESPONSE_HEADERS)
194         notifyStream(obj, stream->url, stream->headers);
195
196     if (obj->onStreamLoad)
197         executeScript(obj, obj->onStreamLoad);
198
199     return NPERR_NO_ERROR;
200 }
201
202 static NPError
203 webkit_test_plugin_destroy_stream(NPP instance, NPStream *stream, NPError reason)
204 {
205     PluginObject* obj = (PluginObject*)instance->pdata;
206
207     if (obj->onStreamDestroy)
208         executeScript(obj, obj->onStreamDestroy);
209
210     return NPERR_NO_ERROR;
211 }
212
213 static void
214 webkit_test_plugin_stream_as_file(NPP instance, NPStream *stream, const char* fname)
215 {
216 }
217
218 static int32
219 webkit_test_plugin_write_ready(NPP instance, NPStream *stream)
220 {
221     return 0;
222 }
223
224 static int32
225 webkit_test_plugin_write(NPP instance,
226                          NPStream *stream,
227                          int32_t offset,
228                          int32_t len,
229                          void *buffer)
230 {
231     return 0;
232 }
233
234 static void
235 webkit_test_plugin_print(NPP instance, NPPrint* platformPrint)
236 {
237 }
238
239 static int16_t
240 webkit_test_plugin_handle_event(NPP instance, void* event)
241 {
242     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
243     if (!obj->eventLogging)
244         return 0;
245
246     XEvent* evt = static_cast<XEvent*>(event);
247     log(instance, "event %d", evt->type);
248
249     return 0;
250 }
251
252 static void
253 webkit_test_plugin_url_notify(NPP instance, const char* url, NPReason reason, void* notifyData)
254 {
255     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
256
257     if (obj->onURLNotify)
258         executeScript(obj, obj->onURLNotify);
259
260     handleCallback(obj, url, reason, notifyData);
261 }
262
263 static NPError
264 webkit_test_plugin_get_value(NPP instance, NPPVariable variable, void *value)
265 {
266     NPError err = NPERR_NO_ERROR;
267
268     switch (variable) {
269         case NPPVpluginNameString:
270             *((char **)value) = "WebKit Test PlugIn";
271             break;
272         case NPPVpluginDescriptionString:
273             *((char **)value) = "Simple Netscape plug-in that handles test content for WebKit";
274             break;
275         case NPPVpluginNeedsXEmbed:
276             *((NPBool *)value) = TRUE;
277             break;
278         case NPPVpluginScriptableIID:
279         case NPPVpluginScriptableInstance:
280         case NPPVpluginScriptableNPObject:
281             err = NPERR_GENERIC_ERROR;
282             break;
283         default:
284             fprintf(stderr, "Unhandled variable\n");
285             err = NPERR_GENERIC_ERROR;
286             break;
287     }
288
289     if (variable == NPPVpluginScriptableNPObject) {
290         void **v = (void **)value;
291         PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
292         browser->retainobject((NPObject *)obj);
293         *v = obj;
294         err = NPERR_NO_ERROR;
295     }
296
297     return err;
298 }
299
300 static NPError
301 webkit_test_plugin_set_value(NPP instance, NPNVariable variable, void *value)
302 {
303     return NPERR_NO_ERROR;
304 }
305
306 char *
307 NP_GetMIMEDescription(void)
308 {
309     return "application/x-webkit-test-netscape:testnetscape:test netscape content";
310 }
311
312 NPError
313 NP_Initialize (NPNetscapeFuncs *aMozillaVTable, NPPluginFuncs *aPluginVTable)
314 {
315     if (aMozillaVTable == NULL || aPluginVTable == NULL)
316         return NPERR_INVALID_FUNCTABLE_ERROR;
317
318     if ((aMozillaVTable->version >> 8) > NP_VERSION_MAJOR)
319         return NPERR_INCOMPATIBLE_VERSION_ERROR;
320
321     if (aMozillaVTable->size < sizeof (NPNetscapeFuncs))
322         return NPERR_INVALID_FUNCTABLE_ERROR;
323     if (aPluginVTable->size < sizeof (NPPluginFuncs))
324         return NPERR_INVALID_FUNCTABLE_ERROR;
325
326     browser = aMozillaVTable;
327
328         aPluginVTable->size           = sizeof (NPPluginFuncs);
329         aPluginVTable->version        = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
330         aPluginVTable->newp           = webkit_test_plugin_new_instance;
331         aPluginVTable->destroy        = webkit_test_plugin_destroy_instance;
332         aPluginVTable->setwindow      = webkit_test_plugin_set_window;
333         aPluginVTable->newstream      = webkit_test_plugin_new_stream;
334         aPluginVTable->destroystream  = webkit_test_plugin_destroy_stream;
335         aPluginVTable->asfile         = webkit_test_plugin_stream_as_file;
336         aPluginVTable->writeready     = webkit_test_plugin_write_ready;
337         aPluginVTable->write          = webkit_test_plugin_write;
338         aPluginVTable->print          = webkit_test_plugin_print;
339         aPluginVTable->event          = webkit_test_plugin_handle_event;
340         aPluginVTable->urlnotify      = webkit_test_plugin_url_notify;
341         aPluginVTable->javaClass      = NULL;
342         aPluginVTable->getvalue       = webkit_test_plugin_get_value;
343         aPluginVTable->setvalue       = webkit_test_plugin_set_value;
344
345     return NPERR_NO_ERROR;
346 }
347
348 NPError
349 NP_Shutdown(void)
350 {
351     return NPERR_NO_ERROR;
352 }
353
354 NPError
355 NP_GetValue(void *future, NPPVariable variable, void *value)
356 {
357     return webkit_test_plugin_get_value(NULL, variable, value);
358 }