OSDN Git Service

Merge WebKit at r71558: Initial merge by git.
[android-x86/external-webkit.git] / WebKit / chromium / src / WebPluginContainerImpl.cpp
index 86cac26..43d9757 100644 (file)
 
 #include "Chrome.h"
 #include "ChromeClientImpl.h"
+#include "PluginLayerChromium.h"
+#include "WebClipboard.h"
 #include "WebCursorInfo.h"
 #include "WebDataSourceImpl.h"
+#include "WebElement.h"
 #include "WebInputEvent.h"
 #include "WebInputEventConversion.h"
 #include "WebKit.h"
+#include "WebKitClient.h"
 #include "WebPlugin.h"
 #include "WebRect.h"
+#include "WebString.h"
+#include "WebURL.h"
 #include "WebURLError.h"
 #include "WebURLRequest.h"
 #include "WebVector.h"
+#include "WebViewImpl.h"
 #include "WrappedResourceResponse.h"
 
 #include "EventNames.h"
 #include "HTMLFormElement.h"
 #include "HTMLNames.h"
 #include "HTMLPlugInElement.h"
+#include "KeyboardCodes.h"
 #include "KeyboardEvent.h"
 #include "MouseEvent.h"
 #include "Page.h"
+#include "RenderBox.h"
 #include "ScrollView.h"
+#include "WheelEvent.h"
 
 #if WEBKIT_USING_SKIA
 #include "PlatformContextSkia.h"
@@ -124,13 +134,13 @@ void WebPluginContainerImpl::invalidateRect(const IntRect& rect)
     IntRect clipRect = parent()->windowClipRect();
     damageRect.intersect(clipRect);
 
-    parent()->hostWindow()->repaint(damageRect, true);
+    parent()->hostWindow()->invalidateContentsAndWindow(damageRect, false /*immediate*/);
 }
 
-void WebPluginContainerImpl::setFocus()
+void WebPluginContainerImpl::setFocus(bool focused)
 {
-    Widget::setFocus();
-    m_webPlugin->updateFocus(true);
+    Widget::setFocus(focused);
+    m_webPlugin->updateFocus(focused);
 }
 
 void WebPluginContainerImpl::show()
@@ -160,8 +170,15 @@ void WebPluginContainerImpl::handleEvent(Event* event)
     // where mozilla behaves differently than the spec.
     if (event->isMouseEvent())
         handleMouseEvent(static_cast<MouseEvent*>(event));
+    else if (event->isWheelEvent())
+        handleWheelEvent(static_cast<WheelEvent*>(event));
     else if (event->isKeyboardEvent())
         handleKeyboardEvent(static_cast<KeyboardEvent*>(event));
+
+    // FIXME: it would be cleaner if Widget::handleEvent returned true/false and
+    // HTMLPluginElement called setDefaultHandled or defaultEventHandler.
+    if (!event->defaultHandled())
+        m_element->Node::defaultEventHandler(event);
 }
 
 void WebPluginContainerImpl::frameRectsChanged()
@@ -170,6 +187,12 @@ void WebPluginContainerImpl::frameRectsChanged()
     reportGeometry();
 }
 
+void WebPluginContainerImpl::widgetPositionsUpdated()
+{
+    Widget::widgetPositionsUpdated();
+    reportGeometry();
+}
+
 void WebPluginContainerImpl::setParentVisible(bool parentVisible)
 {
     // We override this function to make sure that geometry updates are sent
@@ -200,6 +223,49 @@ void WebPluginContainerImpl::setParent(ScrollView* view)
         reportGeometry();
 }
 
+bool WebPluginContainerImpl::supportsPaginatedPrint() const
+{
+    return m_webPlugin->supportsPaginatedPrint();
+}
+
+int WebPluginContainerImpl::printBegin(const IntRect& printableArea,
+                                       int printerDPI) const
+{
+    return m_webPlugin->printBegin(printableArea, printerDPI);
+}
+
+bool WebPluginContainerImpl::printPage(int pageNumber,
+                                       WebCore::GraphicsContext* gc)
+{
+    gc->save();
+#if WEBKIT_USING_SKIA
+    WebCanvas* canvas = gc->platformContext()->canvas();
+#elif WEBKIT_USING_CG
+    WebCanvas* canvas = gc->platformContext();
+#endif
+    bool ret = m_webPlugin->printPage(pageNumber, canvas);
+    gc->restore();
+    return ret;
+}
+
+void WebPluginContainerImpl::printEnd()
+{
+    return m_webPlugin->printEnd();
+}
+
+void WebPluginContainerImpl::copy()
+{
+    if (!plugin()->hasSelection())
+        return;
+
+    webKitClient()->clipboard()->writeHTML(plugin()->selectionAsMarkup(), WebURL(), plugin()->selectionAsText(), false);
+}
+
+WebElement WebPluginContainerImpl::element()
+{
+    return WebElement(m_element);
+}
+
 void WebPluginContainerImpl::invalidate()
 {
     Widget::invalidate();
@@ -210,6 +276,25 @@ void WebPluginContainerImpl::invalidateRect(const WebRect& rect)
     invalidateRect(static_cast<IntRect>(rect));
 }
 
