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;
}
bool PluginView::platformStart()
{
    ASSERT(m_isStarted);
    ASSERT(m_status == PluginStatusLoadedSuccessfully);
    
    show();

    if (m_isWindowed) {
        QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
        QGraphicsProxyWidget* proxy = 0;
        if (QGraphicsWebView *webView = qobject_cast<QGraphicsWebView*>(client->pluginParent()))
            proxy = new QGraphicsProxyWidget(webView);

        PluginContainerSymbian* container = new PluginContainerSymbian(this, proxy ? 0 : client->ownerWidget(), proxy);
        setPlatformWidget(container);
        if (proxy)
            proxy->setWidget(container);
        
        m_npWindow.type = NPWindowTypeWindow;
        m_npWindow.window = (void*)platformPluginWidget();

    } else {
        setPlatformWidget(0);
        m_npWindow.type = NPWindowTypeDrawable;
        m_npWindow.window = 0; // Not used?
    }    
    updatePluginWidget();
    setNPWindowIfNeeded();

    if (qtwebkit_page_plugin_created)
        qtwebkit_page_plugin_created(QWebFramePrivate::kit(m_parentFrame.get()), m_instance, (void*)(m_plugin->pluginFuncs()));

    return true;
}
void PopupMenu::show(const IntRect& r, FrameView* v, int index)
{
    QWebPageClient* client = v->hostWindow()->platformPageClient();
    populate(r);
    QRect rect = r;
    rect.moveTopLeft(v->contentsToWindow(r.topLeft()));
    rect.setHeight(m_popup->sizeHint().height());

    if (QGraphicsView* view = qobject_cast<QGraphicsView*>(client->ownerWidget())) {
        if (!m_proxy) {
            m_proxy = new QGraphicsProxyWidget(qobject_cast<QGraphicsWebView*>(client->pluginParent()));
            m_proxy->setWidget(m_popup);
        } else
            m_proxy->setVisible(true);
        m_proxy->setGeometry(rect);
    } else {
        m_popup->setParent(client->ownerWidget());
        m_popup->setGeometry(rect);
    }

    m_popup->setCurrentIndex(index);
    m_popup->exec();
}
void PluginView::paint(GraphicsContext* context, const IntRect& rect)
{
    if (!m_isStarted) {
        paintMissingPluginIcon(context, rect);
        return;
    }

    if (context->paintingDisabled())
        return;

    setNPWindowIfNeeded();

    if (m_isWindowed || !m_drawable)
        return;

    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;
        QPaintDevice* backingStoreDevice =  QPainter::redirected(painter->device(), &offset);
        offset = -offset; // negating the offset gives us the offset of the view within the backing store pixmap

        const bool hasValidBackingStore = backingStoreDevice && backingStoreDevice->devType() == QInternal::Pixmap;
        QPixmap* backingStorePixmap = static_cast<QPixmap*>(backingStoreDevice);

        // We cannot grab contents from the backing store when painting on QGraphicsView items
        // (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 = 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() + 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(exposedRect, Qt::white);
        }

        if (syncX)
            QApplication::syncX();
    }

    XEvent xevent;
    memset(&xevent, 0, sizeof(XEvent));
    XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose;
    exposeEvent.type = GraphicsExpose;
    exposeEvent.display = QX11Info::display();
    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(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), qtDrawable,
                        exposedRect);
}
Exemple #5
0
PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames,
                                          const Vector<String>& paramValues, const String& mimeType, bool loadManually)
{
//     qDebug()<<"------ Creating plugin in FrameLoaderClientQt::createPlugin for "<<url.prettyURL() << mimeType;
//     qDebug()<<"------\t url = "<<url.prettyURL();

    if (!m_webFrame)
        return 0;

    QStringList params;
    QStringList values;
    QString classid(element->getAttribute("classid"));

    for (unsigned i = 0; i < paramNames.size(); ++i) {
        params.append(paramNames[i]);
        if (paramNames[i] == "classid")
            classid = paramValues[i];
    }
    for (unsigned i = 0; i < paramValues.size(); ++i)
        values.append(paramValues[i]);

    QString urlStr(url.string());
    QUrl qurl = urlStr;

    QObject* object = 0;

    if (mimeType == "application/x-qt-plugin" || mimeType == "application/x-qt-styled-widget") {
        object = m_webFrame->page()->createPlugin(classid, qurl, params, values);
#ifndef QT_NO_STYLE_STYLESHEET
        QWidget* widget = qobject_cast<QWidget*>(object);
        if (widget && mimeType == "application/x-qt-styled-widget") {

            QString styleSheet = element->getAttribute("style");
            if (!styleSheet.isEmpty())
                styleSheet += QLatin1Char(';');

            for (unsigned i = 0; i < numqStyleSheetProperties; ++i) {
                CSSPropertyID property = qstyleSheetProperties[i];

                styleSheet += QString::fromLatin1(::getPropertyName(property));
                styleSheet += QLatin1Char(':');
                styleSheet += computedStyle(element)->getPropertyValue(property);
                styleSheet += QLatin1Char(';');
            }

            widget->setStyleSheet(styleSheet);
        }
#endif // QT_NO_STYLE_STYLESHEET
    }

        if (!object) {
            QWebPluginFactory* factory = m_webFrame->page()->pluginFactory();
            if (factory)
                object = factory->create(mimeType, qurl, params, values);
        }

        if (object) {
            QWidget* widget = qobject_cast<QWidget*>(object);
            if (widget) {
                QWidget* parentWidget = 0;
                if (m_webFrame->page()->d->client)
                    parentWidget = qobject_cast<QWidget*>(m_webFrame->page()->d->client->pluginParent());
                if (parentWidget) // don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose.
                    widget->setParent(parentWidget);
                widget->hide();
                RefPtr<QtPluginWidget> w = adoptRef(new QtPluginWidget());
                w->setPlatformWidget(widget);
                // Make sure it's invisible until properly placed into the layout
                w->setFrameRect(IntRect(0, 0, 0, 0));
                return w;
            }
#if QT_VERSION >= 0x040600
            QGraphicsWidget* graphicsWidget = qobject_cast<QGraphicsWidget*>(object);
            if (graphicsWidget) {
                QGraphicsObject* parentWidget = 0;
                if (m_webFrame->page()->d->client)
                    parentWidget = qobject_cast<QGraphicsObject*>(m_webFrame->page()->d->client->pluginParent());
                graphicsWidget->hide();
                if (parentWidget) // don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose.
                    graphicsWidget->setParentItem(parentWidget);
                RefPtr<QtPluginGraphicsWidget> w = QtPluginGraphicsWidget::create(graphicsWidget);
                // Make sure it's invisible until properly placed into the layout
                w->setFrameRect(IntRect(0, 0, 0, 0));
                return w;
            }
#endif
            // FIXME: make things work for widgetless plugins as well
            delete object;
    } else { // NPAPI Plugins
        Vector<String> params = paramNames;
        Vector<String> values = paramValues;
        if (mimeType == "application/x-shockwave-flash") {
            QWebPageClient* client = m_webFrame->page()->d->client;
            const bool isQWebView = client && qobject_cast<QWidget*>(client->pluginParent());
#if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO == 5)
            size_t wmodeIndex = params.find("wmode");
            if (wmodeIndex == -1) {
                // Disable XEmbed mode and force it to opaque mode
                params.append("wmode");
                values.append("opaque");
            } else if (!isQWebView) {
                // Disable transparency if client is not a QWebView
                values[wmodeIndex] = "opaque";
            }
#else
            if (!isQWebView) {
                // inject wmode=opaque when there is no client or the client is not a QWebView
                size_t wmodeIndex = params.find("wmode");
                if (wmodeIndex == -1) {
                    params.append("wmode");
                    values.append("opaque");
                } else
                    values[wmodeIndex] = "opaque";
            }
#endif
        }

        RefPtr<PluginView> pluginView = PluginView::create(m_frame, pluginSize, element, url,
            params, values, mimeType, loadManually);
        return pluginView;
    }

    return 0;
}