Home | History | Annotate | Download | only in TestNetscapePlugIn.subproj
      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 #import "PluginObject.h"
     27 
     28 // Mach-o entry points
     29 extern "C" {
     30     NPError NP_Initialize(NPNetscapeFuncs *browserFuncs);
     31     NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs);
     32     void NP_Shutdown(void);
     33 }
     34 
     35 // Mach-o entry points
     36 NPError NP_Initialize(NPNetscapeFuncs *browserFuncs)
     37 {
     38     browser = browserFuncs;
     39     return NPERR_NO_ERROR;
     40 }
     41 
     42 NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs)
     43 {
     44     pluginFuncs->version = 11;
     45     pluginFuncs->size = sizeof(pluginFuncs);
     46     pluginFuncs->newp = NPP_New;
     47     pluginFuncs->destroy = NPP_Destroy;
     48     pluginFuncs->setwindow = NPP_SetWindow;
     49     pluginFuncs->newstream = NPP_NewStream;
     50     pluginFuncs->destroystream = NPP_DestroyStream;
     51     pluginFuncs->asfile = NPP_StreamAsFile;
     52     pluginFuncs->writeready = NPP_WriteReady;
     53     pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
     54     pluginFuncs->print = NPP_Print;
     55     pluginFuncs->event = NPP_HandleEvent;
     56     pluginFuncs->urlnotify = NPP_URLNotify;
     57     pluginFuncs->getvalue = NPP_GetValue;
     58     pluginFuncs->setvalue = NPP_SetValue;
     59 
     60     return NPERR_NO_ERROR;
     61 }
     62 
     63 void NP_Shutdown(void)
     64 {
     65 }
     66 
     67 static void executeScript(const PluginObject* obj, const char* script);
     68 
     69 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved)
     70 {
     71     bool forceCarbon = false;
     72 
     73     // Always turn on the CG model
     74     NPBool supportsCoreGraphics;
     75     if (browser->getvalue(instance, NPNVsupportsCoreGraphicsBool, &supportsCoreGraphics) != NPERR_NO_ERROR)
     76         supportsCoreGraphics = false;
     77 
     78     if (!supportsCoreGraphics)
     79         return NPERR_INCOMPATIBLE_VERSION_ERROR;
     80 
     81     browser->setvalue(instance, NPPVpluginDrawingModel, (void *)NPDrawingModelCoreGraphics);
     82 
     83     PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
     84     instance->pdata = obj;
     85 
     86     for (int i = 0; i < argc; i++) {
     87         if (strcasecmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
     88             obj->onStreamLoad = strdup(argv[i]);
     89         else if (strcasecmp(argn[i], "onStreamDestroy") == 0 && !obj->onStreamDestroy)
     90             obj->onStreamDestroy = strdup(argv[i]);
     91         else if (strcasecmp(argn[i], "onURLNotify") == 0 && !obj->onURLNotify)
     92             obj->onURLNotify = strdup(argv[i]);
     93         else if (strcasecmp(argn[i], "src") == 0 &&
     94                  strcasecmp(argv[i], "data:application/x-webkit-test-netscape,returnerrorfromnewstream") == 0)
     95             obj->returnErrorFromNewStream = TRUE;
     96         else if (strcasecmp(argn[i], "logfirstsetwindow") == 0)
     97             obj->logSetWindow = TRUE;
     98         else if (strcasecmp(argn[i], "testnpruntime") == 0)
     99             testNPRuntime(instance);
    100         else if (strcasecmp(argn[i], "forcecarbon") == 0)
    101             forceCarbon = true;
    102         else if (strcasecmp(argn[i], "logSrc") == 0) {
    103             for (int i = 0; i < argc; i++)
    104                 if (strcasecmp(argn[i], "src") == 0)
    105                     pluginLog(instance, "src: %s", argv[i]);
    106         } else if (strcasecmp(argn[i], "cleardocumentduringnew") == 0)
    107             executeScript(obj, "document.body.innerHTML = ''");
    108         else if (!strcasecmp(argn[i], "ondestroy"))
    109             obj->onDestroy = strdup(argv[i]);
    110         else if (strcasecmp(argn[i], "testdocumentopenindestroystream") == 0)
    111             obj->testDocumentOpenInDestroyStream = TRUE;
    112         else if (strcasecmp(argn[i], "testwindowopen") == 0)
    113             obj->testWindowOpen = TRUE;
    114     }
    115 
    116 #ifndef NP_NO_CARBON
    117     NPBool supportsCarbon = false;
    118 #endif
    119     NPBool supportsCocoa = false;
    120 
    121 #ifndef NP_NO_CARBON
    122     // A browser that doesn't know about NPNVsupportsCarbonBool is one that only supports Carbon event model.
    123     if (browser->getvalue(instance, NPNVsupportsCarbonBool, &supportsCarbon) != NPERR_NO_ERROR)
    124         supportsCarbon = true;
    125 #endif
    126 
    127     if (browser->getvalue(instance, NPNVsupportsCocoaBool, &supportsCocoa) != NPERR_NO_ERROR)
    128         supportsCocoa = false;
    129 
    130     if (supportsCocoa && !forceCarbon) {
    131         obj->eventModel = NPEventModelCocoa;
    132 #ifndef NP_NO_CARBON
    133     } else if (supportsCarbon) {
    134         obj->eventModel = NPEventModelCarbon;
    135 #endif
    136     } else {
    137         return NPERR_INCOMPATIBLE_VERSION_ERROR;
    138     }
    139 
    140     browser->getvalue(instance, NPNVprivateModeBool, (void *)&obj->cachedPrivateBrowsingMode);
    141     browser->setvalue(instance, NPPVpluginEventModel, (void *)obj->eventModel);
    142 
    143     return NPERR_NO_ERROR;
    144 }
    145 
    146 NPError NPP_Destroy(NPP instance, NPSavedData **save)
    147 {
    148     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    149     if (obj) {
    150         if (obj->onDestroy) {
    151             executeScript(obj, obj->onDestroy);
    152             free(obj->onDestroy);
    153         }
    154 
    155         if (obj->onStreamLoad)
    156             free(obj->onStreamLoad);
    157 
    158         if (obj->onStreamDestroy)
    159             free(obj->onStreamDestroy);
    160 
    161         if (obj->onURLNotify)
    162             free(obj->onURLNotify);
    163 
    164         if (obj->logDestroy)
    165             pluginLog(instance, "NPP_Destroy");
    166 
    167         browser->releaseobject(&obj->header);
    168     }
    169     return NPERR_NO_ERROR;
    170 }
    171 
    172 NPError NPP_SetWindow(NPP instance, NPWindow *window)
    173 {
    174     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    175 
    176     if (obj) {
    177         if (obj->logSetWindow) {
    178             pluginLog(instance, "NPP_SetWindow: %d %d", (int)window->width, (int)window->height);
    179             obj->logSetWindow = false;
    180         }
    181 
    182         if (obj->testWindowOpen) {
    183             testWindowOpen(instance);
    184             obj->testWindowOpen = FALSE;
    185         }
    186     }
    187 
    188     return NPERR_NO_ERROR;
    189 }
    190 
    191 static void executeScript(const PluginObject* obj, const char* script)
    192 {
    193     NPObject *windowScriptObject;
    194     browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
    195 
    196     NPString npScript;
    197     npScript.UTF8Characters = script;
    198     npScript.UTF8Length = strlen(script);
    199 
    200     NPVariant browserResult;
    201     browser->evaluate(obj->npp, windowScriptObject, &npScript, &browserResult);
    202     browser->releasevariantvalue(&browserResult);
    203 }
    204 
    205 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
    206 {
    207     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    208     obj->stream = stream;
    209     *stype = NP_ASFILEONLY;
    210 
    211     if (obj->returnErrorFromNewStream)
    212         return NPERR_GENERIC_ERROR;
    213 
    214     if (browser->version >= NPVERS_HAS_RESPONSE_HEADERS)
    215         notifyStream(obj, stream->url, stream->headers);
    216 
    217     if (obj->onStreamLoad)
    218         executeScript(obj, obj->onStreamLoad);
    219 
    220     return NPERR_NO_ERROR;
    221 }
    222 
    223 NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
    224 {
    225     PluginObject* obj = (PluginObject*)instance->pdata;
    226 
    227     if (obj->onStreamDestroy)
    228         executeScript(obj, obj->onStreamDestroy);
    229 
    230     if (obj->testDocumentOpenInDestroyStream) {
    231         testDocumentOpen(instance);
    232         obj->testDocumentOpenInDestroyStream = FALSE;
    233     }
    234 
    235     return NPERR_NO_ERROR;
    236 }
    237 
    238 int32 NPP_WriteReady(NPP instance, NPStream *stream)
    239 {
    240     return 0;
    241 }
    242 
    243 int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
    244 {
    245     return 0;
    246 }
    247 
    248 void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
    249 {
    250 }
    251 
    252 void NPP_Print(NPP instance, NPPrint *platformPrint)
    253 {
    254 }
    255 
    256 #ifndef NP_NO_CARBON
    257 static int16_t handleEventCarbon(NPP instance, PluginObject* obj, EventRecord* event)
    258 {
    259     Point pt = { event->where.v, event->where.h };
    260 
    261     switch (event->what) {
    262         case nullEvent:
    263             // these are delivered non-deterministically, don't log.
    264             break;
    265         case mouseDown:
    266             GlobalToLocal(&pt);
    267             pluginLog(instance, "mouseDown at (%d, %d)", pt.h, pt.v);
    268             break;
    269         case mouseUp:
    270             GlobalToLocal(&pt);
    271             pluginLog(instance, "mouseUp at (%d, %d)", pt.h, pt.v);
    272             break;
    273         case keyDown:
    274             pluginLog(instance, "keyDown '%c'", (char)(event->message & 0xFF));
    275             break;
    276         case keyUp:
    277             pluginLog(instance, "keyUp '%c'", (char)(event->message & 0xFF));
    278             break;
    279         case autoKey:
    280             pluginLog(instance, "autoKey '%c'", (char)(event->message & 0xFF));
    281             break;
    282         case updateEvt:
    283             pluginLog(instance, "updateEvt");
    284             break;
    285         case diskEvt:
    286             pluginLog(instance, "diskEvt");
    287             break;
    288         case activateEvt:
    289             pluginLog(instance, "activateEvt");
    290             break;
    291         case osEvt:
    292             printf("PLUGIN: osEvt - ");
    293             switch ((event->message & 0xFF000000) >> 24) {
    294                 case suspendResumeMessage:
    295                     printf("%s\n", (event->message & 0x1) ? "resume" : "suspend");
    296                     break;
    297                 case mouseMovedMessage:
    298                     printf("mouseMoved\n");
    299                     break;
    300                 default:
    301                     printf("%08lX\n", event->message);
    302             }
    303             break;
    304         case kHighLevelEvent:
    305             pluginLog(instance, "kHighLevelEvent");
    306             break;
    307         // NPAPI events
    308         case getFocusEvent:
    309             pluginLog(instance, "getFocusEvent");
    310             break;
    311         case loseFocusEvent:
    312             pluginLog(instance, "loseFocusEvent");
    313             break;
    314         case adjustCursorEvent:
    315             pluginLog(instance, "adjustCursorEvent");
    316             break;
    317         default:
    318             pluginLog(instance, "event %d", event->what);
    319     }
    320 
    321     return 0;
    322 }
    323 #endif
    324 
    325 static int16_t handleEventCocoa(NPP instance, PluginObject* obj, NPCocoaEvent* event)
    326 {
    327     switch (event->type) {
    328         case NPCocoaEventWindowFocusChanged:
    329 
    330         case NPCocoaEventFocusChanged:
    331             if (event->data.focus.hasFocus)
    332                 pluginLog(instance, "getFocusEvent");
    333             else
    334                 pluginLog(instance, "loseFocusEvent");
    335             return 1;
    336 
    337         case NPCocoaEventDrawRect:
    338             return 1;
    339 
    340         case NPCocoaEventKeyDown:
    341         case NPCocoaEventKeyUp:
    342         case NPCocoaEventFlagsChanged:
    343             return 1;
    344 
    345         case NPCocoaEventMouseDown:
    346             pluginLog(instance, "mouseDown at (%d, %d)",
    347                    (int)event->data.mouse.pluginX,
    348                    (int)event->data.mouse.pluginY);
    349             return 1;
    350         case NPCocoaEventMouseUp:
    351             pluginLog(instance, "mouseUp at (%d, %d)",
    352                    (int)event->data.mouse.pluginX,
    353                    (int)event->data.mouse.pluginY);
    354             return 1;
    355 
    356         case NPCocoaEventMouseMoved:
    357         case NPCocoaEventMouseEntered:
    358         case NPCocoaEventMouseExited:
    359         case NPCocoaEventMouseDragged:
    360         case NPCocoaEventScrollWheel:
    361         case NPCocoaEventTextInput:
    362             return 1;
    363     }
    364 
    365     return 0;
    366 }
    367 
    368 int16 NPP_HandleEvent(NPP instance, void *event)
    369 {
    370     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    371     if (!obj->eventLogging)
    372         return 0;
    373 
    374 #ifndef NP_NO_CARBON
    375     if (obj->eventModel == NPEventModelCarbon)
    376         return handleEventCarbon(instance, obj, static_cast<EventRecord*>(event));
    377 #endif
    378 
    379     assert(obj->eventModel == NPEventModelCocoa);
    380     return handleEventCocoa(instance, obj, static_cast<NPCocoaEvent*>(event));
    381 }
    382 
    383 void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
    384 {
    385     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    386 
    387      if (obj->onURLNotify)
    388          executeScript(obj, obj->onURLNotify);
    389 
    390     handleCallback(obj, url, reason, notifyData);
    391 }
    392 
    393 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
    394 {
    395     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    396 
    397     if (variable == NPPVpluginScriptableNPObject) {
    398         void **v = (void **)value;
    399         // Return value is expected to be retained
    400         browser->retainobject((NPObject *)obj);
    401         *v = obj;
    402         return NPERR_NO_ERROR;
    403     }
    404 
    405     return NPERR_GENERIC_ERROR;
    406 }
    407 
    408 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
    409 {
    410     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    411 
    412     switch (variable) {
    413         case NPNVprivateModeBool:
    414             obj->cachedPrivateBrowsingMode = *(NPBool*)value;
    415             return NPERR_NO_ERROR;
    416         default:
    417             return NPERR_GENERIC_ERROR;
    418     }
    419 }
    420