Rename WebKitTools to Tools
[WebKit-https.git] / Tools / DumpRenderTree / TestNetscapePlugIn / main.cpp
1 /*
2  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. 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 APPLE INC. ``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 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 "PluginObject.h"
27
28 #include "PluginTest.h"
29 #include <cstdlib>
30 #include <string>
31
32 #ifdef XP_UNIX
33 #include <X11/Xlib.h>
34 #endif
35
36 #if !defined(NP_NO_CARBON) && defined(QD_HEADERS_ARE_PRIVATE) && QD_HEADERS_ARE_PRIVATE
37 extern "C" void GlobalToLocal(Point*);
38 #endif
39
40 using namespace std;
41
42 #define CRASH() do { \
43     *(int *)(uintptr_t)0xbbadbeef = 0; \
44     ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
45 } while(false)
46
47 static bool getEntryPointsWasCalled;
48 static bool initializeWasCalled;
49
50 #if XP_WIN
51 #define STDCALL __stdcall
52
53 static inline int strcasecmp(const char* s1, const char* s2)
54 {
55     return _stricmp(s1, s2);
56 }
57
58 #else
59 #define STDCALL
60 #endif
61
62 extern "C" {
63 NPError STDCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs);
64 }
65
66 // Entry points
67 extern "C"
68 NPError STDCALL NP_Initialize(NPNetscapeFuncs *browserFuncs
69 #ifdef XP_UNIX
70                               , NPPluginFuncs *pluginFuncs
71 #endif
72                               )
73 {
74     initializeWasCalled = true;
75
76 #if XP_WIN
77     // Simulate Flash and QuickTime's behavior of crashing when NP_Initialize is called before NP_GetEntryPoints.
78     if (!getEntryPointsWasCalled)
79         CRASH();
80 #endif
81
82     browser = browserFuncs;
83
84 #ifdef XP_UNIX
85     return NP_GetEntryPoints(pluginFuncs);
86 #else
87     return NPERR_NO_ERROR;
88 #endif
89 }
90
91 extern "C"
92 NPError STDCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs)
93 {
94     getEntryPointsWasCalled = true;
95
96 #ifdef XP_MACOSX
97     // Simulate Silverlight's behavior of crashing when NP_GetEntryPoints is called before NP_Initialize.
98     if (!initializeWasCalled)
99         CRASH();
100 #endif
101
102     pluginFunctions = pluginFuncs;
103
104     pluginFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
105     pluginFuncs->size = sizeof(pluginFuncs);
106     pluginFuncs->newp = NPP_New;
107     pluginFuncs->destroy = NPP_Destroy;
108     pluginFuncs->setwindow = NPP_SetWindow;
109     pluginFuncs->newstream = NPP_NewStream;
110     pluginFuncs->destroystream = NPP_DestroyStream;
111     pluginFuncs->asfile = NPP_StreamAsFile;
112     pluginFuncs->writeready = NPP_WriteReady;
113     pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
114     pluginFuncs->print = NPP_Print;
115     pluginFuncs->event = NPP_HandleEvent;
116     pluginFuncs->urlnotify = NPP_URLNotify;
117     pluginFuncs->getvalue = NPP_GetValue;
118     pluginFuncs->setvalue = NPP_SetValue;
119     
120     return NPERR_NO_ERROR;
121 }
122
123 extern "C"
124 void STDCALL NP_Shutdown(void)
125 {
126 }
127
128 static void executeScript(const PluginObject* obj, const char* script);
129
130 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved)
131 {
132     bool forceCarbon = false;
133
134 #ifdef XP_MACOSX
135     NPEventModel eventModel;
136     
137     // Always turn on the CG model
138     NPBool supportsCoreGraphics;
139     if (browser->getvalue(instance, NPNVsupportsCoreGraphicsBool, &supportsCoreGraphics) != NPERR_NO_ERROR)
140         supportsCoreGraphics = false;
141     
142     if (!supportsCoreGraphics)
143         return NPERR_INCOMPATIBLE_VERSION_ERROR;
144
145     NPDrawingModel drawingModelToUse = NPDrawingModelCoreGraphics;
146
147     NPBool supportsCoreAnimation;
148     if (browser->getvalue(instance, NPNVsupportsCoreAnimationBool, &supportsCoreAnimation) != NPERR_NO_ERROR)
149         supportsCoreAnimation = false;
150
151 #ifndef NP_NO_CARBON
152     NPBool supportsCarbon = false;
153 #endif
154     NPBool supportsCocoa = false;
155
156 #ifndef NP_NO_CARBON
157     // A browser that doesn't know about NPNVsupportsCarbonBool is one that only supports Carbon event model.
158     if (browser->getvalue(instance, NPNVsupportsCarbonBool, &supportsCarbon) != NPERR_NO_ERROR)
159         supportsCarbon = true;
160 #endif
161
162     if (browser->getvalue(instance, NPNVsupportsCocoaBool, &supportsCocoa) != NPERR_NO_ERROR)
163         supportsCocoa = false;
164
165     if (supportsCocoa && !forceCarbon) {
166         eventModel = NPEventModelCocoa;
167 #ifndef NP_NO_CARBON
168     } else if (supportsCarbon) {
169         eventModel = NPEventModelCarbon;
170 #endif
171     } else {
172         return NPERR_INCOMPATIBLE_VERSION_ERROR;
173     }
174
175      browser->setvalue(instance, NPPVpluginEventModel, (void *)eventModel);
176 #endif // XP_MACOSX
177
178     PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
179     instance->pdata = obj;
180
181 #ifdef XP_MACOSX
182     obj->eventModel = eventModel;
183 #if !defined(BUILDING_ON_TIGER)
184     obj->coreAnimationLayer = 0;
185 #endif
186 #endif // XP_MACOSX
187
188     string testIdentifier;
189     const char* onNewScript = 0;
190     
191     for (int i = 0; i < argc; i++) {
192         if (strcasecmp(argn[i], "test") == 0)
193             testIdentifier = argv[i];
194         if (strcasecmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
195             obj->onStreamLoad = strdup(argv[i]);
196         else if (strcasecmp(argn[i], "onStreamDestroy") == 0 && !obj->onStreamDestroy)
197             obj->onStreamDestroy = strdup(argv[i]);
198         else if (strcasecmp(argn[i], "onURLNotify") == 0 && !obj->onURLNotify)
199             obj->onURLNotify = strdup(argv[i]);
200         else if (strcasecmp(argn[i], "src") == 0 &&
201                  strcasecmp(argv[i], "data:application/x-webkit-test-netscape,returnerrorfromnewstream") == 0)
202             obj->returnErrorFromNewStream = TRUE;
203         else if (strcasecmp(argn[i], "onSetWindow") == 0 && !obj->onSetWindow)
204             obj->onSetWindow = strdup(argv[i]);
205         else if (strcasecmp(argn[i], "onNew") == 0 && !onNewScript)
206             onNewScript = argv[i];
207         else if (strcasecmp(argn[i], "onPaintEvent") == 0 && !obj->onPaintEvent)
208             obj->onPaintEvent = strdup(argv[i]);
209         else if (strcasecmp(argn[i], "logfirstsetwindow") == 0)
210             obj->logSetWindow = TRUE;
211         else if (strcasecmp(argn[i], "testnpruntime") == 0)
212             testNPRuntime(instance);
213         else if (strcasecmp(argn[i], "forcecarbon") == 0)
214             forceCarbon = true;
215         else if (strcasecmp(argn[i], "logSrc") == 0) {
216             for (int i = 0; i < argc; i++)
217                 if (strcasecmp(argn[i], "src") == 0)
218                     pluginLog(instance, "src: %s", argv[i]);
219         } else if (strcasecmp(argn[i], "cleardocumentduringnew") == 0)
220             executeScript(obj, "document.body.innerHTML = ''");
221         else if (!strcasecmp(argn[i], "ondestroy"))
222             obj->onDestroy = strdup(argv[i]);
223         else if (strcasecmp(argn[i], "testwindowopen") == 0)
224             obj->testWindowOpen = TRUE;
225         else if (strcasecmp(argn[i], "drawingmodel") == 0) {
226 #if defined(XP_MACOSX) && !defined(BUILDING_ON_TIGER)
227             const char* value = argv[i];
228             if (strcasecmp(value, "coreanimation") == 0) {
229                 if (supportsCoreAnimation)
230                     drawingModelToUse = NPDrawingModelCoreAnimation;
231                 else
232                     return NPERR_INCOMPATIBLE_VERSION_ERROR;
233              } else if (strcasecmp(value, "coregraphics") == 0) {
234                 if (supportsCoreGraphics)
235                     drawingModelToUse = NPDrawingModelCoreGraphics;
236                 else
237                     return NPERR_INCOMPATIBLE_VERSION_ERROR;
238              } else
239                 return NPERR_INCOMPATIBLE_VERSION_ERROR;
240 #endif
241         } else if (strcasecmp(argn[i], "testGetURLOnDestroy") == 0) {
242 #if XP_WIN
243             // FIXME: When https://bugs.webkit.org/show_bug.cgi?id=41831 is fixed, this #ifdef can be removed.
244             obj->testGetURLOnDestroy = TRUE;
245 #endif
246         } else if (!strcasecmp(argn[i], "src") && strstr(argv[i], "plugin-document-has-focus.pl"))
247             obj->testKeyboardFocusForPlugins = TRUE;
248         else if (!strcasecmp(argn[i], "evaluatescript")) {
249             char* script = argv[i];
250             if (script == strstr(script, "mouse::")) {
251                 obj->mouseDownForEvaluateScript = true;
252                 obj->evaluateScriptOnMouseDownOrKeyDown = strdup(script + sizeof("mouse::") - 1);
253             } else if (script == strstr(script, "key::")) {
254                 obj->evaluateScriptOnMouseDownOrKeyDown = strdup(script + sizeof("key::") - 1);
255             }
256             // When testing evaluate script on mouse-down or key-down, allow event logging to handle events.
257             if (obj->evaluateScriptOnMouseDownOrKeyDown)
258                 obj->eventLogging = true;
259         }
260     }
261
262 #ifdef XP_MACOSX
263     browser->setvalue(instance, NPPVpluginDrawingModel, (void *)drawingModelToUse);
264 #if !defined(BUILDING_ON_TIGER)
265     if (drawingModelToUse == NPDrawingModelCoreAnimation)
266         obj->coreAnimationLayer = createCoreAnimationLayer();
267 #endif
268 #endif
269
270     browser->getvalue(instance, NPNVprivateModeBool, (void *)&obj->cachedPrivateBrowsingMode);
271
272     obj->pluginTest = PluginTest::create(instance, testIdentifier);
273
274 #ifdef XP_UNIX
275     // On Unix, plugins only get events if they are windowless.
276     browser->setvalue(instance, NPPVpluginWindowBool, 0);
277 #endif
278
279     if (onNewScript)
280         executeScript(obj, onNewScript);
281
282     return obj->pluginTest->NPP_New(pluginType, mode, argc, argn, argv, saved);
283 }
284
285 NPError NPP_Destroy(NPP instance, NPSavedData **save)
286 {
287     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
288     if (obj) {
289         if (obj->testGetURLOnDestroy)
290             browser->geturlnotify(obj->npp, "about:blank", "", 0);
291
292         if (obj->onDestroy) {
293             executeScript(obj, obj->onDestroy);
294             free(obj->onDestroy);
295         }
296
297         if (obj->onStreamLoad)
298             free(obj->onStreamLoad);
299
300         if (obj->onStreamDestroy)
301             free(obj->onStreamDestroy);
302
303         if (obj->onURLNotify)
304             free(obj->onURLNotify);
305
306         if (obj->onSetWindow)
307             free(obj->onSetWindow);
308
309         if (obj->onPaintEvent)
310             free(obj->onPaintEvent);
311         
312         if (obj->logDestroy)
313             pluginLog(instance, "NPP_Destroy");
314
315 #if defined(XP_MACOSX) && !defined(BUILDING_ON_TIGER)
316         if (obj->coreAnimationLayer)
317             CFRelease(obj->coreAnimationLayer);
318 #endif
319
320         obj->pluginTest->NPP_Destroy(save);
321
322         browser->releaseobject(&obj->header);
323     }
324     return NPERR_NO_ERROR;
325 }
326
327 NPError NPP_SetWindow(NPP instance, NPWindow *window)
328 {
329     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
330
331     if (obj) {
332         obj->lastWindow = *window;
333
334         if (obj->logSetWindow) {
335             pluginLog(instance, "NPP_SetWindow: %d %d", (int)window->width, (int)window->height);
336             obj->logSetWindow = FALSE;
337         }
338
339         if (obj->onSetWindow)
340             executeScript(obj, obj->onSetWindow);
341
342         if (obj->testWindowOpen) {
343             testWindowOpen(instance);
344             obj->testWindowOpen = FALSE;
345         }
346
347         if (obj->testKeyboardFocusForPlugins) {
348             obj->eventLogging = true;
349             executeScript(obj, "eventSender.keyDown('A');");
350         }
351     }
352     
353     return obj->pluginTest->NPP_SetWindow(instance, window);
354 }
355
356 static void executeScript(const PluginObject* obj, const char* script)
357 {
358     NPObject *windowScriptObject;
359     browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
360
361     NPString npScript;
362     npScript.UTF8Characters = script;
363     npScript.UTF8Length = strlen(script);
364
365     NPVariant browserResult;
366     browser->evaluate(obj->npp, windowScriptObject, &npScript, &browserResult);
367     browser->releasevariantvalue(&browserResult);
368 }
369
370 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16_t *stype)
371 {
372     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
373     obj->stream = stream;
374     *stype = NP_NORMAL;
375
376     if (obj->returnErrorFromNewStream)
377         return NPERR_GENERIC_ERROR;
378     
379     if (browser->version >= NPVERS_HAS_RESPONSE_HEADERS)
380         notifyStream(obj, stream->url, stream->headers);
381
382     if (obj->onStreamLoad)
383         executeScript(obj, obj->onStreamLoad);
384
385     return NPERR_NO_ERROR;
386 }
387
388 NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
389 {
390     PluginObject* obj = (PluginObject*)instance->pdata;
391
392     if (obj->onStreamDestroy) {
393         NPObject* windowObject = 0;
394         NPError error = browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
395         
396         if (error == NPERR_NO_ERROR) {
397             NPVariant onStreamDestroyVariant;
398             if (browser->getproperty(instance, windowObject, browser->getstringidentifier(obj->onStreamDestroy), &onStreamDestroyVariant)) {
399                 if (NPVARIANT_IS_OBJECT(onStreamDestroyVariant)) {
400                     NPObject* onStreamDestroyFunction = NPVARIANT_TO_OBJECT(onStreamDestroyVariant);
401
402                     NPVariant reasonVariant;
403                     INT32_TO_NPVARIANT(reason, reasonVariant);
404
405                     NPVariant result;
406                     browser->invokeDefault(instance, onStreamDestroyFunction, &reasonVariant, 1, &result);
407                     browser->releasevariantvalue(&result);
408                 }
409                 browser->releasevariantvalue(&onStreamDestroyVariant);
410             }
411             browser->releaseobject(windowObject);
412         }
413     }
414
415     return obj->pluginTest->NPP_DestroyStream(stream, reason);
416 }
417
418 int32_t NPP_WriteReady(NPP instance, NPStream *stream)
419 {
420     return 4096;
421 }
422
423 int32_t NPP_Write(NPP instance, NPStream *stream, int32_t offset, int32_t len, void *buffer)
424 {
425     PluginObject* obj = (PluginObject*)instance->pdata;
426
427     if (obj->returnNegativeOneFromWrite)
428         return -1;
429
430     return len;
431 }
432
433 void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
434 {
435 }
436
437 void NPP_Print(NPP instance, NPPrint *platformPrint)
438 {
439 }
440
441 #ifdef XP_MACOSX
442 #ifndef NP_NO_CARBON
443 static int16_t handleEventCarbon(NPP instance, PluginObject* obj, EventRecord* event)
444 {
445     Point pt = { event->where.v, event->where.h };
446
447     switch (event->what) {
448         case nullEvent:
449             // these are delivered non-deterministically, don't log.
450             break;
451         case mouseDown:
452             if (obj->eventLogging) {
453                 GlobalToLocal(&pt);
454                 pluginLog(instance, "mouseDown at (%d, %d)", pt.h, pt.v);
455             }
456             if (obj->evaluateScriptOnMouseDownOrKeyDown && obj->mouseDownForEvaluateScript)
457                 executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
458             break;
459         case mouseUp:
460             if (obj->eventLogging) {
461                 GlobalToLocal(&pt);
462                 pluginLog(instance, "mouseUp at (%d, %d)", pt.h, pt.v);
463             }
464             break;
465         case keyDown:
466             if (obj->eventLogging)
467                 pluginLog(instance, "keyDown '%c'", (char)(event->message & 0xFF));
468             if (obj->evaluateScriptOnMouseDownOrKeyDown && !obj->mouseDownForEvaluateScript)
469                 executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
470             break;
471         case keyUp:
472             if (obj->eventLogging)
473                 pluginLog(instance, "keyUp '%c'", (char)(event->message & 0xFF));
474             if (obj->testKeyboardFocusForPlugins) {
475                 obj->eventLogging = false;
476                 obj->testKeyboardFocusForPlugins = FALSE;
477                 executeScript(obj, "layoutTestController.notifyDone();");
478             }
479             break;
480         case autoKey:
481             if (obj->eventLogging)
482                 pluginLog(instance, "autoKey '%c'", (char)(event->message & 0xFF));
483             break;
484         case updateEvt:
485             if (obj->eventLogging)
486                 pluginLog(instance, "updateEvt");
487             break;
488         case diskEvt:
489             if (obj->eventLogging)
490                 pluginLog(instance, "diskEvt");
491             break;
492         case activateEvt:
493             if (obj->eventLogging)
494                 pluginLog(instance, "activateEvt");
495             break;
496         case osEvt:
497             if (!obj->eventLogging)
498                 break;
499             printf("PLUGIN: osEvt - ");
500             switch ((event->message & 0xFF000000) >> 24) {
501                 case suspendResumeMessage:
502                     printf("%s\n", (event->message & 0x1) ? "resume" : "suspend");
503                     break;
504                 case mouseMovedMessage:
505                     printf("mouseMoved\n");
506                     break;
507                 default:
508                     printf("%08lX\n", event->message);
509             }
510             break;
511         case kHighLevelEvent:
512             if (obj->eventLogging)
513                 pluginLog(instance, "kHighLevelEvent");
514             break;
515         // NPAPI events
516         case NPEventType_GetFocusEvent:
517             if (obj->eventLogging)
518                 pluginLog(instance, "getFocusEvent");
519             break;
520         case NPEventType_LoseFocusEvent:
521             if (obj->eventLogging)
522                 pluginLog(instance, "loseFocusEvent");
523             break;
524         case NPEventType_AdjustCursorEvent:
525             if (obj->eventLogging)
526                 pluginLog(instance, "adjustCursorEvent");
527             break;
528         default:
529             if (obj->eventLogging)
530                 pluginLog(instance, "event %d", event->what);
531     }
532     
533     return 0;
534 }
535 #endif
536
537 static int16_t handleEventCocoa(NPP instance, PluginObject* obj, NPCocoaEvent* event)
538 {
539     switch (event->type) {
540         case NPCocoaEventWindowFocusChanged:
541             
542         case NPCocoaEventFocusChanged:
543             if (obj->eventLogging) {
544                 if (event->data.focus.hasFocus)
545                     pluginLog(instance, "getFocusEvent");
546                 else
547                     pluginLog(instance, "loseFocusEvent");
548             }
549             return 1;
550
551         case NPCocoaEventDrawRect: {
552             if (obj->onPaintEvent)
553                 executeScript(obj, obj->onPaintEvent);
554             return 1;
555         }
556
557         case NPCocoaEventKeyDown:
558             if (obj->eventLogging && event->data.key.characters)
559                 pluginLog(instance, "keyDown '%c'", CFStringGetCharacterAtIndex(reinterpret_cast<CFStringRef>(event->data.key.characters), 0));
560             if (obj->evaluateScriptOnMouseDownOrKeyDown && !obj->mouseDownForEvaluateScript)
561                 executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
562             return 1;
563
564         case NPCocoaEventKeyUp:
565             if (obj->eventLogging && event->data.key.characters) {
566                 pluginLog(instance, "keyUp '%c'", CFStringGetCharacterAtIndex(reinterpret_cast<CFStringRef>(event->data.key.characters), 0));
567                 if (obj->testKeyboardFocusForPlugins) {
568                     obj->eventLogging = false;
569                     obj->testKeyboardFocusForPlugins = FALSE;
570                     executeScript(obj, "layoutTestController.notifyDone();");
571                 }
572             }
573             return 1;
574
575         case NPCocoaEventFlagsChanged:
576             return 1;
577
578         case NPCocoaEventMouseDown:
579             if (obj->eventLogging) {
580                 pluginLog(instance, "mouseDown at (%d, %d)", 
581                        (int)event->data.mouse.pluginX,
582                        (int)event->data.mouse.pluginY);
583             }
584             if (obj->evaluateScriptOnMouseDownOrKeyDown && obj->mouseDownForEvaluateScript)
585                 executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
586             return 1;
587         case NPCocoaEventMouseUp:
588             if (obj->eventLogging) {
589                 pluginLog(instance, "mouseUp at (%d, %d)", 
590                        (int)event->data.mouse.pluginX,
591                        (int)event->data.mouse.pluginY);
592             }
593             return 1;
594             
595         case NPCocoaEventMouseMoved:
596         case NPCocoaEventMouseEntered:
597         case NPCocoaEventMouseExited:
598         case NPCocoaEventMouseDragged:
599         case NPCocoaEventScrollWheel:
600         case NPCocoaEventTextInput:
601             return 1;
602     }
603     
604     return 0;
605 }
606
607 #endif // XP_MACOSX
608
609 #ifdef XP_UNIX
610 static int16_t handleEventX11(NPP instance, PluginObject* obj, XEvent* event)
611 {
612     XButtonPressedEvent* buttonPressEvent = reinterpret_cast<XButtonPressedEvent*>(event);
613     XButtonReleasedEvent* buttonReleaseEvent = reinterpret_cast<XButtonReleasedEvent*>(event);
614     switch (event->type) {
615     case ButtonPress:
616         if (obj->eventLogging)
617             pluginLog(instance, "mouseDown at (%d, %d)", buttonPressEvent->x, buttonPressEvent->y);
618         if (obj->evaluateScriptOnMouseDownOrKeyDown && obj->mouseDownForEvaluateScript)
619             executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
620         break;
621     case ButtonRelease:
622         if (obj->eventLogging)
623             pluginLog(instance, "mouseUp at (%d, %d)", buttonReleaseEvent->x, buttonReleaseEvent->y);
624         break;
625     case KeyPress:
626         // FIXME: extract key code
627         if (obj->eventLogging)
628             pluginLog(instance, "NOTIMPLEMENTED: keyDown '%c'", ' ');
629         if (obj->evaluateScriptOnMouseDownOrKeyDown && !obj->mouseDownForEvaluateScript)
630             executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
631         break;
632     case KeyRelease:
633         // FIXME: extract key code
634         if (obj->eventLogging)
635             pluginLog(instance, "NOTIMPLEMENTED: keyUp '%c'", ' ');
636         break;
637     case GraphicsExpose:
638         if (obj->eventLogging)
639             pluginLog(instance, "updateEvt");
640         break;
641     // NPAPI events
642     case FocusIn:
643         if (obj->eventLogging)
644             pluginLog(instance, "getFocusEvent");
645         break;
646     case FocusOut:
647         if (obj->eventLogging)
648             pluginLog(instance, "loseFocusEvent");
649         break;
650     case EnterNotify:
651     case LeaveNotify:
652     case MotionNotify:
653         if (obj->eventLogging)
654             pluginLog(instance, "adjustCursorEvent");
655         break;
656     default:
657         if (obj->eventLogging)
658             pluginLog(instance, "event %d", event->type);
659     }
660
661     fflush(stdout);
662     return 0;
663 }
664 #endif // XP_UNIX
665
666 int16_t NPP_HandleEvent(NPP instance, void *event)
667 {
668     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
669
670 #ifdef XP_MACOSX
671 #ifndef NP_NO_CARBON
672     if (obj->eventModel == NPEventModelCarbon)
673         return handleEventCarbon(instance, obj, static_cast<EventRecord*>(event));
674 #endif
675
676     assert(obj->eventModel == NPEventModelCocoa);
677     return handleEventCocoa(instance, obj, static_cast<NPCocoaEvent*>(event));
678 #elif defined(XP_UNIX)
679     return handleEventX11(instance, obj, static_cast<XEvent*>(event));
680 #else
681     // FIXME: Implement for other platforms.
682     return 0;
683 #endif // XP_MACOSX
684 }
685
686 void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
687 {
688     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
689  
690      if (obj->onURLNotify)
691          executeScript(obj, obj->onURLNotify);
692
693     handleCallback(obj, url, reason, notifyData);
694 }
695
696 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
697 {
698 #ifdef XP_UNIX
699     if (variable == NPPVpluginNameString) {
700         *((char **)value) = const_cast<char*>("WebKit Test PlugIn");
701         return NPERR_NO_ERROR;
702     }
703     if (variable == NPPVpluginDescriptionString) {
704         *((char **)value) = const_cast<char*>("Simple Netscape plug-in that handles test content for WebKit");
705         return NPERR_NO_ERROR;
706     }
707 #endif
708
709     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
710
711     // First, check if the PluginTest object supports getting this value.
712     if (obj->pluginTest->NPP_GetValue(variable, value) == NPERR_NO_ERROR)
713         return NPERR_NO_ERROR;
714
715     if (variable == NPPVpluginScriptableNPObject) {
716         void **v = (void **)value;
717         // Return value is expected to be retained
718         browser->retainobject((NPObject *)obj);
719         *v = obj;
720         return NPERR_NO_ERROR;
721     }
722     
723 #if defined(XP_MACOSX) && !defined(BUILDING_ON_TIGER)
724     if (variable == NPPVpluginCoreAnimationLayer) {
725         if (!obj->coreAnimationLayer)
726             return NPERR_GENERIC_ERROR;
727         
728         void **v = (void **)value;
729         *v = (void*)CFRetain(obj->coreAnimationLayer);
730         return NPERR_NO_ERROR;
731     }
732 #endif
733
734     return NPERR_GENERIC_ERROR;
735 }
736
737 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
738 {
739     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
740
741     switch (variable) {
742         case NPNVprivateModeBool:
743             obj->cachedPrivateBrowsingMode = *(NPBool*)value;
744             return NPERR_NO_ERROR;
745         default:
746             return NPERR_GENERIC_ERROR;
747     }
748 }
749
750 #ifdef XP_UNIX
751 extern "C"
752 const char* NP_GetMIMEDescription(void)
753 {
754     return "application/x-webkit-test-netscape:testnetscape:test netscape content";
755 }
756
757 extern "C"
758 NPError NP_GetValue(NPP instance, NPPVariable variable, void* value)
759 {
760     return NPP_GetValue(instance, variable, value);
761 }
762 #endif