1 /* 2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "config.h" 27 #include "EventNames.h" 28 #include "FocusController.h" 29 #include "FrameView.h" 30 #include "Image.h" 31 #include <wtf/java/JavaEnv.h> 32 #include "MouseEvent.h" 33 #include "NotImplemented.h" 34 #include "PluginWidgetJava.h" 35 #include "RenderBox.h" 36 #include "StringJava.h" 37 38 #include "com_sun_webkit_WCPluginWidget.h" 39 40 namespace WebCore { 41 42 jmethodID pluginWidgetPaintMID; 43 jmethodID pluginWidgetCreateMID; 44 jmethodID pluginWidgetBlurMID; 45 jmethodID pluginWidgetFWKHandleMouseEventMID; 46 jmethodID pluginWidgetFWKSetNativeContainerBoundsMID; 47 jfieldID pluginWidgetPDataFID; 48 49 /************************************************************************ 50 * WCRectangle fields 51 */ 52 53 jfieldID xFID; 54 jfieldID yFID; 55 jfieldID widthFID; 56 jfieldID heightFID; 57 jmethodID wcRectCTOR; 58 JGClass clwcRectangle; 59 60 extern "C" { 61 JNIEXPORT void JNICALL Java_com_sun_webkit_WCPluginWidget_initIDs(JNIEnv* env, jclass pluginWidgetClass) 62 { 63 pluginWidgetPaintMID = env->GetMethodID(pluginWidgetClass, "paint", 64 "(Lcom/sun/webkit/graphics/WCGraphicsContext;IIII)V"); 65 ASSERT(pluginWidgetPaintMID); 66 67 pluginWidgetCreateMID = env->GetStaticMethodID(pluginWidgetClass, "create", 68 "(Lcom/sun/webkit/WebPage;IILjava/lang/String;" 69 "Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)" 70 "Lcom/sun/webkit/WCPluginWidget;"); 71 ASSERT(pluginWidgetCreateMID); 72 73 pluginWidgetFWKSetNativeContainerBoundsMID = env->GetMethodID( 74 pluginWidgetClass, "fwkSetNativeContainerBounds", 75 "(IIII)V"); 76 ASSERT(pluginWidgetFWKSetNativeContainerBoundsMID); 77 78 pluginWidgetFWKHandleMouseEventMID = env->GetMethodID(pluginWidgetClass, 79 "fwkHandleMouseEvent", "(Ljava/lang/String;IIIIIZZZZZJ)Z"); 80 ASSERT(pluginWidgetFWKHandleMouseEventMID); 81 82 pluginWidgetPDataFID = env->GetFieldID(pluginWidgetClass, "pData", "J"); 83 ASSERT(pluginWidgetPDataFID); 84 85 86 clwcRectangle = JLClass(env->FindClass("com/sun/webkit/graphics/WCRectangle")); 87 ASSERT(clwcRectangle); 88 89 wcRectCTOR = env->GetMethodID(clwcRectangle, "<init>", "(FFFF)V"); 90 ASSERT(wcRectCTOR); 91 92 xFID = env->GetFieldID(clwcRectangle, "x", "F"); 93 ASSERT(xFID); 94 95 yFID = env->GetFieldID(clwcRectangle, "y", "F"); 96 ASSERT(yFID); 97 98 widthFID = env->GetFieldID(clwcRectangle, "w", "F"); 99 ASSERT(widthFID); 100 101 heightFID = env->GetFieldID(clwcRectangle, "h", "F"); 102 ASSERT(heightFID); 103 } 104 105 106 JNIEXPORT void JNICALL Java_com_sun_webkit_WCPluginWidget_twkInvalidateWindowlessPluginRect 107 (JNIEnv* env,jobject self, jint x, jint y, jint width, jint height) 108 { 109 PluginWidgetJava *pThis = ((PluginWidgetJava *)jlong_to_ptr(env->GetLongField(self, pluginWidgetPDataFID))); 110 if(pThis) 111 pThis->invalidateWindowlessPluginRect( IntRect(x, y, width, height) ); 112 } 113 114 JNIEXPORT void JNICALL Java_com_sun_webkit_WCPluginWidget_twkSetPlugunFocused 115 (JNIEnv* env, jobject self, jboolean isFocused) 116 { 117 PluginWidgetJava *pThis = ((PluginWidgetJava *)jlong_to_ptr(env->GetLongField(self, pluginWidgetPDataFID))); 118 if(pThis) 119 pThis->focusPluginElement( isFocused ); 120 } 121 122 JNIEXPORT jobject JNICALL Java_com_sun_webkit_WCPluginWidget_twkConvertToPage 123 (JNIEnv* env, jobject self, jobject rc) 124 { 125 PluginWidgetJava *pThis = ((PluginWidgetJava *)jlong_to_ptr(env->GetLongField(self, pluginWidgetPDataFID))); 126 if(pThis){ 127 IntRect irc( 128 (int)env->GetFloatField(rc, xFID), 129 (int)env->GetFloatField(rc, yFID), 130 (int)env->GetFloatField(rc, widthFID), 131 (int)env->GetFloatField(rc, heightFID)); 132 pThis->convertToPage(irc); 133 return env->NewObject( 134 clwcRectangle, 135 wcRectCTOR, 136 jdouble(irc.x()), 137 jdouble(irc.y()), 138 jdouble(irc.width()), 139 jdouble(irc.height())); 140 } 141 return NULL; 142 } 143 144 145 } // extern "C" 146 147 PluginWidgetJava::PluginWidgetJava( 148 jobject wfh, 149 HTMLPlugInElement* element, 150 const IntSize& size, 151 const String& url, 152 const String& mimeType, 153 const Vector<String>& paramNames, 154 const Vector<String>& paramValues) 155 : m_element(element), 156 m_url(url), 157 m_mimeType(mimeType), 158 m_size(size), 159 m_paramNames(paramNames), 160 m_paramValues(paramValues) 161 { 162 //TODO: have to be moved into setParent(non-null) 163 JNIEnv* env = WebCore_GetJavaEnv(); 164 JLString urlJavaString(url.toJavaString(env)); 165 JLString mimeTypeJavaString(mimeType.toJavaString(env)); 166 167 //better to delegate this upto org/webkit/webcore/platform/api/WebPage 168 //as for "createScrollView" 169 JLClass cls(env->FindClass("com/sun/webkit/WCPluginWidget")); 170 ASSERT(cls); 171 172 jobjectArray pNames = strVect2JArray(env, paramNames); 173 jobjectArray pValues = strVect2JArray(env, paramValues); 174 175 JLObject obj(env->CallStaticObjectMethod( 176 cls, 177 pluginWidgetCreateMID, 178 wfh, 179 size.width(), size.height(), 180 (jstring)urlJavaString, 181 (jstring)mimeTypeJavaString, 182 pNames, pValues)); 183 CheckAndClearException(env); 184 185 ASSERT(obj); 186 if (obj) { 187 setPlatformWidget(obj); 188 env->SetLongField(obj, pluginWidgetPDataFID, ptr_to_jlong(this)); 189 setSelfVisible(true); 190 setParentVisible(true); 191 } 192 } 193 194 void PluginWidgetJava::invalidateRect(const IntRect&) 195 { 196 notImplemented(); 197 } 198 199 PluginWidgetJava::~PluginWidgetJava() { 200 } 201 202 void PluginWidgetJava::paint( 203 GraphicsContext& context, 204 const IntRect& rc /*page coordinates*/, 205 SecurityOriginPaintPolicy) { 206 //Widget::paint(context, rc); 207 /* 208 if (!m_isStarted) { 209 // Draw the "missing plugin" image 210 paintMissingPluginIcon(context, rect); 211 return; 212 } 213 */ 214 if (context.paintingDisabled()) 215 return; 216 217 JLObject obj = platformWidget(); 218 if (obj){ 219 JNIEnv *env = WebCore_GetJavaEnv(); 220 context.save(); 221 env->CallVoidMethod( 222 jobject(obj), 223 pluginWidgetPaintMID, 224 context.platformContext(), 225 rc.x(), rc.y(), rc.width(), rc.height()); 226 context.restore(); 227 } 228 } 229 230 231 void PluginWidgetJava::convertToPage(IntRect&) 232 { 233 if (!isVisible()) 234 return; 235 236 if (!m_element || !m_element->renderer()) 237 return; 238 239 RenderBox* renderer = downcast<RenderBox>(m_element->renderer()); // FIXME-java: recheck 240 if(renderer){ 241 renderer->offsetFromContainer(*renderer->container(), LayoutPoint()); 242 } 243 244 } 245 246 void PluginWidgetJava::setFrameRect(const IntRect& rect) 247 { 248 if (m_element->document().printing()) 249 return; 250 251 if (rect != frameRect()) 252 Widget::setFrameRect(rect); 253 254 updatePluginWidget(); 255 } 256 257 void PluginWidgetJava::frameRectsChanged() 258 { 259 updatePluginWidget(); 260 } 261 262 void PluginWidgetJava::updatePluginWidget() 263 { 264 if (!parent()) 265 return; 266 267 ASSERT(parent()->isFrameView()); 268 269 FrameView* frameView = static_cast<FrameView*>(parent()); 270 IntRect windowRect(frameView->contentsToWindow(frameRect().location()), frameRect().size()); 271 JLObject obj = platformWidget(); 272 if(obj){ 273 JNIEnv *env = WebCore_GetJavaEnv(); 274 env->CallVoidMethod( 275 jobject(obj), 276 pluginWidgetFWKSetNativeContainerBoundsMID, 277 (jint)windowRect.x(), 278 (jint)windowRect.y(), 279 (jint)windowRect.width(), 280 (jint)windowRect.height()); 281 282 } 283 } 284 285 286 void PluginWidgetJava::invalidateWindowlessPluginRect( 287 const IntRect& rect //client coordinates 288 ){ 289 if (!isVisible()) 290 return; 291 292 if (!m_element || !m_element->renderer()) 293 return; 294 295 RenderBox* renderer = downcast<RenderBox>(m_element->renderer()); //XXX: recheck 296 if(renderer){ 297 renderer->repaintRectangle(rect); 298 } 299 } 300 301 //look at "void PluginView::focusPluginElement()" 302 void PluginWidgetJava::focusPluginElement(bool) 303 { 304 /* 305 if( isFocused ){ 306 // Focus the plugin 307 Frame *parentFrame = static_cast<FrameView*>(parent())->frame(); 308 if (Page* page = parentFrame->page()) 309 page->focusController()->setFocusedFrame(parentFrame); 310 parentFrame->document()->setFocusedNode(m_element); 311 } 312 */ 313 } 314 315 void PluginWidgetJava::handleEvent(Event& event) 316 { 317 JNIEnv* env = WebCore_GetJavaEnv(); 318 JLObject obj = platformWidget(); 319 jboolean cancelBubble = false; 320 if (obj && event.isMouseEvent()) { 321 MouseEvent* me = static_cast<MouseEvent*>(&event); 322 //look at "void PluginView::handleMouseEvent(MouseEvent* event)" 323 //takes into account zoomFactor for offsetX, offsetY 324 IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow( 325 IntPoint(me->pageX(), me->pageY())); 326 cancelBubble = env->CallBooleanMethod( 327 jobject(obj), 328 pluginWidgetFWKHandleMouseEventMID, 329 (jstring)me->type().string().toJavaString(env), 330 (jint)p.x(), 331 (jint)p.y(), 332 (jint)me->screenX(), 333 (jint)me->screenY(), 334 (jint)me->button(), 335 (jboolean)me->buttonDown(), 336 (jboolean)me->altKey(), 337 (jboolean)me->metaKey(), 338 (jboolean)me->ctrlKey(), 339 (jboolean)me->shiftKey(), 340 (jlong)me->timeStamp().approximateWallTime().secondsSinceEpoch().milliseconds()); 341 } 342 343 if(cancelBubble) { 344 event.setDefaultHandled(); 345 event.cancelBubble(); 346 } else { 347 Widget::handleEvent(event); 348 } 349 } 350 351 }