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