#include "config.h"
#include "PageClientQt.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#if defined(Q_WS_X11)
#include <QX11Info>
#endif
#if ENABLE(WEBGL)
#include <QGLWidget>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#include <QWindow>
#endif
static void createPlatformGraphicsContext3DFromWidget(QWidget* widget, PlatformGraphicsContext3D* context,
PlatformGraphicsSurface3D* surface)
{
*context = 0;
*surface = 0;
QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>(widget);
if (!scrollArea)
return;
QGLWidget* glViewport = qobject_cast<QGLWidget*>(scrollArea->viewport());
if (!glViewport)
return;
QGLWidget* glWidget = new QGLWidget(0, glViewport);
if (glWidget->isValid()) {
glWidget->setGeometry(0, 0, 0, 0);
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
*surface = glWidget->windowHandle();
*context = glWidget->context()->contextHandle();
#else
*surface = glWidget;
*context = const_cast<QGLContext*>(glWidget->context());
#endif
} else {
delete glWidget;
glWidget = 0;
}
}
#endif
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
#include "TextureMapper.h"
#include "texmap/TextureMapperLayer.h"
#endif
namespace WebCore {
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
TextureMapperLayerClientQt::TextureMapperLayerClientQt(QWebFrame* frame, GraphicsLayer* layer)
: m_frame(frame)
, m_rootGraphicsLayer(GraphicsLayer::create(0))
{
m_frame->d->rootTextureMapperLayer = rootLayer();
m_rootGraphicsLayer->addChild(layer);
m_rootGraphicsLayer->setDrawsContent(false);
m_rootGraphicsLayer->setMasksToBounds(false);
m_rootGraphicsLayer->setSize(IntSize(1, 1));
}
void TextureMapperLayerClientQt::setTextureMapper(const PassOwnPtr<TextureMapper>& textureMapper)
{
m_frame->d->textureMapper = textureMapper;
m_frame->d->rootTextureMapperLayer->setTextureMapper(m_frame->d->textureMapper.get());
}
TextureMapperLayerClientQt::~TextureMapperLayerClientQt()
{
m_frame->d->rootTextureMapperLayer = 0;
}
void TextureMapperLayerClientQt::syncRootLayer()
{
m_rootGraphicsLayer->syncCompositingStateForThisLayerOnly();
}
TextureMapperLayer* TextureMapperLayerClientQt::rootLayer()
{
return toTextureMapperLayer(m_rootGraphicsLayer.get());
}
void PageClientQWidget::setRootGraphicsLayer(GraphicsLayer* layer)
{
if (layer) {
TextureMapperLayerClient = adoptPtr(new TextureMapperLayerClientQt(page->mainFrame(), layer));
TextureMapperLayerClient->setTextureMapper(TextureMapper::create());
TextureMapperLayerClient->syncRootLayer();
return;
}
TextureMapperLayerClient.clear();
}
void PageClientQWidget::markForSync(bool scheduleSync)
{
if (syncTimer.isActive())
return;
syncTimer.startOneShot(0);
}
void PageClientQWidget::syncLayers(Timer<PageClientQWidget>*)
{
if (TextureMapperLayerClient)
TextureMapperLayerClient->syncRootLayer();
QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
if (!TextureMapperLayerClient)
return;
if (TextureMapperLayerClient->rootLayer()->descendantsOrSelfHaveRunningAnimations() && !syncTimer.isActive())
syncTimer.startOneShot(1.0 / 60.0);
update(view->rect());
}
#endif
void PageClientQWidget::scroll(int dx, int dy, const QRect& rectToScroll)
{
view->scroll(qreal(dx), qreal(dy), rectToScroll);
}
void PageClientQWidget::update(const QRect & dirtyRect)
{
view->update(dirtyRect);
}
void PageClientQWidget::setInputMethodEnabled(bool enable)
{
view->setAttribute(Qt::WA_InputMethodEnabled, enable);
}
bool PageClientQWidget::inputMethodEnabled() const
{
return view->testAttribute(Qt::WA_InputMethodEnabled);
}
void PageClientQWidget::setInputMethodHints(Qt::InputMethodHints hints)
{
view->setInputMethodHints(hints);
}
PageClientQWidget::~PageClientQWidget()
{
}
#ifndef QT_NO_CURSOR
QCursor PageClientQWidget::cursor() const
{
return view->cursor();
}
void PageClientQWidget::updateCursor(const QCursor& cursor)
{
view->setCursor(cursor);
}
#endif
QPalette PageClientQWidget::palette() const
{
return view->palette();
}
int PageClientQWidget::screenNumber() const
{
#if defined(Q_WS_X11)
return view->x11Info().screen();
#endif
return 0;
}
QWidget* PageClientQWidget::ownerWidget() const
{
return view;
}
QRect PageClientQWidget::geometryRelativeToOwnerWidget() const
{
return view->geometry();
}
QObject* PageClientQWidget::pluginParent() const
{
return view;
}
QStyle* PageClientQWidget::style() const
{
return view->style();
}
QRectF PageClientQWidget::windowRect() const
{
return QRectF(view->window()->geometry());
}
void PageClientQWidget::setWidgetVisible(Widget* widget, bool visible)
{
QWidget* qtWidget = qobject_cast<QWidget*>(widget->platformWidget());
if (!qtWidget)
return;
qtWidget->setVisible(visible);
}
#if ENABLE(WEBGL)
void PageClientQWidget::createPlatformGraphicsContext3D(PlatformGraphicsContext3D* context,
PlatformGraphicsSurface3D* surface)
{
createPlatformGraphicsContext3DFromWidget(view, context, surface);
}
#endif
#if !defined(QT_NO_GRAPHICSVIEW)
PageClientQGraphicsWidget::~PageClientQGraphicsWidget()
{
delete overlay;
#if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER)
if (!rootGraphicsLayer)
return;
rootGraphicsLayer.data()->setParentItem(0);
view->scene()->removeItem(rootGraphicsLayer.data());
#endif
}
void PageClientQGraphicsWidget::scroll(int dx, int dy, const QRect& rectToScroll)
{
view->scroll(qreal(dx), qreal(dy), rectToScroll);
}
void PageClientQGraphicsWidget::update(const QRect& dirtyRect)
{
view->update(dirtyRect);
createOrDeleteOverlay();
if (overlay)
overlay->update(QRectF(dirtyRect));
#if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER)
syncLayers();
#endif
}
void PageClientQGraphicsWidget::createOrDeleteOverlay()
{
#if !USE(TEXTURE_MAPPER)
bool useOverlay = false;
if (!viewResizesToContents) {
#if USE(ACCELERATED_COMPOSITING)
useOverlay = useOverlay || rootGraphicsLayer;
#endif
#if USE(TILED_BACKING_STORE)
useOverlay = useOverlay || QWebFramePrivate::core(page->mainFrame())->tiledBackingStore();
#endif
}
if (useOverlay == !!overlay)
return;
if (useOverlay) {
overlay = new QGraphicsItemOverlay(view, page);
overlay->setZValue(OverlayZValue);
} else {
overlay->deleteLater();
overlay = 0;
}
#endif // !USE(TEXTURE_MAPPER)
}
#if USE(ACCELERATED_COMPOSITING)
void PageClientQGraphicsWidget::syncLayers()
{
#if USE(TEXTURE_MAPPER)
if (TextureMapperLayerClient)
TextureMapperLayerClient->syncRootLayer();
#endif
QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
#if USE(TEXTURE_MAPPER)
if (!TextureMapperLayerClient)
return;
if (TextureMapperLayerClient->rootLayer()->descendantsOrSelfHaveRunningAnimations() && !syncTimer.isActive())
syncTimer.startOneShot(1.0 / 60.0);
update(view->boundingRect().toAlignedRect());
#endif
}
#if USE(TEXTURE_MAPPER)
void PageClientQGraphicsWidget::setRootGraphicsLayer(GraphicsLayer* layer)
{
if (layer) {
TextureMapperLayerClient = adoptPtr(new TextureMapperLayerClientQt(page->mainFrame(), layer));
#if USE(TEXTURE_MAPPER_GL)
QGraphicsView* graphicsView = view->scene()->views()[0];
if (graphicsView && graphicsView->viewport() && graphicsView->viewport()->inherits("QGLWidget")) {
TextureMapperLayerClient->setTextureMapper(TextureMapper::create(TextureMapper::OpenGLMode));
return;
}
#endif
TextureMapperLayerClient->setTextureMapper(TextureMapper::create());
return;
}
TextureMapperLayerClient.clear();
}
#else
void PageClientQGraphicsWidget::setRootGraphicsLayer(GraphicsLayer* layer)
{
if (rootGraphicsLayer) {
rootGraphicsLayer.data()->setParentItem(0);
view->scene()->removeItem(rootGraphicsLayer.data());
QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
}
rootGraphicsLayer = layer ? layer->platformLayer() : 0;
if (rootGraphicsLayer) {
rootGraphicsLayer.data()->setParentItem(view);
rootGraphicsLayer.data()->setZValue(RootGraphicsLayerZValue);
}
createOrDeleteOverlay();
}
#endif
void PageClientQGraphicsWidget::markForSync(bool scheduleSync)
{
if (syncTimer.isActive())
return;
syncTimer.startOneShot(0);
}
#endif
#if USE(TILED_BACKING_STORE)
void PageClientQGraphicsWidget::updateTiledBackingStoreScale()
{
WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(page->mainFrame())->tiledBackingStore();
if (!backingStore)
return;
backingStore->setContentsScale(view->scale());
}
#endif
void PageClientQGraphicsWidget::setInputMethodEnabled(bool enable)
{
view->setFlag(QGraphicsItem::ItemAcceptsInputMethod, enable);
}
bool PageClientQGraphicsWidget::inputMethodEnabled() const
{
return view->flags() & QGraphicsItem::ItemAcceptsInputMethod;
}
void PageClientQGraphicsWidget::setInputMethodHints(Qt::InputMethodHints hints)
{
view->setInputMethodHints(hints);
}
#ifndef QT_NO_CURSOR
QCursor PageClientQGraphicsWidget::cursor() const
{
return view->cursor();
}
void PageClientQGraphicsWidget::updateCursor(const QCursor& cursor)
{
view->setCursor(cursor);
}
#endif
QPalette PageClientQGraphicsWidget::palette() const
{
return view->palette();
}
int PageClientQGraphicsWidget::screenNumber() const
{
#if defined(Q_WS_X11)
if (QGraphicsScene* scene = view->scene()) {
const QList<QGraphicsView*> views = scene->views();
if (!views.isEmpty())
return views.at(0)->x11Info().screen();
}
#endif
return 0;
}
QWidget* PageClientQGraphicsWidget::ownerWidget() const
{
if (QGraphicsScene* scene = view->scene()) {
const QList<QGraphicsView*> views = scene->views();
return views.value(0);
}
return 0;
}
QRect PageClientQGraphicsWidget::geometryRelativeToOwnerWidget() const
{
if (!view->scene())
return QRect();
QList<QGraphicsView*> views = view->scene()->views();
if (views.isEmpty())
return QRect();
QGraphicsView* graphicsView = views.at(0);
return graphicsView->mapFromScene(view->boundingRect()).boundingRect();
}
#if USE(TILED_BACKING_STORE)
QRectF PageClientQGraphicsWidget::graphicsItemVisibleRect() const
{
if (!view->scene())
return QRectF();
QList<QGraphicsView*> views = view->scene()->views();
if (views.isEmpty())
return QRectF();
QGraphicsView* graphicsView = views.at(0);
int xOffset = graphicsView->horizontalScrollBar()->value();
int yOffset = graphicsView->verticalScrollBar()->value();
return view->mapRectFromScene(QRectF(QPointF(xOffset, yOffset), graphicsView->viewport()->size()));
}
#endif
QObject* PageClientQGraphicsWidget::pluginParent() const
{
return view;
}
QStyle* PageClientQGraphicsWidget::style() const
{
return view->style();
}
void PageClientQGraphicsWidget::setWidgetVisible(Widget*, bool)
{
}
QRectF PageClientQGraphicsWidget::windowRect() const
{
if (!view->scene())
return QRectF();
return view->scene()->sceneRect();
}
#endif // QT_NO_GRAPHICSVIEW
#if ENABLE(WEBGL)
void PageClientQGraphicsWidget::createPlatformGraphicsContext3D(PlatformGraphicsContext3D* context,
PlatformGraphicsSurface3D* surface)
{
createPlatformGraphicsContext3DFromWidget(ownerWidget(), context, surface);
}
#endif
}