--- a/src/3rdparty/webkit/WebCore/plugins/PluginView.cpp Wed Jun 23 19:07:03 2010 +0300
+++ b/src/3rdparty/webkit/WebCore/plugins/PluginView.cpp Tue Jul 06 15:10:48 2010 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008 Collabora Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,48 +27,50 @@
#include "config.h"
#include "PluginView.h"
+#include "Bridge.h"
+#include "Chrome.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "Element.h"
+#include "FocusController.h"
+#include "Frame.h"
#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
#include "FrameTree.h"
-#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
-#include "Image.h"
#include "HTMLNames.h"
#include "HTMLPlugInElement.h"
+#include "Image.h"
+#include "JSDOMBinding.h"
#include "JSDOMWindow.h"
#include "KeyboardEvent.h"
#include "MIMETypeRegistry.h"
#include "MouseEvent.h"
#include "NotImplemented.h"
#include "Page.h"
-#include "FocusController.h"
#include "PlatformMouseEvent.h"
-#if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API)
-#include "PluginMessageThrottlerWin.h"
-#endif
-#include "PluginPackage.h"
-#include "JSDOMBinding.h"
-#include "ScriptController.h"
-#include "ScriptValue.h"
-#include "SecurityOrigin.h"
#include "PluginDatabase.h"
#include "PluginDebug.h"
#include "PluginMainThreadScheduler.h"
#include "PluginPackage.h"
#include "RenderBox.h"
#include "RenderObject.h"
+#include "ScriptController.h"
+#include "ScriptValue.h"
+#include "SecurityOrigin.h"
+#include "Settings.h"
#include "c_instance.h"
#include "npruntime_impl.h"
#include "runtime_root.h"
-#include "Settings.h"
-#include "runtime.h"
#include <runtime/JSLock.h>
#include <runtime/JSValue.h>
#include <wtf/ASCIICType.h>
+#if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
+#include "PluginMessageThrottlerWin.h"
+#endif
+
using JSC::ExecState;
using JSC::JSLock;
using JSC::JSObject;
@@ -85,6 +87,14 @@
static int s_callingPlugin;
+typedef HashMap<NPP, PluginView*> InstanceMap;
+
+static InstanceMap& instanceMap()
+{
+ static InstanceMap& map = *new InstanceMap;
+ return map;
+}
+
static String scriptStringIfJavaScriptURL(const KURL& url)
{
if (!protocolIsJavaScript(url))
@@ -124,10 +134,10 @@
updatePluginWidget();
-#if PLATFORM(WIN_OS) || PLATFORM(SYMBIAN)
+#if OS(WINDOWS) || OS(SYMBIAN)
// On Windows and Symbian, always call plugin to change geometry.
setNPWindowRect(rect);
-#elif XP_UNIX
+#elif defined(XP_UNIX)
// On Unix, multiple calls to setNPWindow() in windowed mode causes Flash to crash
if (m_mode == NP_FULL || !m_isWindowed)
setNPWindowRect(rect);
@@ -144,11 +154,14 @@
if (!m_plugin || m_isWindowed)
return;
+ // Protect the plug-in from deletion while dispatching the event.
+ RefPtr<PluginView> protect(this);
+
if (event->isMouseEvent())
handleMouseEvent(static_cast<MouseEvent*>(event));
else if (event->isKeyboardEvent())
handleKeyboardEvent(static_cast<KeyboardEvent*>(event));
-#if defined(Q_WS_X11) && ENABLE(NETSCAPE_PLUGIN_API)
+#if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
else if (event->type() == eventNames().DOMFocusOutEvent)
handleFocusOutEvent();
else if (event->type() == eventNames().DOMFocusInEvent)
@@ -189,8 +202,11 @@
if (!m_parentFrame->page())
return false;
- if (!m_parentFrame->page()->canStartPlugins()) {
- m_parentFrame->page()->addUnstartedPlugin(this);
+ // We only delay starting the plug-in if we're going to kick off the load
+ // ourselves. Otherwise, the loader will try to deliver data before we've
+ // started the plug-in.
+ if (!m_loadManually && !m_parentFrame->page()->canStartMedia()) {
+ m_parentFrame->page()->addMediaCanStartListener(this);
m_isWaitingToStart = true;
return true;
}
@@ -250,10 +266,21 @@
return true;
}
+void PluginView::mediaCanStart()
+{
+ ASSERT(!m_isStarted);
+ if (!start())
+ parentFrame()->loader()->client()->dispatchDidFailToStartPlugin(this);
+}
+
PluginView::~PluginView()
{
LOG(Plugins, "PluginView::~PluginView()");
+ ASSERT(!m_lifeSupportTimer.isActive());
+
+ instanceMap().remove(m_instance);
+
removeFromUnstartedListIfNecessary();
stop();
@@ -279,7 +306,7 @@
if (!m_parentFrame->page())
return;
- m_parentFrame->page()->removeUnstartedPlugin(this);
+ m_parentFrame->page()->removeMediaCanStartListener(this);
}
void PluginView::stop()
@@ -306,11 +333,10 @@
JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
#if ENABLE(NETSCAPE_PLUGIN_API)
-#if !PLATFORM(WX) // FIXME: Revisit this when implementing plugins for wx
#ifdef XP_WIN
// Unsubclass the window
if (m_isWindowed) {
-#if PLATFORM(WINCE)
+#if OS(WINCE)
WNDPROC currentWndProc = (WNDPROC)GetWindowLong(platformPluginWidget(), GWL_WNDPROC);
if (currentWndProc == PluginViewWndProc)
@@ -319,11 +345,10 @@
WNDPROC currentWndProc = (WNDPROC)GetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC);
if (currentWndProc == PluginViewWndProc)
- SetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC, (LONG)m_pluginWndProc);
+ SetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC, (LONG_PTR)m_pluginWndProc);
#endif
}
#endif // XP_WIN
-#endif // !PLATFORM(WX)
#endif // ENABLE(NETSCAPE_PLUGIN_API)
#if !defined(XP_MACOSX)
@@ -421,7 +446,7 @@
// if this is not a targeted request, create a stream for it. otherwise,
// just pass it off to the loader
if (targetFrameName.isEmpty()) {
- RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame, request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
+ RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame.get(), request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
m_streams.add(stream);
stream->start();
} else {
@@ -459,7 +484,7 @@
if (getString(parentFrame->script(), result, resultString))
cstr = resultString.utf8();
- RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame, request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
+ RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame.get(), request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
m_streams.add(stream);
stream->sendJavaScriptStream(requestURL, cstr);
}
@@ -508,12 +533,10 @@
String jsString = scriptStringIfJavaScriptURL(url);
if (!jsString.isNull()) {
- Settings* settings = m_parentFrame->settings();
+ // Return NPERR_GENERIC_ERROR if JS is disabled. This is what Mozilla does.
+ if (!m_parentFrame->script()->canExecuteScripts(NotAboutToExecuteScript))
+ return NPERR_GENERIC_ERROR;
- // Return NPERR_GENERIC_ERROR if JS is disabled. This is what Mozilla does.
- if (!settings || !settings->isJavaScriptEnabled())
- return NPERR_GENERIC_ERROR;
-
// For security reasons, only allow JS requests to be made on the frame that contains the plug-in.
if (!targetFrameName.isNull() && m_parentFrame->tree()->find(targetFrameName) != m_parentFrame)
return NPERR_INVALID_PARAM;
@@ -598,7 +621,7 @@
void PluginView::status(const char* message)
{
if (Page* page = m_parentFrame->page())
- page->chrome()->setStatusbarText(m_parentFrame, String(message));
+ page->chrome()->setStatusbarText(m_parentFrame.get(), String(message));
}
NPError PluginView::setValue(NPPVariable variable, void* value)
@@ -790,6 +813,8 @@
, m_requestTimer(this, &PluginView::requestTimerFired)
, m_invalidateTimer(this, &PluginView::invalidateTimerFired)
, m_popPopupsStateTimer(this, &PluginView::popPopupsStateTimerFired)
+ , m_lifeSupportTimer(this, &PluginView::lifeSupportTimerFired)
+ , m_mode(loadManually ? NP_FULL : NP_EMBED)
, m_paramNames(0)
, m_paramValues(0)
, m_mimeType(mimeType)
@@ -801,25 +826,27 @@
, m_isTransparent(false)
, m_haveInitialized(false)
, m_isWaitingToStart(false)
-#if defined(XP_UNIX) || defined(Q_WS_X11)
+#if defined(XP_UNIX)
, m_needsXEmbed(false)
#endif
-#if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API)
+#if OS(WINDOWS) && ENABLE(NETSCAPE_PLUGIN_API)
, m_pluginWndProc(0)
, m_lastMessage(0)
, m_isCallingPluginWndProc(false)
, m_wmPrintHDC(0)
, m_haveUpdatedPluginWidget(false)
#endif
-#if (PLATFORM(QT) && PLATFORM(WIN_OS)) || defined(XP_MACOSX)
+#if (PLATFORM(QT) && OS(WINDOWS)) || defined(XP_MACOSX)
, m_window(0)
#endif
#if defined(XP_MACOSX)
, m_drawingModel(NPDrawingModel(-1))
, m_eventModel(NPEventModel(-1))
+ , m_contextRef(0)
+ , m_fakeWindow(0)
#endif
-#if defined(Q_WS_X11) && ENABLE(NETSCAPE_PLUGIN_API)
- , m_hasPendingGeometryChange(false)
+#if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
+ , m_hasPendingGeometryChange(true)
, m_drawable(0)
, m_visual(0)
, m_colormap(0)
@@ -840,6 +867,8 @@
m_instance->ndata = this;
m_instance->pdata = 0;
+ instanceMap().add(m_instance, this);
+
setParameters(paramNames, paramValues);
memset(&m_npWindow, 0, sizeof(m_npWindow));
@@ -847,8 +876,6 @@
memset(&m_npCgContext, 0, sizeof(m_npCgContext));
#endif
- m_mode = m_loadManually ? NP_FULL : NP_EMBED;
-
resize(size);
}
@@ -868,7 +895,7 @@
ASSERT(m_loadManually);
ASSERT(!m_manualStream);
- m_manualStream = PluginStream::create(this, m_parentFrame, m_parentFrame->loader()->activeDocumentLoader()->request(), false, 0, plugin()->pluginFuncs(), instance(), m_plugin->quirks());
+ m_manualStream = PluginStream::create(this, m_parentFrame.get(), m_parentFrame->loader()->activeDocumentLoader()->request(), false, 0, plugin()->pluginFuncs(), instance(), m_plugin->quirks());
m_manualStream->setLoadManually(true);
m_manualStream->didReceiveResponse(0, response);
@@ -1198,7 +1225,7 @@
context->save();
context->clip(windowClipRect());
- context->drawImage(nullPluginImage.get(), imageRect.location());
+ context->drawImage(nullPluginImage.get(), DeviceColorSpace, imageRect.location());
context->restore();
}
@@ -1209,7 +1236,7 @@
"Windows; U; Windows NT 5.1;"
#elif defined(XP_UNIX)
// The Gtk port uses X11 plugins in Mac.
-#if PLATFORM(DARWIN) && PLATFORM(GTK)
+#if OS(DARWIN) && PLATFORM(GTK)
"X11; U; Intel Mac OS X;"
#else
"X11; U; Linux i686;"
@@ -1241,4 +1268,120 @@
return m_element;
}
+String PluginView::pluginName() const
+{
+ return m_plugin->name();
+}
+
+void PluginView::lifeSupportTimerFired(Timer<PluginView>*)
+{
+ deref();
+}
+
+void PluginView::keepAlive()
+{
+ if (m_lifeSupportTimer.isActive())
+ return;
+
+ ref();
+ m_lifeSupportTimer.startOneShot(0);
+}
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+void PluginView::keepAlive(NPP instance)
+{
+ PluginView* view = instanceMap().get(instance);
+ if (!view)
+ return;
+
+ view->keepAlive();
+}
+
+NPError PluginView::getValueStatic(NPNVariable variable, void* value)
+{
+ LOG(Plugins, "PluginView::getValueStatic(%s)", prettyNameForNPNVariable(variable).data());
+
+ NPError result;
+ if (platformGetValueStatic(variable, value, &result))
+ return result;
+
+ return NPERR_GENERIC_ERROR;
+}
+
+NPError PluginView::getValue(NPNVariable variable, void* value)
+{
+ LOG(Plugins, "PluginView::getValue(%s)", prettyNameForNPNVariable(variable).data());
+
+ NPError result;
+ if (platformGetValue(variable, value, &result))
+ return result;
+
+ if (platformGetValueStatic(variable, value, &result))
+ return result;
+
+ switch (variable) {
+ case NPNVWindowNPObject: {
+ if (m_isJavaScriptPaused)
+ return NPERR_GENERIC_ERROR;
+
+ NPObject* windowScriptObject = m_parentFrame->script()->windowScriptNPObject();
+
+ // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugin/npruntime.html>
+ if (windowScriptObject)
+ _NPN_RetainObject(windowScriptObject);
+
+ void** v = (void**)value;
+ *v = windowScriptObject;
+
+ return NPERR_NO_ERROR;
+ }
+
+ case NPNVPluginElementNPObject: {
+ if (m_isJavaScriptPaused)
+ return NPERR_GENERIC_ERROR;
+
+ NPObject* pluginScriptObject = 0;
+
+ if (m_element->hasTagName(appletTag) || m_element->hasTagName(embedTag) || m_element->hasTagName(objectTag))
+ pluginScriptObject = static_cast<HTMLPlugInElement*>(m_element)->getNPObject();
+
+ // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugin/npruntime.html>
+ if (pluginScriptObject)
+ _NPN_RetainObject(pluginScriptObject);
+
+ void** v = (void**)value;
+ *v = pluginScriptObject;
+
+ return NPERR_NO_ERROR;
+ }
+
+ case NPNVprivateModeBool: {
+ Page* page = m_parentFrame->page();
+ if (!page)
+ return NPERR_GENERIC_ERROR;
+ *((NPBool*)value) = !page->settings() || page->settings()->privateBrowsingEnabled();
+ return NPERR_NO_ERROR;
+ }
+
+ default:
+ return NPERR_GENERIC_ERROR;
+ }
+}
+#endif
+
+void PluginView::privateBrowsingStateChanged(bool privateBrowsingEnabled)
+{
+ NPP_SetValueProcPtr setValue = m_plugin->pluginFuncs()->setvalue;
+ if (!setValue)
+ return;
+
+ PluginView::setCurrentPluginView(this);
+ JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+ setCallingPlugin(true);
+ NPBool value = privateBrowsingEnabled;
+ setValue(m_instance, NPNVprivateModeBool, &value);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+}
+
} // namespace WebCore