WebCore/plugins/symbian/PluginViewSymbian.cpp
changeset 0 4f2f89ce4247
child 2 303757a437d3
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2     Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
       
     3 
       
     4     This library is free software; you can redistribute it and/or
       
     5     modify it under the terms of the GNU Library General Public
       
     6     License as published by the Free Software Foundation; either
       
     7     version 2 of the License, or (at your option) any later version.
       
     8 
       
     9     This library is distributed in the hope that it will be useful,
       
    10     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    12     Library General Public License for more details.
       
    13 
       
    14     You should have received a copy of the GNU Library General Public License
       
    15     along with this library; see the file COPYING.LIB.  If not, write to
       
    16     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    17     Boston, MA 02110-1301, USA.
       
    18 */
       
    19 #include "config.h"
       
    20 #include "PluginView.h"
       
    21 
       
    22 #include "Bridge.h"
       
    23 #include "Document.h"
       
    24 #include "DocumentLoader.h"
       
    25 #include "Element.h"
       
    26 #include "FocusController.h"
       
    27 #include "Frame.h"
       
    28 #include "FrameLoadRequest.h"
       
    29 #include "FrameLoader.h"
       
    30 #include "FrameTree.h"
       
    31 #include "FrameView.h"
       
    32 #include "GraphicsContext.h"
       
    33 #include "HTMLNames.h"
       
    34 #include "HTMLPlugInElement.h"
       
    35 #include "HostWindow.h"
       
    36 #include "Image.h"
       
    37 #include "JSDOMBinding.h"
       
    38 #include "KeyboardEvent.h"
       
    39 #include "MouseEvent.h"
       
    40 #include "NotImplemented.h"
       
    41 #include "Page.h"
       
    42 #include "PlatformKeyboardEvent.h"
       
    43 #include "PlatformMouseEvent.h"
       
    44 #include "PluginContainerSymbian.h"
       
    45 #include "PluginDebug.h"
       
    46 #include "PluginMainThreadScheduler.h"
       
    47 #include "PluginPackage.h"
       
    48 #include "QWebPageClient.h"
       
    49 #include "RenderLayer.h"
       
    50 #include "ScriptController.h"
       
    51 #include "Settings.h"
       
    52 #include "npfunctions.h"
       
    53 #include "npinterface.h"
       
    54 #include "npruntime_impl.h"
       
    55 #include "qgraphicswebview.h"
       
    56 #include "runtime_root.h"
       
    57 #include <QGraphicsProxyWidget>
       
    58 #include <QKeyEvent>
       
    59 #include <QPixmap>
       
    60 #include <QRegion>
       
    61 #include <QVector>
       
    62 #include <QWidget>
       
    63 #include <runtime/JSLock.h>
       
    64 #include <runtime/JSValue.h>
       
    65 
       
    66 using JSC::ExecState;
       
    67 using JSC::Interpreter;
       
    68 using JSC::JSLock;
       
    69 using JSC::JSObject;
       
    70 using JSC::UString;
       
    71 
       
    72 using namespace std;
       
    73 
       
    74 using namespace WTF;
       
    75 
       
    76 namespace WebCore {
       
    77 
       
    78 using namespace HTMLNames;
       
    79 
       
    80 void PluginView::updatePluginWidget()
       
    81 {
       
    82     if (!parent())
       
    83         return;
       
    84     ASSERT(parent()->isFrameView());
       
    85     FrameView* frameView = static_cast<FrameView*>(parent());
       
    86     IntRect oldWindowRect = m_windowRect;
       
    87     IntRect oldClipRect = m_clipRect;
       
    88     
       
    89     m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size());
       
    90     
       
    91     m_clipRect = windowClipRect();
       
    92     m_clipRect.move(-m_windowRect.x(), -m_windowRect.y());
       
    93     if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect)
       
    94         return;
       
    95 
       
    96     // in order to move/resize the plugin window at the same time as the rest of frame
       
    97     // during e.g. scrolling, we set the mask and geometry in the paint() function, but
       
    98     // as paint() isn't called when the plugin window is outside the frame which can
       
    99     // be caused by a scroll, we need to move/resize immediately.
       
   100     if (!m_windowRect.intersects(frameView->frameRect()))
       
   101         setNPWindowIfNeeded();
       
   102 }
       
   103 
       
   104 void PluginView::setFocus(bool focused)
       
   105 {
       
   106     if (platformPluginWidget()) {
       
   107         if (focused)
       
   108             platformPluginWidget()->setFocus(Qt::OtherFocusReason);
       
   109     } else {
       
   110         Widget::setFocus(focused);
       
   111     }
       
   112 }
       
   113 
       
   114 void PluginView::show()
       
   115 {
       
   116     setSelfVisible(true);
       
   117 
       
   118     if (isParentVisible() && platformPluginWidget())
       
   119         platformPluginWidget()->setVisible(true);
       
   120 }
       
   121 
       
   122 void PluginView::hide()
       
   123 {
       
   124     setSelfVisible(false);
       
   125 
       
   126     if (isParentVisible() && platformPluginWidget())
       
   127         platformPluginWidget()->setVisible(false);
       
   128 }
       
   129 
       
   130 void PluginView::paint(GraphicsContext* context, const IntRect& rect)
       
   131 {
       
   132     if (!m_isStarted) {
       
   133         paintMissingPluginIcon(context, rect);
       
   134         return;
       
   135     }
       
   136     
       
   137     if (context->paintingDisabled())
       
   138         return;
       
   139     m_npWindow.ws_info = (void*)(context->platformContext());
       
   140     setNPWindowIfNeeded();
       
   141 
       
   142     if (m_isWindowed && platformPluginWidget())
       
   143         static_cast<PluginContainerSymbian*>(platformPluginWidget())->adjustGeometry();
       
   144 
       
   145     if (m_isWindowed)
       
   146         return;
       
   147 
       
   148     context->save();
       
   149     IntRect clipRect(rect);
       
   150     clipRect.intersect(frameRect());
       
   151     context->clip(clipRect);
       
   152     context->translate(frameRect().location().x(), frameRect().location().y());
       
   153 
       
   154     QPaintEvent ev(rect);
       
   155     QEvent& npEvent = ev;
       
   156     dispatchNPEvent(npEvent);
       
   157 
       
   158     context->restore();
       
   159 }
       
   160 
       
   161 // TODO: Unify across ports.
       
   162 bool PluginView::dispatchNPEvent(NPEvent& event)
       
   163 {
       
   164     if (!m_plugin->pluginFuncs()->event)
       
   165         return false;
       
   166 
       
   167     PluginView::setCurrentPluginView(this);
       
   168     JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
       
   169 
       
   170     setCallingPlugin(true);
       
   171     bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event);
       
   172     setCallingPlugin(false);
       
   173     PluginView::setCurrentPluginView(0);
       
   174 
       
   175     return accepted;
       
   176 }
       
   177 
       
   178 void PluginView::handleKeyboardEvent(KeyboardEvent* event)
       
   179 {
       
   180     if (m_isWindowed)
       
   181         return;
       
   182 
       
   183     QEvent& npEvent = *(event->keyEvent()->qtEvent());
       
   184     if (!dispatchNPEvent(npEvent))
       
   185         event->setDefaultHandled();
       
   186 }
       
   187 
       
   188 void PluginView::handleMouseEvent(MouseEvent* event)
       
   189 {
       
   190     if (m_isWindowed)
       
   191         return;
       
   192 
       
   193     if (event->type() == eventNames().mousedownEvent) {
       
   194         // Give focus to the plugin on click
       
   195         if (Page* page = m_parentFrame->page())
       
   196             page->focusController()->setActive(true);
       
   197 
       
   198         focusPluginElement();
       
   199     }
       
   200 
       
   201     QEvent::Type type;
       
   202     if (event->type() == eventNames().mousedownEvent)
       
   203         type = QEvent::MouseButtonPress;
       
   204     else if (event->type() == eventNames().mousemoveEvent)
       
   205         type = QEvent::MouseMove;
       
   206     else if (event->type() == eventNames().mouseupEvent)
       
   207         type = QEvent::MouseButtonRelease;
       
   208     else
       
   209         return;
       
   210 
       
   211     QPoint position(event->offsetX(), event->offsetY());
       
   212     Qt::MouseButton button;
       
   213     switch (event->which()) {
       
   214     case 1:
       
   215         button = Qt::LeftButton;
       
   216         break;
       
   217     case 2:
       
   218         button = Qt::MidButton;
       
   219         break;
       
   220     case 3:
       
   221         button = Qt::RightButton;
       
   222         break;
       
   223     default:
       
   224         button = Qt::NoButton;
       
   225     }
       
   226     Qt::KeyboardModifiers modifiers = 0;
       
   227     if (event->ctrlKey())
       
   228         modifiers |= Qt::ControlModifier;
       
   229     if (event->altKey())
       
   230         modifiers |= Qt::AltModifier;
       
   231     if (event->shiftKey())
       
   232         modifiers |= Qt::ShiftModifier;
       
   233     if (event->metaKey())
       
   234         modifiers |= Qt::MetaModifier;
       
   235     QMouseEvent mouseEvent(type, position, button, button, modifiers); 
       
   236     QEvent& npEvent = mouseEvent;
       
   237     if (!dispatchNPEvent(npEvent))
       
   238         event->setDefaultHandled();
       
   239 }
       
   240 
       
   241 void PluginView::setParent(ScrollView* parent)
       
   242 {
       
   243     Widget::setParent(parent);
       
   244 
       
   245     if (parent)
       
   246         init();
       
   247 }
       
   248 
       
   249 void PluginView::setNPWindowRect(const IntRect&)
       
   250 {
       
   251     if (!m_isWindowed)
       
   252         setNPWindowIfNeeded();
       
   253 }
       
   254 
       
   255 void PluginView::setNPWindowIfNeeded()
       
   256 {
       
   257     if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow)
       
   258         return;
       
   259     if (m_isWindowed) {
       
   260         ASSERT(platformPluginWidget());
       
   261         platformPluginWidget()->setGeometry(m_windowRect);
       
   262         // if setMask is set with an empty QRegion, no clipping will
       
   263         // be performed, so in that case we hide the plugin view
       
   264         platformPluginWidget()->setVisible(!m_clipRect.isEmpty());
       
   265         platformPluginWidget()->setMask(QRegion(m_clipRect));
       
   266 
       
   267         m_npWindow.x = m_windowRect.x();
       
   268         m_npWindow.y = m_windowRect.y();
       
   269 
       
   270         m_npWindow.clipRect.left = max(0, m_clipRect.x());
       
   271         m_npWindow.clipRect.top = max(0, m_clipRect.y());
       
   272         m_npWindow.clipRect.right = m_clipRect.x() + m_clipRect.width();
       
   273         m_npWindow.clipRect.bottom = m_clipRect.y() + m_clipRect.height();
       
   274     
       
   275     } else {
       
   276         // always call this method before painting.
       
   277         m_npWindow.x = 0;
       
   278         m_npWindow.y = 0;
       
   279     
       
   280         m_npWindow.clipRect.left = 0;
       
   281         m_npWindow.clipRect.top = 0;
       
   282         m_npWindow.clipRect.right = m_windowRect.width();
       
   283         m_npWindow.clipRect.bottom = m_windowRect.height();
       
   284         m_npWindow.window = 0;
       
   285     }
       
   286 
       
   287     m_npWindow.width = m_windowRect.width();
       
   288     m_npWindow.height = m_windowRect.height();
       
   289     
       
   290     PluginView::setCurrentPluginView(this);
       
   291     JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
       
   292     setCallingPlugin(true);
       
   293     m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
       
   294     setCallingPlugin(false);
       
   295     PluginView::setCurrentPluginView(0);
       
   296 }
       
   297 
       
   298 void PluginView::setParentVisible(bool visible)
       
   299 {
       
   300     if (isParentVisible() == visible)
       
   301         return;
       
   302 
       
   303     Widget::setParentVisible(visible);
       
   304 
       
   305     if (isSelfVisible() && platformPluginWidget())
       
   306         platformPluginWidget()->setVisible(visible);
       
   307 }
       
   308 
       
   309 NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf)
       
   310 {
       
   311     notImplemented();
       
   312     return NPERR_NO_ERROR;
       
   313 }
       
   314 
       
   315 bool PluginView::platformGetValueStatic(NPNVariable variable, void* value, NPError* result)
       
   316 {
       
   317     switch (variable) {
       
   318     case NPNVjavascriptEnabledBool:
       
   319         *static_cast<NPBool*>(value) = true;
       
   320         *result = NPERR_NO_ERROR;
       
   321         return true;
       
   322 
       
   323     case NPNVSupportsWindowless:
       
   324         *static_cast<NPBool*>(value) = true;
       
   325         *result = NPERR_NO_ERROR;
       
   326         return true;
       
   327 
       
   328     default:
       
   329         return false;
       
   330     }
       
   331 }
       
   332 
       
   333 bool PluginView::platformGetValue(NPNVariable, void*, NPError*)
       
   334 {
       
   335     return false;
       
   336 }
       
   337 
       
   338 void PluginView::invalidateRect(const IntRect& rect)
       
   339 {
       
   340     if (m_isWindowed) {
       
   341         platformWidget()->update(rect);
       
   342         return;
       
   343     }
       
   344     
       
   345     invalidateWindowlessPluginRect(rect);
       
   346 }
       
   347     
       
   348 void PluginView::invalidateRect(NPRect* rect)
       
   349 {
       
   350     if (m_isWindowed)
       
   351         return;
       
   352     if (!rect) {
       
   353         invalidate();
       
   354         return;
       
   355     }
       
   356     IntRect r(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top);
       
   357     m_invalidRects.append(r);
       
   358     if (!m_invalidateTimer.isActive())
       
   359         m_invalidateTimer.startOneShot(0.001);
       
   360 }
       
   361 
       
   362 void PluginView::invalidateRegion(NPRegion region)
       
   363 {
       
   364     if (m_isWindowed)
       
   365         return;
       
   366     
       
   367     if (!region) 
       
   368         return;
       
   369     
       
   370     QVector<QRect> rects = region->rects();
       
   371     for (int i = 0; i < rects.size(); ++i) {
       
   372         const QRect& qRect = rects.at(i);
       
   373         m_invalidRects.append(qRect);
       
   374         if (!m_invalidateTimer.isActive())
       
   375             m_invalidateTimer.startOneShot(0.001);
       
   376     }
       
   377 }
       
   378 
       
   379 void PluginView::forceRedraw()
       
   380 {
       
   381     if (m_isWindowed)
       
   382         return;
       
   383     invalidate();
       
   384 }
       
   385 
       
   386 bool PluginView::platformStart()
       
   387 {
       
   388     ASSERT(m_isStarted);
       
   389     ASSERT(m_status == PluginStatusLoadedSuccessfully);
       
   390     
       
   391     show();
       
   392 
       
   393     if (m_isWindowed) {
       
   394         QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
       
   395         QGraphicsProxyWidget* proxy = 0;
       
   396         if (QGraphicsWebView *webView = qobject_cast<QGraphicsWebView*>(client->pluginParent()))
       
   397             proxy = new QGraphicsProxyWidget(webView);
       
   398 
       
   399         PluginContainerSymbian* container = new PluginContainerSymbian(this, proxy ? 0 : client->ownerWidget(), proxy);
       
   400         setPlatformWidget(container);
       
   401         if (proxy)
       
   402             proxy->setWidget(container);
       
   403         
       
   404         m_npWindow.type = NPWindowTypeWindow;
       
   405         m_npWindow.window = (void*)platformPluginWidget();
       
   406 
       
   407     } else {
       
   408         setPlatformWidget(0);
       
   409         m_npWindow.type = NPWindowTypeDrawable;
       
   410         m_npWindow.window = 0; // Not used?
       
   411     }    
       
   412     setNPWindowIfNeeded();
       
   413     
       
   414     return true;
       
   415 }
       
   416 
       
   417 void PluginView::platformDestroy()
       
   418 {
       
   419     if (platformPluginWidget()) {
       
   420         PluginContainerSymbian* container = static_cast<PluginContainerSymbian*>(platformPluginWidget());
       
   421         if (container && container->proxy())
       
   422             delete container->proxy();
       
   423         else
       
   424             delete container;
       
   425     }
       
   426 }
       
   427 
       
   428 void PluginView::halt()
       
   429 {
       
   430 }
       
   431 
       
   432 void PluginView::restart()
       
   433 {
       
   434 }
       
   435 
       
   436 } // namespace WebCore