+void WebPluginContainerImpl::scrollRect(int dx, int dy, const WebRect& rect)
+{
+    Widget* parentWidget = parent();
+    if (parentWidget->isFrameView()) {
+        FrameView* parentFrameView = static_cast<FrameView*>(parentWidget);
+        if (!parentFrameView->isOverlapped()) {
+            IntRect damageRect = convertToContainingWindow(static_cast<IntRect>(rect));
+            IntSize scrollDelta(dx, dy);
+            // scroll() only uses the second rectangle, clipRect, and ignores the first
+            // rectangle.
+            parent()->hostWindow()->scroll(scrollDelta, damageRect, damageRect);
+            return;
+        }
+    }
+
+    // Use slow scrolling instead.
+    invalidateRect(rect);
+}
+
 void WebPluginContainerImpl::reportGeometry()
 {
     if (!parent())
@@ -222,6 +307,14 @@ void WebPluginContainerImpl::reportGeometry()
     m_webPlugin->updateGeometry(windowRect, clipRect, cutOutRects, isVisible());
 }
 
+void WebPluginContainerImpl::commitBackingTexture()
+{
+#if USE(ACCELERATED_COMPOSITING)
+    if (platformLayer())
+        platformLayer()->setNeedsDisplay();
+#endif
+}
+
 void WebPluginContainerImpl::clearScriptObjects()
 {
     Frame* frame = m_element->document()->frame();
@@ -284,6 +377,12 @@ void WebPluginContainerImpl::loadFrameRequest(
         SendReferrer);
 }
 
+void WebPluginContainerImpl::zoomLevelChanged(double zoomLevel)
+{
+    WebViewImpl* view = WebViewImpl::fromPage(m_element->document()->frame()->page());
+    view->fullFramePluginZoomLevelChanged(zoomLevel);
+}
+
 void WebPluginContainerImpl::didReceiveResponse(const ResourceResponse& response)
 {
     // Make sure that the plugin receives window geometry before data, or else
@@ -322,8 +421,33 @@ void WebPluginContainerImpl::willDestroyPluginLoadObserver(WebPluginLoadObserver
     m_pluginLoadObservers.remove(pos);
 }
 
+#if USE(ACCELERATED_COMPOSITING)
+WebCore::LayerChromium* WebPluginContainerImpl::platformLayer() const
+{
+    // FIXME: In the event of a context lost, the texture needs to be recreated on the compositor's
+    // context and rebound to the platform layer here.
+    unsigned backingTextureId = m_webPlugin->getBackingTextureId();
+    if (!backingTextureId)
+        return 0;
+
+    m_platformLayer->setTextureId(backingTextureId);
+
+    return m_platformLayer.get();
+}
+#endif
+
 // Private methods -------------------------------------------------------------
 
+WebPluginContainerImpl::WebPluginContainerImpl(WebCore::HTMLPlugInElement* element, WebPlugin* webPlugin)
+    : WebCore::PluginViewBase(0)
+    , m_element(element)
+    , m_webPlugin(webPlugin)
+#if USE(ACCELERATED_COMPOSITING)
+    , m_platformLayer(PluginLayerChromium::create(0))
+#endif
+{
+}
+
 WebPluginContainerImpl::~WebPluginContainerImpl()
 {
     for (size_t i = 0; i < m_pluginLoadObservers.size(); ++i)
@@ -339,7 +463,7 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event)
     // in the call to HandleEvent. See http://b/issue?id=1362948
     FrameView* parentView = static_cast<FrameView*>(parent());
 
-    WebMouseEventBuilder webEvent(parentView, *event);
+    WebMouseEventBuilder webEvent(this, *event);
     if (webEvent.type == WebInputEvent::Undefined)
         return;
 
@@ -353,22 +477,7 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event)
     }
 
     WebCursorInfo cursorInfo;
