diff options
author | Steve Block <steveblock@google.com> | 2009-11-05 09:23:40 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-11-10 22:41:12 +0000 |
commit | cac0f67c402d107cdb10971b95719e2ff9c7c76b (patch) | |
tree | d182c7f87211c6f201a5f038e332336493ebdbe7 /WebCore/plugins | |
parent | 4b2ef0f288e7c6c4602f621b7a0e9feed304b70e (diff) | |
download | external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.zip external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.tar.gz external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.tar.bz2 |
Merge webkit.org at r50258 : Initial merge by git.
Change-Id: I1a9e1dc4ed654b69174ad52a4f031a07240f37b0
Diffstat (limited to 'WebCore/plugins')
20 files changed, 1086 insertions, 164 deletions
diff --git a/WebCore/plugins/PluginDataNone.cpp b/WebCore/plugins/PluginDataNone.cpp index 28e3967..3b98383 100644 --- a/WebCore/plugins/PluginDataNone.cpp +++ b/WebCore/plugins/PluginDataNone.cpp @@ -27,18 +27,14 @@ #include "config.h" #include "PluginData.h" -#include "NotImplemented.h" - namespace WebCore { void PluginData::initPlugins() { - notImplemented(); } void PluginData::refresh() { - notImplemented(); } }; diff --git a/WebCore/plugins/PluginDatabase.cpp b/WebCore/plugins/PluginDatabase.cpp index f7304df..25e6000 100644 --- a/WebCore/plugins/PluginDatabase.cpp +++ b/WebCore/plugins/PluginDatabase.cpp @@ -325,7 +325,7 @@ void PluginDatabase::clear() m_preferredPlugins.clear(); } -#if !PLATFORM(WIN_OS) || PLATFORM(WX) +#if (!PLATFORM(SYMBIAN)) && (!PLATFORM(WIN_OS) || PLATFORM(WX) || !ENABLE(NETSCAPE_PLUGIN_API)) // For Safari/Win the following three methods are implemented // in PluginDatabaseWin.cpp, but if we can use WebCore constructs // for the logic we should perhaps move it here under XP_WIN? @@ -438,6 +438,6 @@ void PluginDatabase::getPluginPathsInDirectories(HashSet<String>& paths) const } } -#endif // !PLATFORM(WIN_OS) +#endif // !PLATFORM(SYMBIAN) && !PLATFORM(WIN_OS) } diff --git a/WebCore/plugins/PluginPackage.cpp b/WebCore/plugins/PluginPackage.cpp index 258cbb7..06aedd9 100644 --- a/WebCore/plugins/PluginPackage.cpp +++ b/WebCore/plugins/PluginPackage.cpp @@ -119,6 +119,7 @@ PluginPackage::PluginPackage(const String& path, const time_t& lastModified) m_parentDirectory = m_path.left(m_path.length() - m_fileName.length() - 1); } +#if !PLATFORM(SYMBIAN) void PluginPackage::unload() { if (!m_isLoaded) @@ -131,6 +132,7 @@ void PluginPackage::unload() unloadWithoutShutdown(); } +#endif //!PLATFORM(SYMBIAN) void PluginPackage::unloadWithoutShutdown() { @@ -323,15 +325,24 @@ bool PluginPackage::equal(const PluginPackage& a, const PluginPackage& b) { return a.m_description == b.m_description; } +#endif int PluginPackage::compareFileVersion(const PlatformModuleVersion& compareVersion) const { // return -1, 0, or 1 if plug-in version is less than, equal to, or greater than // the passed version + +#if PLATFORM(WIN_OS) + if (m_moduleVersion.mostSig != compareVersion.mostSig) + return m_moduleVersion.mostSig > compareVersion.mostSig ? 1 : -1; + if (m_moduleVersion.leastSig != compareVersion.leastSig) + return m_moduleVersion.leastSig > compareVersion.leastSig ? 1 : -1; +#else if (m_moduleVersion != compareVersion) return m_moduleVersion > compareVersion ? 1 : -1; +#endif + return 0; } -#endif } diff --git a/WebCore/plugins/PluginPackage.h b/WebCore/plugins/PluginPackage.h index 2055391..c46c7eb 100644 --- a/WebCore/plugins/PluginPackage.h +++ b/WebCore/plugins/PluginPackage.h @@ -39,6 +39,11 @@ #include <nativehelper/jni.h> #endif +#if PLATFORM(SYMBIAN) +class QPluginLoader; +class NPInterface; +#endif + namespace WebCore { typedef HashMap<String, String> MIMEToDescriptionsMap; typedef HashMap<String, Vector<String> > MIMEToExtensionsMap; @@ -73,9 +78,17 @@ namespace WebCore { int compare(const PluginPackage&) const; PluginQuirkSet quirks() const { return m_quirks; } const PlatformModuleVersion& version() const { return m_moduleVersion; } +#if PLATFORM(SYMBIAN) + NPInterface* npInterface() const { return m_npInterface; } +#endif // PLATFORM(SYMBIAN) private: PluginPackage(const String& path, const time_t& lastModified); + +#if PLATFORM(SYMBIAN) + NPInterface* m_npInterface; + QPluginLoader* m_pluginLoader; +#endif // PLATFORM(SYMBIAN) bool fetchInfo(); bool isPluginBlacklisted(); void determineQuirks(const String& mimeType); diff --git a/WebCore/plugins/PluginPackageNone.cpp b/WebCore/plugins/PluginPackageNone.cpp index 487450a..b943d88 100644 --- a/WebCore/plugins/PluginPackageNone.cpp +++ b/WebCore/plugins/PluginPackageNone.cpp @@ -26,52 +26,20 @@ #include "config.h" #include "PluginPackage.h" -#include "CString.h" -#include "MIMETypeRegistry.h" -#include "NotImplemented.h" -#include "npruntime_impl.h" -#include "PluginDatabase.h" -#include "PluginDebug.h" - namespace WebCore { void PluginPackage::determineQuirks(const String&) { - notImplemented(); } bool PluginPackage::fetchInfo() { - notImplemented(); return false; } bool PluginPackage::load() { - notImplemented(); - return false; -} - -#if !ENABLE(PLUGIN_PACKAGE_SIMPLE_HASH) -unsigned PluginPackage::hash() const -{ - notImplemented(); - - return 0; -} - -bool PluginPackage::equal(const PluginPackage&, const PluginPackage&) -{ - notImplemented(); return false; } -int PluginPackage::compareFileVersion(const PlatformModuleVersion&) const -{ - notImplemented(); - return 0; -} - -#endif - } diff --git a/WebCore/plugins/PluginView.cpp b/WebCore/plugins/PluginView.cpp index 13d8511..3632774 100644 --- a/WebCore/plugins/PluginView.cpp +++ b/WebCore/plugins/PluginView.cpp @@ -138,8 +138,8 @@ void PluginView::setFrameRect(const IntRect& rect) updatePluginWidget(); -#if PLATFORM(WIN_OS) - // On Windows, always call plugin to change geometry. +#if PLATFORM(WIN_OS) || PLATFORM(SYMBIAN) + // On Windows and Symbian, always call plugin to change geometry. setNPWindowRect(rect); #elif XP_UNIX // On Unix, multiple calls to setNPWindow() in windowed mode causes Flash to crash @@ -162,6 +162,7 @@ void PluginView::handleEvent(Event* event) handleMouseEvent(static_cast<MouseEvent*>(event)); else if (event->isKeyboardEvent()) handleKeyboardEvent(static_cast<KeyboardEvent*>(event)); +<<<<<<< HEAD:WebCore/plugins/PluginView.cpp #if defined(ANDROID_PLUGINS) else if (event->isTouchEvent()) handleTouchEvent(static_cast<TouchEvent*>(event)); @@ -171,6 +172,9 @@ void PluginView::handleEvent(Event* event) handleFocusEvent(true); #endif #if defined(Q_WS_X11) +======= +#if defined(Q_WS_X11) && ENABLE(NETSCAPE_PLUGIN_API) +>>>>>>> webkit.org at r50258.:WebCore/plugins/PluginView.cpp else if (event->type() == eventNames().DOMFocusOutEvent) handleFocusOutEvent(); else if (event->type() == eventNames().DOMFocusInEvent) @@ -426,7 +430,7 @@ static bool getString(ScriptController* proxy, JSValue result, String& string) return false; JSLock lock(JSC::SilenceAssertionsOnly); - ExecState* exec = proxy->globalObject()->globalExec(); + ExecState* exec = proxy->globalObject(pluginWorld())->globalExec(); UString ustring = result.toString(exec); exec->clearException(); @@ -486,7 +490,7 @@ void PluginView::performRequest(PluginRequest* request) #if USE(JSC) // Executing a script can cause the plugin view to be destroyed, so we keep a reference to the parent frame. RefPtr<Frame> parentFrame = m_parentFrame; - JSValue result = m_parentFrame->loader()->executeScript(jsString, request->shouldAllowPopups()).jsValue(); + JSValue result = m_parentFrame->script()->executeScript(jsString, request->shouldAllowPopups()).jsValue(); if (targetFrameName.isNull()) { String resultString; @@ -891,7 +895,7 @@ PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* p , m_drawingModel(NPDrawingModel(-1)) , m_eventModel(NPEventModel(-1)) #endif -#if defined(Q_WS_X11) +#if defined(Q_WS_X11) && ENABLE(NETSCAPE_PLUGIN_API) , m_hasPendingGeometryChange(false) , m_drawable(0) , m_visual(0) @@ -901,6 +905,8 @@ PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* p , m_loadManually(loadManually) , m_manualStream(0) , m_isJavaScriptPaused(false) + , m_isHalted(false) + , m_hasBeenHalted(false) { #if defined(ANDROID_PLUGINS) platformInit(); diff --git a/WebCore/plugins/PluginView.h b/WebCore/plugins/PluginView.h index b385d41..c805352 100644 --- a/WebCore/plugins/PluginView.h +++ b/WebCore/plugins/PluginView.h @@ -72,6 +72,7 @@ class NPObject; namespace WebCore { class Element; class Frame; + class Image; class KeyboardEvent; class MouseEvent; #ifdef ANDROID_PLUGINS @@ -222,6 +223,9 @@ namespace WebCore { virtual void restart(); virtual Node* node() const; + bool isHalted() const { return m_isHalted; } + bool hasBeenHalted() const { return m_hasBeenHalted; } + static bool isCallingPlugin(); #ifdef ANDROID_PLUGINS @@ -251,7 +255,7 @@ namespace WebCore { void invalidateWindowlessPluginRect(const IntRect&); #if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API) - void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&) const; + void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&); static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*); static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*); #endif @@ -283,22 +287,32 @@ namespace WebCore { void handleKeyboardEvent(KeyboardEvent*); void handleMouseEvent(MouseEvent*); -#if defined(Q_WS_X11) +#if defined(Q_WS_X11) && ENABLE(NETSCAPE_PLUGIN_API) void handleFocusInEvent(); void handleFocusOutEvent(); #endif +<<<<<<< HEAD:WebCore/plugins/PluginView.h #ifdef ANDROID_PLUGINS void handleFocusEvent(bool hasFocus); void handleTouchEvent(TouchEvent*); // called at the end of the base constructor void platformInit(); +======= +#if PLATFORM(WIN_OS) + void paintIntoTransformedContext(HDC); + PassRefPtr<Image> snapshot(); +>>>>>>> webkit.org at r50258.:WebCore/plugins/PluginView.h #endif +<<<<<<< HEAD:WebCore/plugins/PluginView.h #ifdef PLUGIN_PLATFORM_SETVALUE // called if the default setValue does not recognize the variable NPError platformSetValue(NPPVariable variable, void* value); #endif +======= + +>>>>>>> webkit.org at r50258.:WebCore/plugins/PluginView.h int m_mode; int m_paramCount; char** m_paramNames; @@ -358,7 +372,7 @@ public: private: -#if defined(XP_UNIX) || defined(Q_WS_X11) +#if defined(XP_UNIX) || defined(Q_WS_X11) || PLATFORM(SYMBIAN) void setNPWindowIfNeeded(); #elif defined(XP_MACOSX) NP_CGContext m_npCgContext; @@ -371,7 +385,7 @@ private: Point globalMousePosForPlugin() const; #endif -#if defined(Q_WS_X11) +#if defined(Q_WS_X11) && ENABLE(NETSCAPE_PLUGIN_API) bool m_hasPendingGeometryChange; Pixmap m_drawable; Visual* m_visual; @@ -389,6 +403,9 @@ private: bool m_isJavaScriptPaused; + bool m_isHalted; + bool m_hasBeenHalted; + static PluginView* s_currentPluginView; }; diff --git a/WebCore/plugins/PluginViewNone.cpp b/WebCore/plugins/PluginViewNone.cpp index d4601d4..725af82 100644 --- a/WebCore/plugins/PluginViewNone.cpp +++ b/WebCore/plugins/PluginViewNone.cpp @@ -26,114 +26,90 @@ #include "config.h" #include "PluginView.h" -#include "NotImplemented.h" -#include "PluginPackage.h" - using namespace WTF; namespace WebCore { void PluginView::setFocus() { - notImplemented(); } void PluginView::show() { - notImplemented(); } void PluginView::hide() { - notImplemented(); } void PluginView::paint(GraphicsContext*, const IntRect&) { - notImplemented(); } void PluginView::handleKeyboardEvent(KeyboardEvent*) { - notImplemented(); } void PluginView::handleMouseEvent(MouseEvent*) { - notImplemented(); } void PluginView::setParent(ScrollView*) { - notImplemented(); } void PluginView::setNPWindowRect(const IntRect&) { - notImplemented(); } NPError PluginView::handlePostReadFile(Vector<char>&, uint32, const char*) { - notImplemented(); - return 0; } NPError PluginView::getValue(NPNVariable, void*) { - notImplemented(); return 0; } #if ENABLE(NETSCAPE_PLUGIN_API) NPError PluginView::getValueStatic(NPNVariable variable, void* value) { - notImplemented(); return 0; } #endif void PluginView::invalidateRect(NPRect*) { - notImplemented(); } void PluginView::invalidateRect(const IntRect&) { - notImplemented(); } void PluginView::invalidateRegion(NPRegion) { - notImplemented(); } void PluginView::forceRedraw() { - notImplemented(); } bool PluginView::platformStart() { - notImplemented(); - return true; } void PluginView::platformDestroy() { - notImplemented(); } void PluginView::setParentVisible(bool) { - notImplemented(); } void PluginView::updatePluginWidget() { - notImplemented(); } void PluginView::halt() diff --git a/WebCore/plugins/mac/PluginPackageMac.cpp b/WebCore/plugins/mac/PluginPackageMac.cpp index d242fb8..325bc4d 100644 --- a/WebCore/plugins/mac/PluginPackageMac.cpp +++ b/WebCore/plugins/mac/PluginPackageMac.cpp @@ -159,7 +159,8 @@ bool PluginPackage::fetchInfo() plist = readPListFile(path.get(), /*createFile*/ true, m_module); } - mimeDict = (CFDictionaryRef)CFDictionaryGetValue(plist.get(), CFSTR("WebPluginMIMETypes")); + if (plist) + mimeDict = (CFDictionaryRef)CFDictionaryGetValue(plist.get(), CFSTR("WebPluginMIMETypes")); } if (!mimeDict) diff --git a/WebCore/plugins/mac/PluginViewMac.cpp b/WebCore/plugins/mac/PluginViewMac.cpp index 0ab91d1..6521c84 100644 --- a/WebCore/plugins/mac/PluginViewMac.cpp +++ b/WebCore/plugins/mac/PluginViewMac.cpp @@ -174,8 +174,8 @@ bool PluginView::platformStart() #if PLATFORM(QT) if (QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient()) { - if (QWidget* window = QWidget::find(client->winId())) { - setPlatformPluginWidget(window); + if (QWidget* widget = client->ownerWidget()) { + setPlatformPluginWidget(widget); } } #endif diff --git a/WebCore/plugins/qt/PluginContainerQt.cpp b/WebCore/plugins/qt/PluginContainerQt.cpp index 59ab5bc..cb894a7 100644 --- a/WebCore/plugins/qt/PluginContainerQt.cpp +++ b/WebCore/plugins/qt/PluginContainerQt.cpp @@ -73,6 +73,7 @@ PluginContainerQt::PluginContainerQt(PluginView* view, QWidget* parent) PluginContainerQt::~PluginContainerQt() { delete m_clientWrapper; + m_pluginView->setPlatformPluginWidget(0); } void PluginContainerQt::on_clientClosed() diff --git a/WebCore/plugins/qt/PluginViewQt.cpp b/WebCore/plugins/qt/PluginViewQt.cpp index 27639e1..e61736b 100644 --- a/WebCore/plugins/qt/PluginViewQt.cpp +++ b/WebCore/plugins/qt/PluginViewQt.cpp @@ -107,10 +107,10 @@ void PluginView::updatePluginWidget() if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect) return; - if (m_drawable) - XFreePixmap(QX11Info::display(), m_drawable); + if (!m_isWindowed && m_windowRect.size() != oldWindowRect.size()) { + if (m_drawable) + XFreePixmap(QX11Info::display(), m_drawable); - if (!m_isWindowed) { m_drawable = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), m_windowRect.width(), m_windowRect.height(), ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth); QApplication::syncX(); // make sure that the server knows about the Drawable @@ -178,11 +178,20 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) const bool syncX = m_pluginDisplay && m_pluginDisplay != QX11Info::display(); QPainter* painter = context->platformContext(); + IntRect exposedRect(rect); + exposedRect.intersect(frameRect()); + exposedRect.move(-frameRect().x(), -frameRect().y()); QPixmap qtDrawable = QPixmap::fromX11Pixmap(m_drawable, QPixmap::ExplicitlyShared); const int drawableDepth = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth; ASSERT(drawableDepth == qtDrawable.depth()); + // When printing, Qt uses a QPicture to capture the output in preview mode. The + // QPicture holds a reference to the X Pixmap. As a result, the print preview would + // update itself when the X Pixmap changes. To prevent this, we create a copy. + if (m_element->document()->printing()) + qtDrawable = qtDrawable.copy(); + if (m_isTransparent && drawableDepth != 32) { // Attempt content propagation for drawable with no alpha by copying over from the backing store QPoint offset; @@ -196,17 +205,17 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) // (because backing store contents are already transformed). What we really mean to do // here is to check if we are painting on QWebView, but let's be a little permissive :) QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); - const bool backingStoreHasUntransformedContents = qobject_cast<QWidget*>(client->pluginParent()); + const bool backingStoreHasUntransformedContents = client && qobject_cast<QWidget*>(client->pluginParent()); if (hasValidBackingStore && backingStorePixmap->depth() == drawableDepth && backingStoreHasUntransformedContents) { GC gc = XDefaultGC(QX11Info::display(), QX11Info::appScreen()); XCopyArea(QX11Info::display(), backingStorePixmap->handle(), m_drawable, gc, - offset.x() + m_windowRect.x() + m_clipRect.x(), offset.y() + m_windowRect.y() + m_clipRect.y(), - m_clipRect.width(), m_clipRect.height(), m_clipRect.x(), m_clipRect.y()); + offset.x() + m_windowRect.x() + exposedRect.x(), offset.y() + m_windowRect.y() + exposedRect.y(), + exposedRect.width(), exposedRect.height(), exposedRect.x(), exposedRect.y()); } else { // no backing store, clean the pixmap because the plugin thinks its transparent QPainter painter(&qtDrawable); - painter.fillRect(m_clipRect, Qt::white); + painter.fillRect(exposedRect, Qt::white); } if (syncX) @@ -218,19 +227,19 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose; exposeEvent.type = GraphicsExpose; exposeEvent.display = QX11Info::display(); - exposeEvent.drawable = m_drawable; - exposeEvent.x = m_clipRect.x(); - exposeEvent.y = m_clipRect.y(); - exposeEvent.width = m_clipRect.x() + m_clipRect.width(); // flash bug? it thinks width is the right - exposeEvent.height = m_clipRect.y() + m_clipRect.height(); // flash bug? it thinks height is the bottom + exposeEvent.drawable = qtDrawable.handle(); + exposeEvent.x = exposedRect.x(); + exposeEvent.y = exposedRect.y(); + exposeEvent.width = exposedRect.x() + exposedRect.width(); // flash bug? it thinks width is the right in transparent mode + exposeEvent.height = exposedRect.y() + exposedRect.height(); // flash bug? it thinks height is the bottom in transparent mode dispatchNPEvent(xevent); if (syncX) XSync(m_pluginDisplay, False); // sync changes by plugin - painter->drawPixmap(frameRect().x() + m_clipRect.x(), frameRect().y() + m_clipRect.y(), qtDrawable, - m_clipRect.x(), m_clipRect.y(), m_clipRect.width(), m_clipRect.height()); + painter->drawPixmap(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), qtDrawable, + exposedRect); } // TODO: Unify across ports. @@ -240,24 +249,24 @@ bool PluginView::dispatchNPEvent(NPEvent& event) return false; PluginView::setCurrentPluginView(this); - JSC::JSLock::DropAllLocks dropAllLocks(false); - + JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly); setCallingPlugin(true); bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event); setCallingPlugin(false); + PluginView::setCurrentPluginView(0); return accepted; } -void setSharedXEventFields(XEvent* xEvent, QWidget* hostWindow) +void setSharedXEventFields(XEvent* xEvent, QWidget* ownerWidget) { xEvent->xany.serial = 0; // we are unaware of the last request processed by X Server xEvent->xany.send_event = false; - xEvent->xany.display = hostWindow->x11Info().display(); + xEvent->xany.display = QX11Info::display(); // NOTE: event->xany.window doesn't always respond to the .window property of other XEvent's // but does in the case of KeyPress, KeyRelease, ButtonPress, ButtonRelease, and MotionNotify // events; thus, this is right: - xEvent->xany.window = hostWindow->window()->handle(); + xEvent->xany.window = ownerWidget ? ownerWidget->window()->handle() : 0; } void PluginView::initXEvent(XEvent* xEvent) @@ -265,8 +274,8 @@ void PluginView::initXEvent(XEvent* xEvent) memset(xEvent, 0, sizeof(XEvent)); QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); - QWidget* window = QWidget::find(client->winId()); - setSharedXEventFields(xEvent, window); + QWidget* ownerWidget = client ? client->ownerWidget() : 0; + setSharedXEventFields(xEvent, ownerWidget); } void setXKeyEventSpecificFields(XEvent* xEvent, KeyboardEvent* event) @@ -458,16 +467,23 @@ void PluginView::setNPWindowIfNeeded() if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow) return; + // If the plugin didn't load sucessfully, no point in calling setwindow + if (m_status != PluginStatusLoadedSuccessfully) + return; + // On Unix, only call plugin if it's full-page or windowed if (m_mode != NP_FULL && m_mode != NP_EMBED) return; + // Check if the platformPluginWidget still exists + if (m_isWindowed && !platformPluginWidget()) + return; + if (!m_hasPendingGeometryChange) return; m_hasPendingGeometryChange = false; if (m_isWindowed) { - ASSERT(platformPluginWidget()); platformPluginWidget()->setGeometry(m_windowRect); // if setMask is set with an empty QRegion, no clipping will // be performed, so in that case we hide the plugin view @@ -577,13 +593,7 @@ NPError PluginView::getValue(NPNVariable variable, void* value) switch (variable) { case NPNVxDisplay: - if (platformPluginWidget()) - *(void **)value = platformPluginWidget()->x11Info().display(); - else { - QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); - QWidget* window = QWidget::find(client->winId()); - *(void **)value = window->x11Info().display(); - } + *(void **)value = QX11Info::display(); return NPERR_NO_ERROR; case NPNVxtAppContext: @@ -628,7 +638,8 @@ NPError PluginView::getValue(NPNVariable variable, void* value) case NPNVnetscapeWindow: { void* w = reinterpret_cast<void*>(value); - *((XID *)w) = m_parentFrame->view()->hostWindow()->platformPageClient()->winId(); + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + *((XID *)w) = client ? client->ownerWidget()->window()->winId() : 0; return NPERR_NO_ERROR; } @@ -659,7 +670,7 @@ void PluginView::invalidateRect(NPRect* rect) invalidate(); return; } - IntRect r(rect->left, rect->top, rect->right + rect->left, rect->bottom + rect->top); + IntRect r(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top); invalidateWindowlessPluginRect(r); } @@ -754,9 +765,9 @@ bool PluginView::platformStart() } if (m_isWindowed) { - if (m_needsXEmbed) { - QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); - setPlatformWidget(new PluginContainerQt(this, QWidget::find(client->winId()))); + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + if (m_needsXEmbed && client) { + setPlatformWidget(new PluginContainerQt(this, client->ownerWidget())); // sync our XEmbed container window creation before sending the xid to plugins. QApplication::syncX(); } else { diff --git a/WebCore/plugins/symbian/PluginContainerSymbian.cpp b/WebCore/plugins/symbian/PluginContainerSymbian.cpp new file mode 100644 index 0000000..aece0e4 --- /dev/null +++ b/WebCore/plugins/symbian/PluginContainerSymbian.cpp @@ -0,0 +1,77 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "PluginContainerSymbian.h" + +#include "FocusController.h" +#include "Frame.h" +#include "FrameView.h" +#include "Page.h" +#include "PlatformKeyboardEvent.h" +#include "PluginView.h" + +#include <QApplication> +#include <QWidget> + +using namespace WebCore; + +PluginContainerSymbian::PluginContainerSymbian(PluginView* view, QWidget* parent) + : m_parent(parent) + , m_pluginView(view) + , m_hasPendingGeometryChange(false) +{ + setParent(m_parent); +} + +PluginContainerSymbian::~PluginContainerSymbian() +{ +} + +void PluginContainerSymbian::requestGeometry(const QRect& rect, const QRegion& clip) +{ + if (m_windowRect != rect || m_clipRegion != clip) { + m_windowRect = rect; + m_clipRegion = clip; + m_hasPendingGeometryChange = true; + } +} + +void PluginContainerSymbian::adjustGeometry() +{ + if (m_hasPendingGeometryChange) { + setGeometry(m_windowRect); + setMask(m_clipRegion); + m_hasPendingGeometryChange = false; + } +} + +void PluginContainerSymbian::focusInEvent(QFocusEvent* event) +{ + if (Page* page = m_pluginView->parentFrame()->page()) + page->focusController()->setActive(true); + + m_pluginView->focusPluginElement(); +} + +void PluginContainerSymbian::focusOutEvent(QFocusEvent*) +{ + if (Page* page = m_pluginView->parentFrame()->page()) + page->focusController()->setActive(false); +} diff --git a/WebCore/plugins/symbian/PluginContainerSymbian.h b/WebCore/plugins/symbian/PluginContainerSymbian.h new file mode 100644 index 0000000..fce4a71 --- /dev/null +++ b/WebCore/plugins/symbian/PluginContainerSymbian.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PluginContainerSymbian_h +#define PluginContainerSymbian_h + +#include <QWidget> + +namespace WebCore { + + class PluginView; + + class PluginContainerSymbian : public QWidget { + Q_OBJECT + public: + PluginContainerSymbian(PluginView*, QWidget* parent); + ~PluginContainerSymbian(); + + void requestGeometry(const QRect&, const QRegion& clip = QRegion()); + void adjustGeometry(); + + protected: + virtual void focusInEvent(QFocusEvent*); + virtual void focusOutEvent(QFocusEvent*); + private: + PluginView* m_pluginView; + QWidget* m_parent; + QRect m_windowRect; + QRegion m_clipRegion; + bool m_hasPendingGeometryChange; + }; +} + +#endif // PluginContainerSymbian_h diff --git a/WebCore/plugins/symbian/PluginDatabaseSymbian.cpp b/WebCore/plugins/symbian/PluginDatabaseSymbian.cpp new file mode 100644 index 0000000..2e09296 --- /dev/null +++ b/WebCore/plugins/symbian/PluginDatabaseSymbian.cpp @@ -0,0 +1,79 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include "config.h" +#include "PluginDatabase.h" + +#include <QFileInfo> +#include <f32file.h> + +static const char QTPLUGIN_FILTER[] = "*.qtplugin"; +static const char QT_PLUGIN_FOLDER[] = ":\\resource\\qt\\plugins\\npqtplugins\\"; + +namespace WebCore { + +Vector<String> PluginDatabase::defaultPluginDirectories() +{ + Vector<String> directories; + //find the installation drive + TDriveList drivelist; + TChar driveLetter; + RFs fsSession; + + if (fsSession.Connect() == KErrNone && fsSession.DriveList(drivelist) == KErrNone) { + for (TInt driveNumber = EDriveA; driveNumber <= EDriveZ; driveNumber++) { + if (drivelist[driveNumber] && fsSession.DriveToChar(driveNumber, driveLetter) == KErrNone) { + QString driveStringValue(QChar((uint)driveLetter.GetUpperCase())); + QString stubDirPath; + stubDirPath.append(driveStringValue); + stubDirPath.append(QT_PLUGIN_FOLDER); + if (QFileInfo(stubDirPath).exists()) + directories.append(stubDirPath); + } + } + } + + fsSession.Close(); + return directories; +} + +bool PluginDatabase::isPreferredPluginDirectory(const String& path) +{ + return true; +} + +void PluginDatabase::getPluginPathsInDirectories(HashSet<String>& paths) const +{ + // FIXME: This should be a case insensitive set. + HashSet<String> uniqueFilenames; + + String fileNameFilter(QTPLUGIN_FILTER); + + Vector<String>::const_iterator dirsEnd = m_pluginDirectories.end(); + for (Vector<String>::const_iterator dIt = m_pluginDirectories.begin(); dIt != dirsEnd; ++dIt) { + Vector<String> pluginPaths = listDirectory(*dIt, fileNameFilter); + Vector<String>::const_iterator pluginsEnd = pluginPaths.end(); + for (Vector<String>::const_iterator pIt = pluginPaths.begin(); pIt != pluginsEnd; ++pIt) { + if (!fileExists(*pIt)) + continue; + paths.add(*pIt); + } + } +} + +} diff --git a/WebCore/plugins/symbian/PluginPackageSymbian.cpp b/WebCore/plugins/symbian/PluginPackageSymbian.cpp new file mode 100644 index 0000000..d5c7533 --- /dev/null +++ b/WebCore/plugins/symbian/PluginPackageSymbian.cpp @@ -0,0 +1,177 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include "config.h" +#include "PluginPackage.h" + +#include "CString.h" +#include "MIMETypeRegistry.h" +#include "npinterface.h" +#include "npruntime_impl.h" +#include "PluginDatabase.h" +#include "PluginDebug.h" +#include <QPluginLoader> + +namespace WebCore { + +bool PluginPackage::fetchInfo() +{ + if (!load()) + return false; + + char* buf = 0; + NPError err = m_pluginFuncs.getvalue(0, NPPVpluginNameString, (void *)&buf); + m_name = buf; + err = m_pluginFuncs.getvalue(0, NPPVpluginDescriptionString, (void *)&buf); + m_description = buf; + + determineModuleVersionFromDescription(); + + String s = m_npInterface->NP_GetMIMEDescription(); + Vector<String> types; + s.split(UChar('|'), false, types); // <MIME1>;<ext1,ext2,ext3,...>;<Description>|<MIME2>|<MIME3>|... + + for (int i = 0; i < types.size(); ++i) { + Vector<String> mime; + types[i].split(UChar(';'), true, mime); // <MIME1>;<ext1,ext2,ext3,...>;<Description> + if (mime.size() > 0) { + Vector<String> exts; + if (mime.size() > 1) + mime[1].split(UChar(','), false, exts); // <ext1,ext2,ext3,...> + + m_mimeToExtensions.add(mime[0], exts); // <MIME>,<ext1,ext2,ext3> + if (mime.size() > 2) + m_mimeToDescriptions.add(mime[0], mime[2]); // <MIME>,<Description> + } + } + unload(); + return true; +} + +bool PluginPackage::load() +{ + if (m_isLoaded) { + m_loadCount++; + return true; + } + + m_pluginLoader = new QPluginLoader(m_path); + if (!m_pluginLoader->load()) { + delete m_pluginLoader; + m_pluginLoader = 0; + return false; + } + + QObject* plugin = m_pluginLoader->instance(); + if (!plugin) { + m_pluginLoader->unload(); + delete m_pluginLoader; + m_pluginLoader = 0; + return false; + } + + // Plugin instance created + // Cast plugin to NPInterface, + m_npInterface = qobject_cast<NPInterface*>(plugin); + if (!m_npInterface) { + m_pluginLoader->unload(); + delete m_pluginLoader; + m_pluginLoader = 0; + return false; + } + + m_isLoaded = true; + + NPError npErr; + memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs)); + m_pluginFuncs.size = sizeof(m_pluginFuncs); + m_browserFuncs.size = sizeof(m_browserFuncs); + m_browserFuncs.version = NP_VERSION_MINOR; + m_browserFuncs.geturl = NPN_GetURL; + m_browserFuncs.posturl = NPN_PostURL; + m_browserFuncs.requestread = NPN_RequestRead; + m_browserFuncs.newstream = NPN_NewStream; + m_browserFuncs.write = NPN_Write; + m_browserFuncs.destroystream = NPN_DestroyStream; + m_browserFuncs.status = NPN_Status; + m_browserFuncs.uagent = NPN_UserAgent; + m_browserFuncs.memalloc = NPN_MemAlloc; + m_browserFuncs.memfree = NPN_MemFree; + m_browserFuncs.memflush = NPN_MemFlush; + m_browserFuncs.reloadplugins = NPN_ReloadPlugins; + m_browserFuncs.geturlnotify = NPN_GetURLNotify; + m_browserFuncs.posturlnotify = NPN_PostURLNotify; + m_browserFuncs.getvalue = NPN_GetValue; + m_browserFuncs.setvalue = NPN_SetValue; + m_browserFuncs.invalidaterect = NPN_InvalidateRect; + m_browserFuncs.invalidateregion = NPN_InvalidateRegion; + m_browserFuncs.forceredraw = NPN_ForceRedraw; + m_browserFuncs.getJavaEnv = NPN_GetJavaEnv; + m_browserFuncs.getJavaPeer = NPN_GetJavaPeer; + m_browserFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState; + m_browserFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState; + m_browserFuncs.releasevariantvalue = _NPN_ReleaseVariantValue; + m_browserFuncs.getstringidentifier = _NPN_GetStringIdentifier; + m_browserFuncs.getstringidentifiers = _NPN_GetStringIdentifiers; + m_browserFuncs.getintidentifier = _NPN_GetIntIdentifier; + m_browserFuncs.identifierisstring = _NPN_IdentifierIsString; + m_browserFuncs.utf8fromidentifier = _NPN_UTF8FromIdentifier; + m_browserFuncs.createobject = _NPN_CreateObject; + m_browserFuncs.retainobject = _NPN_RetainObject; + m_browserFuncs.releaseobject = _NPN_ReleaseObject; + m_browserFuncs.invoke = _NPN_Invoke; + m_browserFuncs.invokeDefault = _NPN_InvokeDefault; + m_browserFuncs.evaluate = _NPN_Evaluate; + m_browserFuncs.getproperty = _NPN_GetProperty; + m_browserFuncs.setproperty = _NPN_SetProperty; + m_browserFuncs.removeproperty = _NPN_RemoveProperty; + m_browserFuncs.hasproperty = _NPN_HasMethod; + m_browserFuncs.hasmethod = _NPN_HasProperty; + m_browserFuncs.setexception = _NPN_SetException; + m_browserFuncs.enumerate = _NPN_Enumerate; + m_browserFuncs.construct = _NPN_Construct; + + npErr = m_npInterface->NP_Initialize(&m_browserFuncs, &m_pluginFuncs); + if (npErr != NPERR_NO_ERROR) { + m_pluginLoader->unload(); + delete m_pluginLoader; + m_pluginLoader = 0; + return false; + } + + m_loadCount++; + return true; +} + +void PluginPackage::unload() +{ + if (!m_isLoaded) + return; + + if (--m_loadCount > 0) + return; + + m_isLoaded = false; + m_npInterface->NP_Shutdown(); + + m_pluginLoader->unload(); + delete m_pluginLoader; + m_pluginLoader = 0; +} +} + diff --git a/WebCore/plugins/symbian/PluginViewSymbian.cpp b/WebCore/plugins/symbian/PluginViewSymbian.cpp new file mode 100644 index 0000000..14e25b1 --- /dev/null +++ b/WebCore/plugins/symbian/PluginViewSymbian.cpp @@ -0,0 +1,462 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include "config.h" +#include "PluginView.h" + +#include "Document.h" +#include "DocumentLoader.h" +#include "Element.h" +#include "FocusController.h" +#include "Frame.h" +#include "FrameLoadRequest.h" +#include "FrameLoader.h" +#include "FrameTree.h" +#include "FrameView.h" +#include "GraphicsContext.h" +#include "HTMLNames.h" +#include "HTMLPlugInElement.h" +#include "Image.h" +#include "JSDOMBinding.h" +#include "KeyboardEvent.h" +#include "MouseEvent.h" +#include "NotImplemented.h" +#include "npfunctions.h" +#include "npinterface.h" +#include "Page.h" +#include "PlatformKeyboardEvent.h" +#include "PlatformMouseEvent.h" +#include "PluginContainerSymbian.h" +#include "PluginDebug.h" +#include "PluginMainThreadScheduler.h" +#include "PluginPackage.h" +#include "RenderLayer.h" +#include "ScriptController.h" +#include "Settings.h" +#include "npruntime_impl.h" +#include "runtime.h" +#include "runtime_root.h" +#include "QWebPageClient.h" +#include <QKeyEvent> +#include <QPixmap.h> +#include <QRegion> +#include <QVector> +#include <QWidget> +#include <runtime/JSLock.h> +#include <runtime/JSValue.h> + +using JSC::ExecState; +using JSC::Interpreter; +using JSC::JSLock; +using JSC::JSObject; +using JSC::UString; + +using namespace std; + +using namespace WTF; + +namespace WebCore { + +using namespace HTMLNames; + +void PluginView::updatePluginWidget() +{ + if (!parent()) + return; + ASSERT(parent()->isFrameView()); + FrameView* frameView = static_cast<FrameView*>(parent()); + IntRect oldWindowRect = m_windowRect; + IntRect oldClipRect = m_clipRect; + + m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size()); + m_clipRect = windowClipRect(); + m_clipRect.move(-m_windowRect.x(), -m_windowRect.y()); + if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect) + return; + + // in order to move/resize the plugin window at the same time as the rest of frame + // during e.g. scrolling, we set the mask and geometry in the paint() function, but + // as paint() isn't called when the plugin window is outside the frame which can + // be caused by a scroll, we need to move/resize immediately. + if (!m_windowRect.intersects(frameView->frameRect())) + setNPWindowIfNeeded(); +} + +void PluginView::setFocus() +{ + if (platformPluginWidget()) + platformPluginWidget()->setFocus(Qt::OtherFocusReason); + else + Widget::setFocus(); +} + +void PluginView::show() +{ + setSelfVisible(true); + + if (isParentVisible() && platformPluginWidget()) + platformPluginWidget()->setVisible(true); +} + +void PluginView::hide() +{ + setSelfVisible(false); + + if (isParentVisible() && platformPluginWidget()) + platformPluginWidget()->setVisible(false); +} + +void PluginView::paint(GraphicsContext* context, const IntRect& rect) +{ + if (!m_isStarted) { + paintMissingPluginIcon(context, rect); + return; + } + + if (context->paintingDisabled()) + return; + m_npWindow.ws_info = (void*)(context->platformContext()); + setNPWindowIfNeeded(); + + if (m_isWindowed && platformPluginWidget()) + static_cast<PluginContainerSymbian*>(platformPluginWidget())->adjustGeometry(); + + if (m_isWindowed) + return; + + context->save(); + IntRect clipRect(rect); + clipRect.intersect(frameRect()); + context->clip(clipRect); + context->translate(frameRect().location().x(), frameRect().location().y()); + + QPaintEvent ev(rect); + QEvent& npEvent = ev; + dispatchNPEvent(npEvent); + + context->restore(); +} + +// TODO: Unify across ports. +bool PluginView::dispatchNPEvent(NPEvent& event) +{ + if (!m_plugin->pluginFuncs()->event) + return false; + + PluginView::setCurrentPluginView(this); + JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly); + + setCallingPlugin(true); + bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event); + setCallingPlugin(false); + PluginView::setCurrentPluginView(0); + + return accepted; +} + +void PluginView::handleKeyboardEvent(KeyboardEvent* event) +{ + if (m_isWindowed) + return; + + QEvent& npEvent = *(event->keyEvent()->qtEvent()); + if (!dispatchNPEvent(npEvent)) + event->setDefaultHandled(); +} + +void PluginView::handleMouseEvent(MouseEvent* event) +{ + if (m_isWindowed) + return; + + if (event->type() == eventNames().mousedownEvent) { + // Give focus to the plugin on click + if (Page* page = m_parentFrame->page()) + page->focusController()->setActive(true); + + focusPluginElement(); + } + + QEvent::Type type; + if (event->type() == eventNames().mousedownEvent) + type = QEvent::MouseButtonPress; + else if (event->type() == eventNames().mousemoveEvent) + type = QEvent::MouseMove; + else if (event->type() == eventNames().mouseupEvent) + type = QEvent::MouseButtonRelease; + else + return; + + QPoint position(event->offsetX(), event->offsetY()); + Qt::MouseButton button; + switch (event->which()) { + case 1: + button = Qt::LeftButton; + break; + case 2: + button = Qt::MidButton; + break; + case 3: + button = Qt::RightButton; + break; + default: + button = Qt::NoButton; + } + Qt::KeyboardModifiers modifiers = 0; + if (event->ctrlKey()) + modifiers |= Qt::ControlModifier; + if (event->altKey()) + modifiers |= Qt::AltModifier; + if (event->shiftKey()) + modifiers |= Qt::ShiftModifier; + if (event->metaKey()) + modifiers |= Qt::MetaModifier; + QMouseEvent mouseEvent(type, position, button, button, modifiers); + QEvent& npEvent = mouseEvent; + if (!dispatchNPEvent(npEvent)) + event->setDefaultHandled(); +} + +void PluginView::setParent(ScrollView* parent) +{ + Widget::setParent(parent); + + if (parent) + init(); +} + +void PluginView::setNPWindowRect(const IntRect&) +{ + if (!m_isWindowed) + setNPWindowIfNeeded(); +} + +void PluginView::setNPWindowIfNeeded() +{ + if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow) + return; + if (m_isWindowed) { + ASSERT(platformPluginWidget()); + platformPluginWidget()->setGeometry(m_windowRect); + // if setMask is set with an empty QRegion, no clipping will + // be performed, so in that case we hide the plugin view + platformPluginWidget()->setVisible(!m_clipRect.isEmpty()); + platformPluginWidget()->setMask(QRegion(m_clipRect)); + + m_npWindow.x = m_windowRect.x(); + m_npWindow.y = m_windowRect.y(); + + m_npWindow.clipRect.left = m_clipRect.x(); + m_npWindow.clipRect.top = m_clipRect.y(); + m_npWindow.clipRect.right = m_clipRect.width(); + m_npWindow.clipRect.bottom = m_clipRect.height(); + + } else { + // always call this method before painting. + m_npWindow.x = 0; + m_npWindow.y = 0; + + m_npWindow.clipRect.left = 0; + m_npWindow.clipRect.top = 0; + m_npWindow.clipRect.right = m_windowRect.width(); + m_npWindow.clipRect.bottom = m_windowRect.height(); + m_npWindow.window = 0; + } + + m_npWindow.width = m_windowRect.width(); + m_npWindow.height = m_windowRect.height(); + if (m_npWindow.x < 0 || m_npWindow.y < 0 || m_npWindow.width <= 0 || m_npWindow.height <= 0) + return; + + PluginView::setCurrentPluginView(this); + JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly); + setCallingPlugin(true); + m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow); + setCallingPlugin(false); + PluginView::setCurrentPluginView(0); +} + +void PluginView::setParentVisible(bool visible) +{ + if (isParentVisible() == visible) + return; + + Widget::setParentVisible(visible); + + if (isSelfVisible() && platformPluginWidget()) + platformPluginWidget()->setVisible(visible); +} + +NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf) +{ + notImplemented(); + return NPERR_NO_ERROR; +} + +NPError PluginView::getValueStatic(NPNVariable variable, void* value) +{ + LOG(Plugins, "PluginView::getValueStatic(%s)", prettyNameForNPNVariable(variable).data()); + + switch (variable) { + case NPNVjavascriptEnabledBool: + *static_cast<NPBool*>(value) = true; + return NPERR_NO_ERROR; + + case NPNVSupportsWindowless: + *static_cast<NPBool*>(value) = true; + return NPERR_NO_ERROR; + + default: + return NPERR_GENERIC_ERROR; + } +} + +NPError PluginView::getValue(NPNVariable variable, void* value) +{ + LOG(Plugins, "PluginView::getValue(%s)", prettyNameForNPNVariable(variable).data()); + + 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; + } + default: + return getValueStatic(variable, value); + } +} + +void PluginView::invalidateRect(const IntRect& rect) +{ + if (m_isWindowed) { + platformWidget()->update(rect); + return; + } + + invalidateWindowlessPluginRect(rect); +} + +void PluginView::invalidateRect(NPRect* rect) +{ + if (m_isWindowed) + return; + if (!rect) { + invalidate(); + return; + } + IntRect r(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top); + m_invalidRects.append(r); + if (!m_invalidateTimer.isActive()) + m_invalidateTimer.startOneShot(0.001); +} + +void PluginView::invalidateRegion(NPRegion region) +{ + if (m_isWindowed) + return; + + if (!region) + return; + + QVector<QRect> rects = region->rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect& qRect = rects.at(i); + m_invalidRects.append(qRect); + if (!m_invalidateTimer.isActive()) + m_invalidateTimer.startOneShot(0.001); + } +} + +void PluginView::forceRedraw() +{ + if (m_isWindowed) + return; + invalidate(); +} + +bool PluginView::platformStart() +{ + ASSERT(m_isStarted); + ASSERT(m_status == PluginStatusLoadedSuccessfully); + + show(); + + if (m_isWindowed) { + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + // FIXME this will not work for QGraphicsView. + // But we cannot use winId because it will create a window and on S60, + // QWidgets should not create a window. + Q_ASSERT(qobject_cast<QWidget*>(client->pluginParent())); + setPlatformWidget(new PluginContainerSymbian(this, + qobject_cast<QWidget*>(client->pluginParent()))); + m_npWindow.type = NPWindowTypeWindow; + m_npWindow.window = (void*)platformPluginWidget(); + + } else { + setPlatformWidget(0); + m_npWindow.type = NPWindowTypeDrawable; + m_npWindow.window = 0; // Not used? + } + setNPWindowIfNeeded(); + + return true; +} + +void PluginView::platformDestroy() +{ + delete platformPluginWidget(); +} + +void PluginView::halt() +{ +} + +void PluginView::restart() +{ +} + +} // namespace WebCore diff --git a/WebCore/plugins/symbian/npinterface.h b/WebCore/plugins/symbian/npinterface.h new file mode 100644 index 0000000..0f0b6ca --- /dev/null +++ b/WebCore/plugins/symbian/npinterface.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef npinterface_H +#define npinterface_H + +#include "npfunctions.h" +#include <QtPlugin> + +class NPInterface { +public: + virtual NPError NP_Initialize(NPNetscapeFuncs* aNPNFuncs, NPPluginFuncs* aNPPFuncs) = 0; + virtual void NP_Shutdown() = 0; + virtual char* NP_GetMIMEDescription() = 0; +}; + + +QT_BEGIN_NAMESPACE +Q_DECLARE_INTERFACE(NPInterface, "com.nokia.qts60.webplugin/1.0"); +QT_END_NAMESPACE + +#endif // npinterface_H diff --git a/WebCore/plugins/win/PluginPackageWin.cpp b/WebCore/plugins/win/PluginPackageWin.cpp index e6fb9d5..dc9ec17 100644 --- a/WebCore/plugins/win/PluginPackageWin.cpp +++ b/WebCore/plugins/win/PluginPackageWin.cpp @@ -56,17 +56,6 @@ static String getVersionInfo(const LPVOID versionInfoData, const String& info) return String(reinterpret_cast<UChar*>(buffer), bufferLength - 1); } -int PluginPackage::compareFileVersion(const PlatformModuleVersion& compareVersion) const -{ - // return -1, 0, or 1 if plug-in version is less than, equal to, or greater than - // the passed version - if (m_moduleVersion.mostSig != compareVersion.mostSig) - return m_moduleVersion.mostSig > compareVersion.mostSig ? 1 : -1; - if (m_moduleVersion.leastSig != compareVersion.leastSig) - return m_moduleVersion.leastSig > compareVersion.leastSig ? 1 : -1; - return 0; -} - bool PluginPackage::isPluginBlacklisted() { if (name() == "Citrix ICA Client") { diff --git a/WebCore/plugins/win/PluginViewWin.cpp b/WebCore/plugins/win/PluginViewWin.cpp index ccbf6f8..5ccce0e 100644 --- a/WebCore/plugins/win/PluginViewWin.cpp +++ b/WebCore/plugins/win/PluginViewWin.cpp @@ -30,6 +30,7 @@ #include "PluginView.h" #include "BitmapImage.h" +#include "BitmapInfo.h" #include "Document.h" #include "DocumentLoader.h" #include "Element.h" @@ -77,6 +78,7 @@ #if PLATFORM(QT) #include "QWebPageClient.h" +#include <QWidget> #endif static inline HWND windowHandleForPageClient(PlatformPageClient client) @@ -84,7 +86,7 @@ static inline HWND windowHandleForPageClient(PlatformPageClient client) #if PLATFORM(QT) if (!client) return 0; - return client->winId(); + return client->ownerWidget()->winId(); #else return client; #endif @@ -494,7 +496,54 @@ bool PluginView::dispatchNPEvent(NPEvent& npEvent) return result; } -void PluginView::paintWindowedPluginIntoContext(GraphicsContext* context, const IntRect& rect) const +void PluginView::paintIntoTransformedContext(HDC hdc) +{ + if (m_isWindowed) { + SendMessage(platformPluginWidget(), WM_PRINTCLIENT, reinterpret_cast<WPARAM>(hdc), PRF_CLIENT | PRF_CHILDREN | PRF_OWNED); + return; + } + + m_npWindow.type = NPWindowTypeDrawable; + m_npWindow.window = hdc; + + WINDOWPOS windowpos = { 0 }; + +#if PLATFORM(WINCE) + IntRect r = static_cast<FrameView*>(parent())->contentsToWindow(frameRect()); + + windowpos.x = r.x(); + windowpos.y = r.y(); + windowpos.cx = r.width(); + windowpos.cy = r.height(); +#else + IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(frameRect().location()); + + windowpos.x = p.x(); + windowpos.y = p.y(); + windowpos.cx = frameRect().width(); + windowpos.cy = frameRect().height(); +#endif + + NPEvent npEvent; + npEvent.event = WM_WINDOWPOSCHANGED; + npEvent.lParam = reinterpret_cast<uint32>(&windowpos); + npEvent.wParam = 0; + + dispatchNPEvent(npEvent); + + setNPWindowRect(frameRect()); + + npEvent.event = WM_PAINT; + npEvent.wParam = reinterpret_cast<uint32>(hdc); + + // This is supposed to be a pointer to the dirty rect, but it seems that the Flash plugin + // ignores it so we just pass null. + npEvent.lParam = 0; + + dispatchNPEvent(npEvent); +} + +void PluginView::paintWindowedPluginIntoContext(GraphicsContext* context, const IntRect& rect) { #if !PLATFORM(WINCE) ASSERT(m_isWindowed); @@ -516,7 +565,7 @@ void PluginView::paintWindowedPluginIntoContext(GraphicsContext* context, const SetWorldTransform(hdc, &transform); - SendMessage(platformPluginWidget(), WM_PRINTCLIENT, reinterpret_cast<WPARAM>(hdc), PRF_CLIENT | PRF_CHILDREN | PRF_OWNED); + paintIntoTransformedContext(hdc); SetWorldTransform(hdc, &originalTransform); @@ -546,7 +595,6 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) ASSERT(parent()->isFrameView()); IntRect rectInWindow = static_cast<FrameView*>(parent())->contentsToWindow(frameRect()); HDC hdc = context->getWindowsContext(rectInWindow, m_isTransparent); - NPEvent npEvent; // On Safari/Windows without transparency layers the GraphicsContext returns the HDC // of the window and the plugin expects that the passed in DC has window coordinates. @@ -562,44 +610,7 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) } #endif - m_npWindow.type = NPWindowTypeDrawable; - m_npWindow.window = hdc; - - WINDOWPOS windowpos; - memset(&windowpos, 0, sizeof(windowpos)); - -#if PLATFORM(WINCE) - IntRect r = static_cast<FrameView*>(parent())->contentsToWindow(frameRect()); - - windowpos.x = r.x(); - windowpos.y = r.y(); - windowpos.cx = r.width(); - windowpos.cy = r.height(); -#else - IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(frameRect().location()); - - windowpos.x = p.x(); - windowpos.y = p.y(); - windowpos.cx = frameRect().width(); - windowpos.cy = frameRect().height(); -#endif - - npEvent.event = WM_WINDOWPOSCHANGED; - npEvent.lParam = reinterpret_cast<uint32>(&windowpos); - npEvent.wParam = 0; - - dispatchNPEvent(npEvent); - - setNPWindowRect(frameRect()); - - npEvent.event = WM_PAINT; - npEvent.wParam = reinterpret_cast<uint32>(hdc); - - // This is supposed to be a pointer to the dirty rect, but it seems that the Flash plugin - // ignores it so we just pass null. - npEvent.lParam = 0; - - dispatchNPEvent(npEvent); + paintIntoTransformedContext(hdc); context->releaseWindowsContext(hdc, frameRect(), m_isTransparent); } @@ -1017,14 +1028,52 @@ void PluginView::platformDestroy() setPlatformPluginWidget(0); } +PassRefPtr<Image> PluginView::snapshot() +{ + OwnPtr<HDC> hdc(CreateCompatibleDC(0)); + + if (!m_isWindowed) { + // Enable world transforms. + SetGraphicsMode(hdc.get(), GM_ADVANCED); + + XFORM transform; + GetWorldTransform(hdc.get(), &transform); + + // Windowless plug-ins assume that they're drawing onto the view's DC. + // Translate the context so that the plug-in draws at (0, 0). + ASSERT(parent()->isFrameView()); + IntPoint position = static_cast<FrameView*>(parent())->contentsToWindow(frameRect()).location(); + transform.eDx = -position.x(); + transform.eDy = -position.y(); + SetWorldTransform(hdc.get(), &transform); + } + + void* bits; + BitmapInfo bmp = BitmapInfo::createBottomUp(frameRect().size()); + OwnPtr<HBITMAP> hbmp(CreateDIBSection(0, &bmp, DIB_RGB_COLORS, &bits, 0, 0)); + + HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc.get(), hbmp.get())); + + paintIntoTransformedContext(hdc.get()); + + SelectObject(hdc.get(), hbmpOld); + + return BitmapImage::create(hbmp.get()); +} + void PluginView::halt() { + ASSERT(!m_isHalted); + ASSERT(m_isStarted); + #if !PLATFORM(QT) // Show a screenshot of the plug-in. - OwnPtr<HBITMAP> nodeImage(m_parentFrame->nodeImage(m_element)); - toRenderWidget(m_element->renderer())->showSubstituteImage(BitmapImage::create(nodeImage.get())); + toRenderWidget(m_element->renderer())->showSubstituteImage(snapshot()); #endif + m_isHalted = true; + m_hasBeenHalted = true; + stop(); platformDestroy(); } @@ -1032,10 +1081,12 @@ void PluginView::halt() void PluginView::restart() { ASSERT(!m_isStarted); + ASSERT(m_isHalted); // Clear any substitute image. toRenderWidget(m_element->renderer())->showSubstituteImage(0); + m_isHalted = false; m_haveUpdatedPluginWidget = false; start(); } |