• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2009, The Android Open Source Project
3  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #define LOG_TAG "WebCore"
28 
29 #include "config.h"
30 #include "PluginView.h"
31 
32 #include "Document.h"
33 #include "Element.h"
34 #include "EventNames.h"
35 #include "FocusController.h"
36 #include "FrameLoader.h"
37 #include "FrameLoadRequest.h"
38 #include "FrameTree.h"
39 #include "Frame.h"
40 #include "FrameView.h"
41 #include "GraphicsContext.h"
42 #include "HTMLNames.h"
43 #include "HTMLPlugInElement.h"
44 #include "Image.h"
45 #include "KeyboardEvent.h"
46 #include "MIMETypeRegistry.h"
47 #include "MouseEvent.h"
48 #include "NetworkStateNotifier.h"
49 #include "NotImplemented.h"
50 #include "Page.h"
51 #include "PlatformGraphicsContext.h"
52 #include "PlatformKeyboardEvent.h"
53 #include "PluginMainThreadScheduler.h"
54 #include "PluginPackage.h"
55 #include "Touch.h"
56 #include "TouchEvent.h"
57 #include "TouchList.h"
58 #include "SkCanvas.h"
59 #include "npruntime_impl.h"
60 // #include "runtime_root.h"
61 #include "utils/SystemClock.h"
62 #include "ScriptController.h"
63 #include "Settings.h"
64 
65 #include <wtf/ASCIICType.h>
66 // #include "runtime.h"
67 #include "WebViewCore.h"
68 
69 /* Controls the printing of log messages in this file. This must be defined
70    before PluginDebugAndroid.h is included.
71  */
72 // #define PLUGIN_DEBUG_LOCAL
73 #define TRACE_KEY_EVENTS 0
74 
75 #include "PluginDebug.h"
76 #include "PluginDebugAndroid.h"
77 #include "PluginViewBridgeAndroid.h"
78 #include "PluginWidgetAndroid.h"
79 
80 #include "android_npapi.h"
81 #include "ANPNativeWindow_npapi.h"
82 #include "ANPSurface_npapi.h"
83 #include "ANPSystem_npapi.h"
84 #include "ANPVideo_npapi.h"
85 #include "SkANP.h"
86 #include "SkFlipPixelRef.h"
87 
88 ///////////////////////////////////////////////////////////////////////////////
89 
90 extern void ANPAudioTrackInterfaceV0_Init(ANPInterface* value);
91 extern void ANPAudioTrackInterfaceV1_Init(ANPInterface* value);
92 extern void ANPBitmapInterfaceV0_Init(ANPInterface* value);
93 extern void ANPCanvasInterfaceV0_Init(ANPInterface* value);
94 extern void ANPEventInterfaceV0_Init(ANPInterface* value);
95 extern void ANPLogInterfaceV0_Init(ANPInterface* value);
96 extern void ANPMatrixInterfaceV0_Init(ANPInterface* value);
97 extern void ANPOffscreenInterfaceV0_Init(ANPInterface* value);
98 extern void ANPPaintInterfaceV0_Init(ANPInterface* value);
99 extern void ANPPathInterfaceV0_Init(ANPInterface* value);
100 extern void ANPSurfaceInterfaceV0_Init(ANPInterface* value);
101 extern void ANPTypefaceInterfaceV0_Init(ANPInterface* value);
102 extern void ANPWindowInterfaceV0_Init(ANPInterface* value);
103 extern void ANPWindowInterfaceV1_Init(ANPInterface* value);
104 extern void ANPWindowInterfaceV2_Init(ANPInterface* value);
105 extern void ANPSystemInterfaceV0_Init(ANPInterface* value);
106 extern void ANPSystemInterfaceV1_Init(ANPInterface* value);
107 extern void ANPSystemInterfaceV2_Init(ANPInterface* value);
108 extern void ANPNativeWindowInterfaceV0_Init(ANPInterface* value);
109 extern void ANPVideoInterfaceV0_Init(ANPInterface* value);
110 extern void ANPVideoInterfaceV1_Init(ANPInterface* value);
111 
112 struct VarProcPair {
113     int         enumValue;
114     size_t      size;
115     void        (*proc)(ANPInterface*);
116 };
117 
118 #define VARPROCLINE(name)   \
119     k##name##_ANPGetValue, sizeof(ANP##name), ANP##name##_Init
120 
121 static const VarProcPair gVarProcs[] = {
122     { VARPROCLINE(AudioTrackInterfaceV0)    },
123     { VARPROCLINE(AudioTrackInterfaceV1)    },
124     { VARPROCLINE(BitmapInterfaceV0)        },
125     { VARPROCLINE(CanvasInterfaceV0)        },
126     { VARPROCLINE(EventInterfaceV0)         },
127     { VARPROCLINE(LogInterfaceV0)           },
128     { VARPROCLINE(MatrixInterfaceV0)        },
129     { VARPROCLINE(PaintInterfaceV0)         },
130     { VARPROCLINE(PathInterfaceV0)          },
131     { VARPROCLINE(SurfaceInterfaceV0)       },
132     { VARPROCLINE(TypefaceInterfaceV0)      },
133     { VARPROCLINE(WindowInterfaceV0)        },
134     { VARPROCLINE(WindowInterfaceV1)        },
135     { VARPROCLINE(WindowInterfaceV2)        },
136     { VARPROCLINE(SystemInterfaceV0)        },
137     { VARPROCLINE(SystemInterfaceV1)        },
138     { VARPROCLINE(SystemInterfaceV2)        },
139     { VARPROCLINE(NativeWindowInterfaceV0)  },
140     { VARPROCLINE(VideoInterfaceV0)         },
141     { VARPROCLINE(VideoInterfaceV1)         },
142 };
143 
144 /*  return true if var was an interface request (error will be set accordingly)
145     return false if var is not a recognized interface (and ignore error param)
146  */
anp_getInterface(NPNVariable var,void * value,NPError * error)147 static bool anp_getInterface(NPNVariable var, void* value, NPError* error) {
148     const VarProcPair* iter = gVarProcs;
149     const VarProcPair* stop = gVarProcs + SK_ARRAY_COUNT(gVarProcs);
150     while (iter < stop) {
151         if (iter->enumValue == var) {
152             ANPInterface* i = reinterpret_cast<ANPInterface*>(value);
153             if (i->inSize < iter->size) {
154                 SkDebugf("------- interface %d, expected size %d, allocated %d\n",
155                          var, iter->size, i->inSize);
156                 *error = NPERR_INCOMPATIBLE_VERSION_ERROR;
157             } else {
158                 iter->proc(i);
159                 *error = NPERR_NO_ERROR;
160             }
161             return true;
162         }
163         iter += 1;
164     }
165     SkDebugf("------ unknown NPNVariable %d\n", var);
166     return false;
167 }
168 
169 ///////////////////////////////////////////////////////////////////////////////
170 
171 using std::min;
172 
173 using namespace WTF;
174 
175 namespace WebCore {
176 
177 using namespace HTMLNames;
178 
platformInit()179 void PluginView::platformInit()
180 {
181     setPlatformWidget(new PluginViewBridgeAndroid());
182 
183     m_isWindowed = false;   // we don't support windowed yet
184 
185     m_window = new PluginWidgetAndroid(this);
186 
187     m_npWindow.type = NPWindowTypeDrawable;
188     m_npWindow.window = 0;
189 }
190 
platformStart()191 bool PluginView::platformStart()
192 {
193     return true;
194 }
195 
platformDestroy()196 void PluginView::platformDestroy()
197 {
198     delete m_window;
199 }
200 
platformLayer() const201 PlatformLayer* PluginView::platformLayer() const
202 {
203     return (PlatformLayer*) m_window->getLayer();
204 }
205 
206 #if ENABLE(TOUCH_EVENTS)
handleTouchEvent(TouchEvent * event)207 void PluginView::handleTouchEvent(TouchEvent* event)
208 {
209     if (!m_window->isAcceptingEvent(kTouch_ANPEventFlag))
210         return;
211 
212     if (!m_window->inFullScreen() && m_parentFrame->document()->focusedNode() != m_element)
213         return;
214 
215     ANPEvent evt;
216     SkANP::InitEvent(&evt, kMultiTouch_ANPEventType);
217 
218     const AtomicString& type = event->type();
219     if (eventNames().touchstartEvent == type)
220         evt.data.multiTouch.action = kDown_ANPTouchAction;
221     else if (eventNames().touchendEvent == type)
222         evt.data.multiTouch.action = kUp_ANPTouchAction;
223     else if (eventNames().touchmoveEvent == type)
224         evt.data.multiTouch.action = kMove_ANPTouchAction;
225     else if (eventNames().touchcancelEvent == type)
226         evt.data.multiTouch.action = kCancel_ANPTouchAction;
227     else if (eventNames().touchlongpressEvent == type)
228         evt.data.multiTouch.action = kLongPress_ANPTouchAction;
229     else if (eventNames().touchdoubletapEvent == type)
230         evt.data.multiTouch.action = kDoubleTap_ANPTouchAction;
231     else
232         return;
233 
234     // set the id and timestamp
235     evt.data.multiTouch.id = 0; // TODO
236     evt.data.multiTouch.timestamp = 0; // TODO
237 
238     // In the event of a touchend (up) or touchcancel event, we must ask the changedTouch for the
239     // co-ordinates as there is no touch in touches anymore.
240     TouchList* touches = (evt.data.multiTouch.action == kUp_ANPTouchAction
241         || evt.data.multiTouch.action == kCancel_ANPTouchAction) ? event->changedTouches() : event->touches();
242 
243     // set each touchPoint
244     int pointerCount = touches->length();
245     evt.data.multiTouch.pointerCount = pointerCount;
246     evt.data.multiTouch.touchPoint = new TouchPoint[pointerCount];
247 
248     for (int x = 0; x < evt.data.multiTouch.pointerCount; x++) {
249         Touch* touch = touches->item(x);
250         // Convert to coordinates that are relative to the plugin.
251         IntPoint localPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(IntPoint(touch->pageX(), touch->pageY())));
252 
253         evt.data.multiTouch.touchPoint[x].id = touch->identifier();
254         evt.data.multiTouch.touchPoint[x].x = localPos.x();
255         evt.data.multiTouch.touchPoint[x].y = localPos.y();
256         evt.data.multiTouch.touchPoint[x].pressure = 1; // TODO
257         evt.data.multiTouch.touchPoint[x].size = 1; // TODO
258     }
259 
260     if (m_window->sendEvent(evt))
261         event->preventDefault();
262 
263     // cleanup the touch points we allocated
264     delete[] evt.data.multiTouch.touchPoint;
265 }
266 #endif
267 
handleMouseEvent(MouseEvent * event)268 void PluginView::handleMouseEvent(MouseEvent* event)
269 {
270     const AtomicString& type = event->type();
271     bool isUp = (eventNames().mouseupEvent == type);
272     bool isDown = (eventNames().mousedownEvent == type);
273 
274     ANPEvent    evt;
275 
276     if (isUp || isDown) {
277         SkANP::InitEvent(&evt, kMouse_ANPEventType);
278         evt.data.mouse.action = isUp ? kUp_ANPMouseAction : kDown_ANPMouseAction;
279 
280         // Convert to coordinates that are relative to the plugin.
281         IntPoint localPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(event->absoluteLocation()));
282         evt.data.mouse.x = localPos.x();
283         evt.data.mouse.y = localPos.y();
284 
285         if (isDown) {
286             // The plugin needs focus to receive keyboard and touch events
287             m_element->focus();
288             event->setDefaultHandled();
289         }
290     }
291     else {
292       return;
293     }
294 
295     if (m_window->sendEvent(evt)) {
296         event->setDefaultHandled();
297     }
298 }
299 
make_modifiers(bool shift,bool alt)300 static ANPKeyModifier make_modifiers(bool shift, bool alt) {
301     ANPKeyModifier mod = 0;
302     if (shift) {
303         mod |= kShift_ANPKeyModifier;
304     }
305     if (alt) {
306         mod |= kAlt_ANPKeyModifier;
307     }
308     return mod;
309 }
310 
handleFocusEvent(bool hasFocus)311 void PluginView::handleFocusEvent(bool hasFocus)
312 {
313     ANPEvent evt;
314     SkANP::InitEvent(&evt, kLifecycle_ANPEventType);
315     evt.data.lifecycle.action = hasFocus ? kGainFocus_ANPLifecycleAction :
316                                            kLoseFocus_ANPLifecycleAction;
317     m_window->sendEvent(evt);
318 
319     // redraw the plugin which subsequently invalidates the nav cache
320     IntRect rect = IntRect(m_npWindow.x, m_npWindow.y,
321                            m_npWindow.width, m_npWindow.height);
322     m_window->webViewCore()->contentInvalidate(rect);
323 }
324 
handleKeyboardEvent(KeyboardEvent * event)325 void PluginView::handleKeyboardEvent(KeyboardEvent* event)
326 {
327     if (!m_window->isAcceptingEvent(kKey_ANPEventFlag))
328         return;
329 
330     const PlatformKeyboardEvent* pke = event->keyEvent();
331     if (NULL == pke) {
332         return;
333     }
334 
335     bool ignoreEvent = false;
336 
337     ANPEvent evt;
338     SkANP::InitEvent(&evt, kKey_ANPEventType);
339 
340     switch (pke->type()) {
341         case PlatformKeyboardEvent::KeyDown:
342 #if TRACE_KEY_EVENTS
343             PLUGIN_LOG("--------- KeyDown, ignore\n");
344 #endif
345             ignoreEvent = true;
346             break;
347         case PlatformKeyboardEvent::RawKeyDown:
348             evt.data.key.action = kDown_ANPKeyAction;
349             break;
350         case PlatformKeyboardEvent::Char:
351 #if TRACE_KEY_EVENTS
352             PLUGIN_LOG("--------- Char, ignore\n");
353 #endif
354             ignoreEvent = true;
355             break;
356         case PlatformKeyboardEvent::KeyUp:
357             evt.data.key.action = kUp_ANPKeyAction;
358             break;
359         default:
360 #if TRACE_KEY_EVENTS
361             PLUGIN_LOG("------ unexpected keyevent type %d\n", pke->type());
362 #endif
363             ignoreEvent = true;
364             break;
365     }
366 
367     /* the plugin should be the only party able to return nav control to the
368      * browser UI. Therefore, if we discard an event on behalf of the plugin
369      * we should mark the event as being handled.
370      */
371     if (ignoreEvent) {
372         int keyCode = pke->nativeVirtualKeyCode();
373         if (keyCode >= kDpadUp_ANPKeyCode && keyCode <= kDpadCenter_ANPKeyCode)
374             event->setDefaultHandled();
375         return;
376     }
377 
378     evt.data.key.nativeCode = pke->nativeVirtualKeyCode();
379     evt.data.key.virtualCode = pke->windowsVirtualKeyCode();
380     evt.data.key.repeatCount = pke->repeatCount();
381     evt.data.key.modifiers = make_modifiers(pke->shiftKey(), pke->altKey());
382     evt.data.key.unichar = pke->unichar();
383 
384     if (m_window->sendEvent(evt)) {
385         event->setDefaultHandled();
386     } else if (m_window->inFullScreen()){
387         // while in the full screen mode, always consumes the key events and
388         // keeps the document focus
389         event->setDefaultHandled();
390     } else {
391         // remove the plugin from the document's focus
392         m_parentFrame->document()->focusedNodeRemoved();
393     }
394 }
395 
handlePostReadFile(Vector<char> & buffer,uint32_t len,const char * buf)396 NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf)
397 {
398     notImplemented();
399     return NPERR_GENERIC_ERROR;
400 }
401 
platformGetValueStatic(NPNVariable variable,void * value,NPError * result)402 bool PluginView::platformGetValueStatic(NPNVariable variable, void* value, NPError* result)
403 {
404     // our interface query is valid with no NPP instance
405     *result = NPERR_GENERIC_ERROR;
406 
407     switch ((int)variable) {
408         case NPNVisOfflineBool: {
409             if (value != NULL) {
410                 bool* retValue = static_cast<bool*>(value);
411                 *retValue = !networkStateNotifier().onLine();
412                 *result = NPERR_NO_ERROR;
413                 return true;
414             }
415             break;
416         }
417         case kJavaContext_ANPGetValue: {
418             jobject* retObject = static_cast<jobject*>(value);
419             *retObject = android::WebViewCore::getApplicationContext();
420             *result = NPERR_NO_ERROR;
421             return true;
422         }
423         default:
424             break; // do nothing
425     }
426 
427     (void)anp_getInterface(variable, value, result);
428     return true;
429 }
430 
setParent(ScrollView * parent)431 void PluginView::setParent(ScrollView* parent)
432 {
433     PLUGIN_LOG("--%p SetParent old=[%p], new=[%p] \n", instance(), this->parent(), parent);
434 
435     Widget::setParent(parent);
436 
437     if (parent) {
438         // the widget needs initialized now so that the plugin has access to
439         // WebViewCore when NPP_New is called
440         if (m_window && !m_window->webViewCore()) {
441             android::WebViewCore* c = android::WebViewCore::getWebViewCore(this->parent());
442             m_window->init(c);
443         }
444         init();
445 
446         /* Our widget needs to recompute its m_windowRect which then sets
447            the NPWindowRect if necessary.  This ensures that if NPWindowRect
448            is set prior to parent() being set that we still (1) notify the
449            plugin of its current rect and (2) that we execute our logic in
450            PluginWidgetAndroid in response to changes to NPWindowRect.
451          */
452         updatePluginWidget();
453     }
454 }
455 
setNPWindowRect(const IntRect &)456 void PluginView::setNPWindowRect(const IntRect&)
457 {
458     setNPWindowIfNeeded();
459 }
460 
setNPWindowIfNeeded()461 void PluginView::setNPWindowIfNeeded()
462 {
463     PLUGIN_LOG("--%p SetWindow isStarted=[%d] \n", instance(), m_isStarted);
464 
465     if (!m_isStarted || !parent())
466         return;
467 
468     // in Android, plugin always get the setwindow() in the page coordinate.
469 
470     // the m_npWindow is relative to the page
471     m_npWindow.x = m_pageRect.x();
472     m_npWindow.y = m_pageRect.y();
473     m_npWindow.width = m_pageRect.width();
474     m_npWindow.height = m_pageRect.height();
475 
476     m_npWindow.clipRect.left = m_pageRect.x();
477     m_npWindow.clipRect.top = m_pageRect.y();
478     m_npWindow.clipRect.right = m_pageRect.x() + m_pageRect.width();
479     m_npWindow.clipRect.bottom = m_pageRect.y() + m_pageRect.height();
480 
481     if (m_plugin->pluginFuncs()->setwindow) {
482         setCallingPlugin(true);
483         m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
484         setCallingPlugin(false);
485     }
486 
487     m_window->setWindow(&m_npWindow, m_isTransparent);
488 }
489 
platformGetValue(NPNVariable variable,void * value,NPError * result)490 bool PluginView::platformGetValue(NPNVariable variable, void* value, NPError* result)
491 {
492     switch ((int)variable) {
493         case NPNVWindowNPObject: {
494             NPObject* windowScriptObject =
495                     m_parentFrame->script()->windowScriptNPObject();
496 
497             // Return value is expected to be retained, as described
498             // here:
499             // <http://www.mozilla.org/projects/plugin/npruntime.html>
500             if (windowScriptObject)
501                 _NPN_RetainObject(windowScriptObject);
502 
503             void** v = (void**)value;
504             *v = windowScriptObject;
505 
506             *result = NPERR_NO_ERROR;
507             return true;
508         }
509 
510         case NPNVPluginElementNPObject: {
511             NPObject* pluginScriptObject = 0;
512 
513             if (m_element->hasTagName(appletTag) ||
514                 m_element->hasTagName(embedTag) ||
515                 m_element->hasTagName(objectTag)) {
516                 HTMLPlugInElement* pluginElement =
517                         static_cast<HTMLPlugInElement*>(m_element);
518                 pluginScriptObject = pluginElement->getNPObject();
519             }
520 
521             // Return value is expected to be retained, as described
522             // here:
523             // <http://www.mozilla.org/projects/plugin/npruntime.html>
524             if (pluginScriptObject)
525                 _NPN_RetainObject(pluginScriptObject);
526 
527             void** v = (void**)value;
528             *v = pluginScriptObject;
529 
530            *result = NPERR_NO_ERROR;
531             return true;
532         }
533 
534         case NPNVnetscapeWindow: {
535             // Return the top level WebView Java object associated
536             // with this instance.
537             jobject *retObject = static_cast<jobject*>(value);
538             // TODO: Is it safe for this to be NULL? It looks from the NPNVWindowNPObject case that it is.
539             *retObject = android::WebViewCore::getWebViewCore(parent())->getWebViewJavaObject();
540             *result = NPERR_NO_ERROR;
541             return true;
542         }
543 
544         case NPNVisOfflineBool: {
545             if (value == NULL) {
546               *result = NPERR_GENERIC_ERROR;
547               return true;
548             }
549             bool* retValue = static_cast<bool*>(value);
550             *retValue = !networkStateNotifier().onLine();
551             *result = NPERR_NO_ERROR;
552             return true;
553         }
554 
555         case kSupportedDrawingModel_ANPGetValue: {
556             uint32_t* bits = reinterpret_cast<uint32_t*>(value);
557             *bits = kBitmap_ANPDrawingModel & kSurface_ANPDrawingModel;
558             *result = NPERR_NO_ERROR;
559             return true;
560         }
561 
562         case kJavaContext_ANPGetValue: {
563             jobject* retObject = static_cast<jobject*>(value);
564             // TODO: Is it safe for this to be NULL? It looks from the NPNVWindowNPObject case that it is.
565             *retObject = android::WebViewCore::getWebViewCore(parent())->getContext();
566             *result = NPERR_NO_ERROR;
567             return true;
568         }
569 
570         default: {
571             NPError error = NPERR_GENERIC_ERROR;
572             (void)anp_getInterface(variable, value, &error);
573             *result = error;
574             return true;
575         }
576     }
577 }
578 
platformSetValue(NPPVariable variable,void * value)579 NPError PluginView::platformSetValue(NPPVariable variable, void* value)
580 {
581     NPError error = NPERR_GENERIC_ERROR;
582 
583     switch ((int)variable) {
584         case kRequestDrawingModel_ANPSetValue: {
585             ANPDrawingModel model = reinterpret_cast<ANPDrawingModel>(value);
586             if (m_window->setDrawingModel(model))
587                 error = NPERR_NO_ERROR;
588             break;
589         }
590         case kAcceptEvents_ANPSetValue : {
591             if(value) {
592                 ANPEventFlags flags = *reinterpret_cast<ANPEventFlags*>(value);
593                 m_window->updateEventFlags(flags);
594                 error = NPERR_NO_ERROR;
595             }
596             break;
597         }
598         default:
599             break;
600     }
601     return error;
602 }
603 
invalidateRect(const IntRect & r)604 void PluginView::invalidateRect(const IntRect& r)
605 {
606     m_window->inval(r, true);
607 }
608 
invalidateRect(NPRect * rect)609 void PluginView::invalidateRect(NPRect* rect)
610 {
611     IntRect r;
612 
613     if (rect) {
614         r = IntRect(rect->left, rect->top,
615                     rect->right - rect->left, rect->bottom - rect->top);
616     } else {
617         r = IntRect(0, 0, m_npWindow.width, m_npWindow.height);
618     }
619 
620     m_window->inval(r, true);
621 }
622 
invalidateRegion(NPRegion region)623 void PluginView::invalidateRegion(NPRegion region)
624 {
625     // we don't support/define regions (yet), so do nothing
626 }
627 
forceRedraw()628 void PluginView::forceRedraw()
629 {
630     this->invalidateRect(0);
631 }
632 
setFocus(bool focused)633 void PluginView::setFocus(bool focused)
634 {
635     Widget::setFocus(focused);
636 //    SkDebugf("------------- setFocus %p\n", this);
637 }
638 
show()639 void PluginView::show()
640 {
641     setSelfVisible(true);
642     Widget::show();
643 
644     if (platformPluginWidget())
645         platformPluginWidget()->layoutSurface();
646 
647 }
648 
hide()649 void PluginView::hide()
650 {
651     setSelfVisible(false);
652     Widget::hide();
653 
654    if (platformPluginWidget())
655         platformPluginWidget()->layoutSurface();
656 }
657 
setParentVisible(bool visible)658 void PluginView::setParentVisible(bool visible) {
659 
660     if (isParentVisible() == visible)
661         return;
662 
663     Widget::setParentVisible(visible);
664 
665     if (platformPluginWidget())
666         platformPluginWidget()->layoutSurface();
667 
668 }
669 
paint(GraphicsContext * context,const IntRect & rect)670 void PluginView::paint(GraphicsContext* context, const IntRect& rect)
671 {
672     if (!m_isStarted) {
673         // Draw the "missing plugin" image
674         paintMissingPluginIcon(context, rect);
675         return;
676     }
677 
678     IntRect frame = frameRect();
679     if (!frame.width() || !frame.height()) {
680         PLUGIN_LOG("--%p FrameRect Dimensions are (0,0).\n", instance());
681         return;
682     }
683 
684     if (m_window->isSurfaceDrawingModel()) {
685         /* the document position of the frame (e.g. iFrame) containing the
686            surface may have changed, which requires us to to update the global
687            coordinates of the surface. This is necessary because the plugin has
688            not moved within its parent frame and therefore will not get any
689            notification of its global position change.
690          */
691         updatePluginWidget();
692         m_window->setSurfaceClip(context->platformContext()->getTotalClipBounds());
693     } else {
694         m_window->inval(rect, false);
695         context->save();
696         context->translate(frame.x(), frame.y());
697         m_window->draw(context->platformContext());
698         context->restore();
699     }
700 
701 
702 }
703 
updatePluginWidget()704 void PluginView::updatePluginWidget()
705 {
706     FrameView* frameView = static_cast<FrameView*>(parent());
707     PLUGIN_LOG("--%p UpdatePluginWidget frame=[%p] \n", instance(), frameView);
708     if (frameView) {
709         m_windowRect = frameView->contentsToWindow(frameRect());
710 
711         IntRect oldPageRect = m_pageRect;
712 
713         // only the top ScrollView can have the offset
714         m_pageRect = m_windowRect;
715         ScrollView* top = parent();
716         while (top->parent())
717             top = top->parent();
718         m_pageRect.move(top->scrollOffset());
719 
720         if (m_pageRect != oldPageRect)
721             setNPWindowIfNeeded();
722     }
723 }
724 
halt()725 void PluginView::halt() {
726     notImplemented();
727 }
728 
restart()729 void PluginView::restart() {
730     notImplemented();
731 }
732 
733 } // namespace WebCore
734