-    bool handled = m_webPlugin->handleInputEvent(webEvent, cursorInfo);
-#if !OS(DARWIN)
-    // TODO(pkasting): http://b/1119691 This conditional seems exactly
-    // backwards, but if I reverse it, giving focus to a transparent
-    // (windowless) plugin fails.
-    handled = !handled;
-    // TODO(awalker): oddly, the above is not true in Mac builds.  Looking
-    // at Apple's corresponding code for Mac and Windows (PluginViewMac and
-    // PluginViewWin), setDefaultHandled() gets called when handleInputEvent()
-    // returns true, which then indicates to WebCore that the plugin wants to
-    // swallow the event--which is what we want.  Calling setDefaultHandled()
-    // fixes several Mac Chromium bugs, but does indeed prevent windowless plugins
-    // from getting focus in Windows builds, as pkasting notes above.  So for
-    // now, we only do so in Mac builds.
-#endif
-    if (handled)
+    if (m_webPlugin->handleInputEvent(webEvent, cursorInfo))
         event->setDefaultHandled();
 
     // A windowless plugin can change the cursor in response to a mouse move
@@ -382,19 +491,48 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event)
     chromeClient->setCursorForPlugin(cursorInfo);
 }
 
+void WebPluginContainerImpl::handleWheelEvent(WheelEvent* event)
+{
+    WebMouseWheelEventBuilder webEvent(this, *event);
+    if (webEvent.type == WebInputEvent::Undefined)
+        return;
+
+    WebCursorInfo cursorInfo;
+    if (m_webPlugin->handleInputEvent(webEvent, cursorInfo))
+        event->setDefaultHandled();
+}
+
 void WebPluginContainerImpl::handleKeyboardEvent(KeyboardEvent* event)
 {
     WebKeyboardEventBuilder webEvent(*event);
     if (webEvent.type == WebInputEvent::Undefined)
         return;
 
-    WebCursorInfo cursor_info;
-    bool handled = m_webPlugin->handleInputEvent(webEvent, cursor_info);
-#if !OS(DARWIN)
-    // TODO(pkasting): http://b/1119691 See above.
-    handled = !handled;
+    if (webEvent.type == WebInputEvent::KeyDown) {
+#if defined(OS_MACOSX)
+        if (webEvent.modifiers == WebInputEvent::MetaKey
+#else
+        if (webEvent.modifiers == WebInputEvent::ControlKey
 #endif
-    if (handled)
+            && webEvent.windowsKeyCode == VKEY_C) {
+            copy();
+            event->setDefaultHandled();
+            return;
+        }
+    }
+
+    const WebInputEvent* currentInputEvent = WebViewImpl::currentInputEvent();
+
+    // Copy stashed info over, and only copy here in order not to interfere
+    // the ctrl-c logic above.
+    if (currentInputEvent
+        && WebInputEvent::isKeyboardEventType(currentInputEvent->type)) {
+        webEvent.modifiers |= currentInputEvent->modifiers &
+            (WebInputEvent::CapsLockOn | WebInputEvent::NumLockOn);
+    }
+
+    WebCursorInfo cursorInfo;
+    if (m_webPlugin->handleInputEvent(webEvent, cursorInfo))
         event->setDefaultHandled();
 }
 
@@ -473,11 +611,20 @@ static bool checkStackOnTop(
                     return false;
             }
 
-            // For compatibility with IE: when the plugin is not positioned,
-            // it stacks behind the iframe, even if it's later in the
-            // document order.
-            if (ro2->style()->position() == StaticPosition)
+            // If the plugin does not have an explicit z-index it stacks behind the iframe.
+            // This is for maintaining compatibility with IE.
+            if (ro2->style()->position() == StaticPosition) {
+                // The 0'th elements of these RenderObject arrays represent the plugin node and
+                // the iframe.
+                const RenderObject* pluginRenderObject = pluginZstack[0];
+                const RenderObject* iframeRenderObject = iframeZstack[0];
+
+                if (pluginRenderObject->style() && iframeRenderObject->style()) {
+                    if (pluginRenderObject->style()->zIndex() > iframeRenderObject->style()->zIndex())
+                        return false;
+                }
                 return true;
+            }
 
             // Inspect the document order.  Later order means higher
             // stacking.