Home | History | Annotate | Download | only in animation
      1 /*
      2  * Copyright 2008, 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 "AnimationPlugin.h"
     27 
     28 #include <math.h>
     29 #include <string.h>
     30 
     31 extern NPNetscapeFuncs*        browser;
     32 extern ANPLogInterfaceV0       gLogI;
     33 extern ANPCanvasInterfaceV0    gCanvasI;
     34 extern ANPPaintInterfaceV0     gPaintI;
     35 extern ANPPathInterfaceV0      gPathI;
     36 extern ANPSystemInterfaceV0    gSystemI;
     37 extern ANPWindowInterfaceV1    gWindowI;
     38 
     39 static uint16_t rnd16(float x, int inset) {
     40     int ix = (int)roundf(x) + inset;
     41     if (ix < 0) {
     42         ix = 0;
     43     }
     44     return static_cast<uint16_t>(ix);
     45 }
     46 
     47 ///////////////////////////////////////////////////////////////////////////////
     48 
     49 BallAnimation::BallAnimation(NPP inst) : SurfaceSubPlugin(inst) {
     50     //register for touch events
     51     ANPEventFlags flags = kTouch_ANPEventFlag;
     52     NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
     53     if (err != NPERR_NO_ERROR) {
     54         gLogI.log(kError_ANPLogType, "Error selecting input events.");
     55     }
     56 
     57     gLogI.log(kError_ANPLogType, "Starting Rendering Thread");
     58 
     59     //start a thread and do your drawing there
     60     m_renderingThread = new AnimationThread(inst);
     61     m_renderingThread->incStrong(inst);
     62     m_renderingThread->run("AnimationThread");
     63 }
     64 
     65 BallAnimation::~BallAnimation() {
     66     m_renderingThread->requestExitAndWait();
     67     destroySurface();
     68 }
     69 
     70 bool BallAnimation::supportsDrawingModel(ANPDrawingModel model) {
     71     return (model == kOpenGL_ANPDrawingModel);
     72 }
     73 
     74 jobject BallAnimation::getSurface() {
     75 
     76     if (m_surface) {
     77         return m_surface;
     78     }
     79 
     80     // load the appropriate java class and instantiate it
     81     JNIEnv* env = NULL;
     82     if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
     83         gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
     84         return NULL;
     85     }
     86 
     87     const char* className = "com.android.sampleplugin.AnimationSurface";
     88     jclass fullScreenClass = gSystemI.loadJavaClass(inst(), className);
     89 
     90     if(!fullScreenClass) {
     91         gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
     92         return NULL;
     93     }
     94 
     95     jmethodID constructor = env->GetMethodID(fullScreenClass, "<init>", "(Landroid/content/Context;)V");
     96     jobject fullScreenSurface = env->NewObject(fullScreenClass, constructor, m_context);
     97 
     98     if(!fullScreenSurface) {
     99         gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
    100         return NULL;
    101     }
    102 
    103     gLogI.log(kError_ANPLogType, " ---- object %p", fullScreenSurface);
    104 
    105     m_surface = env->NewGlobalRef(fullScreenSurface);
    106     return m_surface;
    107 }
    108 
    109 void BallAnimation::destroySurface() {
    110     JNIEnv* env = NULL;
    111     if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
    112         env->DeleteGlobalRef(m_surface);
    113         m_surface = NULL;
    114     }
    115 }
    116 
    117 void BallAnimation::showEntirePluginOnScreen() {
    118     NPP instance = this->inst();
    119     PluginObject *obj = (PluginObject*) instance->pdata;
    120     NPWindow *window = obj->window;
    121 
    122     // log the current visible rect
    123     ANPRectI visibleRect = gWindowI.visibleRect(instance);
    124     gLogI.log(kDebug_ANPLogType, "Current VisibleRect: (%d,%d,%d,%d)",
    125             visibleRect.left, visibleRect.top, visibleRect.right, visibleRect.bottom);
    126 
    127     ANPRectI visibleRects[1];
    128 
    129     visibleRects[0].left = 0;
    130     visibleRects[0].top = 0;
    131     visibleRects[0].right = window->width;
    132     visibleRects[0].bottom = window->height;
    133 
    134     gWindowI.setVisibleRects(instance, visibleRects, 1);
    135     gWindowI.clearVisibleRects(instance);
    136 }
    137 
    138 int16_t BallAnimation::handleEvent(const ANPEvent* evt) {
    139     NPP instance = this->inst();
    140 
    141     switch (evt->eventType) {
    142         case kDraw_ANPEventType:
    143             switch (evt->data.draw.model) {
    144                 case kOpenGL_ANPDrawingModel: {
    145                     //send the width and height to the rendering thread
    146                     int width = evt->data.draw.data.surface.width;
    147                     int height = evt->data.draw.data.surface.height;
    148                     gLogI.log(kError_ANPLogType, "New Dimensions (%d,%d)", width, height);
    149                     m_renderingThread->setDimensions(width, height);
    150                     return 1;
    151                 }
    152                 default:
    153                     return 0;   // unknown drawing model
    154             }
    155         case kTouch_ANPEventType:
    156              if (kDown_ANPTouchAction == evt->data.touch.action) {
    157                  showEntirePluginOnScreen();
    158              }
    159             else if (kDoubleTap_ANPTouchAction == evt->data.touch.action) {
    160                 browser->geturl(inst(), "javascript:alert('Detected double tap event.')", 0);
    161                 gWindowI.requestFullScreen(inst());
    162             }
    163             return 1;
    164         default:
    165             break;
    166     }
    167     return 0;   // unknown or unhandled event
    168 }
    169