Home | History | Annotate | Download | only in event
      1 /*
      2  * Copyright 2009, 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 "EventPlugin.h"
     27 #include "android_npapi.h"
     28 
     29 #include <stdio.h>
     30 #include <sys/time.h>
     31 #include <time.h>
     32 #include <math.h>
     33 #include <string.h>
     34 
     35 extern NPNetscapeFuncs*        browser;
     36 extern ANPCanvasInterfaceV0    gCanvasI;
     37 extern ANPLogInterfaceV0       gLogI;
     38 extern ANPPaintInterfaceV0     gPaintI;
     39 extern ANPTypefaceInterfaceV0  gTypefaceI;
     40 
     41 ///////////////////////////////////////////////////////////////////////////////
     42 
     43 EventPlugin::EventPlugin(NPP inst) : SubPlugin(inst) { }
     44 
     45 EventPlugin::~EventPlugin() { }
     46 
     47 void EventPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
     48 
     49     gLogI.log(kDebug_ANPLogType, " ------ %p drawing the plugin (%d,%d)",
     50               inst(), bitmap.width, bitmap.height);
     51 
     52     // get the plugin's dimensions according to the DOM
     53     PluginObject *obj = (PluginObject*) inst()->pdata;
     54     const int W = obj->window->width;
     55     const int H = obj->window->height;
     56 
     57     // compute the current zoom level
     58     const float zoomFactorW = static_cast<float>(bitmap.width) / W;
     59     const float zoomFactorH = static_cast<float>(bitmap.height) / H;
     60 
     61     // check to make sure the zoom level is uniform
     62     if (zoomFactorW + .01 < zoomFactorH && zoomFactorW - .01 > zoomFactorH)
     63         gLogI.log(kError_ANPLogType, " ------ %p zoom is out of sync (%f,%f)",
     64                   inst(), zoomFactorW, zoomFactorH);
     65 
     66     // scale the variables based on the zoom level
     67     const int fontSize = (int)(zoomFactorW * 16);
     68     const int leftMargin = (int)(zoomFactorW * 10);
     69 
     70     // create and clip a canvas
     71     ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
     72 
     73     ANPRectF clipR;
     74     clipR.left = clip.left;
     75     clipR.top = clip.top;
     76     clipR.right = clip.right;
     77     clipR.bottom = clip.bottom;
     78     gCanvasI.clipRect(canvas, &clipR);
     79 
     80     gCanvasI.drawColor(canvas, 0xFFFFFFFF);
     81 
     82     // configure the paint
     83     ANPPaint* paint = gPaintI.newPaint();
     84     gPaintI.setFlags(paint, gPaintI.getFlags(paint) | kAntiAlias_ANPPaintFlag);
     85     gPaintI.setColor(paint, 0xFF0000FF);
     86     gPaintI.setTextSize(paint, fontSize);
     87 
     88     // configure the font
     89     ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
     90     gPaintI.setTypeface(paint, tf);
     91     gTypefaceI.unref(tf);
     92 
     93     // retrieve the font metrics
     94     ANPFontMetrics fm;
     95     gPaintI.getFontMetrics(paint, &fm);
     96 
     97     // write text on the canvas
     98     const char c[] = "Browser Test Plugin";
     99     gCanvasI.drawText(canvas, c, sizeof(c)-1, leftMargin, -fm.fTop, paint);
    100 
    101     // clean up variables
    102     gPaintI.deletePaint(paint);
    103     gCanvasI.deleteCanvas(canvas);
    104 }
    105 
    106 void EventPlugin::printToDiv(const char* text, int length) {
    107     // Get the plugin's DOM object
    108     NPObject* windowObject = NULL;
    109     browser->getvalue(inst(), NPNVWindowNPObject, &windowObject);
    110 
    111     if (!windowObject)
    112         gLogI.log(kError_ANPLogType, " ------ %p Unable to retrieve DOM Window", inst());
    113 
    114     // create a string (JS code) that is stored in memory allocated by the browser
    115     const char* jsBegin = "var outputDiv = document.getElementById('eventOutput'); outputDiv.innerHTML += ' ";
    116     const char* jsEnd = "';";
    117 
    118     // allocate memory and configure pointers
    119     int totalLength = strlen(jsBegin) + length + strlen(jsEnd);
    120     char* beginMem = (char*)browser->memalloc(totalLength);
    121     char* middleMem = beginMem + strlen(jsBegin);
    122     char* endMem = middleMem + length;
    123 
    124     // copy into the allocated memory
    125     memcpy(beginMem, jsBegin, strlen(jsBegin));
    126     memcpy(middleMem, text, length);
    127     memcpy(endMem, jsEnd, strlen(jsEnd));
    128 
    129     gLogI.log(kDebug_ANPLogType, "text: %.*s\n", totalLength, (char*)beginMem);
    130 
    131     // execute the javascript in the plugin's DOM object
    132     NPString script = { (char*)beginMem, totalLength };
    133     NPVariant scriptVariant;
    134     if (!browser->evaluate(inst(), windowObject, &script, &scriptVariant))
    135         gLogI.log(kError_ANPLogType, " ------ %p Unable to eval the JS.", inst());
    136 
    137     // free the memory allocated within the browser
    138     browser->memfree(beginMem);
    139 }
    140 
    141 int16_t EventPlugin::handleEvent(const ANPEvent* evt) {
    142     switch (evt->eventType) {
    143 
    144         case kDraw_ANPEventType: {
    145             switch (evt->data.draw.model) {
    146                 case kBitmap_ANPDrawingModel:
    147                     drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
    148                     return 1;
    149                 default:
    150                     break;   // unknown drawing model
    151             }
    152         }
    153         case kLifecycle_ANPEventType:
    154             switch (evt->data.lifecycle.action) {
    155                 case kOnLoad_ANPLifecycleAction: {
    156                     char msg[] = "lifecycle-onLoad";
    157                     printToDiv(msg, strlen(msg));
    158                     break;
    159                 }
    160                 case kGainFocus_ANPLifecycleAction: {
    161                     char msg[] = "lifecycle-gainFocus";
    162                     printToDiv(msg, strlen(msg));
    163                     break;
    164                 }
    165                 case kLoseFocus_ANPLifecycleAction: {
    166                     char msg[] = "lifecycle-loseFocus";
    167                     printToDiv(msg, strlen(msg));
    168                     break;
    169                 }
    170             }
    171             return 1;
    172         case kTouch_ANPEventType:
    173             gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request touch events", inst());
    174             break;
    175         case kKey_ANPEventType:
    176             gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
    177             break;
    178         default:
    179             break;
    180     }
    181     return 0;   // unknown or unhandled event
    182 }
    183