summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/qt
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/qt')
-rw-r--r--Source/WebKit2/UIProcess/qt/BackingStoreQt.cpp75
-rw-r--r--Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp635
-rw-r--r--Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp136
-rw-r--r--Source/WebKit2/UIProcess/qt/QtDialogRunner.h63
-rw-r--r--Source/WebKit2/UIProcess/qt/QtDownloadManager.cpp145
-rw-r--r--Source/WebKit2/UIProcess/qt/QtDownloadManager.h64
-rw-r--r--Source/WebKit2/UIProcess/qt/QtGestureRecognizer.cpp49
-rw-r--r--Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h55
-rw-r--r--Source/WebKit2/UIProcess/qt/QtPageClient.cpp256
-rw-r--r--Source/WebKit2/UIProcess/qt/QtPageClient.h107
-rw-r--r--Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp104
-rw-r--r--Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h54
-rw-r--r--Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp157
-rw-r--r--Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h83
-rw-r--r--Source/WebKit2/UIProcess/qt/QtSGTileNode.cpp73
-rw-r--r--Source/WebKit2/UIProcess/qt/QtSGTileNode.h54
-rw-r--r--Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.cpp170
-rw-r--r--Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.h82
-rw-r--r--Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp161
-rw-r--r--Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h76
-rw-r--r--Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp589
-rw-r--r--Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h171
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebContext.cpp157
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebContext.h82
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebError.cpp67
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebError.h60
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp122
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h67
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp500
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h97
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp197
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h67
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp136
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.h43
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPageUIClient.cpp147
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPageUIClient.h64
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebUndoController.cpp63
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebUndoController.h41
-rw-r--r--Source/WebKit2/UIProcess/qt/TextCheckerQt.cpp129
-rw-r--r--Source/WebKit2/UIProcess/qt/TiledDrawingAreaProxyQt.cpp83
-rw-r--r--Source/WebKit2/UIProcess/qt/WebContextMenuProxyQt.cpp53
-rw-r--r--Source/WebKit2/UIProcess/qt/WebContextMenuProxyQt.h51
-rw-r--r--Source/WebKit2/UIProcess/qt/WebContextQt.cpp107
-rw-r--r--Source/WebKit2/UIProcess/qt/WebFullScreenManagerProxyQt.cpp86
-rw-r--r--Source/WebKit2/UIProcess/qt/WebGeolocationProviderQt.cpp119
-rw-r--r--Source/WebKit2/UIProcess/qt/WebGeolocationProviderQt.h56
-rw-r--r--Source/WebKit2/UIProcess/qt/WebInspectorProxyQt.cpp97
-rw-r--r--Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp105
-rw-r--r--Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp316
-rw-r--r--Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.h76
-rw-r--r--Source/WebKit2/UIProcess/qt/WebPreferencesQt.cpp51
51 files changed, 6598 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/qt/BackingStoreQt.cpp b/Source/WebKit2/UIProcess/qt/BackingStoreQt.cpp
new file mode 100644
index 000000000..1af16d842
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/BackingStoreQt.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011 Andreas Kling <kling@webkit.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BackingStore.h"
+
+#include "UpdateInfo.h"
+#include "ShareableBitmap.h"
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/IntRect.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void BackingStore::paint(QPainter* painter, const IntRect& rect)
+{
+ ASSERT(!m_pixmap.isNull());
+ painter->drawPixmap(rect, m_pixmap, rect);
+}
+
+void BackingStore::incorporateUpdate(ShareableBitmap* bitmap, const UpdateInfo& updateInfo)
+{
+ if (m_pixmap.isNull())
+ m_pixmap = QPixmap(m_size);
+
+ scroll(updateInfo.scrollRect, updateInfo.scrollOffset);
+
+ IntPoint updateRectLocation = updateInfo.updateRectBounds.location();
+
+ QPainter painter(&m_pixmap);
+ GraphicsContext graphicsContext(&painter);
+
+ // Paint all update rects.
+ for (size_t i = 0; i < updateInfo.updateRects.size(); ++i) {
+ IntRect updateRect = updateInfo.updateRects[i];
+ IntRect srcRect = updateRect;
+ srcRect.move(-updateRectLocation.x(), -updateRectLocation.y());
+ bitmap->paint(graphicsContext, updateRect.location(), srcRect);
+ }
+}
+
+void BackingStore::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
+{
+ if (scrollOffset.isZero())
+ return;
+
+ m_pixmap.scroll(scrollOffset.width(), scrollOffset.height(), scrollRect);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp b/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp
new file mode 100644
index 000000000..a1dd272a7
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp
@@ -0,0 +1,635 @@
+/*
+ Copyright (C) 2011 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"
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "LayerTreeHostProxy.h"
+
+#include "LayerTreeHostMessages.h"
+#include "MainThread.h"
+#include "MessageID.h"
+#include "ShareableBitmap.h"
+#include "TextureMapperGL.h"
+#include "UpdateInfo.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebLayerTreeInfo.h"
+#include "WebPageProxy.h"
+#include "WebProcessProxy.h"
+#include "texmap/GraphicsLayerTextureMapper.h"
+#include "texmap/TextureMapper.h"
+#include "texmap/TextureMapperNode.h"
+#include <QDateTime>
+#include <cairo/OpenGLShims.h>
+
+namespace WebKit {
+
+class LayerTreeMessageToRenderer {
+public:
+ enum Type {
+ DeleteLayer,
+ CreateTile,
+ RemoveTile,
+ UpdateTile,
+ CreateImage,
+ DestroyImage,
+ SyncLayerParameters,
+ FlushLayerChanges,
+ SetRootLayer
+ };
+ virtual ~LayerTreeMessageToRenderer() { }
+ virtual Type type() const = 0;
+};
+
+template<class MessageData, LayerTreeMessageToRenderer::Type messageType>
+class LayerTreeMessageToRendererWithData : public LayerTreeMessageToRenderer {
+public:
+ virtual Type type() const { return messageType; }
+
+ static PassOwnPtr<LayerTreeMessageToRenderer> create(const MessageData& data = MessageData())
+ {
+ return adoptPtr(new LayerTreeMessageToRendererWithData(data));
+ }
+
+ const MessageData& data() const
+ {
+ return m_data;
+ }
+
+private:
+ LayerTreeMessageToRendererWithData(const MessageData& data)
+ : m_data(data)
+ {
+ }
+
+ MessageData m_data;
+};
+
+
+namespace {
+struct CreateTileMessageData {
+ WebLayerID layerID;
+ int remoteTileID;
+ float scale;
+};
+
+struct UpdateTileMessageData {
+ WebLayerID layerID;
+ int remoteTileID;
+ IntRect sourceRect;
+ IntRect targetRect;
+ QImage image;
+};
+
+struct RemoveTileMessageData {
+ WebLayerID layerID;
+ int remoteTileID;
+};
+
+struct CreateImageMessageData {
+ int64_t imageID;
+ QImage image;
+};
+
+struct DestroyImageMessageData {
+ int64_t imageID;
+};
+
+struct SyncLayerParametersMessageData {
+ WebLayerInfo layerInfo;
+};
+
+struct EmptyMessageData { };
+struct DeleteLayerMessageData {
+ WebLayerID layerID;
+};
+struct SetRootLayerMessageData {
+ WebLayerID layerID;
+};
+
+class CreateTileMessage
+ : public LayerTreeMessageToRendererWithData<CreateTileMessageData, LayerTreeMessageToRenderer::CreateTile> { };
+class UpdateTileMessage
+ : public LayerTreeMessageToRendererWithData<UpdateTileMessageData, LayerTreeMessageToRenderer::UpdateTile> { };
+class RemoveTileMessage
+ : public LayerTreeMessageToRendererWithData<RemoveTileMessageData, LayerTreeMessageToRenderer::RemoveTile> { };
+class CreateImageMessage
+ : public LayerTreeMessageToRendererWithData<CreateImageMessageData, LayerTreeMessageToRenderer::CreateImage> { };
+class DestroyImageMessage
+ : public LayerTreeMessageToRendererWithData<DestroyImageMessageData, LayerTreeMessageToRenderer::DestroyImage> { };
+class FlushLayerChangesMessage
+ : public LayerTreeMessageToRendererWithData<EmptyMessageData, LayerTreeMessageToRenderer::FlushLayerChanges> { };
+class SyncLayerParametersMessage
+ : public LayerTreeMessageToRendererWithData<SyncLayerParametersMessageData, LayerTreeMessageToRenderer::SyncLayerParameters> { };
+class DeleteLayerMessage
+ : public LayerTreeMessageToRendererWithData<DeleteLayerMessageData, LayerTreeMessageToRenderer::DeleteLayer> { };
+class SetRootLayerMessage
+ : public LayerTreeMessageToRendererWithData<SetRootLayerMessageData, LayerTreeMessageToRenderer::SetRootLayer> { };
+}
+
+PassOwnPtr<GraphicsLayer> LayerTreeHostProxy::createLayer(WebLayerID layerID)
+{
+ GraphicsLayer* newLayer = new GraphicsLayerTextureMapper(this);
+ TextureMapperNode* node = toTextureMapperNode(newLayer);
+ node->setID(layerID);
+ node->setTileOwnership(TextureMapperNode::ExternallyManagedTiles);
+ return adoptPtr(newLayer);
+}
+
+LayerTreeHostProxy::LayerTreeHostProxy(DrawingAreaProxy* drawingAreaProxy)
+ : m_animationTimer(RunLoop::main(), this, &LayerTreeHostProxy::updateViewport)
+ , m_drawingAreaProxy(drawingAreaProxy)
+ , m_viewportUpdateTimer(this, &LayerTreeHostProxy::didFireViewportUpdateTimer)
+ , m_rootLayerID(0)
+{
+}
+
+LayerTreeHostProxy::~LayerTreeHostProxy()
+{
+}
+
+// This function needs to be reentrant.
+void LayerTreeHostProxy::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity)
+{
+ if (!m_textureMapper)
+ m_textureMapper = TextureMapperGL::create();
+
+ syncRemoteContent();
+ GraphicsLayer* currentRootLayer = rootLayer();
+ if (!currentRootLayer)
+ return;
+
+ TextureMapperNode* node = toTextureMapperNode(currentRootLayer);
+
+ if (!node)
+ return;
+
+ GLint viewport[4];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ IntRect viewportRect(viewport[0], viewport[1], viewport[2], viewport[3]);
+ m_textureMapper->setViewportSize(IntSize(viewport[2], viewport[3]));
+ node->setTextureMapper(m_textureMapper.get());
+ m_textureMapper->beginPainting();
+ m_textureMapper->bindSurface(0);
+
+ if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
+ currentRootLayer->setOpacity(opacity);
+ currentRootLayer->setTransform(matrix);
+ currentRootLayer->syncCompositingStateForThisLayerOnly();
+ }
+
+ TextureMapperNode::NodeRectMap nodeVisualContentsRectMap;
+ if (node->collectVisibleContentsRects(nodeVisualContentsRectMap, viewportRect)) {
+ TextureMapperNode::NodeRectMap::iterator endIterator = nodeVisualContentsRectMap.end();
+ for (TextureMapperNode::NodeRectMap::iterator it = nodeVisualContentsRectMap.begin(); it != endIterator; ++it) {
+ WebLayerID layerID = it->first->id();
+ // avoid updating non-synced root layer
+ if (!layerID)
+ continue;
+ IntRect visibleRect = IntRect(it->second);
+ setVisibleContentsRectForLayer(layerID, visibleRect);
+ }
+ }
+ node->paint();
+
+ m_textureMapper->endPainting();
+
+ if (node->descendantsOrSelfHaveRunningAnimations()) {
+ node->syncAnimationsRecursively();
+ m_viewportUpdateTimer.startOneShot(0);
+ }
+}
+
+void LayerTreeHostProxy::didFireViewportUpdateTimer(Timer<LayerTreeHostProxy>*)
+{
+ updateViewport();
+}
+
+void LayerTreeHostProxy::updateViewport()
+{
+ m_drawingAreaProxy->updateViewport();
+}
+
+void LayerTreeHostProxy::setVisibleContentsRectForLayer(WebLayerID layerID, const IntRect& rect)
+{
+ m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::SetVisibleContentRectForLayer(layerID, rect), m_drawingAreaProxy->page()->pageID());
+}
+
+int LayerTreeHostProxy::remoteTileIDToNodeTileID(int tileID) const
+{
+ HashMap<int, int>::const_iterator it = m_tileToNodeTile.find(tileID);
+ if (it == m_tileToNodeTile.end())
+ return 0;
+ return it->second;
+}
+
+void LayerTreeHostProxy::syncLayerParameters(const WebLayerInfo& layerInfo)
+{
+ WebLayerID id = layerInfo.id;
+ ensureLayer(id);
+ LayerMap::iterator it = m_layers.find(id);
+ GraphicsLayer* layer = it->second;
+
+ layer->setName(layerInfo.name);
+
+ layer->setReplicatedByLayer(layerByID(layerInfo.replica));
+ layer->setMaskLayer(layerByID(layerInfo.mask));
+
+ layer->setPosition(layerInfo.pos);
+ layer->setSize(layerInfo.size);
+ layer->setTransform(layerInfo.transform);
+ layer->setAnchorPoint(layerInfo.anchorPoint);
+ layer->setChildrenTransform(layerInfo.childrenTransform);
+ layer->setBackfaceVisibility(layerInfo.backfaceVisible);
+ layer->setContentsOpaque(layerInfo.contentsOpaque);
+ layer->setContentsRect(layerInfo.contentsRect);
+ layer->setDrawsContent(layerInfo.drawsContent);
+
+ if (layerInfo.imageIsUpdated)
+ assignImageToLayer(layer, layerInfo.imageBackingStoreID);
+
+ // Never make the root layer clip.
+ layer->setMasksToBounds(layerInfo.isRootLayer ? false : layerInfo.masksToBounds);
+ layer->setOpacity(layerInfo.opacity);
+ layer->setPreserves3D(layerInfo.preserves3D);
+ Vector<GraphicsLayer*> children;
+
+ for (size_t i = 0; i < layerInfo.children.size(); ++i) {
+ WebLayerID childID = layerInfo.children[i];
+ GraphicsLayer* child = layerByID(childID);
+ if (!child) {
+ child = createLayer(childID).leakPtr();
+ m_layers.add(childID, child);
+ }
+ children.append(child);
+ }
+ layer->setChildren(children);
+
+ for (size_t i = 0; i < layerInfo.animations.size(); ++i) {
+ const WebKit::WebLayerAnimation anim = layerInfo.animations[i];
+
+ switch (anim.operation) {
+ case WebKit::WebLayerAnimation::AddAnimation: {
+ const IntSize boxSize = anim.boxSize;
+ layer->addAnimation(anim.keyframeList, boxSize, anim.animation.get(), anim.name, anim.startTime);
+ break;
+ }
+ case WebKit::WebLayerAnimation::RemoveAnimation:
+ layer->removeAnimation(anim.name);
+ break;
+ case WebKit::WebLayerAnimation::PauseAnimation:
+ double offset = WTF::currentTime() - anim.startTime;
+ layer->pauseAnimation(anim.name, offset);
+ break;
+ }
+ }
+
+ if (layerInfo.isRootLayer && m_rootLayerID != id)
+ setRootLayerID(id);
+}
+
+void LayerTreeHostProxy::deleteLayer(WebLayerID layerID)
+{
+ GraphicsLayer* layer = layerByID(layerID);
+ if (!layer)
+ return;
+
+ layer->removeFromParent();
+ m_layers.remove(layerID);
+ delete layer;
+}
+
+
+void LayerTreeHostProxy::ensureLayer(WebLayerID id)
+{
+ // We have to leak the new layer's pointer and manage it ourselves,
+ // because OwnPtr is not copyable.
+ if (m_layers.find(id) == m_layers.end())
+ m_layers.add(id, createLayer(id).leakPtr());
+}
+
+void LayerTreeHostProxy::setRootLayerID(WebLayerID layerID)
+{
+ if (layerID == m_rootLayerID)
+ return;
+
+ m_rootLayerID = layerID;
+
+ m_rootLayer->removeAllChildren();
+
+ if (!layerID)
+ return;
+
+ GraphicsLayer* layer = layerByID(layerID);
+ if (!layer)
+ return;
+
+ m_rootLayer->addChild(layer);
+}
+
+void LayerTreeHostProxy::createTile(WebLayerID layerID, int tileID, float scale)
+{
+ ensureLayer(layerID);
+ TextureMapperNode* node = toTextureMapperNode(layerByID(layerID));
+
+ int nodeTileID = node->createContentsTile(scale);
+ m_tileToNodeTile.add(tileID, nodeTileID);
+}
+
+void LayerTreeHostProxy::removeTile(WebLayerID layerID, int tileID)
+{
+ TextureMapperNode* node = toTextureMapperNode(layerByID(layerID));
+ if (!node)
+ return;
+
+ int nodeTileID = remoteTileIDToNodeTileID(tileID);
+ if (!nodeTileID)
+ return;
+
+ node->removeContentsTile(nodeTileID);
+ m_tileToNodeTile.remove(tileID);
+}
+
+void LayerTreeHostProxy::updateTile(WebLayerID layerID, int tileID, const IntRect& sourceRect, const IntRect& targetRect, const QImage& image)
+{
+ ensureLayer(layerID);
+ TextureMapperNode* node = toTextureMapperNode(layerByID(layerID));
+ if (!node)
+ return;
+
+ int nodeTileID = remoteTileIDToNodeTileID(tileID);
+ if (!nodeTileID)
+ return;
+
+ QImage imageRef(image);
+ node->setTextureMapper(m_textureMapper.get());
+ node->setContentsTileBackBuffer(nodeTileID, sourceRect, targetRect, imageRef.bits(), BitmapTexture::BGRAFormat);
+}
+
+void LayerTreeHostProxy::createImage(int64_t imageID, const QImage& image)
+{
+ TiledImage tiledImage;
+ static const int TileDimension = 1024;
+ bool imageHasAlpha = image.hasAlphaChannel();
+ IntRect imageRect(0, 0, image.width(), image.height());
+ for (int y = 0; y < image.height(); y += TileDimension) {
+ for (int x = 0; x < image.width(); x += TileDimension) {
+ QImage subImage;
+ IntRect rect(x, y, TileDimension, TileDimension);
+ rect.intersect(imageRect);
+ if (QSize(rect.size()) == image.size())
+ subImage = image;
+ else
+ subImage = image.copy(rect);
+ RefPtr<BitmapTexture> texture = m_textureMapper->createTexture();
+ texture->reset(rect.size(), !imageHasAlpha);
+ texture->updateContents(imageHasAlpha ? BitmapTexture::BGRAFormat : BitmapTexture::BGRFormat, IntRect(IntPoint::zero(), rect.size()), subImage.bits());
+ tiledImage.add(rect.location(), texture);
+ }
+ }
+
+ m_directlyCompositedImages.remove(imageID);
+ m_directlyCompositedImages.add(imageID, tiledImage);
+}
+
+void LayerTreeHostProxy::destroyImage(int64_t imageID)
+{
+ m_directlyCompositedImages.remove(imageID);
+}
+
+void LayerTreeHostProxy::assignImageToLayer(GraphicsLayer* layer, int64_t imageID)
+{
+ TextureMapperNode* node = toTextureMapperNode(layer);
+ if (!node)
+ return;
+
+ if (!imageID) {
+ node->clearAllDirectlyCompositedImageTiles();
+ return;
+ }
+
+ FloatSize size(layer->size());
+ FloatRect contentsRect(layer->contentsRect());
+ float horizontalFactor = contentsRect.width() / size.width();
+ float verticalFactor = contentsRect.height() / size.height();
+ HashMap<int64_t, TiledImage>::iterator it = m_directlyCompositedImages.find(imageID);
+ if (it == m_directlyCompositedImages.end())
+ return;
+
+ TiledImage::iterator endTileIterator = it->second.end();
+ for (TiledImage::iterator tileIt = it->second.begin(); tileIt != endTileIterator; ++tileIt) {
+ FloatRect sourceRect(FloatPoint(tileIt->first), FloatSize(tileIt->second->size()));
+ FloatRect targetRect(sourceRect.x() * horizontalFactor + contentsRect.x(),
+ sourceRect.y() * verticalFactor + contentsRect.y(),
+ sourceRect.width() * horizontalFactor,
+ sourceRect.height() * verticalFactor);
+ int newTileID = node->createContentsTile(1.0);
+ node->setTileBackBufferTextureForDirectlyCompositedImage(newTileID, IntRect(sourceRect), targetRect, tileIt->second.get());
+ }
+}
+
+void LayerTreeHostProxy::flushLayerChanges()
+{
+ m_rootLayer->syncCompositingState(FloatRect());
+}
+
+void LayerTreeHostProxy::ensureRootLayer()
+{
+ if (m_rootLayer)
+ return;
+ m_rootLayer = createLayer(InvalidWebLayerID);
+ m_rootLayer->setMasksToBounds(false);
+ m_rootLayer->setDrawsContent(false);
+ m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
+
+ // The root layer should not have zero size, or it would be optimized out.
+ m_rootLayer->setSize(FloatSize(1.0, 1.0));
+ m_textureMapper = TextureMapperGL::create();
+ toTextureMapperNode(m_rootLayer.get())->setTextureMapper(m_textureMapper.get());
+}
+
+void LayerTreeHostProxy::syncRemoteContent()
+{
+ // We enqueue messages and execute them during paint, as they require an active GL context.
+ ensureRootLayer();
+
+ while (OwnPtr<LayerTreeMessageToRenderer> nextMessage = m_messagesToRenderer.tryGetMessage()) {
+ switch (nextMessage->type()) {
+ case LayerTreeMessageToRenderer::SetRootLayer: {
+ const SetRootLayerMessageData& data = static_cast<SetRootLayerMessage*>(nextMessage.get())->data();
+ setRootLayerID(data.layerID);
+ break;
+ }
+
+ case LayerTreeMessageToRenderer::DeleteLayer: {
+ const DeleteLayerMessageData& data = static_cast<DeleteLayerMessage*>(nextMessage.get())->data();
+ deleteLayer(data.layerID);
+ break;
+ }
+
+ case LayerTreeMessageToRenderer::SyncLayerParameters: {
+ const SyncLayerParametersMessageData& data = static_cast<SyncLayerParametersMessage*>(nextMessage.get())->data();
+ syncLayerParameters(data.layerInfo);
+ break;
+ }
+
+ case LayerTreeMessageToRenderer::CreateTile: {
+ const CreateTileMessageData& data = static_cast<CreateTileMessage*>(nextMessage.get())->data();
+ createTile(data.layerID, data.remoteTileID, data.scale);
+ break;
+ }
+
+ case LayerTreeMessageToRenderer::RemoveTile: {
+ const RemoveTileMessageData& data = static_cast<RemoveTileMessage*>(nextMessage.get())->data();
+ removeTile(data.layerID, data.remoteTileID);
+ break;
+ }
+
+ case LayerTreeMessageToRenderer::UpdateTile: {
+ const UpdateTileMessageData& data = static_cast<UpdateTileMessage*>(nextMessage.get())->data();
+ updateTile(data.layerID, data.remoteTileID, data.sourceRect, data.targetRect, data.image);
+ break;
+ }
+
+ case LayerTreeMessageToRenderer::CreateImage: {
+ const CreateImageMessageData& data = static_cast<CreateImageMessage*>(nextMessage.get())->data();
+ createImage(data.imageID, data.image);
+ break;
+ }
+
+ case LayerTreeMessageToRenderer::DestroyImage: {
+ const CreateImageMessageData& data = static_cast<CreateImageMessage*>(nextMessage.get())->data();
+ destroyImage(data.imageID);
+ break;
+ }
+
+ case LayerTreeMessageToRenderer::FlushLayerChanges:
+ flushLayerChanges();
+ break;
+ }
+ }
+}
+
+void LayerTreeHostProxy::pushUpdateToQueue(PassOwnPtr<LayerTreeMessageToRenderer> message)
+{
+ m_messagesToRenderer.append(message);
+ updateViewport();
+}
+
+void LayerTreeHostProxy::createTileForLayer(int layerID, int tileID, const WebKit::UpdateInfo& updateInfo)
+{
+ CreateTileMessageData data;
+ data.layerID = layerID;
+ data.remoteTileID = tileID;
+ data.scale = updateInfo.updateScaleFactor;
+ pushUpdateToQueue(CreateTileMessage::create(data));
+ updateTileForLayer(layerID, tileID, updateInfo);
+}
+
+void LayerTreeHostProxy::updateTileForLayer(int layerID, int tileID, const WebKit::UpdateInfo& updateInfo)
+{
+ UpdateTileMessageData data;
+ data.layerID = layerID;
+ data.remoteTileID = tileID;
+ RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(updateInfo.bitmapHandle);
+ data.image = bitmap->createQImage().copy();
+ data.sourceRect = IntRect(IntPoint::zero(), updateInfo.updateRectBounds.size());
+ data.targetRect = updateInfo.updateRectBounds;
+ pushUpdateToQueue(UpdateTileMessage::create(data));
+}
+
+void LayerTreeHostProxy::removeTileForLayer(int layerID, int tileID)
+{
+ RemoveTileMessageData data;
+ data.layerID = layerID;
+ data.remoteTileID = tileID;
+ pushUpdateToQueue(RemoveTileMessage::create(data));
+}
+
+
+void LayerTreeHostProxy::deleteCompositingLayer(WebLayerID id)
+{
+ DeleteLayerMessageData data;
+ data.layerID = id;
+ pushUpdateToQueue(DeleteLayerMessage::create(data));
+}
+
+void LayerTreeHostProxy::setRootCompositingLayer(WebLayerID id)
+{
+ SetRootLayerMessageData data;
+ data.layerID = id;
+ pushUpdateToQueue(SetRootLayerMessage::create(data));
+}
+
+void LayerTreeHostProxy::syncCompositingLayerState(const WebLayerInfo& info)
+{
+ SyncLayerParametersMessageData data;
+ data.layerInfo = info;
+ pushUpdateToQueue(SyncLayerParametersMessage::create(data));
+}
+
+void LayerTreeHostProxy::didRenderFrame()
+{
+ m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::RenderNextFrame(), m_drawingAreaProxy->page()->pageID());
+ pushUpdateToQueue(FlushLayerChangesMessage::create());
+ updateViewport();
+}
+
+void LayerTreeHostProxy::createDirectlyCompositedImage(int64_t key, const WebKit::ShareableBitmap::Handle& handle)
+{
+ CreateImageMessageData data;
+ RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
+ data.imageID = key;
+ data.image = bitmap->createQImage().copy();
+ pushUpdateToQueue(CreateImageMessage::create(data));
+}
+
+void LayerTreeHostProxy::destroyDirectlyCompositedImage(int64_t key)
+{
+ DestroyImageMessageData data;
+ data.imageID = key;
+ pushUpdateToQueue(DestroyImageMessage::create(data));
+}
+
+void LayerTreeHostProxy::setVisibleContentRectTrajectoryVector(const FloatPoint& trajectoryVector)
+{
+ m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::SetVisibleContentRectTrajectoryVector(trajectoryVector), m_drawingAreaProxy->page()->pageID());
+}
+
+void LayerTreeHostProxy::setVisibleContentsRectAndScale(const IntRect& rect, float scale)
+{
+ m_visibleContentsRect = rect;
+ m_contentsScale = scale;
+ m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::SetVisibleContentRectAndScale(rect, scale), m_drawingAreaProxy->page()->pageID());
+}
+
+void LayerTreeHostProxy::purgeGLResources()
+{
+ TextureMapperNode* node = toTextureMapperNode(rootLayer());
+
+ node->purgeNodeTexturesRecursive();
+ m_directlyCompositedImages.clear();
+
+ m_textureMapper.clear();
+
+ m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::PurgeBackingStores(), m_drawingAreaProxy->page()->pageID());
+}
+
+}
+#endif
diff --git a/Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp b/Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp
new file mode 100644
index 000000000..32de21af7
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtDialogRunner.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 "QtDialogRunner.h"
+
+#include <QtDeclarative/QDeclarativeComponent>
+#include <QtDeclarative/QDeclarativeContext>
+#include <QtDeclarative/QDeclarativeEngine>
+#include <QtQuick/QQuickItem>
+#include <wtf/PassOwnPtr.h>
+
+QtDialogRunner::QtDialogRunner()
+ : QEventLoop()
+ , m_wasAccepted(false)
+{
+}
+
+QtDialogRunner::~QtDialogRunner()
+{
+}
+
+class DialogContextObject : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QString message READ message CONSTANT)
+ Q_PROPERTY(QString defaultValue READ defaultValue CONSTANT)
+
+public:
+ DialogContextObject(const QString& message, const QString& defaultValue = QString())
+ : QObject()
+ , m_message(message)
+ , m_defaultValue(defaultValue)
+ {
+ }
+ QString message() const { return m_message; }
+ QString defaultValue() const { return m_defaultValue; }
+
+public slots:
+ void dismiss() { emit dismissed(); }
+ void accept() { emit accepted(); }
+ void accept(const QString& result) { emit accepted(result); }
+ void reject() { emit rejected(); }
+
+signals:
+ void dismissed();
+ void accepted();
+ void accepted(const QString& result);
+ void rejected();
+
+private:
+ QString m_message;
+ QString m_defaultValue;
+};
+
+bool QtDialogRunner::initForAlert(QDeclarativeComponent* component, QQuickItem* dialogParent, const QString& message)
+{
+ DialogContextObject* contextObject = new DialogContextObject(message);
+ if (!createDialog(component, dialogParent, contextObject))
+ return false;
+
+ connect(contextObject, SIGNAL(dismissed()), SLOT(quit()));
+ return true;
+}
+
+bool QtDialogRunner::initForConfirm(QDeclarativeComponent* component, QQuickItem* dialogParent, const QString& message)
+{
+ DialogContextObject* contextObject = new DialogContextObject(message);
+ if (!createDialog(component, dialogParent, contextObject))
+ return false;
+
+ connect(contextObject, SIGNAL(accepted()), SLOT(onAccepted()));
+ connect(contextObject, SIGNAL(accepted()), SLOT(quit()));
+ connect(contextObject, SIGNAL(rejected()), SLOT(quit()));
+ return true;
+}
+
+bool QtDialogRunner::initForPrompt(QDeclarativeComponent* component, QQuickItem* dialogParent, const QString& message, const QString& defaultValue)
+{
+ DialogContextObject* contextObject = new DialogContextObject(message, defaultValue);
+ if (!createDialog(component, dialogParent, contextObject))
+ return false;
+
+ connect(contextObject, SIGNAL(accepted(QString)), SLOT(onAccepted(QString)));
+ connect(contextObject, SIGNAL(accepted(QString)), SLOT(quit()));
+ connect(contextObject, SIGNAL(rejected()), SLOT(quit()));
+ return true;
+}
+
+bool QtDialogRunner::createDialog(QDeclarativeComponent* component, QQuickItem* dialogParent, QObject* contextObject)
+{
+ QDeclarativeContext* baseContext = component->creationContext();
+ if (!baseContext)
+ baseContext = QDeclarativeEngine::contextForObject(dialogParent);
+ m_dialogContext = adoptPtr(new QDeclarativeContext(baseContext));
+
+ // This makes both "message" and "model.message" work for the dialog, just like QtQuick's ListView delegates.
+ contextObject->setParent(m_dialogContext.get());
+ m_dialogContext->setContextProperty(QLatin1String("model"), contextObject);
+ m_dialogContext->setContextObject(contextObject);
+
+ QObject* object = component->create(m_dialogContext.get());
+ if (!object) {
+ m_dialogContext.clear();
+ return false;
+ }
+
+ m_dialog = adoptPtr(qobject_cast<QQuickItem*>(object));
+ if (!m_dialog) {
+ m_dialogContext.clear();
+ m_dialog.clear();
+ return false;
+ }
+
+ m_dialog->setParentItem(dialogParent);
+ return true;
+}
+
+#include "QtDialogRunner.moc"
+#include "moc_QtDialogRunner.cpp"
diff --git a/Source/WebKit2/UIProcess/qt/QtDialogRunner.h b/Source/WebKit2/UIProcess/qt/QtDialogRunner.h
new file mode 100644
index 000000000..bfa530264
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtDialogRunner.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 QtDialogRunner_h
+#define QtDialogRunner_h
+
+#include <QtCore/QEventLoop>
+#include <wtf/OwnPtr.h>
+
+class QDeclarativeComponent;
+class QDeclarativeContext;
+class QQuickItem;
+
+class QtDialogRunner : public QEventLoop {
+ Q_OBJECT
+
+public:
+ QtDialogRunner();
+ virtual ~QtDialogRunner();
+
+ bool initForAlert(QDeclarativeComponent*, QQuickItem* dialogParent, const QString& message);
+ bool initForConfirm(QDeclarativeComponent*, QQuickItem* dialogParent, const QString& message);
+ bool initForPrompt(QDeclarativeComponent*, QQuickItem* dialogParent, const QString& message, const QString& defaultValue);
+
+ QQuickItem* dialog() const { return m_dialog.get(); }
+
+ bool wasAccepted() const { return m_wasAccepted; }
+ QString result() const { return m_result; }
+
+public slots:
+ void onAccepted(const QString& result = QString())
+ {
+ m_wasAccepted = true;
+ m_result = result;
+ }
+
+private:
+ bool createDialog(QDeclarativeComponent*, QQuickItem* dialogParent, QObject* contextObject);
+
+ OwnPtr<QDeclarativeContext> m_dialogContext;
+ OwnPtr<QQuickItem> m_dialog;
+ QString m_result;
+ bool m_wasAccepted;
+};
+
+#endif // QtDialogRunner_h
diff --git a/Source/WebKit2/UIProcess/qt/QtDownloadManager.cpp b/Source/WebKit2/UIProcess/qt/QtDownloadManager.cpp
new file mode 100644
index 000000000..99c4dc58e
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtDownloadManager.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010, 2011 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 program 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 program; 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 "QtDownloadManager.h"
+
+#include "DownloadProxy.h"
+#include "QtWebError.h"
+#include "WKStringQt.h"
+#include "WKURLQt.h"
+#include "WebContext.h"
+#include "qwebdownloaditem_p.h"
+#include "qwebdownloaditem_p_p.h"
+
+namespace WebKit {
+
+QtDownloadManager::QtDownloadManager(WebContext* context)
+{
+ WKContextDownloadClient downloadClient;
+ memset(&downloadClient, 0, sizeof(WKContextDownloadClient));
+ downloadClient.version = kWKContextDownloadClientCurrentVersion;
+ downloadClient.clientInfo = this;
+ downloadClient.didReceiveResponse = didReceiveResponse;
+ downloadClient.didReceiveData = didReceiveDataForDownload;
+ downloadClient.didCreateDestination = didCreateDestination;
+ downloadClient.didFinish = didFinishDownload;
+ downloadClient.didFail = didFailDownload;
+ WKContextSetDownloadClient(toAPI(context), &downloadClient);
+}
+
+QtDownloadManager::~QtDownloadManager()
+{
+}
+
+void QtDownloadManager::addDownload(DownloadProxy* download, QWebDownloadItem* downloadItem)
+{
+ m_downloads[download->downloadID()] = downloadItem;
+}
+
+void QtDownloadManager::downloadReceivedResponse(DownloadProxy* download, const WebCore::ResourceResponse& response)
+{
+ // Will be called when the headers are read by WebProcess.
+ QWebDownloadItem* downloadItem = m_downloads.value(download->downloadID());
+ ASSERT(downloadItem);
+
+ downloadItem->d->sourceUrl = response.url();
+ downloadItem->d->mimeType = response.mimeType();
+ downloadItem->d->expectedContentLength = response.expectedContentLength();
+ downloadItem->d->suggestedFilename = response.suggestedFilename();
+
+ downloadItem->d->didReceiveResponse(downloadItem);
+}
+
+void QtDownloadManager::downloadCreatedDestination(DownloadProxy* download, const QString& path)
+{
+ QWebDownloadItem* downloadItem = m_downloads.value(download->downloadID());
+ ASSERT(downloadItem);
+ downloadItem->d->destinationPath = path;
+ emit downloadItem->destinationFileCreated(downloadItem->d->destinationPath);
+}
+
+void QtDownloadManager::downloadFinished(DownloadProxy* download)
+{
+ // Will be called when download finishes with success.
+ QWebDownloadItem* downloadItem = m_downloads.take(download->downloadID());
+ ASSERT(downloadItem);
+ emit downloadItem->succeeded();
+}
+
+void QtDownloadManager::downloadFailed(DownloadProxy* download, const QtWebError& error)
+{
+ // Will be called when download fails or is aborted.
+ QWebDownloadItem* downloadItem = m_downloads.take(download->downloadID());
+ ASSERT(downloadItem);
+
+ // If the parent is null at this point, the download failed before it
+ // received a response and downloadRequested was emitted.
+ // Due to this the item will never be parented and we have to delete it
+ // manually at this point.
+ if (!downloadItem->parent()) {
+ delete downloadItem;
+ return;
+ }
+
+ emit downloadItem->failed(error.errorCodeAsDownloadError(), error.url(), error.description());
+}
+
+void QtDownloadManager::downloadDataReceived(DownloadProxy* download, uint64_t length)
+{
+ // Will be called everytime bytes were written to destination file by WebProcess.
+ QWebDownloadItem* downloadItem = m_downloads.value(download->downloadID());
+ ASSERT(downloadItem);
+ downloadItem->d->totalBytesReceived += length;
+ emit downloadItem->totalBytesReceivedChanged(length);
+}
+
+static inline QtDownloadManager* toQtDownloadManager(const void* clientInfo)
+{
+ ASSERT(clientInfo);
+ return reinterpret_cast<QtDownloadManager*>(const_cast<void*>(clientInfo));
+}
+
+void QtDownloadManager::didReceiveResponse(WKContextRef, WKDownloadRef download, WKURLResponseRef response, const void *clientInfo)
+{
+ toQtDownloadManager(clientInfo)->downloadReceivedResponse(toImpl(download), toImpl(response)->resourceResponse());
+}
+
+void QtDownloadManager::didCreateDestination(WKContextRef, WKDownloadRef download, WKStringRef path, const void *clientInfo)
+{
+ toQtDownloadManager(clientInfo)->downloadCreatedDestination(toImpl(download), WKStringCopyQString(path));
+}
+
+void QtDownloadManager::didFinishDownload(WKContextRef, WKDownloadRef download, const void *clientInfo)
+{
+ toQtDownloadManager(clientInfo)->downloadFinished(toImpl(download));
+}
+
+void QtDownloadManager::didFailDownload(WKContextRef, WKDownloadRef download, WKErrorRef error, const void *clientInfo)
+{
+ toQtDownloadManager(clientInfo)->downloadFailed(toImpl(download), QtWebError(error));
+}
+
+void QtDownloadManager::didReceiveDataForDownload(WKContextRef, WKDownloadRef download, uint64_t length, const void *clientInfo)
+{
+ toQtDownloadManager(clientInfo)->downloadDataReceived(toImpl(download), length);
+}
+
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtDownloadManager.h b/Source/WebKit2/UIProcess/qt/QtDownloadManager.h
new file mode 100644
index 000000000..5e8d5ee43
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtDownloadManager.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010, 2011 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 program 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 program; 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 QtDownloadManager_h
+#define QtDownloadManager_h
+
+#include <QMap>
+#include <WKContext.h>
+
+class QtWebError;
+class QWebDownloadItem;
+
+namespace WebCore {
+class ResourceResponse;
+}
+
+namespace WebKit {
+
+class DownloadProxy;
+class WebContext;
+
+class QtDownloadManager {
+public:
+ QtDownloadManager(WebContext*);
+ ~QtDownloadManager();
+
+ void addDownload(DownloadProxy*, QWebDownloadItem*);
+
+private:
+ void downloadReceivedResponse(DownloadProxy*, const WebCore::ResourceResponse&);
+ void downloadCreatedDestination(DownloadProxy*, const QString& path);
+ void downloadFinished(DownloadProxy*);
+ void downloadFailed(DownloadProxy*, const QtWebError&);
+ void downloadDataReceived(DownloadProxy*, uint64_t length);
+
+ // WKContextDownloadClient callbacks.
+ static void didReceiveResponse(WKContextRef, WKDownloadRef, WKURLResponseRef, const void* clientInfo);
+ static void didCreateDestination(WKContextRef, WKDownloadRef, WKStringRef path, const void* clientInfo);
+ static void didFinishDownload(WKContextRef, WKDownloadRef, const void* clientInfo);
+ static void didFailDownload(WKContextRef, WKDownloadRef, WKErrorRef, const void* clientInfo);
+ static void didReceiveDataForDownload(WKContextRef, WKDownloadRef, uint64_t length, const void* clientInfo);
+
+ QMap<uint64_t, QWebDownloadItem*> m_downloads;
+};
+
+}
+#endif /* QtDownloadManager_h */
diff --git a/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.cpp
new file mode 100644
index 000000000..0c62452c6
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "QtGestureRecognizer.h"
+
+#include "QtWebPageEventHandler.h"
+
+namespace WebKit {
+
+QtGestureRecognizer::QtGestureRecognizer(QtWebPageEventHandler* eventHandler)
+ : m_eventHandler(eventHandler)
+ , m_state(NoGesture)
+{
+}
+
+void QtGestureRecognizer::reset()
+{
+ m_state = NoGesture;
+}
+
+QtViewportInteractionEngine* QtGestureRecognizer::interactionEngine()
+{
+ return m_eventHandler->interactionEngine();
+}
+
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h
new file mode 100644
index 000000000..4c191f6e2
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef QtGestureRecognizer_h
+#define QtGestureRecognizer_h
+
+class QtWebPageEventHandler;
+
+namespace WebKit {
+
+class QtViewportInteractionEngine;
+
+class QtGestureRecognizer {
+public:
+ bool isRecognized() const { return m_state == GestureRecognized; }
+
+protected:
+ QtGestureRecognizer(QtWebPageEventHandler*);
+ void reset();
+
+ QtWebPageEventHandler* m_eventHandler;
+ enum State {
+ NoGesture,
+ GestureRecognitionStarted,
+ GestureRecognized
+ } m_state;
+
+ QtViewportInteractionEngine* interactionEngine();
+};
+
+}
+
+#endif /* QtGestureRecognizer_h */
diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp
new file mode 100644
index 000000000..b173776d8
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 "QtPageClient.h"
+
+#include "QtWebPageEventHandler.h"
+#include "QtWebUndoController.h"
+#include "WebContextMenuProxyQt.h"
+#include "WebEditCommandProxy.h"
+#include "WebPopupMenuProxyQt.h"
+#include "qquickwebview_p.h"
+#include "qquickwebview_p_p.h"
+#include <QGuiApplication>
+#include <WebCore/Cursor.h>
+#include <WebCore/DragData.h>
+#include <WebCore/FloatRect.h>
+#include <WebCore/NotImplemented.h>
+
+using namespace WebKit;
+using namespace WebCore;
+
+QtPageClient::QtPageClient()
+ : m_webView(0)
+ , m_eventHandler(0)
+ , m_undoController(0)
+{
+}
+
+QtPageClient::~QtPageClient()
+{
+}
+
+void QtPageClient::initialize(QQuickWebView* webView, QtWebPageEventHandler* eventHandler, QtWebUndoController* undoController)
+{
+ m_webView = webView;
+ m_eventHandler = eventHandler;
+ m_undoController = undoController;
+}
+
+PassOwnPtr<DrawingAreaProxy> QtPageClient::createDrawingAreaProxy()
+{
+ return QQuickWebViewPrivate::get(m_webView)->createDrawingAreaProxy();
+}
+
+void QtPageClient::setViewNeedsDisplay(const WebCore::IntRect& rect)
+{
+ m_webView->page()->update();
+}
+
+void QtPageClient::pageDidRequestScroll(const IntPoint& pos)
+{
+ QQuickWebViewPrivate::get(m_webView)->pageDidRequestScroll(pos);
+}
+
+void QtPageClient::processDidCrash()
+{
+ QQuickWebViewPrivate::get(m_webView)->processDidCrash();
+}
+
+void QtPageClient::didRelaunchProcess()
+{
+ QQuickWebViewPrivate::get(m_webView)->didRelaunchProcess();
+}
+
+void QtPageClient::didChangeContentsSize(const IntSize& newSize)
+{
+ QQuickWebViewPrivate::get(m_webView)->didChangeContentsSize(newSize);
+}
+
+void QtPageClient::didChangeViewportProperties(const WebCore::ViewportArguments& args)
+{
+ QQuickWebViewPrivate::get(m_webView)->didChangeViewportProperties(args);
+}
+
+void QtPageClient::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage)
+{
+ m_eventHandler->startDrag(dragData, dragImage);
+}
+
+void QtPageClient::handleDownloadRequest(DownloadProxy* download)
+{
+ QQuickWebViewPrivate::get(m_webView)->handleDownloadRequest(download);
+}
+
+void QtPageClient::handleApplicationSchemeRequest(PassRefPtr<QtNetworkRequestData> requestData)
+{
+ if (!m_webView || !m_webView->experimental())
+ return;
+ m_webView->experimental()->invokeApplicationSchemeHandler(requestData.get());
+}
+
+void QtPageClient::setCursor(const WebCore::Cursor& cursor)
+{
+ // FIXME: This is a temporary fix until we get cursor support in QML items.
+ QGuiApplication::setOverrideCursor(*cursor.platformCursor());
+}
+
+void QtPageClient::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
+{
+ notImplemented();
+}
+
+void QtPageClient::toolTipChanged(const String&, const String& newTooltip)
+{
+ // There is not yet any UI defined for the tooltips for mobile so we ignore the change.
+}
+
+void QtPageClient::registerEditCommand(PassRefPtr<WebEditCommandProxy> command, WebPageProxy::UndoOrRedo undoOrRedo)
+{
+ m_undoController->registerEditCommand(command, undoOrRedo);
+}
+
+void QtPageClient::clearAllEditCommands()
+{
+ m_undoController->clearAllEditCommands();
+}
+
+bool QtPageClient::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
+{
+ return m_undoController->canUndoRedo(undoOrRedo);
+}
+
+void QtPageClient::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
+{
+ m_undoController->executeUndoRedo(undoOrRedo);
+}
+
+FloatRect QtPageClient::convertToDeviceSpace(const FloatRect& rect)
+{
+ return rect;
+}
+
+FloatRect QtPageClient::convertToUserSpace(const FloatRect& rect)
+{
+ return rect;
+}
+
+IntPoint QtPageClient::screenToWindow(const IntPoint& point)
+{
+ return point;
+}
+
+IntRect QtPageClient::windowToScreen(const IntRect& rect)
+{
+ return rect;
+}
+
+PassRefPtr<WebPopupMenuProxy> QtPageClient::createPopupMenuProxy(WebPageProxy* webPageProxy)
+{
+ return WebPopupMenuProxyQt::create(webPageProxy, m_webView);
+}
+
+PassRefPtr<WebContextMenuProxy> QtPageClient::createContextMenuProxy(WebPageProxy* webPageProxy)
+{
+ return WebContextMenuProxyQt::create(webPageProxy);
+}
+
+void QtPageClient::flashBackingStoreUpdates(const Vector<IntRect>&)
+{
+ notImplemented();
+}
+
+void QtPageClient::didFindZoomableArea(const IntPoint& target, const IntRect& area)
+{
+ ASSERT(m_eventHandler);
+ m_eventHandler->didFindZoomableArea(target, area);
+}
+
+void QtPageClient::focusEditableArea(const IntRect& caret, const IntRect& area)
+{
+ ASSERT(m_eventHandler);
+ m_eventHandler->focusEditableArea(caret, area);
+}
+
+void QtPageClient::didReceiveMessageFromNavigatorQtObject(const String& message)
+{
+ QQuickWebViewPrivate::get(m_webView)->didReceiveMessageFromNavigatorQtObject(message);
+}
+
+#if ENABLE(TOUCH_EVENTS)
+void QtPageClient::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
+{
+ ASSERT(m_eventHandler);
+ m_eventHandler->doneWithTouchEvent(event, wasEventHandled);
+}
+#endif
+
+void QtPageClient::displayView()
+{
+ // FIXME: Implement.
+}
+
+void QtPageClient::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset)
+{
+ // FIXME: Implement.
+}
+
+WebCore::IntSize QtPageClient::viewSize()
+{
+ return QQuickWebViewPrivate::get(m_webView)->viewSize();
+}
+
+bool QtPageClient::isViewWindowActive()
+{
+ // FIXME: The scene graph does not have the concept of being active or not when this was written.
+ return true;
+}
+
+bool QtPageClient::isViewFocused()
+{
+ if (!m_webView)
+ return false;
+ return m_webView->hasFocus();
+}
+
+bool QtPageClient::isViewVisible()
+{
+ if (!m_webView)
+ return false;
+ return m_webView->isVisible() && m_webView->page()->isVisible();
+}
+
+bool QtPageClient::isViewInWindow()
+{
+ // FIXME: Implement.
+ return true;
+}
+
+void QtPageClient::enterAcceleratedCompositingMode(const LayerTreeContext&)
+{
+ // FIXME: Implement.
+}
+
+void QtPageClient::exitAcceleratedCompositingMode()
+{
+ // FIXME: Implement.
+}
+
diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.h b/Source/WebKit2/UIProcess/qt/QtPageClient.h
new file mode 100644
index 000000000..a3149b631
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtPageClient.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2010, 2011 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 program 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 program; 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 QtPageClient_h
+#define QtPageClient_h
+
+#include "DrawingAreaProxy.h"
+#include "LayerTreeContext.h"
+#include "PageClient.h"
+#include "ShareableBitmap.h"
+#include "ViewportArguments.h"
+
+class QtWebPageEventHandler;
+class QtWebUndoController;
+class QQuickWebView;
+
+using namespace WebKit;
+
+class QtPageClient : public WebKit::PageClient {
+public:
+ QtPageClient();
+ ~QtPageClient();
+
+ void initialize(QQuickWebView*, QtWebPageEventHandler*, QtWebUndoController*);
+
+ // QQuickWebView.
+ virtual void setViewNeedsDisplay(const WebCore::IntRect&);
+ virtual WebCore::IntSize viewSize();
+ virtual bool isViewFocused();
+ virtual bool isViewVisible();
+ virtual void didReceiveMessageFromNavigatorQtObject(const String&);
+ virtual void pageDidRequestScroll(const WebCore::IntPoint&);
+ virtual void didChangeContentsSize(const WebCore::IntSize&);
+ virtual void didChangeViewportProperties(const WebCore::ViewportArguments&);
+ virtual void processDidCrash();
+ virtual void didRelaunchProcess();
+ virtual PassOwnPtr<DrawingAreaProxy> createDrawingAreaProxy();
+ virtual void handleDownloadRequest(DownloadProxy*);
+ virtual void handleApplicationSchemeRequest(PassRefPtr<QtNetworkRequestData>);
+
+ virtual void displayView();
+ virtual void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset);
+ virtual bool isViewWindowActive();
+ virtual bool isViewInWindow();
+#if USE(ACCELERATED_COMPOSITING)
+ virtual void enterAcceleratedCompositingMode(const LayerTreeContext&);
+ virtual void exitAcceleratedCompositingMode();
+#endif // USE(ACCELERATED_COMPOSITING)
+ virtual void pageClosed() { }
+ virtual void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage);
+ virtual void setCursor(const WebCore::Cursor&);
+ virtual void setCursorHiddenUntilMouseMoves(bool);
+ virtual void toolTipChanged(const String&, const String&);
+
+ // QtWebUndoController
+ virtual void registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo);
+ virtual void clearAllEditCommands();
+ virtual bool canUndoRedo(WebPageProxy::UndoOrRedo);
+ virtual void executeUndoRedo(WebPageProxy::UndoOrRedo);
+
+ virtual WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&);
+ virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&);
+ virtual WebCore::IntPoint screenToWindow(const WebCore::IntPoint&);
+ virtual WebCore::IntRect windowToScreen(const WebCore::IntRect&);
+ virtual void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) { }
+ virtual PassRefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy*);
+ virtual PassRefPtr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy*);
+ virtual void setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut, bool animate) { }
+ virtual void didCommitLoadForMainFrame(bool useCustomRepresentation) { }
+ virtual void didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&) { }
+ virtual double customRepresentationZoomFactor() { return 1; }
+ virtual void setCustomRepresentationZoomFactor(double) { }
+ virtual void didChangeScrollbarsForMainFrame() const { }
+ virtual void flashBackingStoreUpdates(const Vector<WebCore::IntRect>& updateRects);
+ virtual void findStringInCustomRepresentation(const String&, WebKit::FindOptions, unsigned maxMatchCount) { }
+ virtual void countStringMatchesInCustomRepresentation(const String&, WebKit::FindOptions, unsigned maxMatchCount) { }
+ virtual void didFindZoomableArea(const WebCore::IntPoint&, const WebCore::IntRect&);
+ virtual void focusEditableArea(const WebCore::IntRect&, const WebCore::IntRect&);
+
+#if ENABLE(TOUCH_EVENTS)
+ virtual void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled);
+#endif
+
+private:
+ QQuickWebView* m_webView;
+ QtWebPageEventHandler* m_eventHandler;
+ QtWebUndoController* m_undoController;
+};
+
+#endif /* QtPageClient_h */
diff --git a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp
new file mode 100644
index 000000000..6f93c9391
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#include "QtPanGestureRecognizer.h"
+
+#include "QtWebPageEventHandler.h"
+#include <QTouchEvent>
+
+namespace WebKit {
+
+QtPanGestureRecognizer::QtPanGestureRecognizer(QtWebPageEventHandler* eventHandler)
+ : QtGestureRecognizer(eventHandler)
+{
+ reset();
+}
+
+bool QtPanGestureRecognizer::recognize(const QTouchEvent* event, qint64 eventTimestampMillis)
+{
+ if (!interactionEngine())
+ return false;
+
+ // Pan gesture always starts on TouchBegin unless the engine is suspended, or
+ // we ignored the event.
+ if (m_state == NoGesture && event->type() != QEvent::TouchBegin)
+ return false;
+
+ // Having multiple touch points cancel the panning gesture.
+ if (event->touchPoints().size() > 1) {
+ if (m_state == GestureRecognized)
+ interactionEngine()->panGestureCancelled();
+ reset();
+ return false;
+ }
+
+ const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first();
+
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ ASSERT(m_state == NoGesture);
+ m_state = GestureRecognitionStarted;
+ m_firstPosition = touchPoint.screenPos();
+ return false;
+ case QEvent::TouchUpdate: {
+ ASSERT(m_state != NoGesture);
+ if (m_state == GestureRecognitionStarted) {
+ // To start the gesture, the delta from start in screen coordinates
+ // must be bigger than the trigger threshold.
+ QPointF totalOffsetFromStart(touchPoint.screenPos() - m_firstPosition);
+ if (qAbs(totalOffsetFromStart.x()) < panningInitialTriggerDistanceThreshold && qAbs(totalOffsetFromStart.y()) < panningInitialTriggerDistanceThreshold)
+ return false;
+
+ m_state = GestureRecognized;
+ interactionEngine()->panGestureStarted(touchPoint.pos(), eventTimestampMillis);
+ }
+
+ ASSERT(m_state == GestureRecognized);
+ interactionEngine()->panGestureRequestUpdate(touchPoint.pos(), eventTimestampMillis);
+ return true;
+ }
+ case QEvent::TouchEnd:
+ if (m_state == GestureRecognized) {
+ interactionEngine()->panGestureEnded(touchPoint.pos(), eventTimestampMillis);
+ reset();
+ return true;
+ }
+ ASSERT(m_state == GestureRecognitionStarted);
+ reset();
+ return false;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ return false;
+}
+
+void QtPanGestureRecognizer::reset()
+{
+ QtGestureRecognizer::reset();
+ m_firstPosition = QPointF();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h
new file mode 100644
index 000000000..532507e09
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef QtPanGestureRecognizer_h
+#define QtPanGestureRecognizer_h
+
+#include "QtGestureRecognizer.h"
+
+#include <QPointF>
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+class QTouchEvent;
+QT_END_NAMESPACE
+
+namespace WebKit {
+
+const qreal panningInitialTriggerDistanceThreshold = 5.;
+
+class QtPanGestureRecognizer : public QtGestureRecognizer {
+public:
+ QtPanGestureRecognizer(QtWebPageEventHandler*);
+ bool recognize(const QTouchEvent*, qint64 eventTimestampMillis);
+ void reset();
+
+private:
+ QPointF m_firstPosition;
+};
+
+} // namespace WebKit
+
+#endif /* QtPanGestureRecognizer_h */
diff --git a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp
new file mode 100644
index 000000000..9167792c4
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "QtPinchGestureRecognizer.h"
+
+#include "QtWebPageEventHandler.h"
+#include <QtCore/QLineF>
+
+namespace WebKit {
+
+const qreal pinchInitialTriggerDistanceThreshold = 5.;
+
+static inline int findTouchPointIndex(const QList<QTouchEvent::TouchPoint>& touchPoints, const QtPinchGestureRecognizer::TouchPointInformation& pointInformation)
+{
+ const int touchCount = touchPoints.size();
+ for (int i = 0; i < touchCount; ++i) {
+ const QTouchEvent::TouchPoint& touchPoint = touchPoints.at(i);
+ if (touchPoint.id() == pointInformation.id)
+ return i;
+ }
+ return -1;
+}
+
+static inline QPointF computePinchCenter(const QTouchEvent::TouchPoint& point1, const QTouchEvent::TouchPoint& point2)
+{
+ return (point1.pos() + point2.pos()) / 2.0f;
+}
+
+QtPinchGestureRecognizer::QtPinchGestureRecognizer(QtWebPageEventHandler* eventHandler)
+ : QtGestureRecognizer(eventHandler)
+{
+ reset();
+}
+
+bool QtPinchGestureRecognizer::recognize(const QTouchEvent* event)
+{
+ if (!interactionEngine())
+ return false;
+
+ const QList<QTouchEvent::TouchPoint>& touchPoints = event->touchPoints();
+ if (touchPoints.size() < 2) {
+ if (m_state == GestureRecognized)
+ interactionEngine()->pinchGestureEnded();
+ reset();
+ return false;
+ }
+
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ switch (m_state) {
+ case NoGesture:
+ initializeGesture(touchPoints);
+ return false;
+ case GestureRecognitionStarted:
+ case GestureRecognized:
+ ASSERT(m_point1.isValid());
+ ASSERT(m_point2.isValid());
+
+ const int point1Index = findTouchPointIndex(touchPoints, m_point1);
+ if (point1Index < 0) {
+ reset();
+ return false;
+ }
+ const int point2Index = findTouchPointIndex(touchPoints, m_point2);
+ if (point2Index < 0) {
+ reset();
+ return false;
+ }
+
+ const QTouchEvent::TouchPoint& point1 = touchPoints.at(point1Index);
+ const QTouchEvent::TouchPoint& point2 = touchPoints.at(point2Index);
+ if (m_state == GestureRecognitionStarted) {
+ // FIXME: The gesture should only start if the touch events were not accepted at the start of the touch sequence.
+ const qreal pinchDistance = qAbs(QLineF(point1.screenPos(), point2.screenPos()).length() - QLineF(m_point1.initialScreenPosition, m_point2.initialScreenPosition).length());
+ if (pinchDistance < pinchInitialTriggerDistanceThreshold)
+ return false;
+ m_state = GestureRecognized;
+ interactionEngine()->pinchGestureStarted(computePinchCenter(point1, point2));
+
+ // We reset the initial position to the previous position in order to avoid the jump caused
+ // by skipping all the events between the beginning and when the threshold is hit.
+ m_point1.initialPosition = point1.lastPos();
+ m_point1.initialScreenPosition = point1.lastScreenPos();
+ m_point2.initialPosition = point2.lastPos();
+ m_point2.initialScreenPosition = point2.lastScreenPos();
+ }
+ ASSERT(m_state == GestureRecognized);
+ const qreal currentSpanDistance = QLineF(point1.screenPos(), point2.screenPos()).length();
+ const qreal initialSpanDistance = QLineF(m_point1.initialScreenPosition, m_point2.initialScreenPosition).length();
+ const qreal totalScaleFactor = currentSpanDistance / initialSpanDistance;
+ const QPointF touchCenterInPageViewCoordinates = computePinchCenter(point1, point2);
+ interactionEngine()->pinchGestureRequestUpdate(touchCenterInPageViewCoordinates, totalScaleFactor);
+ return true;
+ break;
+ }
+ break;
+ case QEvent::TouchEnd:
+ if (m_state == GestureRecognized) {
+ interactionEngine()->pinchGestureEnded();
+ reset();
+ return true;
+ }
+ reset();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return false;
+}
+
+void QtPinchGestureRecognizer::reset()
+{
+ QtGestureRecognizer::reset();
+ m_point1 = TouchPointInformation();
+ m_point2 = TouchPointInformation();
+}
+
+void QtPinchGestureRecognizer::initializeGesture(const QList<QTouchEvent::TouchPoint>& touchPoints)
+{
+ ASSERT(!m_point1.isValid());
+ ASSERT(!m_point2.isValid());
+
+ m_state = GestureRecognitionStarted;
+
+ m_point1 = TouchPointInformation(touchPoints.at(0));
+ m_point2 = TouchPointInformation(touchPoints.at(1));
+
+ ASSERT(m_point1.isValid());
+ ASSERT(m_point2.isValid());
+}
+
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h
new file mode 100644
index 000000000..7dd3d911b
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef QtPinchGestureRecognizer_h
+#define QtPinchGestureRecognizer_h
+
+#include "QtGestureRecognizer.h"
+
+#include <QTouchEvent>
+#include <QtCore/QList>
+#include <QtCore/QPointF>
+
+QT_BEGIN_NAMESPACE
+class QTouchEvent;
+QT_END_NAMESPACE
+
+namespace WebKit {
+
+class QtPinchGestureRecognizer : public QtGestureRecognizer {
+public:
+ struct TouchPointInformation {
+ inline TouchPointInformation();
+ inline TouchPointInformation(const QTouchEvent::TouchPoint&);
+ inline bool isValid() const;
+
+ int id;
+ QPointF initialScreenPosition;
+ QPointF initialPosition;
+ };
+
+ QtPinchGestureRecognizer(QtWebPageEventHandler*);
+ bool recognize(const QTouchEvent*);
+ void reset();
+
+private:
+ void initializeGesture(const QList<QTouchEvent::TouchPoint>& touchPoints);
+
+ TouchPointInformation m_point1;
+ TouchPointInformation m_point2;
+};
+
+inline QtPinchGestureRecognizer::TouchPointInformation::TouchPointInformation()
+ : id(-1)
+{
+}
+
+inline QtPinchGestureRecognizer::TouchPointInformation::TouchPointInformation(const QTouchEvent::TouchPoint& touchPoint)
+ : id(touchPoint.id())
+ , initialScreenPosition(touchPoint.screenPos())
+ , initialPosition(touchPoint.pos())
+{
+}
+
+inline bool QtPinchGestureRecognizer::TouchPointInformation::isValid() const
+{
+ return id >= 0;
+}
+
+}
+
+#endif /* QtPinchGestureRecognizer_h */
diff --git a/Source/WebKit2/UIProcess/qt/QtSGTileNode.cpp b/Source/WebKit2/UIProcess/qt/QtSGTileNode.cpp
new file mode 100644
index 000000000..229bafc7c
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtSGTileNode.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010, 2011 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 program 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 program; 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 "QtSGTileNode.h"
+
+#include <QtQuick/QSGEngine>
+#include <QtQuick/QSGFlatColorMaterial>
+#include <QtQuick/QSGTexture>
+
+namespace WebKit {
+
+QtSGTileNode::QtSGTileNode(QSGEngine* engine)
+ : m_engine(engine)
+ , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
+ , m_textureMaterialsCreated(false)
+{
+ setFlags(OwnsMaterial | OwnsOpaqueMaterial);
+ setGeometry(&m_geometry);
+ setMaterial(new QSGFlatColorMaterial);
+ setOpaqueMaterial(new QSGFlatColorMaterial);
+}
+
+void QtSGTileNode::setBackBuffer(const QImage& backBuffer, const QRectF& sourceRect, const QRectF& targetRect)
+{
+ m_backBufferTexture.reset(m_engine->createTextureFromImage(backBuffer));
+ m_backBufferTargetRect = targetRect;
+ m_backBufferSourceRect = m_backBufferTexture->convertToNormalizedSourceRect(sourceRect);
+
+ // Force the texture upload.
+ m_backBufferTexture->bind();
+}
+
+void QtSGTileNode::swapBuffersIfNeeded()
+{
+ if (!m_backBufferTexture)
+ return;
+
+ if (!m_textureMaterialsCreated) {
+ setMaterial(new QSGTextureMaterial);
+ setOpaqueMaterial(new QSGOpaqueTextureMaterial);
+ m_textureMaterialsCreated = true;
+ }
+
+ static_cast<QSGTextureMaterial*>(material())->setTexture(m_backBufferTexture.data());
+ static_cast<QSGOpaqueTextureMaterial*>(opaqueMaterial())->setTexture(m_backBufferTexture.data());
+ markDirty(DirtyMaterial);
+
+ QSGGeometry::updateTexturedRectGeometry(&m_geometry, m_backBufferTargetRect, m_backBufferSourceRect);
+ markDirty(DirtyGeometry);
+
+ m_frontBufferTexture.swap(m_backBufferTexture);
+ m_backBufferTexture.reset();
+}
+
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtSGTileNode.h b/Source/WebKit2/UIProcess/qt/QtSGTileNode.h
new file mode 100644
index 000000000..11aaecad8
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtSGTileNode.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 QtSGTileNode_h
+#define QtSGTileNode_h
+
+#include <QtQuick/QSGGeometryNode>
+#include <QtQuick/QSGOpaqueTextureMaterial>
+#include <QtQuick/QSGTextureMaterial>
+
+QT_BEGIN_NAMESPACE
+class QSGEngine;
+class QSGTexture;
+QT_END_NAMESPACE
+
+namespace WebKit {
+
+class QtSGTileNode : public QSGGeometryNode {
+public:
+ QtSGTileNode(QSGEngine*);
+ void setBackBuffer(const QImage&, const QRectF& sourceRect, const QRectF& targetRect);
+ void swapBuffersIfNeeded();
+
+private:
+ QSGEngine* m_engine;
+ QSGGeometry m_geometry;
+ QScopedPointer<QSGTexture> m_frontBufferTexture;
+ QScopedPointer<QSGTexture> m_backBufferTexture;
+ bool m_textureMaterialsCreated;
+
+ QRectF m_backBufferTargetRect;
+ QRectF m_backBufferSourceRect;
+};
+
+}
+
+#endif // QtSGTileNode_h
diff --git a/Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.cpp b/Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.cpp
new file mode 100644
index 000000000..7b1675dfe
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2010, 2011 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 program 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 program; 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 "QtSGUpdateQueue.h"
+
+#include "PassOwnPtr.h"
+#include "QtSGTileNode.h"
+#include <QtQuick/QQuickItem>
+
+namespace WebKit {
+
+struct NodeUpdateCreateTile : public NodeUpdate {
+ NodeUpdateCreateTile(int nodeID, float scale)
+ : NodeUpdate(CreateTile)
+ , nodeID(nodeID)
+ , scale(scale)
+ { }
+ int nodeID;
+ float scale;
+};
+
+struct NodeUpdateRemoveTile : public NodeUpdate {
+ NodeUpdateRemoveTile(int nodeID)
+ : NodeUpdate(RemoveTile)
+ , nodeID(nodeID)
+ { }
+ int nodeID;
+};
+
+struct NodeUpdateSetBackBuffer : public NodeUpdate {
+ NodeUpdateSetBackBuffer(int nodeID, const QImage& backBuffer, const QRect& sourceRect, const QRect& targetRect)
+ : NodeUpdate(SetBackBuffer)
+ , nodeID(nodeID)
+ , backBuffer(backBuffer)
+ , sourceRect(sourceRect)
+ , targetRect(targetRect)
+ { }
+ int nodeID;
+ QImage backBuffer;
+ QRect sourceRect;
+ QRect targetRect;
+};
+
+struct NodeUpdateSwapTileBuffers : public NodeUpdate {
+ NodeUpdateSwapTileBuffers()
+ : NodeUpdate(SwapTileBuffers)
+ { }
+};
+
+QtSGUpdateQueue::QtSGUpdateQueue(QQuickItem *item)
+ : item(item)
+ , lastScale(0)
+ , lastScaleNode(0)
+ , nextNodeID(1)
+ , m_isSwapPending(false)
+{
+}
+
+int QtSGUpdateQueue::createTileNode(float scale)
+{
+ int nodeID = nextNodeID++;
+ nodeUpdateQueue.append(adoptPtr(new NodeUpdateCreateTile(nodeID, scale)));
+ item->update();
+ return nodeID;
+}
+
+void QtSGUpdateQueue::removeTileNode(int nodeID)
+{
+ nodeUpdateQueue.append(adoptPtr(new NodeUpdateRemoveTile(nodeID)));
+ item->update();
+}
+
+void QtSGUpdateQueue::setNodeBackBuffer(int nodeID, const QImage& backBuffer, const QRect& sourceRect, const QRect& targetRect)
+{
+ nodeUpdateQueue.append(adoptPtr(new NodeUpdateSetBackBuffer(nodeID, backBuffer, sourceRect, targetRect)));
+ item->update();
+}
+
+void QtSGUpdateQueue::swapTileBuffers()
+{
+ nodeUpdateQueue.append(adoptPtr(new NodeUpdateSwapTileBuffers()));
+ m_isSwapPending = true;
+ item->update();
+}
+
+void QtSGUpdateQueue::applyUpdates(QSGNode* itemNode)
+{
+ while (!nodeUpdateQueue.isEmpty()) {
+ OwnPtr<NodeUpdate> nodeUpdate(nodeUpdateQueue.takeFirst());
+ switch (nodeUpdate->type) {
+ case NodeUpdate::CreateTile: {
+ NodeUpdateCreateTile* createTileUpdate = static_cast<NodeUpdateCreateTile*>(nodeUpdate.get());
+ QtSGTileNode* tileNode = new QtSGTileNode(item->sceneGraphEngine());
+ getScaleNode(createTileUpdate->scale, itemNode)->prependChildNode(tileNode);
+ nodes.set(createTileUpdate->nodeID, tileNode);
+ break;
+ }
+ case NodeUpdate::RemoveTile: {
+ NodeUpdateRemoveTile* removeUpdate = static_cast<NodeUpdateRemoveTile*>(nodeUpdate.get());
+ QSGNode* node = nodes.take(removeUpdate->nodeID);
+ QSGNode* scaleNode = node->parent();
+
+ scaleNode->removeChildNode(node);
+ if (!scaleNode->childCount()) {
+ if (scaleNode == lastScaleNode) {
+ lastScale = 0;
+ lastScaleNode = 0;
+ }
+ delete scaleNode;
+ }
+ delete node;
+ break;
+ }
+ case NodeUpdate::SetBackBuffer: {
+ NodeUpdateSetBackBuffer* setBackBufferUpdate = static_cast<NodeUpdateSetBackBuffer*>(nodeUpdate.get());
+ QtSGTileNode* tileNode = nodes.get(setBackBufferUpdate->nodeID);
+ tileNode->setBackBuffer(setBackBufferUpdate->backBuffer, setBackBufferUpdate->sourceRect, setBackBufferUpdate->targetRect);
+ break;
+ }
+ case NodeUpdate::SwapTileBuffers: {
+ HashMap<int, QtSGTileNode*>::iterator end = nodes.end();
+ for (HashMap<int, QtSGTileNode*>::iterator it = nodes.begin(); it != end; ++it)
+ it->second->swapBuffersIfNeeded();
+ m_isSwapPending = false;
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+}
+
+QSGNode* QtSGUpdateQueue::getScaleNode(float scale, QSGNode* itemNode)
+{
+ if (scale == lastScale)
+ return lastScaleNode;
+
+ QSGTransformNode* scaleNode = new QSGTransformNode;
+ QMatrix4x4 scaleMatrix;
+ // Use scale(float,float) to prevent scaling the Z component.
+ // Reverse the item's transform scale since our tiles were generated for this specific scale.
+ scaleMatrix.scale(1 / scale, 1 / scale);
+ scaleNode->setMatrix(scaleMatrix);
+ // Prepend instead of append to paint the new, incomplete, scale before/behind the previous one.
+ itemNode->prependChildNode(scaleNode);
+
+ lastScale = scale;
+ lastScaleNode = scaleNode;
+ return lastScaleNode;
+}
+
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.h b/Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.h
new file mode 100644
index 000000000..f70c50668
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 QtSGUpdateQueue_h
+#define QtSGUpdateQueue_h
+
+#include "Deque.h"
+#include "HashMap.h"
+#include "OwnPtr.h"
+
+class QImage;
+class QRect;
+class QQuickItem;
+class QSGNode;
+class QSize;
+
+namespace WebKit {
+
+class NodeUpdate;
+class PageNode;
+class QtSGTileNode;
+
+// Takes care of taking update requests then fulfilling them asynchronously on the scene graph thread.
+class QtSGUpdateQueue {
+public:
+ QtSGUpdateQueue(QQuickItem*);
+
+ int createTileNode(float scale);
+ void removeTileNode(int nodeID);
+ void setNodeBackBuffer(int nodeID, const QImage& texture, const QRect& sourceRect, const QRect& targetRect);
+ void swapTileBuffers();
+
+ // Called by the QQuickItem.
+ void applyUpdates(QSGNode* itemNode);
+ bool isSwapPending() const { return m_isSwapPending; }
+
+private:
+ QSGNode* getScaleNode(float scale, QSGNode* itemNode);
+
+ QQuickItem* item;
+ Deque<OwnPtr<NodeUpdate> > nodeUpdateQueue;
+ HashMap<int, QtSGTileNode*> nodes;
+ float lastScale;
+ QSGNode* lastScaleNode;
+ int nextNodeID;
+ bool m_isSwapPending;
+};
+
+struct NodeUpdate {
+ enum Type {
+ CreateTile,
+ RemoveTile,
+ SetBackBuffer,
+ SwapTileBuffers
+ };
+ NodeUpdate(Type type)
+ : type(type)
+ { }
+ virtual ~NodeUpdate() { }
+ Type type;
+};
+
+}
+
+#endif // QtSGUpdateQueue_h
diff --git a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp
new file mode 100644
index 000000000..2ed773c11
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+#include "QtTapGestureRecognizer.h"
+
+#include "QtWebPageEventHandler.h"
+#include <QLineF>
+#include <QTouchEvent>
+
+namespace WebKit {
+
+QtTapGestureRecognizer::QtTapGestureRecognizer(QtWebPageEventHandler* eventHandler)
+ : QtGestureRecognizer(eventHandler)
+ , m_tapState(NoTap)
+{
+ reset();
+}
+
+bool QtTapGestureRecognizer::recognize(const QTouchEvent* event, qint64 eventTimestampMillis)
+{
+ if (event->touchPoints().size() != 1) {
+ reset();
+ return false;
+ }
+
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ ASSERT(m_tapState == NoTap);
+ ASSERT(!m_tapAndHoldTimer.isActive());
+
+ m_tapAndHoldTimer.start(tapAndHoldTime, this);
+
+ if (m_doubleTapTimer.isActive()) {
+ // Might be double tap.
+ ASSERT(m_touchBeginEventForTap);
+ m_doubleTapTimer.stop();
+ QPointF lastPosition = m_touchBeginEventForTap->touchPoints().first().screenPos();
+ QPointF newPosition = event->touchPoints().first().screenPos();
+ if (QLineF(lastPosition, newPosition).length() < maxDoubleTapDistance)
+ m_tapState = DoubleTapCandidate;
+ else {
+ // Received a new tap, that is unrelated to the previous one.
+ tapTimeout();
+ m_tapState = SingleTapStarted;
+ }
+ } else
+ m_tapState = SingleTapStarted;
+ m_touchBeginEventForTap = adoptPtr(new QTouchEvent(*event));
+ break;
+ case QEvent::TouchUpdate:
+ // If the touch point moves further than the threshold, we cancel the tap gesture.
+ if (m_tapState == SingleTapStarted) {
+ const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first();
+ QPointF offset(touchPoint.scenePos() - m_touchBeginEventForTap->touchPoints().first().scenePos());
+ const qreal distX = qAbs(offset.x());
+ const qreal distY = qAbs(offset.y());
+ if (distX > initialTriggerDistanceThreshold || distY > initialTriggerDistanceThreshold)
+ reset();
+ }
+ break;
+ case QEvent::TouchEnd:
+ m_tapAndHoldTimer.stop();
+
+ switch (m_tapState) {
+ case DoubleTapCandidate:
+ {
+ ASSERT(!m_doubleTapTimer.isActive());
+ m_tapState = NoTap;
+
+ const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first();
+ QPointF startPosition = touchPoint.startScreenPos();
+ QPointF endPosition = touchPoint.screenPos();
+ if (QLineF(endPosition, startPosition).length() < maxDoubleTapDistance && m_eventHandler)
+ m_eventHandler->handleDoubleTapEvent(touchPoint);
+ break;
+ }
+ case SingleTapStarted:
+ ASSERT(!m_doubleTapTimer.isActive());
+ m_doubleTapTimer.start(doubleClickInterval, this);
+ m_tapState = NoTap;
+ break;
+ case TapAndHold:
+ m_tapState = NoTap;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void QtTapGestureRecognizer::tapTimeout()
+{
+ m_doubleTapTimer.stop();
+ m_eventHandler->handleSingleTapEvent(m_touchBeginEventForTap->touchPoints().at(0));
+ m_touchBeginEventForTap.clear();
+}
+
+void QtTapGestureRecognizer::tapAndHoldTimeout()
+{
+ ASSERT(m_touchBeginEventForTap);
+ m_tapAndHoldTimer.stop();
+#if 0 // No support for synthetic context menus in WK2 yet.
+ QTouchEvent::TouchPoint tapPoint = m_touchBeginEventForTap->touchPoints().at(0);
+ WebGestureEvent gesture(WebEvent::GestureTapAndHold, tapPoint.pos().toPoint(), tapPoint.screenPos().toPoint(), WebEvent::Modifiers(0), 0);
+ if (m_webPageProxy)
+ m_webPageProxy->handleGestureEvent(gesture);
+#endif
+ m_touchBeginEventForTap.clear();
+ m_tapState = TapAndHold;
+
+ ASSERT(!m_doubleTapTimer.isActive());
+ m_doubleTapTimer.stop();
+}
+
+void QtTapGestureRecognizer::reset()
+{
+ m_tapState = NoTap;
+ m_touchBeginEventForTap.clear();
+ m_tapAndHoldTimer.stop();
+
+ QtGestureRecognizer::reset();
+}
+
+void QtTapGestureRecognizer::timerEvent(QTimerEvent* ev)
+{
+ int timerId = ev->timerId();
+ if (timerId == m_doubleTapTimer.timerId())
+ tapTimeout();
+ else if (timerId == m_tapAndHoldTimer.timerId())
+ tapAndHoldTimeout();
+ else
+ QObject::timerEvent(ev);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h
new file mode 100644
index 000000000..a4ec41eff
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef QtTapGestureRecognizer_h
+#define QtTapGestureRecognizer_h
+
+#include "QtGestureRecognizer.h"
+
+#include <QtCore/QBasicTimer>
+#include <QtCore/QObject>
+#include <QtCore/QtGlobal>
+#include <wtf/OwnPtr.h>
+
+QT_BEGIN_NAMESPACE
+class QTouchEvent;
+QT_END_NAMESPACE
+
+// FIXME: These constants should possibly depend on DPI.
+const qreal initialTriggerDistanceThreshold = 5;
+const qreal maxDoubleTapDistance = 120;
+const int tapAndHoldTime = 800;
+const int doubleClickInterval = 400;
+
+class QtWebPageEventHandler;
+
+namespace WebKit {
+
+class QtTapGestureRecognizer : public QObject, private QtGestureRecognizer {
+public:
+ QtTapGestureRecognizer(QtWebPageEventHandler*);
+ bool recognize(const QTouchEvent*, qint64 eventTimestampMillis);
+ void reset();
+
+protected:
+ void timerEvent(QTimerEvent*);
+ void tapTimeout();
+ void tapAndHoldTimeout();
+
+private:
+ QBasicTimer m_doubleTapTimer;
+ QBasicTimer m_tapAndHoldTimer;
+ OwnPtr<QTouchEvent> m_touchBeginEventForTap;
+
+ enum {
+ NoTap,
+ SingleTapStarted,
+ DoubleTapCandidate,
+ TapAndHold
+ } m_tapState;
+};
+
+} // namespace WebKit
+
+#endif /* QtTapGestureRecognizer_h */
diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp
new file mode 100644
index 000000000..788349ae0
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp
@@ -0,0 +1,589 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
+ *
+ * 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 program 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 program; 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 "QtViewportInteractionEngine.h"
+
+#include "PassOwnPtr.h"
+#include <QPointF>
+#include <QScrollEvent>
+#include <QScrollPrepareEvent>
+#include <QScrollerProperties>
+#include <QWheelEvent>
+#include <QtQuick/qquickitem.h>
+
+namespace WebKit {
+
+static const int kScaleAnimationDurationMillis = 250;
+
+// UPDATE DEFERRING (SUSPEND/RESUME)
+// =================================
+//
+// When interaction with the content, either by animating or by the hand of the user,
+// it is important to ensure smooth animations of at least 60fps in order to give a
+// good user experience.
+//
+// In order to do this we need to get rid of unknown factors. These include device
+// sensors (geolocation, orientation updates etc), CSS3 animations, JavaScript
+// exectution, sub resource loads etc. We do this by emitting suspend and resume
+// signals, which are then handled by the viewport and propagates to the right place.
+//
+// For this reason the ViewportUpdateDeferrer guard must be used when we interact
+// or animate the content.
+//
+// It should be noted that when we update content properties, we might receive notify
+// signals send my the content item itself, and care should be taken to not act on
+// these unconditionally. An example of this is the pinch zoom, which changes the
+// position and will thus result in a QQuickWebPage::geometryChanged() signal getting
+// emitted.
+//
+// If something should only be executed during update deferring, it is possible to
+// check for that using ASSERT(m_suspendCount).
+
+class ViewportUpdateDeferrer {
+public:
+ ViewportUpdateDeferrer(QtViewportInteractionEngine* engine)
+ : engine(engine)
+ {
+ if (engine->m_suspendCount++)
+ return;
+
+ emit engine->contentSuspendRequested();
+ }
+
+ ~ViewportUpdateDeferrer()
+ {
+ if (--(engine->m_suspendCount))
+ return;
+
+ emit engine->contentResumeRequested();
+
+ // Make sure that tiles all around the viewport will be requested.
+ emit engine->viewportTrajectoryVectorChanged(QPointF());
+ }
+
+private:
+ QtViewportInteractionEngine* const engine;
+};
+
+inline qreal QtViewportInteractionEngine::cssScaleFromItem(qreal itemScale)
+{
+ return itemScale / m_constraints.devicePixelRatio;
+}
+
+inline qreal QtViewportInteractionEngine::itemScaleFromCSS(qreal cssScale)
+{
+ return cssScale * m_constraints.devicePixelRatio;
+}
+
+inline qreal QtViewportInteractionEngine::itemCoordFromCSS(qreal value)
+{
+ return value * m_constraints.devicePixelRatio;
+}
+
+inline QRectF QtViewportInteractionEngine::itemRectFromCSS(const QRectF& cssRect)
+{
+ QRectF itemRect;
+
+ itemRect.setX(itemCoordFromCSS(cssRect.x()));
+ itemRect.setY(itemCoordFromCSS(cssRect.y()));
+ itemRect.setWidth(itemCoordFromCSS(cssRect.width()));
+ itemRect.setHeight(itemCoordFromCSS(cssRect.height()));
+
+ return itemRect;
+}
+
+QtViewportInteractionEngine::QtViewportInteractionEngine(const QQuickItem* viewport, QQuickItem* content)
+ : m_viewport(viewport)
+ , m_content(content)
+ , m_suspendCount(0)
+ , m_scaleAnimation(new ScaleAnimation(this))
+ , m_pinchStartScale(-1)
+{
+ reset();
+
+ QScrollerProperties properties = scroller()->scrollerProperties();
+
+ // The QtPanGestureRecognizer is responsible for recognizing the gesture
+ // thus we need to disable the drag start distance.
+ properties.setScrollMetric(QScrollerProperties::DragStartDistance, 0.0);
+
+ // Set some default QScroller constrains to mimic the physics engine of the N9 browser.
+ properties.setScrollMetric(QScrollerProperties::AxisLockThreshold, 0.66);
+ properties.setScrollMetric(QScrollerProperties::ScrollingCurve, QEasingCurve(QEasingCurve::OutExpo));
+ properties.setScrollMetric(QScrollerProperties::DecelerationFactor, 0.05);
+ properties.setScrollMetric(QScrollerProperties::MaximumVelocity, 0.635);
+ properties.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.33);
+ properties.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.33);
+
+ scroller()->setScrollerProperties(properties);
+
+ connect(m_content, SIGNAL(widthChanged()), this, SLOT(itemSizeChanged()), Qt::DirectConnection);
+ connect(m_content, SIGNAL(heightChanged()), this, SLOT(itemSizeChanged()), Qt::DirectConnection);
+
+ connect(m_scaleAnimation, SIGNAL(valueChanged(QVariant)),
+ SLOT(scaleAnimationValueChanged(QVariant)), Qt::DirectConnection);
+ connect(m_scaleAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)),
+ SLOT(scaleAnimationStateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), Qt::DirectConnection);
+
+ connect(scroller(), SIGNAL(stateChanged(QScroller::State)),
+ SLOT(scrollStateChanged(QScroller::State)), Qt::DirectConnection);
+}
+
+QtViewportInteractionEngine::~QtViewportInteractionEngine()
+{
+}
+
+qreal QtViewportInteractionEngine::innerBoundedCSSScale(qreal cssScale)
+{
+ return qBound(m_constraints.minimumScale, cssScale, m_constraints.maximumScale);
+}
+
+qreal QtViewportInteractionEngine::outerBoundedCSSScale(qreal cssScale)
+{
+ if (m_constraints.isUserScalable) {
+ // Bounded by [0.1, 10.0] like the viewport meta code in WebCore.
+ qreal hardMin = qMax<qreal>(0.1, qreal(0.5) * m_constraints.minimumScale);
+ qreal hardMax = qMin<qreal>(10, qreal(2.0) * m_constraints.maximumScale);
+ return qBound(hardMin, cssScale, hardMax);
+ }
+ return innerBoundedCSSScale(cssScale);
+}
+
+void QtViewportInteractionEngine::setItemRectVisible(const QRectF& itemRect)
+{
+ ViewportUpdateDeferrer guard(this);
+
+ qreal itemScale = m_viewport->width() / itemRect.width();
+
+ m_content->setScale(itemScale);
+
+ // We need to animate the content but the position represents the viewport hence we need to invert the position here.
+ // To animate the position together with the scale we multiply the position with the current scale;
+ m_content->setPos(- itemRect.topLeft() * itemScale);
+}
+
+bool QtViewportInteractionEngine::animateItemRectVisible(const QRectF& itemRect)
+{
+ QRectF currentItemRectVisible = m_content->mapRectFromItem(m_viewport, m_viewport->boundingRect());
+ if (itemRect == currentItemRectVisible)
+ return false;
+
+ m_scaleAnimation->setDuration(kScaleAnimationDurationMillis);
+ m_scaleAnimation->setEasingCurve(QEasingCurve::OutCubic);
+
+ m_scaleAnimation->setStartValue(currentItemRectVisible);
+ m_scaleAnimation->setEndValue(itemRect);
+
+ m_scaleAnimation->start();
+ return true;
+}
+
+void QtViewportInteractionEngine::scaleAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State /*oldState*/)
+{
+ switch (newState) {
+ case QAbstractAnimation::Running:
+ if (!m_scaleUpdateDeferrer)
+ m_scaleUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this));
+ break;
+ case QAbstractAnimation::Stopped:
+ m_scaleUpdateDeferrer.clear();
+ break;
+ default:
+ break;
+ }
+}
+
+void QtViewportInteractionEngine::scrollStateChanged(QScroller::State newState)
+{
+ switch (newState) {
+ case QScroller::Inactive:
+ // FIXME: QScroller gets when even when tapping while it is scrolling.
+ m_scrollUpdateDeferrer.clear();
+ break;
+ case QScroller::Pressed:
+ case QScroller::Dragging:
+ case QScroller::Scrolling:
+ if (m_scrollUpdateDeferrer)
+ break;
+ m_scrollUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this));
+ break;
+ default:
+ break;
+ }
+}
+
+bool QtViewportInteractionEngine::event(QEvent* event)
+{
+ switch (event->type()) {
+ case QEvent::ScrollPrepare: {
+ QScrollPrepareEvent* prepareEvent = static_cast<QScrollPrepareEvent*>(event);
+ const QRectF viewportRect = m_viewport->boundingRect();
+ const QRectF contentRect = m_viewport->mapRectFromItem(m_content, m_content->boundingRect());
+ const QRectF posRange = computePosRangeForItemAtScale(m_content->scale());
+ prepareEvent->setContentPosRange(posRange);
+ prepareEvent->setViewportSize(viewportRect.size());
+
+ // As we want to push the contents and not actually scroll it, we need to invert the positions here.
+ prepareEvent->setContentPos(-contentRect.topLeft());
+ prepareEvent->accept();
+ return true;
+ }
+ case QEvent::Scroll: {
+ QScrollEvent* scrollEvent = static_cast<QScrollEvent*>(event);
+ QPointF newPos = -scrollEvent->contentPos() - scrollEvent->overshootDistance();
+ if (m_content->pos() != newPos) {
+ QPointF currentPosInContentCoordinates = m_content->mapToItem(m_content->parentItem(), m_content->pos());
+ QPointF newPosInContentCoordinates = m_content->mapToItem(m_content->parentItem(), newPos);
+
+ // This must be emitted before viewportUpdateRequested so that the web process knows where to look for tiles.
+ emit viewportTrajectoryVectorChanged(currentPosInContentCoordinates- newPosInContentCoordinates);
+ m_content->setPos(newPos);
+ }
+ return true;
+ }
+ default:
+ break;
+ }
+ return QObject::event(event);
+}
+
+static inline QPointF boundPosition(const QPointF minPosition, const QPointF& position, const QPointF& maxPosition)
+{
+ return QPointF(qBound(minPosition.x(), position.x(), maxPosition.x()),
+ qBound(minPosition.y(), position.y(), maxPosition.y()));
+}
+
+void QtViewportInteractionEngine::wheelEvent(QWheelEvent* ev)
+{
+ if (scrollAnimationActive() || scaleAnimationActive() || pinchGestureActive())
+ return; // Ignore.
+
+ int delta = ev->delta();
+ QPointF newPos = -m_content->pos();
+
+ // A delta that is not mod 120 indicates a device that is sending
+ // fine-resolution scroll events, so use the delta as number of wheel ticks
+ // and number of pixels to scroll. See also webkit.org/b/29601
+ bool fullTick = !(delta % 120);
+
+ static const int cDefaultQtScrollStep = 20;
+ static const int wheelScrollLines = 3;
+ int scrollLines = (fullTick) ? wheelScrollLines * cDefaultQtScrollStep : 1;
+
+ delta = (fullTick) ? delta / 120.0f : delta;
+ delta *= scrollLines;
+
+ if (ev->orientation() == Qt::Horizontal)
+ newPos.rx() += delta;
+ else
+ newPos.ry() += delta;
+
+ QRectF endPosRange = computePosRangeForItemAtScale(m_content->scale());
+ m_content->setPos(-boundPosition(endPosRange.topLeft(), newPos, endPosRange.bottomRight()));
+}
+
+void QtViewportInteractionEngine::pagePositionRequest(const QPoint& pagePosition)
+{
+ // Ignore the request if suspended. Can only happen due to delay in event delivery.
+ if (m_suspendCount)
+ return;
+
+ qreal endItemScale = m_content->scale(); // Stay at same scale.
+
+ QRectF endPosRange = computePosRangeForItemAtScale(endItemScale);
+ QPointF endPosition = boundPosition(endPosRange.topLeft(), pagePosition * endItemScale, endPosRange.bottomRight());
+
+ QRectF endVisibleContentRect(endPosition / endItemScale, m_viewport->boundingRect().size() / endItemScale);
+
+ setItemRectVisible(endVisibleContentRect);
+}
+
+QRectF QtViewportInteractionEngine::computePosRangeForItemAtScale(qreal itemScale) const
+{
+ const QSizeF contentItemSize = m_content->boundingRect().size() * itemScale;
+ const QSizeF viewportItemSize = m_viewport->boundingRect().size();
+
+ const qreal horizontalRange = contentItemSize.width() - viewportItemSize.width();
+ const qreal verticalRange = contentItemSize.height() - viewportItemSize.height();
+
+ return QRectF(QPointF(0, 0), QSizeF(horizontalRange, verticalRange));
+}
+
+void QtViewportInteractionEngine::focusEditableArea(const QRectF& caretArea, const QRectF& targetArea)
+{
+ QRectF endArea = itemRectFromCSS(targetArea);
+
+ qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(2.0));
+ const QRectF viewportRect = m_viewport->boundingRect();
+
+ qreal x;
+ const qreal borderOffset = 10;
+ if ((endArea.width() + borderOffset) * endItemScale <= viewportRect.width()) {
+ // Center the input field in the middle of the view, if it is smaller than
+ // the view at the scale target.
+ x = viewportRect.center().x() - endArea.width() * endItemScale / 2.0;
+ } else {
+ // Ensure that the caret always has borderOffset contents pixels to the right
+ // of it, and secondarily (if possible), that the area has borderOffset
+ // contents pixels to the left of it.
+ qreal caretOffset = itemCoordFromCSS(caretArea.x()) - endArea.x();
+ x = qMin(viewportRect.width() - (caretOffset + borderOffset) * endItemScale, borderOffset * endItemScale);
+ }
+
+ const QPointF hotspot = QPointF(endArea.x(), endArea.center().y());
+ const QPointF viewportHotspot = QPointF(x, /* FIXME: visibleCenter */ viewportRect.center().y());
+
+ QPointF endPosition = hotspot * endItemScale - viewportHotspot;
+ QRectF endPosRange = computePosRangeForItemAtScale(endItemScale);
+
+ endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight());
+
+ QRectF endVisibleContentRect(endPosition / endItemScale, viewportRect.size() / endItemScale);
+
+ animateItemRectVisible(endVisibleContentRect);
+}
+
+void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea)
+{
+ if (!targetArea.isValid())
+ return;
+
+ if (scrollAnimationActive() || scaleAnimationActive())
+ return;
+
+ const int margin = 10; // We want at least a little bit or margin.
+ QRectF endArea = itemRectFromCSS(targetArea.adjusted(-margin, -margin, margin, margin));
+
+ const QRectF viewportRect = m_viewport->boundingRect();
+
+ qreal targetCSSScale = cssScaleFromItem(viewportRect.size().width() / endArea.size().width());
+ qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(qMin(targetCSSScale, qreal(2.5))));
+
+ // We want to end up with the target area filling the whole width of the viewport (if possible),
+ // and centralized vertically where the user requested zoom. Thus our hotspot is the center of
+ // the targetArea x-wise and the requested zoom position, y-wise.
+ const QPointF hotspot = QPointF(endArea.center().x(), touchPoint.y() * m_constraints.devicePixelRatio);
+ const QPointF viewportHotspot = viewportRect.center();
+
+ QPointF endPosition = hotspot * endItemScale - viewportHotspot;
+
+ QRectF endPosRange = computePosRangeForItemAtScale(endItemScale);
+ endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight());
+
+ QRectF endVisibleContentRect(endPosition / endItemScale, viewportRect.size() / endItemScale);
+
+ animateItemRectVisible(endVisibleContentRect);
+}
+
+bool QtViewportInteractionEngine::ensureContentWithinViewportBoundary(bool immediate)
+{
+ ASSERT(m_suspendCount);
+
+ if (scrollAnimationActive() || scaleAnimationActive())
+ return false;
+
+ qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(currentCSSScale()));
+
+ const QRectF viewportRect = m_viewport->boundingRect();
+ QPointF viewportHotspot = viewportRect.center();
+
+ QPointF endPosition = m_content->mapFromItem(m_viewport, viewportHotspot) * endItemScale - viewportHotspot;
+
+ QRectF endPosRange = computePosRangeForItemAtScale(endItemScale);
+ endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight());
+
+ QRectF endVisibleContentRect(endPosition / endItemScale, viewportRect.size() / endItemScale);
+
+ if (immediate) {
+ setItemRectVisible(endVisibleContentRect);
+ return true;
+ }
+ return !animateItemRectVisible(endVisibleContentRect);
+}
+
+void QtViewportInteractionEngine::reset()
+{
+ ASSERT(!m_suspendCount);
+
+ m_hadUserInteraction = false;
+
+ scroller()->stop();
+ m_scaleAnimation->stop();
+}
+
+void QtViewportInteractionEngine::applyConstraints(const Constraints& constraints)
+{
+ // We always have to apply the constrains even if they didn't change, as
+ // the initial scale might need to be applied.
+
+ ViewportUpdateDeferrer guard(this);
+
+ m_constraints = constraints;
+
+ if (!m_hadUserInteraction) {
+ qreal initialScale = innerBoundedCSSScale(m_constraints.initialScale);
+ m_content->setScale(itemScaleFromCSS(initialScale));
+ }
+
+ // If the web app changes successively changes the viewport on purpose
+ // it wants to be in control and we should disable animations.
+ ensureContentWithinViewportBoundary(/* immediate */ true);
+}
+
+qreal QtViewportInteractionEngine::currentCSSScale()
+{
+ return cssScaleFromItem(m_content->scale());
+}
+
+bool QtViewportInteractionEngine::scrollAnimationActive() const
+{
+ QScroller* scroller = const_cast<QtViewportInteractionEngine*>(this)->scroller();
+ return scroller->state() == QScroller::Scrolling;
+}
+
+void QtViewportInteractionEngine::interruptScrollAnimation()
+{
+ // Stopping the scroller immediately stops kinetic scrolling and if the view is out of bounds it
+ // is moved inside valid bounds immediately as well. This is the behavior that we want.
+ scroller()->stop();
+}
+
+bool QtViewportInteractionEngine::panGestureActive() const
+{
+ QScroller* scroller = const_cast<QtViewportInteractionEngine*>(this)->scroller();
+ return scroller->state() == QScroller::Pressed || scroller->state() == QScroller::Dragging;
+}
+
+void QtViewportInteractionEngine::panGestureStarted(const QPointF& touchPoint, qint64 eventTimestampMillis)
+{
+ m_hadUserInteraction = true;
+ scroller()->handleInput(QScroller::InputPress, m_viewport->mapFromItem(m_content, touchPoint), eventTimestampMillis);
+}
+
+void QtViewportInteractionEngine::panGestureRequestUpdate(const QPointF& touchPoint, qint64 eventTimestampMillis)
+{
+ scroller()->handleInput(QScroller::InputMove, m_viewport->mapFromItem(m_content, touchPoint), eventTimestampMillis);
+}
+
+void QtViewportInteractionEngine::panGestureCancelled()
+{
+ // Stopping the scroller immediately stops kinetic scrolling and if the view is out of bounds it
+ // is moved inside valid bounds immediately as well. This is the behavior that we want.
+ scroller()->stop();
+}
+
+void QtViewportInteractionEngine::panGestureEnded(const QPointF& touchPoint, qint64 eventTimestampMillis)
+{
+ scroller()->handleInput(QScroller::InputRelease, m_viewport->mapFromItem(m_content, touchPoint), eventTimestampMillis);
+}
+
+bool QtViewportInteractionEngine::scaleAnimationActive() const
+{
+ return m_scaleAnimation->state() == QAbstractAnimation::Running;
+}
+
+void QtViewportInteractionEngine::interruptScaleAnimation()
+{
+ // This interrupts the scale animation exactly where it is, even if it is out of bounds.
+ m_scaleAnimation->stop();
+}
+
+bool QtViewportInteractionEngine::pinchGestureActive() const
+{
+ return m_pinchStartScale > 0;
+}
+
+void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenterInContentCoordinates)
+{
+ ASSERT(!m_suspendCount);
+
+ if (!m_constraints.isUserScalable)
+ return;
+
+ m_hadUserInteraction = true;
+
+ m_scaleUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this));
+
+ m_lastPinchCenterInViewportCoordinates = m_viewport->mapFromItem(m_content, pinchCenterInContentCoordinates);
+ m_pinchStartScale = m_content->scale();
+
+ // Reset the tiling look-ahead vector so that tiles all around the viewport will be requested on pinch-end.
+ emit viewportTrajectoryVectorChanged(QPointF());
+}
+
+void QtViewportInteractionEngine::pinchGestureRequestUpdate(const QPointF& pinchCenterInContentCoordinates, qreal totalScaleFactor)
+{
+ ASSERT(m_suspendCount);
+
+ if (!m_constraints.isUserScalable)
+ return;
+
+ // Changes of the center position should move the page even if the zoom factor
+ // does not change.
+ const qreal cssScale = cssScaleFromItem(m_pinchStartScale * totalScaleFactor);
+
+ // Allow zooming out beyond mimimum scale on pages that do not explicitly disallow it.
+ const qreal targetCSSScale = outerBoundedCSSScale(cssScale);
+
+ QPointF pinchCenterInViewportCoordinates = m_viewport->mapFromItem(m_content, pinchCenterInContentCoordinates);
+
+ scaleContent(pinchCenterInContentCoordinates, targetCSSScale);
+
+ const QPointF positionDiff = pinchCenterInViewportCoordinates - m_lastPinchCenterInViewportCoordinates;
+ m_lastPinchCenterInViewportCoordinates = pinchCenterInViewportCoordinates;
+ m_content->setPos(m_content->pos() + positionDiff);
+}
+
+void QtViewportInteractionEngine::pinchGestureEnded()
+{
+ ASSERT(m_suspendCount);
+
+ if (!m_constraints.isUserScalable)
+ return;
+
+ m_pinchStartScale = -1;
+ // Clear the update deferrer now if we're in our final position and there won't be any animation to clear it later.
+ if (ensureContentWithinViewportBoundary())
+ m_scaleUpdateDeferrer.clear();
+}
+
+void QtViewportInteractionEngine::itemSizeChanged()
+{
+ // FIXME: This needs to be done smarter. What happens if it resizes when we were interacting?
+ if (m_suspendCount)
+ return;
+
+ ViewportUpdateDeferrer guard(this);
+ ensureContentWithinViewportBoundary();
+}
+
+void QtViewportInteractionEngine::scaleContent(const QPointF& centerInContentCoordinates, qreal cssScale)
+{
+ QPointF oldPinchCenterOnParent = m_content->mapToItem(m_content->parentItem(), centerInContentCoordinates);
+ m_content->setScale(itemScaleFromCSS(cssScale));
+ QPointF newPinchCenterOnParent = m_content->mapToItem(m_content->parentItem(), centerInContentCoordinates);
+ m_content->setPos(m_content->pos() - (newPinchCenterOnParent - oldPinchCenterOnParent));
+}
+
+#include "moc_QtViewportInteractionEngine.cpp"
+
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h
new file mode 100644
index 000000000..68377a41c
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
+ *
+ * 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 program 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 program; 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 QtViewportInteractionEngine_h
+#define QtViewportInteractionEngine_h
+
+#include "OwnPtr.h"
+#include <QScroller>
+#include "qwebkitglobal.h"
+#include <QtCore/QObject>
+#include <QtCore/QRectF>
+#include <QtCore/QVariant>
+#include <QtCore/QVariantAnimation>
+
+QT_BEGIN_NAMESPACE
+class QPointF;
+class QQuickItem;
+class QWheelEvent;
+QT_END_NAMESPACE
+
+namespace WebKit {
+
+class ViewportUpdateDeferrer;
+
+class QtViewportInteractionEngine : public QObject {
+ Q_OBJECT
+
+public:
+ QtViewportInteractionEngine(const QQuickItem*, QQuickItem*);
+ ~QtViewportInteractionEngine();
+
+ struct Constraints {
+ Constraints()
+ : initialScale(1.0)
+ , minimumScale(0.25)
+ , maximumScale(1.8)
+ , devicePixelRatio(1.0)
+ , isUserScalable(true)
+ , layoutSize(QSize())
+ { }
+
+ qreal initialScale;
+ qreal minimumScale;
+ qreal maximumScale;
+ qreal devicePixelRatio;
+ bool isUserScalable;
+ QSize layoutSize;
+ };
+
+ bool event(QEvent*);
+
+ void reset();
+ void applyConstraints(const Constraints&);
+
+ void setItemRectVisible(const QRectF&);
+ bool animateItemRectVisible(const QRectF&);
+
+ void wheelEvent(QWheelEvent*);
+ void pagePositionRequest(const QPoint& pos);
+
+ bool scrollAnimationActive() const;
+ void interruptScrollAnimation();
+
+ bool panGestureActive() const;
+ void panGestureStarted(const QPointF& touchPoint, qint64 eventTimestampMillis);
+ void panGestureRequestUpdate(const QPointF& touchPoint, qint64 eventTimestampMillis);
+ void panGestureCancelled();
+ void panGestureEnded(const QPointF& touchPoint, qint64 eventTimestampMillis);
+
+ bool scaleAnimationActive() const;
+ void interruptScaleAnimation();
+
+ bool pinchGestureActive() const;
+ void pinchGestureStarted(const QPointF& pinchCenterInContentCoordinates);
+ void pinchGestureRequestUpdate(const QPointF& pinchCenterInContentCoordinates, qreal totalScaleFactor);
+ void pinchGestureEnded();
+
+ void zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea);
+ void focusEditableArea(const QRectF& caretArea, const QRectF& targetArea);
+
+ const Constraints& constraints() const { return m_constraints; }
+ qreal currentCSSScale();
+
+Q_SIGNALS:
+ void contentSuspendRequested();
+ void contentResumeRequested();
+
+ void viewportTrajectoryVectorChanged(const QPointF&);
+
+private Q_SLOTS:
+ // Respond to changes of content that are not driven by us, like the page resizing itself.
+ void itemSizeChanged();
+
+ void scrollStateChanged(QScroller::State);
+ void scaleAnimationStateChanged(QAbstractAnimation::State, QAbstractAnimation::State);
+ void scaleAnimationValueChanged(QVariant value) { setItemRectVisible(value.toRectF()); }
+
+private:
+ friend class ViewportUpdateDeferrer;
+
+ qreal cssScaleFromItem(qreal);
+ qreal itemScaleFromCSS(qreal);
+ qreal itemCoordFromCSS(qreal);
+ QRectF itemRectFromCSS(const QRectF&);
+
+ qreal innerBoundedCSSScale(qreal);
+ qreal outerBoundedCSSScale(qreal);
+
+ QRectF computePosRangeForItemAtScale(qreal itemScale) const;
+ bool ensureContentWithinViewportBoundary(bool immediate = false);
+
+ void scaleContent(const QPointF& centerInContentCoordinates, qreal scale);
+
+ // As long as the object exists this function will always return the same QScroller instance.
+ QScroller* scroller() { return QScroller::scroller(this); }
+
+
+ const QQuickItem* const m_viewport;
+ QQuickItem* const m_content;
+
+ Constraints m_constraints;
+
+ int m_suspendCount;
+ OwnPtr<ViewportUpdateDeferrer> m_scaleUpdateDeferrer;
+ OwnPtr<ViewportUpdateDeferrer> m_scrollUpdateDeferrer;
+
+ bool m_hadUserInteraction;
+
+ class ScaleAnimation : public QVariantAnimation {
+ public:
+ ScaleAnimation(QObject* parent = 0)
+ : QVariantAnimation(parent)
+ { }
+
+ virtual void updateCurrentValue(const QVariant&) { }
+ };
+
+ ScaleAnimation* m_scaleAnimation;
+ QPointF m_lastPinchCenterInViewportCoordinates;
+ qreal m_pinchStartScale;
+};
+
+inline bool operator==(const QtViewportInteractionEngine::Constraints& a, const QtViewportInteractionEngine::Constraints& b)
+{
+ return a.initialScale == b.initialScale
+ && a.minimumScale == b.minimumScale
+ && a.maximumScale == b.maximumScale
+ && a.isUserScalable == b.isUserScalable;
+}
+
+}
+
+#endif // QtViewportInteractionEngine_h
diff --git a/Source/WebKit2/UIProcess/qt/QtWebContext.cpp b/Source/WebKit2/UIProcess/qt/QtWebContext.cpp
new file mode 100644
index 000000000..29a547ba9
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebContext.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 "QtWebContext.h"
+
+#include "MutableArray.h"
+#include "QtDownloadManager.h"
+#include "QtWebIconDatabaseClient.h"
+#include "WKAPICast.h"
+#include "WebContext.h"
+#include "WebPageProxy.h"
+#include <WKArray.h>
+#include <WKPage.h>
+#include <WKString.h>
+#include <WKType.h>
+
+namespace WebKit {
+
+static uint64_t generateContextID()
+{
+ static uint64_t uniqueContextID = 1;
+ return uniqueContextID++;
+}
+
+static HashMap<uint64_t, QtWebContext*> contextMap;
+
+QtWebContext* QtWebContext::s_defaultContext = 0;
+
+QtWebContext::QtWebContext(WebContext* context)
+ : m_context(context)
+{
+ m_contextID = generateContextID();
+ contextMap.set(m_contextID, this);
+}
+
+QtWebContext::~QtWebContext()
+{
+ if (s_defaultContext == this)
+ s_defaultContext = 0;
+ contextMap.remove(m_contextID);
+}
+
+// Used only by WebKitTestRunner. It avoids calling initialize(), so that we don't register any clients.
+PassRefPtr<QtWebContext> QtWebContext::create(WebContext* context)
+{
+ return adoptRef(new QtWebContext(context));
+}
+
+PassRefPtr<QtWebContext> QtWebContext::defaultContext()
+{
+ if (s_defaultContext)
+ return PassRefPtr<QtWebContext>(s_defaultContext);
+
+ RefPtr<WebContext> context = WebContext::create(String());
+ RefPtr<QtWebContext> defaultContext = QtWebContext::create(context.get());
+ s_defaultContext = defaultContext.get();
+ defaultContext->initialize();
+
+ return defaultContext.release();
+}
+
+PassRefPtr<WebPageProxy> QtWebContext::createWebPage(PageClient* client, WebPageGroup* pageGroup)
+{
+ return m_context->createWebPage(client, pageGroup);
+}
+
+void QtWebContext::setNavigatorQtObjectEnabled(WebPageProxy* webPageProxy, bool enabled)
+{
+ static String messageName("SetNavigatorQtObjectEnabled");
+ RefPtr<MutableArray> body = MutableArray::create();
+ body->append(webPageProxy);
+ RefPtr<WebBoolean> webEnabled = WebBoolean::create(enabled);
+ body->append(webEnabled.get());
+ m_context->postMessageToInjectedBundle(messageName, body.get());
+}
+
+void QtWebContext::postMessageToNavigatorQtObject(WebPageProxy* webPageProxy, const QString& message)
+{
+ static String messageName("MessageToNavigatorQtObject");
+ RefPtr<MutableArray> body = MutableArray::create();
+ body->append(webPageProxy);
+ RefPtr<WebString> contents = WebString::create(String(message));
+ body->append(contents.get());
+ m_context->postMessageToInjectedBundle(messageName, body.get());
+}
+
+QtWebContext* QtWebContext::contextByID(uint64_t id)
+{
+ return contextMap.get(id);
+}
+
+void QtWebContext::initialize()
+{
+ m_downloadManager = adoptPtr(new QtDownloadManager(m_context.get()));
+ m_iconDatabase = adoptPtr(new QtWebIconDatabaseClient(this));
+ initializeContextInjectedBundleClient();
+}
+
+void QtWebContext::initializeContextInjectedBundleClient()
+{
+ WKContextInjectedBundleClient injectedBundleClient;
+ memset(&injectedBundleClient, 0, sizeof(WKContextInjectedBundleClient));
+ injectedBundleClient.version = kWKContextInjectedBundleClientCurrentVersion;
+ injectedBundleClient.clientInfo = this;
+ injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle;
+ WKContextSetInjectedBundleClient(toAPI(m_context.get()), &injectedBundleClient);
+}
+
+static QtWebContext* toQtWebContext(const void* clientInfo)
+{
+ ASSERT(clientInfo);
+ return reinterpret_cast<QtWebContext*>(const_cast<void*>(clientInfo));
+}
+
+void QtWebContext::didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
+{
+ toQtWebContext(clientInfo)->didReceiveMessageFromInjectedBundle(messageName, messageBody);
+}
+
+void QtWebContext::didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
+{
+ if (!WKStringIsEqualToUTF8CString(messageName, "MessageFromNavigatorQtObject"))
+ return;
+
+ ASSERT(messageBody);
+ ASSERT(WKGetTypeID(messageBody) == WKArrayGetTypeID());
+
+ WKArrayRef body = static_cast<WKArrayRef>(messageBody);
+ ASSERT(WKArrayGetSize(body) == 2);
+ ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(body, 0)) == WKPageGetTypeID());
+ ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(body, 1)) == WKStringGetTypeID());
+
+ WKPageRef page = static_cast<WKPageRef>(WKArrayGetItemAtIndex(body, 0));
+ WKStringRef str = static_cast<WKStringRef>(WKArrayGetItemAtIndex(body, 1));
+
+ toImpl(page)->didReceiveMessageFromNavigatorQtObject(toImpl(str)->string());
+}
+
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtWebContext.h b/Source/WebKit2/UIProcess/qt/QtWebContext.h
new file mode 100644
index 000000000..202db2242
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebContext.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 QtWebContext_h
+#define QtWebContext_h
+
+#include <WKContext.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <qglobal.h>
+
+QT_BEGIN_NAMESPACE
+class QString;
+QT_END_NAMESPACE
+
+namespace WebKit {
+
+class PageClient;
+class QtDownloadManager;
+class QtWebIconDatabaseClient;
+class WebContext;
+class WebPageGroup;
+class WebPageProxy;
+
+class QtWebContext : public RefCounted<QtWebContext> {
+public:
+ ~QtWebContext();
+
+ static PassRefPtr<QtWebContext> create(WebContext*);
+ static PassRefPtr<QtWebContext> defaultContext();
+
+ PassRefPtr<WebPageProxy> createWebPage(PageClient*, WebPageGroup*);
+
+ WebContext* context() { return m_context.get(); }
+ QtDownloadManager* downloadManager() { return m_downloadManager.get(); }
+ QtWebIconDatabaseClient* iconDatabase() { return m_iconDatabase.get(); }
+
+ void setNavigatorQtObjectEnabled(WebPageProxy*, bool);
+ void postMessageToNavigatorQtObject(WebPageProxy*, const QString&);
+
+ uint64_t contextID() const { return m_contextID; }
+
+ static QtWebContext* contextByID(uint64_t id);
+
+private:
+ explicit QtWebContext(WebContext*);
+
+ void initialize();
+ void initializeContextInjectedBundleClient();
+
+ static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void*);
+ void didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody);
+
+ static QtWebContext* s_defaultContext;
+
+ uint64_t m_contextID;
+ RefPtr<WebContext> m_context;
+ OwnPtr<QtDownloadManager> m_downloadManager;
+ OwnPtr<QtWebIconDatabaseClient> m_iconDatabase;
+};
+
+}
+
+#endif // QtWebContext_h
diff --git a/Source/WebKit2/UIProcess/qt/QtWebError.cpp b/Source/WebKit2/UIProcess/qt/QtWebError.cpp
new file mode 100644
index 000000000..d5b1cbd1b
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebError.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 Andreas Kling <kling@webkit.org>
+ *
+ * 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 program 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 program; 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 "QtWebError.h"
+
+#include <QtCore/QUrl>
+#include <WKSharedAPICast.h>
+#include <WKString.h>
+#include <WKStringQt.h>
+#include <WKType.h>
+#include <WKURL.h>
+#include <WKURLQt.h>
+
+using namespace WebKit;
+
+QtWebError::QtWebError(WKErrorRef errorRef)
+ : error(errorRef)
+{
+}
+
+QtWebError::Type QtWebError::type() const
+{
+ WKRetainPtr<WKStringRef> errorDomainPtr = adoptWK(WKErrorCopyDomain(error.get()));
+ WTF::String errorDomain = toWTFString(errorDomainPtr.get());
+
+ if (errorDomain == "QtNetwork")
+ return QtWebError::NetworkError;
+ if (errorDomain == "HTTP")
+ return QtWebError::HttpError;
+ if (errorDomain == "Download")
+ return QtWebError::DownloadError;
+ return QtWebError::InternalError;
+}
+
+int QtWebError::errorCode() const
+{
+ return WKErrorGetErrorCode(error.get());
+}
+
+QUrl QtWebError::url() const
+{
+ WKRetainPtr<WKURLRef> failingURL = adoptWK(WKErrorCopyFailingURL(error.get()));
+ return WKURLCopyQUrl(failingURL.get());
+}
+
+QString QtWebError::description() const
+{
+ return WKStringCopyQString(WKErrorCopyLocalizedDescription(error.get()));
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtWebError.h b/Source/WebKit2/UIProcess/qt/QtWebError.h
new file mode 100644
index 000000000..3bd7bd508
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebError.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 Andreas Kling <kling@webkit.org>
+ *
+ * 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 program 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 program; 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 QtWebError_h
+#define QtWebError_h
+
+#include "qwebdownloaditem_p.h"
+#include "qwebkitglobal.h"
+#include <QtNetwork/QNetworkReply>
+#include <WKError.h>
+#include <WKRetainPtr.h>
+
+QT_BEGIN_NAMESPACE
+class QUrl;
+QT_END_NAMESPACE
+
+class QtWebError {
+public:
+ enum Type {
+ InternalError,
+ NetworkError,
+ HttpError,
+ DownloadError
+ };
+
+ Type type() const;
+ QUrl url() const;
+ int errorCode() const;
+ QString description() const;
+
+ int errorCodeAsHttpStatusCode() const { return errorCode(); }
+ QNetworkReply::NetworkError errorCodeAsNetworkError() const { return static_cast<QNetworkReply::NetworkError>(errorCode()); }
+ QWebDownloadItem::DownloadError errorCodeAsDownloadError() const { return static_cast<QWebDownloadItem::DownloadError>(errorCode()); }
+
+ QtWebError(const QtWebError&);
+
+ QtWebError(WKErrorRef);
+
+private:
+ WKRetainPtr<WKErrorRef> error;
+};
+
+#endif /* QtWebError_h */
diff --git a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp
new file mode 100644
index 000000000..8b09b20f3
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp
@@ -0,0 +1,122 @@
+/*
+ Copyright (C) 2011 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 "QtWebIconDatabaseClient.h"
+
+#include "Image.h"
+#include "KURL.h"
+#include "QtWebContext.h"
+#include "SharedBuffer.h"
+#include "WKURLQt.h"
+#include "WebContext.h"
+#include "WebIconDatabase.h"
+#include <QtCore/QHash>
+#include <QtCore/QObject>
+#include <QtCore/QUrl>
+#include <QtGui/QImage>
+
+using namespace WebKit;
+
+static inline QtWebIconDatabaseClient* toQtWebIconDatabaseClient(const void* clientInfo)
+{
+ ASSERT(clientInfo);
+ return reinterpret_cast<QtWebIconDatabaseClient*>(const_cast<void*>(clientInfo));
+}
+
+QtWebIconDatabaseClient::QtWebIconDatabaseClient(QtWebContext *qtWebContext)
+{
+ m_contextId = qtWebContext->contextID();
+ // The setter calls the getter here as it triggers the startup of the icon database.
+ WebContext* context = qtWebContext->context();
+ context->setIconDatabasePath(context->iconDatabasePath());
+ m_iconDatabase = context->iconDatabase();
+
+ WKIconDatabaseClient iconDatabaseClient;
+ memset(&iconDatabaseClient, 0, sizeof(WKIconDatabaseClient));
+ iconDatabaseClient.version = kWKIconDatabaseClientCurrentVersion;
+ iconDatabaseClient.clientInfo = this;
+ iconDatabaseClient.didChangeIconForPageURL = didChangeIconForPageURL;
+ WKIconDatabaseSetIconDatabaseClient(toAPI(m_iconDatabase), &iconDatabaseClient);
+}
+
+QtWebIconDatabaseClient::~QtWebIconDatabaseClient()
+{
+}
+
+void QtWebIconDatabaseClient::didChangeIconForPageURL(WKIconDatabaseRef iconDatabase, WKURLRef pageURL, const void* clientInfo)
+{
+ QUrl qUrl = WKURLCopyQUrl(pageURL);
+ toQtWebIconDatabaseClient(clientInfo)->requestIconForPageURL(qUrl);
+}
+
+QImage QtWebIconDatabaseClient::iconImageForPageURL(const String& pageURL, const QSize& iconSize)
+{
+ MutexLocker locker(m_imageLock);
+
+ WebCore::IntSize size(iconSize.width(), iconSize.height());
+ RefPtr<WebCore::Image> image = m_iconDatabase->imageForPageURL(pageURL, size);
+ if (!image)
+ return QImage();
+
+ QPixmap* nativeImage = image->nativeImageForCurrentFrame();
+ if (!nativeImage)
+ return QImage();
+
+ return nativeImage->toImage();
+}
+
+unsigned QtWebIconDatabaseClient::iconURLHashForPageURL(const String& pageURL)
+{
+ String iconURL;
+ m_iconDatabase->synchronousIconURLForPageURL(pageURL, iconURL);
+ return StringHash::hash(iconURL);
+}
+
+void QtWebIconDatabaseClient::requestIconForPageURL(const QUrl& pageURL)
+{
+ String pageURLString = WebCore::KURL(pageURL).string();
+ if (iconImageForPageURL(pageURLString).isNull())
+ return;
+
+ unsigned iconID = iconURLHashForPageURL(pageURLString);
+ QUrl url;
+ url.setScheme(QStringLiteral("image"));
+ url.setHost(QStringLiteral("webicon"));
+ QString path;
+ path.append(QLatin1Char('/'));
+ path.append(QString::number(m_contextId));
+ path.append(QLatin1Char('/'));
+ path.append(QString::number(iconID));
+ url.setPath(path);
+ url.setEncodedFragment(pageURL.toEncoded());
+ emit iconChangedForPageURL(pageURL, url);
+}
+
+void QtWebIconDatabaseClient::retainIconForPageURL(const String& pageURL)
+{
+ m_iconDatabase->retainIconForPageURL(pageURL);
+}
+
+void QtWebIconDatabaseClient::releaseIconForPageURL(const String& pageURL)
+{
+ m_iconDatabase->releaseIconForPageURL(pageURL);
+}
+
+#include "moc_QtWebIconDatabaseClient.cpp"
diff --git a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h
new file mode 100644
index 000000000..e8d056248
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.h
@@ -0,0 +1,67 @@
+/*
+ Copyright (C) 2011 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 QtWebIconDatabaseClient_h
+#define QtWebIconDatabaseClient_h
+
+#include "WKIconDatabase.h"
+#include "qwebkitglobal.h"
+#include <QtCore/QObject>
+#include <QtCore/QSize>
+#include <wtf/Threading.h>
+#include <wtf/text/WTFString.h>
+
+QT_BEGIN_NAMESPACE
+class QImage;
+class QUrl;
+QT_END_NAMESPACE
+
+namespace WebKit {
+class QtWebContext;
+class WebIconDatabase;
+
+class QtWebIconDatabaseClient : public QObject {
+ Q_OBJECT
+
+public:
+ QtWebIconDatabaseClient(QtWebContext*);
+ ~QtWebIconDatabaseClient();
+
+ QImage iconImageForPageURL(const String& pageURL, const QSize& iconSize = QSize(32, 32));
+ void retainIconForPageURL(const String&);
+ void releaseIconForPageURL(const String&);
+
+public Q_SLOTS:
+ void requestIconForPageURL(const QUrl&);
+
+public:
+ Q_SIGNAL void iconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURL);
+
+private:
+ unsigned iconURLHashForPageURL(const String&);
+ static void didChangeIconForPageURL(WKIconDatabaseRef, WKURLRef pageURL, const void* clientInfo);
+ uint64_t m_contextId;
+ WebKit::WebIconDatabase* m_iconDatabase;
+ Mutex m_imageLock;
+};
+
+}
+
+#endif
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp
new file mode 100644
index 000000000..d0196880d
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp
@@ -0,0 +1,500 @@
+/*
+ * Copyright (C) 2010, 2011 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 program 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 program; 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 "QtWebPageEventHandler.h"
+
+#include "NativeWebKeyboardEvent.h"
+#include "NativeWebMouseEvent.h"
+#include "NativeWebWheelEvent.h"
+#include "QtViewportInteractionEngine.h"
+#include "qquickwebpage_p.h"
+#include <QDrag>
+#include <QGraphicsSceneMouseEvent>
+#include <QGuiApplication>
+#include <QMimeData>
+#include <QtQuick/QQuickCanvas>
+#include <QStyleHints>
+#include <QTextFormat>
+#include <QTouchEvent>
+#include <WebCore/DragData.h>
+#include <WebCore/Editor.h>
+
+using namespace WebKit;
+using namespace WebCore;
+
+static inline Qt::DropAction dragOperationToDropAction(unsigned dragOperation)
+{
+ Qt::DropAction result = Qt::IgnoreAction;
+ if (dragOperation & DragOperationCopy)
+ result = Qt::CopyAction;
+ else if (dragOperation & DragOperationMove)
+ result = Qt::MoveAction;
+ else if (dragOperation & DragOperationGeneric)
+ result = Qt::MoveAction;
+ else if (dragOperation & DragOperationLink)
+ result = Qt::LinkAction;
+ return result;
+}
+
+static inline Qt::DropActions dragOperationToDropActions(unsigned dragOperations)
+{
+ Qt::DropActions result = Qt::IgnoreAction;
+ if (dragOperations & DragOperationCopy)
+ result |= Qt::CopyAction;
+ if (dragOperations & DragOperationMove)
+ result |= Qt::MoveAction;
+ if (dragOperations & DragOperationGeneric)
+ result |= Qt::MoveAction;
+ if (dragOperations & DragOperationLink)
+ result |= Qt::LinkAction;
+ return result;
+}
+
+static inline WebCore::DragOperation dropActionToDragOperation(Qt::DropActions actions)
+{
+ unsigned result = 0;
+ if (actions & Qt::CopyAction)
+ result |= DragOperationCopy;
+ if (actions & Qt::MoveAction)
+ result |= (DragOperationMove | DragOperationGeneric);
+ if (actions & Qt::LinkAction)
+ result |= DragOperationLink;
+ if (result == (DragOperationCopy | DragOperationMove | DragOperationGeneric | DragOperationLink))
+ result = DragOperationEvery;
+ return (DragOperation)result;
+}
+
+QtWebPageEventHandler::QtWebPageEventHandler(WKPageRef pageRef, QQuickWebPage* qmlWebPage)
+ : m_webPageProxy(toImpl(pageRef))
+ , m_panGestureRecognizer(this)
+ , m_pinchGestureRecognizer(this)
+ , m_tapGestureRecognizer(this)
+ , m_webPage(qmlWebPage)
+ , m_previousClickButton(Qt::NoButton)
+ , m_clickCount(0)
+{
+}
+
+QtWebPageEventHandler::~QtWebPageEventHandler()
+{
+}
+
+bool QtWebPageEventHandler::handleEvent(QEvent* ev)
+{
+ switch (ev->type()) {
+ case QEvent::MouseMove:
+ return handleMouseMoveEvent(static_cast<QMouseEvent*>(ev));
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ // If a MouseButtonDblClick was received then we got a MouseButtonPress before
+ // handleMousePressEvent will take care of double clicks.
+ return handleMousePressEvent(static_cast<QMouseEvent*>(ev));
+ case QEvent::MouseButtonRelease:
+ return handleMouseReleaseEvent(static_cast<QMouseEvent*>(ev));
+ case QEvent::Wheel:
+ return handleWheelEvent(static_cast<QWheelEvent*>(ev));
+ case QEvent::HoverLeave:
+ return handleHoverLeaveEvent(static_cast<QHoverEvent*>(ev));
+ case QEvent::HoverEnter: // Fall-through, for WebKit the distinction doesn't matter.
+ case QEvent::HoverMove:
+ return handleHoverMoveEvent(static_cast<QHoverEvent*>(ev));
+ case QEvent::DragEnter:
+ return handleDragEnterEvent(static_cast<QDragEnterEvent*>(ev));
+ case QEvent::DragLeave:
+ return handleDragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
+ case QEvent::DragMove:
+ return handleDragMoveEvent(static_cast<QDragMoveEvent*>(ev));
+ case QEvent::Drop:
+ return handleDropEvent(static_cast<QDropEvent*>(ev));
+ case QEvent::KeyPress:
+ return handleKeyPressEvent(static_cast<QKeyEvent*>(ev));
+ case QEvent::KeyRelease:
+ return handleKeyReleaseEvent(static_cast<QKeyEvent*>(ev));
+ case QEvent::FocusIn:
+ return handleFocusInEvent(static_cast<QFocusEvent*>(ev));
+ case QEvent::FocusOut:
+ return handleFocusOutEvent(static_cast<QFocusEvent*>(ev));
+ case QEvent::TouchBegin:
+ case QEvent::TouchEnd:
+ case QEvent::TouchUpdate:
+ touchEvent(static_cast<QTouchEvent*>(ev));
+ return true;
+ case QEvent::InputMethod:
+ inputMethodEvent(static_cast<QInputMethodEvent*>(ev));
+ return false; // Look at comment in qquickwebpage.cpp
+ }
+
+ // FIXME: Move all common event handling here.
+ return false;
+}
+
+bool QtWebPageEventHandler::handleMouseMoveEvent(QMouseEvent* ev)
+{
+ // For some reason mouse press results in mouse hover (which is
+ // converted to mouse move for WebKit). We ignore these hover
+ // events by comparing lastPos with newPos.
+ // NOTE: lastPos from the event always comes empty, so we work
+ // around that here.
+ static QPointF lastPos = QPointF();
+ if (lastPos == ev->pos())
+ return ev->isAccepted();
+ lastPos = ev->pos();
+
+ m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, /*eventClickCount*/ 0));
+
+ return ev->isAccepted();
+}
+
+bool QtWebPageEventHandler::handleMousePressEvent(QMouseEvent* ev)
+{
+ if (m_clickTimer.isActive()
+ && m_previousClickButton == ev->button()
+ && (ev->pos() - m_lastClick).manhattanLength() < qApp->styleHints()->startDragDistance()) {
+ m_clickCount++;
+ } else {
+ m_clickCount = 1;
+ m_previousClickButton = ev->button();
+ }
+
+ m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, m_clickCount));
+
+ m_lastClick = ev->pos();
+ m_clickTimer.start(qApp->styleHints()->mouseDoubleClickInterval(), this);
+ return ev->isAccepted();
+}
+
+bool QtWebPageEventHandler::handleMouseReleaseEvent(QMouseEvent* ev)
+{
+ m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, /*eventClickCount*/ 0));
+ return ev->isAccepted();
+}
+
+bool QtWebPageEventHandler::handleWheelEvent(QWheelEvent* ev)
+{
+ m_webPageProxy->handleWheelEvent(NativeWebWheelEvent(ev));
+ // FIXME: Handle whether the page used the wheel event or not.
+ if (m_interactionEngine)
+ m_interactionEngine->wheelEvent(ev);
+ return ev->isAccepted();
+}
+
+bool QtWebPageEventHandler::handleHoverLeaveEvent(QHoverEvent* ev)
+{
+ // To get the correct behavior of mouseout, we need to turn the Leave event of our webview into a mouse move
+ // to a very far region.
+ QHoverEvent fakeEvent(QEvent::HoverMove, QPoint(INT_MIN, INT_MIN), ev->oldPos());
+ fakeEvent.setTimestamp(ev->timestamp());
+ return handleHoverMoveEvent(&fakeEvent);
+}
+
+bool QtWebPageEventHandler::handleHoverMoveEvent(QHoverEvent* ev)
+{
+ QMouseEvent me(QEvent::MouseMove, ev->pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
+ me.setAccepted(ev->isAccepted());
+ me.setTimestamp(ev->timestamp());
+
+ return handleMouseMoveEvent(&me);
+}
+
+bool QtWebPageEventHandler::handleDragEnterEvent(QDragEnterEvent* ev)
+{
+ m_webPageProxy->resetDragOperation();
+ // FIXME: Should not use QCursor::pos()
+ DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions()));
+ m_webPageProxy->dragEntered(&dragData);
+ ev->acceptProposedAction();
+ return true;
+}
+
+bool QtWebPageEventHandler::handleDragLeaveEvent(QDragLeaveEvent* ev)
+{
+ bool accepted = ev->isAccepted();
+
+ // FIXME: Should not use QCursor::pos()
+ DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
+ m_webPageProxy->dragExited(&dragData);
+ m_webPageProxy->resetDragOperation();
+
+ ev->setAccepted(accepted);
+ return accepted;
+}
+
+bool QtWebPageEventHandler::handleDragMoveEvent(QDragMoveEvent* ev)
+{
+ bool accepted = ev->isAccepted();
+
+ // FIXME: Should not use QCursor::pos()
+ DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions()));
+ m_webPageProxy->dragUpdated(&dragData);
+ ev->setDropAction(dragOperationToDropAction(m_webPageProxy->dragSession().operation));
+ if (m_webPageProxy->dragSession().operation != DragOperationNone)
+ ev->accept();
+
+ ev->setAccepted(accepted);
+ return accepted;
+}
+
+bool QtWebPageEventHandler::handleDropEvent(QDropEvent* ev)
+{
+ bool accepted = ev->isAccepted();
+
+ // FIXME: Should not use QCursor::pos()
+ DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions()));
+ SandboxExtension::Handle handle;
+ m_webPageProxy->performDrag(&dragData, String(), handle);
+ ev->setDropAction(dragOperationToDropAction(m_webPageProxy->dragSession().operation));
+ ev->accept();
+
+ ev->setAccepted(accepted);
+ return accepted;
+}
+
+void QtWebPageEventHandler::handleSingleTapEvent(const QTouchEvent::TouchPoint& point)
+{
+ WebGestureEvent gesture(WebEvent::GestureSingleTap, point.pos().toPoint(), point.screenPos().toPoint(), WebEvent::Modifiers(0), 0);
+ m_webPageProxy->handleGestureEvent(gesture);
+}
+
+void QtWebPageEventHandler::handleDoubleTapEvent(const QTouchEvent::TouchPoint& point)
+{
+ m_webPageProxy->findZoomableAreaForPoint(point.pos().toPoint());
+}
+
+void QtWebPageEventHandler::timerEvent(QTimerEvent* ev)
+{
+ int timerId = ev->timerId();
+ if (timerId == m_clickTimer.timerId())
+ m_clickTimer.stop();
+ else
+ QObject::timerEvent(ev);
+}
+
+bool QtWebPageEventHandler::handleKeyPressEvent(QKeyEvent* ev)
+{
+ m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
+ return true;
+}
+
+bool QtWebPageEventHandler::handleKeyReleaseEvent(QKeyEvent* ev)
+{
+ m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(ev));
+ return true;
+}
+
+bool QtWebPageEventHandler::handleFocusInEvent(QFocusEvent*)
+{
+ m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
+ return true;
+}
+
+bool QtWebPageEventHandler::handleFocusOutEvent(QFocusEvent*)
+{
+ m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
+ return true;
+}
+
+void QtWebPageEventHandler::setViewportInteractionEngine(QtViewportInteractionEngine* engine)
+{
+ m_interactionEngine = engine;
+}
+
+void QtWebPageEventHandler::inputMethodEvent(QInputMethodEvent* ev)
+{
+ QString commit = ev->commitString();
+ QString composition = ev->preeditString();
+
+ int replacementStart = ev->replacementStart();
+ int replacementLength = ev->replacementLength();
+
+ // NOTE: We might want to handle events of one char as special
+ // and resend them as key events to make web site completion work.
+
+ int cursorPositionWithinComposition = 0;
+
+ Vector<CompositionUnderline> underlines;
+
+ for (int i = 0; i < ev->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute& attr = ev->attributes().at(i);
+ switch (attr.type) {
+ case QInputMethodEvent::TextFormat: {
+ if (composition.isEmpty())
+ break;
+
+ QTextCharFormat textCharFormat = attr.value.value<QTextFormat>().toCharFormat();
+ QColor qcolor = textCharFormat.underlineColor();
+ Color color = makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha());
+ int start = qMin(attr.start, (attr.start + attr.length));
+ int end = qMax(attr.start, (attr.start + attr.length));
+ underlines.append(CompositionUnderline(start, end, color, false));
+ break;
+ }
+ case QInputMethodEvent::Cursor:
+ if (attr.length)
+ cursorPositionWithinComposition = attr.start;
+ break;
+ // Selection is handled further down.
+ default: break;
+ }
+ }
+
+ if (composition.isEmpty()) {
+ int selectionStart = -1;
+ int selectionLength = 0;
+ for (int i = 0; i < ev->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute& attr = ev->attributes().at(i);
+ if (attr.type == QInputMethodEvent::Selection) {
+ selectionStart = attr.start;
+ selectionLength = attr.length;
+
+ ASSERT(selectionStart >= 0);
+ ASSERT(selectionLength >= 0);
+ break;
+ }
+ }
+
+ m_webPageProxy->confirmComposition(commit, selectionStart, selectionLength);
+ } else {
+ ASSERT(cursorPositionWithinComposition >= 0);
+ ASSERT(replacementStart >= 0);
+
+ m_webPageProxy->setComposition(composition, underlines,
+ cursorPositionWithinComposition, cursorPositionWithinComposition,
+ replacementStart, replacementLength);
+ }
+
+ ev->accept();
+}
+
+void QtWebPageEventHandler::touchEvent(QTouchEvent* event)
+{
+#if ENABLE(TOUCH_EVENTS)
+ m_webPageProxy->handleTouchEvent(NativeWebTouchEvent(event));
+ event->accept();
+#else
+ ASSERT_NOT_REACHED();
+ ev->ignore();
+#endif
+}
+
+void QtWebPageEventHandler::resetGestureRecognizers()
+{
+ m_panGestureRecognizer.reset();
+ m_pinchGestureRecognizer.reset();
+ m_tapGestureRecognizer.reset();
+}
+
+void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
+{
+ if (!m_interactionEngine)
+ return;
+
+ if (wasEventHandled || event.type() == WebEvent::TouchCancel) {
+ resetGestureRecognizers();
+ return;
+ }
+
+ const QTouchEvent* ev = event.nativeEvent();
+
+ switch (ev->type()) {
+ case QEvent::TouchBegin:
+ ASSERT(!m_interactionEngine->panGestureActive());
+ ASSERT(!m_interactionEngine->pinchGestureActive());
+
+ // The interaction engine might still be animating kinetic scrolling or a scale animation
+ // such as double-tap to zoom or the bounce back effect. A touch stops the kinetic scrolling
+ // where as it does not stop the scale animation.
+ if (m_interactionEngine->scrollAnimationActive())
+ m_interactionEngine->interruptScrollAnimation();
+ break;
+ case QEvent::TouchUpdate:
+ // The scale animation can only be interrupted by a pinch gesture, which will then take over.
+ if (m_interactionEngine->scaleAnimationActive() && m_pinchGestureRecognizer.isRecognized())
+ m_interactionEngine->interruptScaleAnimation();
+ break;
+ default:
+ break;
+ }
+
+ // If the scale animation is active we don't pass the event to the recognizers. In the future
+ // we would want to queue the event here and repost then when the animation ends.
+ if (m_interactionEngine->scaleAnimationActive())
+ return;
+
+ // Convert the event timestamp from second to millisecond.
+ qint64 eventTimestampMillis = static_cast<qint64>(event.timestamp() * 1000);
+ m_panGestureRecognizer.recognize(ev, eventTimestampMillis);
+ m_pinchGestureRecognizer.recognize(ev);
+
+ if (m_panGestureRecognizer.isRecognized() || m_pinchGestureRecognizer.isRecognized())
+ m_tapGestureRecognizer.reset();
+ else {
+ const QTouchEvent* ev = event.nativeEvent();
+ m_tapGestureRecognizer.recognize(ev, eventTimestampMillis);
+ }
+}
+
+void QtWebPageEventHandler::didFindZoomableArea(const IntPoint& target, const IntRect& area)
+{
+ if (!m_interactionEngine)
+ return;
+
+ // FIXME: As the find method might not respond immediately during load etc,
+ // we should ignore all but the latest request.
+ m_interactionEngine->zoomToAreaGestureEnded(QPointF(target), QRectF(area));
+}
+
+void QtWebPageEventHandler::focusEditableArea(const IntRect& caret, const IntRect& area)
+{
+ if (!m_interactionEngine)
+ return;
+
+ m_interactionEngine->focusEditableArea(QRectF(caret), QRectF(area));
+}
+
+void QtWebPageEventHandler::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage)
+{
+ QImage dragQImage;
+ if (dragImage)
+ dragQImage = dragImage->createQImage();
+ else if (dragData.platformData() && dragData.platformData()->hasImage())
+ dragQImage = qvariant_cast<QImage>(dragData.platformData()->imageData());
+
+ DragOperation dragOperationMask = dragData.draggingSourceOperationMask();
+ QMimeData* mimeData = const_cast<QMimeData*>(dragData.platformData());
+ Qt::DropActions supportedDropActions = dragOperationToDropActions(dragOperationMask);
+
+ QPoint clientPosition;
+ QPoint globalPosition;
+ Qt::DropAction actualDropAction = Qt::IgnoreAction;
+
+ if (QWindow* window = m_webPage->canvas()) {
+ QDrag* drag = new QDrag(window);
+ drag->setPixmap(QPixmap::fromImage(dragQImage));
+ drag->setMimeData(mimeData);
+ actualDropAction = drag->exec(supportedDropActions);
+ globalPosition = QCursor::pos();
+ clientPosition = window->mapFromGlobal(globalPosition);
+ }
+
+ m_webPageProxy->dragEnded(clientPosition, globalPosition, dropActionToDragOperation(actualDropAction));
+}
+
+#include "moc_QtWebPageEventHandler.cpp"
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h
new file mode 100644
index 000000000..dfab4c8b9
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010, 2011 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 program 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 program; 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 QtWebPageEventHandler_h
+#define QtWebPageEventHandler_h
+
+#include "QtPanGestureRecognizer.h"
+#include "QtPinchGestureRecognizer.h"
+#include "QtTapGestureRecognizer.h"
+#include "QtViewportInteractionEngine.h"
+#include "WebPageProxy.h"
+#include <QBasicTimer>
+#include <QKeyEvent>
+#include <QInputMethodEvent>
+#include <QTouchEvent>
+#include <WKPage.h>
+
+class QQuickWebPage;
+
+using namespace WebKit;
+
+class QtWebPageEventHandler : public QObject {
+ Q_OBJECT
+
+public:
+ QtWebPageEventHandler(WKPageRef, QQuickWebPage*);
+ ~QtWebPageEventHandler();
+
+ bool handleEvent(QEvent*);
+
+ void setViewportInteractionEngine(QtViewportInteractionEngine*);
+
+ void handleSingleTapEvent(const QTouchEvent::TouchPoint&);
+ void handleDoubleTapEvent(const QTouchEvent::TouchPoint&);
+
+ void didFindZoomableArea(const WebCore::IntPoint& target, const WebCore::IntRect& area);
+ void focusEditableArea(const WebCore::IntRect& caret, const WebCore::IntRect& area);
+ void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled);
+ void resetGestureRecognizers();
+
+ QtViewportInteractionEngine* interactionEngine() { return m_interactionEngine; }
+
+ void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage);
+
+protected:
+ WebPageProxy* m_webPageProxy;
+ QtViewportInteractionEngine* m_interactionEngine;
+ QtPanGestureRecognizer m_panGestureRecognizer;
+ QtPinchGestureRecognizer m_pinchGestureRecognizer;
+ QtTapGestureRecognizer m_tapGestureRecognizer;
+ QQuickWebPage* m_webPage;
+
+private:
+ bool handleKeyPressEvent(QKeyEvent*);
+ bool handleKeyReleaseEvent(QKeyEvent*);
+ bool handleFocusInEvent(QFocusEvent*);
+ bool handleFocusOutEvent(QFocusEvent*);
+ bool handleMouseMoveEvent(QMouseEvent*);
+ bool handleMousePressEvent(QMouseEvent*);
+ bool handleMouseReleaseEvent(QMouseEvent*);
+ bool handleWheelEvent(QWheelEvent*);
+ bool handleHoverLeaveEvent(QHoverEvent*);
+ bool handleHoverMoveEvent(QHoverEvent*);
+ bool handleDragEnterEvent(QDragEnterEvent*);
+ bool handleDragLeaveEvent(QDragLeaveEvent*);
+ bool handleDragMoveEvent(QDragMoveEvent*);
+ bool handleDropEvent(QDropEvent*);
+
+ void timerEvent(QTimerEvent*);
+
+ void touchEvent(QTouchEvent*);
+ void inputMethodEvent(QInputMethodEvent*);
+
+ QPoint m_lastClick;
+ QBasicTimer m_clickTimer;
+ Qt::MouseButton m_previousClickButton;
+ int m_clickCount;
+};
+
+#endif /* QtWebPageEventHandler_h */
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp
new file mode 100644
index 000000000..3ba8c74f6
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 "QtWebPageLoadClient.h"
+
+#include "WKStringQt.h"
+#include "qquickwebview_p.h"
+#include "qquickwebview_p_p.h"
+#include <WKFrame.h>
+
+QtWebPageLoadClient::QtWebPageLoadClient(WKPageRef pageRef, QQuickWebView* webView)
+ : m_webView(webView)
+ , m_loadProgress(0)
+{
+ WKPageLoaderClient loadClient;
+ memset(&loadClient, 0, sizeof(WKPageLoaderClient));
+ loadClient.version = kWKPageLoaderClientCurrentVersion;
+ loadClient.clientInfo = this;
+ loadClient.didStartProvisionalLoadForFrame = didStartProvisionalLoadForFrame;
+ loadClient.didFailProvisionalLoadWithErrorForFrame = didFailProvisionalLoadWithErrorForFrame;
+ loadClient.didCommitLoadForFrame = didCommitLoadForFrame;
+ loadClient.didFinishLoadForFrame = didFinishLoadForFrame;
+ loadClient.didFailLoadWithErrorForFrame = didFailLoadWithErrorForFrame;
+ loadClient.didSameDocumentNavigationForFrame = didSameDocumentNavigationForFrame;
+ loadClient.didReceiveTitleForFrame = didReceiveTitleForFrame;
+ loadClient.didStartProgress = didStartProgress;
+ loadClient.didChangeProgress = didChangeProgress;
+ loadClient.didFinishProgress = didFinishProgress;
+ loadClient.didFirstVisuallyNonEmptyLayoutForFrame = didFirstVisuallyNonEmptyLayoutForFrame;
+ loadClient.didChangeBackForwardList = didChangeBackForwardList;
+ WKPageSetPageLoaderClient(pageRef, &loadClient);
+}
+
+void QtWebPageLoadClient::didStartProvisionalLoadForFrame()
+{
+ emit m_webView->navigationStateChanged();
+ emit m_webView->loadStarted();
+}
+
+void QtWebPageLoadClient::didCommitLoadForFrame(const QUrl& url)
+{
+ emit m_webView->navigationStateChanged();
+ emit m_webView->urlChanged(url);
+ m_webView->d_func()->loadDidCommit();
+}
+
+void QtWebPageLoadClient::didSameDocumentNavigationForFrame(const QUrl& url)
+{
+ emit m_webView->navigationStateChanged();
+ emit m_webView->urlChanged(url);
+}
+
+void QtWebPageLoadClient::didReceiveTitleForFrame(const QString& title)
+{
+ emit m_webView->titleChanged(title);
+}
+
+void QtWebPageLoadClient::didFirstVisuallyNonEmptyLayoutForFrame()
+{
+ m_webView->d_func()->didFinishFirstNonEmptyLayout();
+}
+
+void QtWebPageLoadClient::didChangeBackForwardList()
+{
+ m_webView->d_func()->didChangeBackForwardList();
+}
+
+void QtWebPageLoadClient::dispatchLoadSucceeded()
+{
+ emit m_webView->navigationStateChanged();
+ emit m_webView->loadSucceeded();
+}
+
+void QtWebPageLoadClient::dispatchLoadFailed(WKErrorRef error)
+{
+ emit m_webView->navigationStateChanged();
+
+ int errorCode = WKErrorGetErrorCode(error);
+ if (toImpl(error)->platformError().isCancellation() || errorCode == kWKErrorCodeFrameLoadInterruptedByPolicyChange || errorCode == kWKErrorCodePlugInWillHandleLoad)
+ return;
+
+ QtWebError qtError(error);
+ emit m_webView->loadFailed(static_cast<QQuickWebView::ErrorDomain>(qtError.type()), qtError.errorCode(), qtError.url(), qtError.description());
+}
+
+void QtWebPageLoadClient::setLoadProgress(int loadProgress)
+{
+ m_loadProgress = loadProgress;
+ emit m_webView->loadProgressChanged(m_loadProgress);
+}
+
+static QtWebPageLoadClient* toQtWebPageLoadClient(const void* clientInfo)
+{
+ ASSERT(clientInfo);
+ return reinterpret_cast<QtWebPageLoadClient*>(const_cast<void*>(clientInfo));
+}
+
+void QtWebPageLoadClient::didStartProvisionalLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
+{
+ if (!WKFrameIsMainFrame(frame))
+ return;
+ toQtWebPageLoadClient(clientInfo)->didStartProvisionalLoadForFrame();
+}
+
+void QtWebPageLoadClient::didFailProvisionalLoadWithErrorForFrame(WKPageRef, WKFrameRef frame, WKErrorRef error, WKTypeRef, const void* clientInfo)
+{
+ if (!WKFrameIsMainFrame(frame))
+ return;
+ toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(error);
+}
+
+void QtWebPageLoadClient::didCommitLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
+{
+ if (!WKFrameIsMainFrame(frame))
+ return;
+ WebFrameProxy* wkframe = toImpl(frame);
+ QString urlStr(wkframe->url());
+ QUrl qUrl = urlStr;
+ toQtWebPageLoadClient(clientInfo)->didCommitLoadForFrame(qUrl);
+}
+
+void QtWebPageLoadClient::didFinishLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
+{
+ if (!WKFrameIsMainFrame(frame))
+ return;
+ toQtWebPageLoadClient(clientInfo)->dispatchLoadSucceeded();
+}
+
+void QtWebPageLoadClient::didFailLoadWithErrorForFrame(WKPageRef, WKFrameRef frame, WKErrorRef error, WKTypeRef, const void* clientInfo)
+{
+ if (!WKFrameIsMainFrame(frame))
+ return;
+ toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(error);
+}
+
+void QtWebPageLoadClient::didSameDocumentNavigationForFrame(WKPageRef page, WKFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef userData, const void* clientInfo)
+{
+ WebFrameProxy* wkframe = toImpl(frame);
+ QString urlStr(wkframe->url());
+ QUrl qUrl = urlStr;
+ toQtWebPageLoadClient(clientInfo)->didSameDocumentNavigationForFrame(qUrl);
+}
+
+void QtWebPageLoadClient::didReceiveTitleForFrame(WKPageRef, WKStringRef title, WKFrameRef frame, WKTypeRef, const void* clientInfo)
+{
+ if (!WKFrameIsMainFrame(frame))
+ return;
+ QString qTitle = WKStringCopyQString(title);
+ toQtWebPageLoadClient(clientInfo)->didReceiveTitleForFrame(qTitle);
+}
+
+void QtWebPageLoadClient::didStartProgress(WKPageRef, const void* clientInfo)
+{
+ QtWebPageLoadClient* client = toQtWebPageLoadClient(clientInfo);
+ client->setLoadProgress(0);
+ client->m_webView->d_func()->setIcon(QUrl());
+}
+
+void QtWebPageLoadClient::didChangeProgress(WKPageRef page, const void* clientInfo)
+{
+ toQtWebPageLoadClient(clientInfo)->setLoadProgress(WKPageGetEstimatedProgress(page) * 100);
+}
+
+void QtWebPageLoadClient::didFinishProgress(WKPageRef, const void* clientInfo)
+{
+ toQtWebPageLoadClient(clientInfo)->setLoadProgress(100);
+}
+
+void QtWebPageLoadClient::didFirstVisuallyNonEmptyLayoutForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void *clientInfo)
+{
+ if (!WKFrameIsMainFrame(frame))
+ return;
+ toQtWebPageLoadClient(clientInfo)->didFirstVisuallyNonEmptyLayoutForFrame();
+}
+
+void QtWebPageLoadClient::didChangeBackForwardList(WKPageRef, WKBackForwardListItemRef, WKArrayRef, const void *clientInfo)
+{
+ toQtWebPageLoadClient(clientInfo)->didChangeBackForwardList();
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h
new file mode 100644
index 000000000..fbdb92e7b
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 QtWebPageLoadClient_h
+#define QtWebPageLoadClient_h
+
+#include "QtWebError.h"
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+#include <WKPage.h>
+
+class QQuickWebView;
+
+class QtWebPageLoadClient {
+public:
+ QtWebPageLoadClient(WKPageRef, QQuickWebView*);
+
+ int loadProgress() const { return m_loadProgress; }
+
+private:
+ void didStartProvisionalLoadForFrame();
+ void didCommitLoadForFrame(const QUrl&);
+ void didSameDocumentNavigationForFrame(const QUrl&);
+ void didReceiveTitleForFrame(const QString&);
+ void didFirstVisuallyNonEmptyLayoutForFrame();
+ void didChangeBackForwardList();
+
+ void dispatchLoadSucceeded();
+ void dispatchLoadFailed(WKErrorRef);
+ void setLoadProgress(int);
+
+ // WKPageLoadClient callbacks.
+ static void didStartProvisionalLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
+ static void didFailProvisionalLoadWithErrorForFrame(WKPageRef, WKFrameRef, WKErrorRef, WKTypeRef userData, const void* clientInfo);
+ static void didCommitLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
+ static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
+ static void didFailLoadWithErrorForFrame(WKPageRef, WKFrameRef, WKErrorRef, WKTypeRef userData, const void* clientInfo);
+ static void didSameDocumentNavigationForFrame(WKPageRef, WKFrameRef, WKSameDocumentNavigationType, WKTypeRef userData, const void* clientInfo);
+ static void didReceiveTitleForFrame(WKPageRef, WKStringRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
+ static void didStartProgress(WKPageRef, const void* clientInfo);
+ static void didChangeProgress(WKPageRef, const void* clientInfo);
+ static void didFinishProgress(WKPageRef, const void* clientInfo);
+ static void didFirstVisuallyNonEmptyLayoutForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
+ static void didChangeBackForwardList(WKPageRef, WKBackForwardListItemRef, WKArrayRef, const void *clientInfo);
+
+ QQuickWebView* m_webView;
+ int m_loadProgress;
+};
+
+#endif // QtWebPageLoadClient_h
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp
new file mode 100644
index 000000000..e77fb1463
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 "QtWebPagePolicyClient.h"
+
+#include "WKFrame.h"
+#include "WKURLQt.h"
+#include "qquickwebview_p.h"
+#include "qquickwebview_p_p.h"
+#include "qwebnavigationrequest_p.h"
+#include <QtCore/QObject>
+#include <WKFramePolicyListener.h>
+#include <WKURLRequest.h>
+
+QtWebPagePolicyClient::QtWebPagePolicyClient(WKPageRef pageRef, QQuickWebView* webView)
+ : m_webView(webView)
+{
+ WKPagePolicyClient policyClient;
+ memset(&policyClient, 0, sizeof(WKPagePolicyClient));
+ policyClient.version = kWKPagePolicyClientCurrentVersion;
+ policyClient.clientInfo = this;
+ policyClient.decidePolicyForNavigationAction = decidePolicyForNavigationAction;
+ policyClient.decidePolicyForResponse = decidePolicyForResponse;
+ WKPageSetPagePolicyClient(pageRef, &policyClient);
+}
+
+void QtWebPagePolicyClient::decidePolicyForNavigationAction(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers, WKFramePolicyListenerRef listener)
+{
+ // NOTE: even though the C API (and the WebKit2 IPC) supports an asynchronous answer, this is not currently working.
+ // We are expected to call the listener immediately. See the patch for https://bugs.webkit.org/show_bug.cgi?id=53785.
+ QWebNavigationRequest navigationRequest(url, originatingUrl, mouseButton, keyboardModifiers);
+ emit m_webView->navigationRequested(&navigationRequest);
+
+ switch (navigationRequest.action()) {
+ case QQuickWebView::IgnoreRequest:
+ WKFramePolicyListenerIgnore(listener);
+ return;
+ case QQuickWebViewExperimental::DownloadRequest:
+ WKFramePolicyListenerDownload(listener);
+ return;
+ case QQuickWebView::AcceptRequest:
+ WKFramePolicyListenerUse(listener);
+ return;
+ }
+ ASSERT_NOT_REACHED();
+}
+
+static inline QtWebPagePolicyClient* toQtWebPagePolicyClient(const void* clientInfo)
+{
+ ASSERT(clientInfo);
+ return reinterpret_cast<QtWebPagePolicyClient*>(const_cast<void*>(clientInfo));
+}
+
+static Qt::MouseButton toQtMouseButton(WKEventMouseButton button)
+{
+ switch (button) {
+ case kWKEventMouseButtonLeftButton:
+ return Qt::LeftButton;
+ case kWKEventMouseButtonMiddleButton:
+ return Qt::MiddleButton;
+ case kWKEventMouseButtonRightButton:
+ return Qt::RightButton;
+ case kWKEventMouseButtonNoButton:
+ return Qt::NoButton;
+ }
+ ASSERT_NOT_REACHED();
+ return Qt::NoButton;
+}
+
+static Qt::KeyboardModifiers toQtKeyboardModifiers(WKEventModifiers modifiers)
+{
+ Qt::KeyboardModifiers qtModifiers = Qt::NoModifier;
+ if (modifiers & kWKEventModifiersShiftKey)
+ qtModifiers |= Qt::ShiftModifier;
+ if (modifiers & kWKEventModifiersControlKey)
+ qtModifiers |= Qt::ControlModifier;
+ if (modifiers & kWKEventModifiersAltKey)
+ qtModifiers |= Qt::AltModifier;
+ if (modifiers & kWKEventModifiersMetaKey)
+ qtModifiers |= Qt::MetaModifier;
+ return qtModifiers;
+}
+
+void QtWebPagePolicyClient::decidePolicyForNavigationAction(WKPageRef, WKFrameRef frame, WKFrameNavigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef, const void* clientInfo)
+{
+ WKRetainPtr<WKURLRef> frameURL(AdoptWK, WKFrameCopyURL(frame));
+ WKRetainPtr<WKURLRef> requestURL(AdoptWK, WKURLRequestCopyURL(request));
+ QUrl qUrlFrame = WKURLCopyQUrl(frameURL.get());
+ QUrl qUrl = WKURLCopyQUrl(requestURL.get());
+ toQtWebPagePolicyClient(clientInfo)->decidePolicyForNavigationAction(qUrl, qUrlFrame, toQtMouseButton(mouseButton), toQtKeyboardModifiers(modifiers), listener);
+}
+
+void QtWebPagePolicyClient::decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef, WKFramePolicyListenerRef listener, WKTypeRef, const void*)
+{
+ String type = toImpl(response)->resourceResponse().mimeType();
+ type.makeLower();
+ bool canShowMIMEType = toImpl(frame)->canShowMIMEType(type);
+
+ if (WKPageGetMainFrame(page) == frame) {
+ if (canShowMIMEType) {
+ WKFramePolicyListenerUse(listener);
+ return;
+ }
+
+ // If we can't use (show) it then we should download it.
+ WKFramePolicyListenerDownload(listener);
+ return;
+ }
+
+ // We should ignore downloadable top-level content for subframes, with an exception for text/xml and application/xml so we can still support Acid3 test.
+ // It makes the browser intentionally behave differently when it comes to text(application)/xml content in subframes vs. mainframe.
+ if (!canShowMIMEType && !(type == "text/xml" || type == "application/xml")) {
+ WKFramePolicyListenerIgnore(listener);
+ return;
+ }
+
+ WKFramePolicyListenerUse(listener);
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.h b/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.h
new file mode 100644
index 000000000..8c6021398
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 QtWebPagePolicyClient_h
+#define QtWebPagePolicyClient_h
+
+#include <QtCore/QUrl>
+#include <WKPage.h>
+
+class QQuickWebView;
+
+class QtWebPagePolicyClient {
+public:
+ QtWebPagePolicyClient(WKPageRef, QQuickWebView*);
+
+private:
+ void decidePolicyForNavigationAction(const QUrl&, const QUrl&, Qt::MouseButton, Qt::KeyboardModifiers, WKFramePolicyListenerRef);
+
+ // WKPagePolicyClient callbacks.
+ static void decidePolicyForNavigationAction(WKPageRef, WKFrameRef, WKFrameNavigationType, WKEventModifiers, WKEventMouseButton, WKURLRequestRef, WKFramePolicyListenerRef, WKTypeRef userData, const void* clientInfo);
+ static void decidePolicyForResponse(WKPageRef, WKFrameRef, WKURLResponseRef, WKURLRequestRef, WKFramePolicyListenerRef, WKTypeRef userData, const void* clientInfo);
+
+ QQuickWebView* m_webView;
+};
+
+#endif // QtWebPagePolicyClient_h
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageUIClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageUIClient.cpp
new file mode 100644
index 000000000..ef764c5c9
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageUIClient.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 "QtWebPageUIClient.h"
+
+#include "WKStringQt.h"
+#include "WKURLQt.h"
+#include "qquickwebview_p.h"
+#include "qquickwebview_p_p.h"
+#include "qwebpermissionrequest_p.h"
+#include <WKAPICast.h>
+#include <WKHitTestResult.h>
+#include <WKOpenPanelParameters.h>
+#include <WKOpenPanelResultListener.h>
+
+QtWebPageUIClient::QtWebPageUIClient(WKPageRef pageRef, QQuickWebView* webView)
+ : m_webView(webView)
+{
+ WKPageUIClient uiClient;
+ memset(&uiClient, 0, sizeof(WKPageUIClient));
+ uiClient.version = kWKPageUIClientCurrentVersion;
+ uiClient.clientInfo = this;
+ uiClient.runJavaScriptAlert = runJavaScriptAlert;
+ uiClient.runJavaScriptConfirm = runJavaScriptConfirm;
+ uiClient.runJavaScriptPrompt = runJavaScriptPrompt;
+ uiClient.runOpenPanel = runOpenPanel;
+ uiClient.mouseDidMoveOverElement = mouseDidMoveOverElement;
+ uiClient.decidePolicyForGeolocationPermissionRequest = policyForGeolocationPermissionRequest;
+ WKPageSetPageUIClient(pageRef, &uiClient);
+}
+
+void QtWebPageUIClient::runJavaScriptAlert(const QString& message)
+{
+ m_webView->d_func()->runJavaScriptAlert(message);
+}
+
+bool QtWebPageUIClient::runJavaScriptConfirm(const QString& message)
+{
+ return m_webView->d_func()->runJavaScriptConfirm(message);
+}
+
+QString QtWebPageUIClient::runJavaScriptPrompt(const QString& message, const QString& defaultValue, bool& ok)
+{
+ return m_webView->d_func()->runJavaScriptPrompt(message, defaultValue, ok);
+}
+
+void QtWebPageUIClient::runOpenPanel(WKOpenPanelResultListenerRef listenerRef, const QStringList& selectedFileNames, FileChooserType type)
+{
+ m_webView->d_func()->chooseFiles(listenerRef, selectedFileNames, type);
+}
+
+void QtWebPageUIClient::mouseDidMoveOverElement(const QUrl& linkURL, const QString& linkTitle)
+{
+ if (linkURL == m_lastHoveredURL && linkTitle == m_lastHoveredTitle)
+ return;
+ m_lastHoveredURL = linkURL;
+ m_lastHoveredTitle = linkTitle;
+ emit m_webView->linkHovered(m_lastHoveredURL, m_lastHoveredTitle);
+}
+
+void QtWebPageUIClient::permissionRequest(QWebPermissionRequest* request)
+{
+ request->setParent(m_webView);
+ emit m_webView->experimental()->permissionRequested(request);
+}
+
+static QtWebPageUIClient* toQtWebPageUIClient(const void* clientInfo)
+{
+ ASSERT(clientInfo);
+ return reinterpret_cast<QtWebPageUIClient*>(const_cast<void*>(clientInfo));
+}
+
+void QtWebPageUIClient::runJavaScriptAlert(WKPageRef, WKStringRef alertText, WKFrameRef, const void* clientInfo)
+{
+ QString qAlertText = WKStringCopyQString(alertText);
+ toQtWebPageUIClient(clientInfo)->runJavaScriptAlert(qAlertText);
+}
+
+bool QtWebPageUIClient::runJavaScriptConfirm(WKPageRef, WKStringRef message, WKFrameRef, const void* clientInfo)
+{
+ QString qMessage = WKStringCopyQString(message);
+ return toQtWebPageUIClient(clientInfo)->runJavaScriptConfirm(qMessage);
+}
+
+static inline WKStringRef createNullWKString()
+{
+ RefPtr<WebString> webString = WebString::createNull();
+ return toAPI(webString.release().leakRef());
+}
+
+WKStringRef QtWebPageUIClient::runJavaScriptPrompt(WKPageRef, WKStringRef message, WKStringRef defaultValue, WKFrameRef, const void* clientInfo)
+{
+ QString qMessage = WKStringCopyQString(message);
+ QString qDefaultValue = WKStringCopyQString(defaultValue);
+ bool ok = false;
+ QString result = toQtWebPageUIClient(clientInfo)->runJavaScriptPrompt(qMessage, qDefaultValue, ok);
+ if (!ok)
+ return createNullWKString();
+ return WKStringCreateWithQString(result);
+}
+
+void QtWebPageUIClient::runOpenPanel(WKPageRef, WKFrameRef, WKOpenPanelParametersRef parameters, WKOpenPanelResultListenerRef listener, const void* clientInfo)
+{
+ Vector<String> wkSelectedFileNames = toImpl(parameters)->selectedFileNames();
+
+ QStringList selectedFileNames;
+ for (size_t i = 0; i < wkSelectedFileNames.size(); ++i)
+ selectedFileNames += wkSelectedFileNames.at(i);
+
+ FileChooserType allowMultipleFiles = WKOpenPanelParametersGetAllowsMultipleFiles(parameters) ? MultipleFilesSelection : SingleFileSelection;
+ toQtWebPageUIClient(clientInfo)->runOpenPanel(listener, selectedFileNames, allowMultipleFiles);
+}
+
+void QtWebPageUIClient::mouseDidMoveOverElement(WKPageRef page, WKHitTestResultRef hitTestResult, WKEventModifiers modifiers, WKTypeRef userData, const void* clientInfo)
+{
+ const QUrl absoluteLinkUrl = WKURLCopyQUrl(adoptWK(WKHitTestResultCopyAbsoluteLinkURL(hitTestResult)).get());
+ const QString linkTitle = WKStringCopyQString(adoptWK(WKHitTestResultCopyLinkTitle(hitTestResult)).get());
+ toQtWebPageUIClient(clientInfo)->mouseDidMoveOverElement(absoluteLinkUrl, linkTitle);
+}
+
+void QtWebPageUIClient::policyForGeolocationPermissionRequest(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKGeolocationPermissionRequestRef request, const void* clientInfo)
+{
+ if (!request)
+ return;
+
+ QWebPermissionRequest* req = QWebPermissionRequest::create(origin, request);
+ toQtWebPageUIClient(clientInfo)->permissionRequest(req);
+}
+
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageUIClient.h b/Source/WebKit2/UIProcess/qt/QtWebPageUIClient.h
new file mode 100644
index 000000000..8cfe13c21
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageUIClient.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 QtWebPageUIClient_h
+#define QtWebPageUIClient_h
+
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+#include <WKFrame.h>
+#include <WKGeolocationPermissionRequest.h>
+#include <WKPage.h>
+#include <WKSecurityOrigin.h>
+
+class QQuickWebView;
+class QWebPermissionRequest;
+
+class QtWebPageUIClient {
+public:
+ enum FileChooserType {
+ SingleFileSelection,
+ MultipleFilesSelection
+ };
+
+ QtWebPageUIClient(WKPageRef, QQuickWebView*);
+
+private:
+ void runJavaScriptAlert(const QString& message);
+ bool runJavaScriptConfirm(const QString& message);
+ QString runJavaScriptPrompt(const QString& message, const QString& defaultValue, bool& ok);
+ void runOpenPanel(WKOpenPanelResultListenerRef, const QStringList& selectedFileNames, FileChooserType);
+ void mouseDidMoveOverElement(const QUrl& linkURL, const QString& linkTitle);
+ void permissionRequest(QWebPermissionRequest*);
+
+ // WKPageUIClient callbacks.
+ static void runJavaScriptAlert(WKPageRef, WKStringRef alertText, WKFrameRef, const void* clientInfo);
+ static bool runJavaScriptConfirm(WKPageRef, WKStringRef message, WKFrameRef, const void* clientInfo);
+ static WKStringRef runJavaScriptPrompt(WKPageRef, WKStringRef message, WKStringRef defaultValue, WKFrameRef, const void* clientInfo);
+ static void runOpenPanel(WKPageRef, WKFrameRef, WKOpenPanelParametersRef, WKOpenPanelResultListenerRef, const void* clientInfo);
+ static void mouseDidMoveOverElement(WKPageRef, WKHitTestResultRef, WKEventModifiers, WKTypeRef userData, const void* clientInfo);
+ static void policyForGeolocationPermissionRequest(WKPageRef, WKFrameRef, WKSecurityOriginRef, WKGeolocationPermissionRequestRef, const void*);
+
+ QQuickWebView* m_webView;
+ QUrl m_lastHoveredURL;
+ QString m_lastHoveredTitle;
+};
+
+#endif // QtWebPageUIClient_h
diff --git a/Source/WebKit2/UIProcess/qt/QtWebUndoController.cpp b/Source/WebKit2/UIProcess/qt/QtWebUndoController.cpp
new file mode 100644
index 000000000..62d31e8ab
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebUndoController.cpp
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2007 Staikos Computing Services Inc.
+
+ 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 "QtWebUndoController.h"
+
+#include <qglobal.h>
+#include <wtf/RefPtr.h>
+
+using namespace WebKit;
+
+void QtWebUndoController::registerEditCommand(PassRefPtr<WebEditCommandProxy> command, WebPageProxy::UndoOrRedo undoOrRedo)
+{
+ if (undoOrRedo == WebPageProxy::Undo)
+ m_undoStack.append(command);
+ else
+ m_redoStack.append(command);
+}
+
+void QtWebUndoController::clearAllEditCommands()
+{
+ m_undoStack.clear();
+ m_redoStack.clear();
+}
+
+bool QtWebUndoController::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
+{
+ if (undoOrRedo == WebPageProxy::Undo)
+ return !m_undoStack.isEmpty();
+ else
+ return !m_redoStack.isEmpty();
+}
+
+void QtWebUndoController::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
+{
+ RefPtr<WebEditCommandProxy> command;
+ if (undoOrRedo == WebPageProxy::Undo) {
+ command = m_undoStack.last();
+ m_undoStack.removeLast();
+ command->unapply();
+ } else {
+ command = m_redoStack.last();
+ m_redoStack.removeLast();
+ command->reapply();
+ }
+}
diff --git a/Source/WebKit2/UIProcess/qt/QtWebUndoController.h b/Source/WebKit2/UIProcess/qt/QtWebUndoController.h
new file mode 100644
index 000000000..a260ca2fd
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/QtWebUndoController.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2007 Staikos Computing Services Inc.
+
+ 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 QtWebUndoController_h
+#define QtWebUndoController_h
+
+#include "PageClient.h"
+#include "WebEditCommandProxy.h"
+#include "WebPageProxy.h"
+
+class QtWebUndoController {
+public:
+ // Page Client.
+ void registerEditCommand(PassRefPtr<WebKit::WebEditCommandProxy>, WebKit::WebPageProxy::UndoOrRedo);
+ void clearAllEditCommands();
+ bool canUndoRedo(WebKit::WebPageProxy::UndoOrRedo);
+ void executeUndoRedo(WebKit::WebPageProxy::UndoOrRedo);
+
+ typedef Vector<RefPtr<WebKit::WebEditCommandProxy> > CommandVector;
+ CommandVector m_undoStack;
+ CommandVector m_redoStack;
+};
+
+#endif // QtWebUndoController_h
diff --git a/Source/WebKit2/UIProcess/qt/TextCheckerQt.cpp b/Source/WebKit2/UIProcess/qt/TextCheckerQt.cpp
new file mode 100644
index 000000000..4a3318405
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/TextCheckerQt.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TextChecker.h"
+
+#include "TextCheckerState.h"
+#include <WebCore/NotImplemented.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static TextCheckerState textCheckerState;
+
+const TextCheckerState& TextChecker::state()
+{
+ notImplemented();
+
+ return textCheckerState;
+}
+
+bool TextChecker::isContinuousSpellCheckingAllowed()
+{
+ notImplemented();
+
+ return false;
+}
+
+void TextChecker::setContinuousSpellCheckingEnabled(bool isContinuousSpellCheckingEnabled)
+{
+ notImplemented();
+}
+
+void TextChecker::setGrammarCheckingEnabled(bool isGrammarCheckingEnabled)
+{
+ notImplemented();
+}
+
+void TextChecker::continuousSpellCheckingEnabledStateChanged(bool enabled)
+{
+ notImplemented();
+}
+
+void TextChecker::grammarCheckingEnabledStateChanged(bool enabled)
+{
+ notImplemented();
+}
+
+int64_t TextChecker::uniqueSpellDocumentTag(WebPageProxy*)
+{
+ notImplemented();
+ return 0;
+}
+
+void TextChecker::closeSpellDocumentWithTag(int64_t)
+{
+ notImplemented();
+}
+
+void TextChecker::checkSpellingOfString(int64_t, const UChar*, uint32_t, int32_t&, int32_t&)
+{
+ notImplemented();
+}
+
+void TextChecker::checkGrammarOfString(int64_t, const UChar*, uint32_t, Vector<WebCore::GrammarDetail>&, int32_t&, int32_t&)
+{
+ notImplemented();
+}
+
+bool TextChecker::spellingUIIsShowing()
+{
+ notImplemented();
+ return false;
+}
+
+void TextChecker::toggleSpellingUIIsShowing()
+{
+ notImplemented();
+}
+
+void TextChecker::updateSpellingUIWithMisspelledWord(int64_t, const String&)
+{
+ notImplemented();
+}
+
+void TextChecker::updateSpellingUIWithGrammarString(int64_t, const String&, const GrammarDetail&)
+{
+ notImplemented();
+}
+
+void TextChecker::getGuessesForWord(int64_t spellDocumentTag, const String& word, const String& context, Vector<String>& guesses)
+{
+ notImplemented();
+}
+
+void TextChecker::learnWord(int64_t, const String&)
+{
+ notImplemented();
+}
+
+void TextChecker::ignoreWord(int64_t spellDocumentTag, const String& word)
+{
+ notImplemented();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/qt/TiledDrawingAreaProxyQt.cpp b/Source/WebKit2/UIProcess/qt/TiledDrawingAreaProxyQt.cpp
new file mode 100644
index 000000000..2c76062f5
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/TiledDrawingAreaProxyQt.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TiledDrawingAreaProxy.h"
+
+#include "QtSGUpdateQueue.h"
+#include "qquickwebpage_p.h"
+#include "ShareableBitmap.h"
+#include "UpdateInfo.h"
+#include "WKAPICast.h"
+#include "WebPageProxy.h"
+
+using namespace WebCore;
+
+#define TILE_DEBUG_LOG
+
+namespace WebKit {
+
+void TiledDrawingAreaProxy::updateWebView(const Vector<IntRect>& paintedArea)
+{
+ // SG updates are triggered through QtSGUpdateQueue.
+}
+
+WebPageProxy* TiledDrawingAreaProxy::page()
+{
+ return m_webPageProxy;
+}
+
+void TiledDrawingAreaProxy::createTile(int tileID, const UpdateInfo& updateInfo)
+{
+ int nodeID = m_webView->sceneGraphUpdateQueue()->createTileNode(updateInfo.updateScaleFactor);
+ m_tileNodeMap.set(tileID, nodeID);
+ updateTile(tileID, updateInfo);
+}
+
+void TiledDrawingAreaProxy::updateTile(int tileID, const UpdateInfo& updateInfo)
+{
+ int nodeID = m_tileNodeMap.get(tileID);
+ ASSERT(nodeID);
+
+ RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(updateInfo.bitmapHandle);
+ // FIXME: We could avoid this copy by carying the ShareableBitmap all the way up to texture uploading.
+ // Currently won't work since the SharedMemory handle is owned by updateInfo.
+ QImage image(bitmap->createQImage().copy());
+ QRect sourceRect(0, 0, updateInfo.updateRectBounds.width(), updateInfo.updateRectBounds.height());
+ m_webView->sceneGraphUpdateQueue()->setNodeBackBuffer(nodeID, image, sourceRect, updateInfo.updateRectBounds);
+}
+
+void TiledDrawingAreaProxy::didRenderFrame()
+{
+ m_webView->sceneGraphUpdateQueue()->swapTileBuffers();
+}
+
+void TiledDrawingAreaProxy::removeTile(int tileID)
+{
+ int nodeID = m_tileNodeMap.take(tileID);
+ m_webView->sceneGraphUpdateQueue()->removeTileNode(nodeID);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/qt/WebContextMenuProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebContextMenuProxyQt.cpp
new file mode 100644
index 000000000..b00951014
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebContextMenuProxyQt.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebContextMenuProxyQt.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebContextMenuProxyQt::WebContextMenuProxyQt(WebPageProxy*)
+{
+}
+
+PassRefPtr<WebContextMenuProxyQt> WebContextMenuProxyQt::create(WebPageProxy* webPageProxy)
+{
+ return adoptRef(new WebContextMenuProxyQt(webPageProxy));
+}
+
+void WebContextMenuProxyQt::showContextMenu(const IntPoint& position, const Vector<WebContextMenuItemData>& items)
+{
+}
+
+void WebContextMenuProxyQt::hideContextMenu()
+{
+}
+
+#include "moc_WebContextMenuProxyQt.cpp"
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/qt/WebContextMenuProxyQt.h b/Source/WebKit2/UIProcess/qt/WebContextMenuProxyQt.h
new file mode 100644
index 000000000..bd7aebd6f
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebContextMenuProxyQt.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebContextMenuProxyQt_h
+#define WebContextMenuProxyQt_h
+
+#include "WebContextMenuProxy.h"
+#include <QtCore/QObject>
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class WebContextMenuProxyQt : public QObject, public WebContextMenuProxy {
+ Q_OBJECT
+public:
+ static PassRefPtr<WebContextMenuProxyQt> create(WebPageProxy*);
+
+private:
+ WebContextMenuProxyQt(WebPageProxy*);
+
+ virtual void showContextMenu(const WebCore::IntPoint&, const Vector<WebContextMenuItemData>&);
+ virtual void hideContextMenu();
+};
+
+} // namespace WebKit
+
+#endif // WebContextMenuProxyQt_h
diff --git a/Source/WebKit2/UIProcess/qt/WebContextQt.cpp b/Source/WebKit2/UIProcess/qt/WebContextQt.cpp
new file mode 100644
index 000000000..b0d5ac4ba
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebContextQt.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 University of Szeged
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebContext.h"
+
+#include "ApplicationCacheStorage.h"
+#include "FileSystem.h"
+#include "WKSharedAPICast.h"
+#if ENABLE(GEOLOCATION)
+#include "WebGeolocationProviderQt.h"
+#endif
+#include "WebProcessCreationParameters.h"
+
+#include <QCoreApplication>
+#include <QStandardPaths>
+#include <QDir>
+#include <QProcess>
+
+namespace WebKit {
+
+static QString defaultDataLocation()
+{
+ static QString s_dataLocation;
+
+ if (!s_dataLocation.isEmpty())
+ return s_dataLocation;
+
+ QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
+ if (dataLocation.isEmpty())
+ dataLocation = WebCore::pathByAppendingComponent(QDir::homePath(), QCoreApplication::applicationName());
+ s_dataLocation = WebCore::pathByAppendingComponent(dataLocation, ".QtWebKit/");
+ WebCore::makeAllDirectories(s_dataLocation);
+ return s_dataLocation;
+}
+
+static QString s_defaultDatabaseDirectory;
+static QString s_defaultLocalStorageDirectory;
+
+String WebContext::applicationCacheDirectory()
+{
+ return WebCore::cacheStorage().cacheDirectory();
+}
+
+void WebContext::platformInitializeWebProcess(WebProcessCreationParameters& parameters)
+{
+ qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
+ parameters.cookieStorageDirectory = defaultDataLocation();
+#if ENABLE(GEOLOCATION)
+ static WebGeolocationProviderQt* location = WebGeolocationProviderQt::create(toAPI(geolocationManagerProxy()));
+ WKGeolocationManagerSetProvider(toAPI(geolocationManagerProxy()), WebGeolocationProviderQt::provider(location));
+#endif
+}
+
+void WebContext::platformInvalidateContext()
+{
+}
+
+String WebContext::platformDefaultDatabaseDirectory() const
+{
+ if (!s_defaultDatabaseDirectory.isEmpty())
+ return s_defaultDatabaseDirectory;
+
+ s_defaultDatabaseDirectory = defaultDataLocation() + QLatin1String("Databases");
+ QDir().mkpath(s_defaultDatabaseDirectory);
+ return s_defaultDatabaseDirectory;
+}
+
+String WebContext::platformDefaultIconDatabasePath() const
+{
+ return defaultDataLocation() + QLatin1String("WebpageIcons.db");
+}
+
+String WebContext::platformDefaultLocalStorageDirectory() const
+{
+ if (!s_defaultLocalStorageDirectory.isEmpty())
+ return s_defaultLocalStorageDirectory;
+
+ s_defaultLocalStorageDirectory = defaultDataLocation() + QLatin1String("LocalStorage");
+ QDir().mkpath(s_defaultLocalStorageDirectory);
+ return s_defaultLocalStorageDirectory;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/qt/WebFullScreenManagerProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebFullScreenManagerProxyQt.cpp
new file mode 100644
index 000000000..c4a13fad8
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebFullScreenManagerProxyQt.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 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 "WebFullScreenManagerProxy.h"
+
+#if ENABLE(FULLSCREEN_API)
+
+#include "WebContext.h"
+#include "WebFullScreenManagerMessages.h"
+#include "WebFullScreenManagerProxyMessages.h"
+#include "WebProcess.h"
+
+#include <WebCore/NotImplemented.h>
+
+namespace WebKit {
+
+void WebFullScreenManagerProxy::invalidate()
+{
+ m_webView = 0;
+}
+
+void WebFullScreenManagerProxy::enterFullScreen()
+{
+ notImplemented();
+}
+
+void WebFullScreenManagerProxy::exitFullScreen()
+{
+ notImplemented();
+}
+
+void WebFullScreenManagerProxy::beganEnterFullScreenAnimation()
+{
+ notImplemented();
+}
+
+void WebFullScreenManagerProxy::finishedEnterFullScreenAnimation(bool completed)
+{
+ notImplemented();
+}
+
+void WebFullScreenManagerProxy::beganExitFullScreenAnimation()
+{
+ notImplemented();
+}
+
+void WebFullScreenManagerProxy::finishedExitFullScreenAnimation(bool completed)
+{
+ notImplemented();
+}
+
+void WebFullScreenManagerProxy::enterAcceleratedCompositingMode(const LayerTreeContext& context)
+{
+ notImplemented();
+}
+
+void WebFullScreenManagerProxy::exitAcceleratedCompositingMode()
+{
+ notImplemented();
+}
+
+void WebFullScreenManagerProxy::getFullScreenRect(WebCore::IntRect& rect)
+{
+ notImplemented();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(FULLSCREEN_API)
diff --git a/Source/WebKit2/UIProcess/qt/WebGeolocationProviderQt.cpp b/Source/WebKit2/UIProcess/qt/WebGeolocationProviderQt.cpp
new file mode 100644
index 000000000..70d7b5733
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebGeolocationProviderQt.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2011 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 program 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 program; 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 "WebGeolocationProviderQt.h"
+
+#if ENABLE(GEOLOCATION)
+
+#include <QtLocation/QGeoPositionInfoSource>
+
+using namespace WebKit;
+
+static inline const WebGeolocationProviderQt* toLocationProvider(const void* clientInfo)
+{
+ return static_cast<const WebGeolocationProviderQt*>(clientInfo);
+}
+
+static void locationStartUpdating(WKGeolocationManagerRef geolocationManager, const void* clientInfo)
+{
+ toLocationProvider(clientInfo)->startUpdating();
+}
+
+static void locationStopUpdating(WKGeolocationManagerRef geolocationManager, const void* clientInfo)
+{
+ toLocationProvider(clientInfo)->stopUpdating();
+}
+
+WebGeolocationProviderQt* WebGeolocationProviderQt::create(WKGeolocationManagerRef manager)
+{
+ return new WebGeolocationProviderQt(manager);
+}
+
+WKGeolocationProvider* WebGeolocationProviderQt::provider(const WebGeolocationProviderQt* location)
+{
+ static WKGeolocationProvider provider = {
+ 0, // This features the version.
+ location, // This points to the object implementer.
+ locationStartUpdating, // The callbacks are next.
+ locationStopUpdating
+ };
+
+ return &provider;
+}
+
+WebGeolocationProviderQt::WebGeolocationProviderQt(WKGeolocationManagerRef manager)
+ : m_manager(manager)
+ , m_source(0)
+{
+}
+
+WebGeolocationProviderQt::~WebGeolocationProviderQt()
+{
+}
+
+void WebGeolocationProviderQt::updateTimeout()
+{
+ WKGeolocationManagerProviderDidFailToDeterminePosition(m_manager);
+}
+
+void WebGeolocationProviderQt::positionUpdated(const QGeoPositionInfo& geoPosition)
+{
+ if (!geoPosition.isValid())
+ return;
+
+ QGeoCoordinate coord = geoPosition.coordinate();
+ double latitude = coord.latitude();
+ double longitude = coord.longitude();
+ double accuracy = geoPosition.attribute(QGeoPositionInfo::HorizontalAccuracy);
+ double timeStampInSeconds = geoPosition.timestamp().toMSecsSinceEpoch() / 1000;
+
+ m_lastPosition.adopt(WKGeolocationPositionCreate(timeStampInSeconds, latitude, longitude, accuracy));
+
+ WKGeolocationManagerProviderDidChangePosition(m_manager, m_lastPosition.get());
+}
+
+void WebGeolocationProviderQt::startUpdating() const
+{
+ if (!m_source) {
+ if (!(m_source = QGeoPositionInfoSource::createDefaultSource(const_cast<WebGeolocationProviderQt*>(this)))) {
+ // Let the manager known that the provider is not available.
+ WKGeolocationManagerSetProvider(m_manager, 0);
+ // Notify failure at retrieving the position.
+ WKGeolocationManagerProviderDidFailToDeterminePosition(m_manager);
+ return;
+ }
+
+ connect(m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
+ connect(m_source, SIGNAL(updateTimeout()), this, SLOT(updateTimeout()));
+ }
+
+ m_source->startUpdates();
+}
+
+void WebGeolocationProviderQt::stopUpdating() const
+{
+ if (m_source)
+ m_source->stopUpdates();
+}
+
+#include "moc_WebGeolocationProviderQt.cpp"
+
+#endif // ENABLE(GEOLOCATION)
diff --git a/Source/WebKit2/UIProcess/qt/WebGeolocationProviderQt.h b/Source/WebKit2/UIProcess/qt/WebGeolocationProviderQt.h
new file mode 100644
index 000000000..e59e3d75b
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebGeolocationProviderQt.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2011 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 WebGeolocationProviderQt_h
+#define WebGeolocationProviderQt_h
+
+#include <QObject>
+#include <WebKit2/WKGeolocationManager.h>
+#include <WebKit2/WKGeolocationPosition.h>
+#include <WebKit2/WKRetainPtr.h>
+
+class QGeoPositionInfoSource;
+class QGeoPositionInfo;
+
+class WebGeolocationProviderQt : public QObject {
+ Q_OBJECT
+public:
+ static WebGeolocationProviderQt* create(WKGeolocationManagerRef);
+ static WKGeolocationProvider* provider(const WebGeolocationProviderQt*);
+
+ virtual ~WebGeolocationProviderQt();
+
+ void startUpdating() const;
+ void stopUpdating() const;
+
+public Q_SLOTS:
+ void updateTimeout();
+ void positionUpdated(const QGeoPositionInfo&);
+
+private:
+ Q_DISABLE_COPY(WebGeolocationProviderQt);
+ WebGeolocationProviderQt(WKGeolocationManagerRef);
+
+ WKGeolocationManagerRef m_manager;
+ WKRetainPtr<WKGeolocationPositionRef> m_lastPosition;
+ mutable QGeoPositionInfoSource* m_source;
+};
+
+#endif /* WebGeolocationProviderQt_h */
diff --git a/Source/WebKit2/UIProcess/qt/WebInspectorProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebInspectorProxyQt.cpp
new file mode 100644
index 000000000..6b69e9975
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebInspectorProxyQt.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebInspectorProxy.h"
+
+#if ENABLE(INSPECTOR)
+
+#include <WebCore/NotImplemented.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+WebPageProxy* WebInspectorProxy::platformCreateInspectorPage()
+{
+ notImplemented();
+ return 0;
+}
+
+void WebInspectorProxy::platformOpen()
+{
+ notImplemented();
+}
+
+void WebInspectorProxy::platformDidClose()
+{
+ notImplemented();
+}
+
+void WebInspectorProxy::platformBringToFront()
+{
+ notImplemented();
+}
+
+void WebInspectorProxy::platformInspectedURLChanged(const String&)
+{
+ notImplemented();
+}
+
+unsigned WebInspectorProxy::platformInspectedWindowHeight()
+{
+ notImplemented();
+ return 0;
+}
+
+void WebInspectorProxy::platformAttach()
+{
+ notImplemented();
+}
+
+void WebInspectorProxy::platformDetach()
+{
+ notImplemented();
+}
+
+void WebInspectorProxy::platformSetAttachedWindowHeight(unsigned)
+{
+ notImplemented();
+}
+
+String WebInspectorProxy::inspectorPageURL() const
+{
+ notImplemented();
+ return String();
+}
+
+String WebInspectorProxy::inspectorBaseURL() const
+{
+ notImplemented();
+ return String();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp
new file mode 100644
index 000000000..ac9fde418
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebPageProxyQt.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebPageProxy.h"
+
+#include "PageClient.h"
+#include "QtNetworkReplyData.h"
+#include "QtPageClient.h"
+#include "qquicknetworkreply_p.h"
+#include "WebPageMessages.h"
+#include "WebProcessProxy.h"
+#include <WebCore/Editor.h>
+#include <WebCore/NotImplemented.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+String WebPageProxy::standardUserAgent(const String& applicationNameForUserAgent)
+{
+ // FIXME: This should not be hard coded.
+ return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6) AppleWebKit/531.4 (KHTML, like Gecko) Version/4.0.3 Safari/531.4";
+}
+
+void WebPageProxy::saveRecentSearches(const String&, const Vector<String>&)
+{
+ notImplemented();
+}
+
+void WebPageProxy::loadRecentSearches(const String&, Vector<String>&)
+{
+ notImplemented();
+}
+
+void WebPageProxy::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd)
+{
+ // FIXME: We need to find out how to proper handle the crashes case.
+ if (!isValid())
+ return;
+
+ process()->send(Messages::WebPage::SetComposition(text, underlines, selectionStart, selectionEnd, replacementRangeStart, replacementRangeEnd), m_pageID);
+}
+
+void WebPageProxy::confirmComposition(const String& compositionString, int64_t selectionStart, int64_t selectionLength)
+{
+ if (!isValid())
+ return;
+
+ process()->send(Messages::WebPage::ConfirmComposition(compositionString, selectionStart, selectionLength), m_pageID);
+}
+
+void WebPageProxy::cancelComposition()
+{
+ if (!isValid())
+ return;
+
+ process()->send(Messages::WebPage::CancelComposition(), m_pageID);
+}
+
+void WebPageProxy::registerApplicationScheme(const String& scheme)
+{
+ process()->send(Messages::WebPage::RegisterApplicationScheme(scheme), m_pageID);
+}
+
+void WebPageProxy::resolveApplicationSchemeRequest(QtNetworkRequestData request)
+{
+ RefPtr<QtNetworkRequestData> requestData = adoptRef(new QtNetworkRequestData(request));
+ m_applicationSchemeRequests.add(requestData);
+ static_cast<QtPageClient*>(m_pageClient)->handleApplicationSchemeRequest(requestData);
+}
+
+void WebPageProxy::sendApplicationSchemeReply(const QQuickNetworkReply* reply)
+{
+ RefPtr<QtNetworkRequestData> requestData = reply->networkRequestData();
+ if (m_applicationSchemeRequests.contains(requestData)) {
+ RefPtr<QtNetworkReplyData> replyData = reply->networkReplyData();
+ process()->send(Messages::WebPage::ApplicationSchemeReply(*replyData), pageID());
+ m_applicationSchemeRequests.remove(requestData);
+ }
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp
new file mode 100644
index 000000000..4c0deadc2
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebPopupMenuProxyQt.h"
+
+#include "PlatformPopupMenuData.h"
+#include "WebPopupItem.h"
+#include "qquickwebview_p.h"
+#include "qquickwebview_p_p.h"
+#include <QtCore/QAbstractListModel>
+#include <QtDeclarative/QDeclarativeContext>
+#include <QtDeclarative/QDeclarativeEngine>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static QHash<int, QByteArray> createRoleNamesHash();
+
+class PopupMenuItemModel : public QAbstractListModel {
+ Q_OBJECT
+
+public:
+ enum Roles {
+ GroupRole = Qt::UserRole,
+ EnabledRole = Qt::UserRole + 1,
+ SelectedRole = Qt::UserRole + 2,
+ IsSeparatorRole = Qt::UserRole + 3
+ };
+
+ PopupMenuItemModel(const Vector<WebPopupItem>&, int selectedOriginalIndex);
+ virtual int rowCount(const QModelIndex& parent = QModelIndex()) const { return m_items.size(); }
+ virtual QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const;
+
+ Q_INVOKABLE void select(int);
+
+ int selectedOriginalIndex() const;
+
+private:
+ struct Item {
+ Item(const WebPopupItem& webPopupItem, const QString& group, int originalIndex, bool selected)
+ : text(webPopupItem.m_text)
+ , toolTip(webPopupItem.m_toolTip)
+ , group(group)
+ , originalIndex(originalIndex)
+ , enabled(webPopupItem.m_isEnabled)
+ , selected(selected)
+ , isSeparator(webPopupItem.m_type == WebPopupItem::Separator)
+ { }
+
+ QString text;
+ QString toolTip;
+ QString group;
+ // Keep track of originalIndex because we don't add the label (group) items to our vector.
+ int originalIndex;
+ bool enabled;
+ bool selected;
+ bool isSeparator;
+ };
+
+ void buildItems(const Vector<WebPopupItem>& webPopupItems, int selectedOriginalIndex);
+
+ Vector<Item> m_items;
+ int m_selectedModelIndex;
+};
+
+class ItemSelectorContextObject : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QRect elementRect READ elementRect CONSTANT FINAL)
+ Q_PROPERTY(QObject* items READ items CONSTANT FINAL)
+
+public:
+ ItemSelectorContextObject(const IntRect& elementRect, const Vector<WebPopupItem>&, int selectedIndex);
+
+ QRect elementRect() const { return m_elementRect; }
+ PopupMenuItemModel* items() { return &m_items; }
+
+ Q_INVOKABLE void accept(int index = -1);
+ Q_INVOKABLE void reject() { emit rejected(); }
+
+Q_SIGNALS:
+ void acceptedWithOriginalIndex(int);
+ void rejected();
+
+private:
+ QRect m_elementRect;
+ PopupMenuItemModel m_items;
+};
+
+ItemSelectorContextObject::ItemSelectorContextObject(const IntRect& elementRect, const Vector<WebPopupItem>& webPopupItems, int selectedIndex)
+ : m_elementRect(elementRect)
+ , m_items(webPopupItems, selectedIndex)
+{
+}
+
+void ItemSelectorContextObject::accept(int index)
+{
+ if (index != -1)
+ m_items.select(index);
+ int originalIndex = m_items.selectedOriginalIndex();
+ emit acceptedWithOriginalIndex(originalIndex);
+}
+
+static QHash<int, QByteArray> createRoleNamesHash()
+{
+ QHash<int, QByteArray> roles;
+ roles[Qt::DisplayRole] = "text";
+ roles[Qt::ToolTipRole] = "tooltip";
+ roles[PopupMenuItemModel::GroupRole] = "group";
+ roles[PopupMenuItemModel::EnabledRole] = "enabled";
+ roles[PopupMenuItemModel::SelectedRole] = "selected";
+ roles[PopupMenuItemModel::IsSeparatorRole] = "isSeparator";
+ return roles;
+}
+
+PopupMenuItemModel::PopupMenuItemModel(const Vector<WebPopupItem>& webPopupItems, int selectedOriginalIndex)
+ : m_selectedModelIndex(-1)
+{
+ static QHash<int, QByteArray> roles = createRoleNamesHash();
+ setRoleNames(roles);
+ buildItems(webPopupItems, selectedOriginalIndex);
+}
+
+QVariant PopupMenuItemModel::data(const QModelIndex& index, int role) const
+{
+ if (!index.isValid() || index.row() < 0 || index.row() >= m_items.size())
+ return QVariant();
+
+ const Item& item = m_items[index.row()];
+ if (item.isSeparator) {
+ if (role == IsSeparatorRole)
+ return true;
+ return QVariant();
+ }
+
+ switch (role) {
+ case Qt::DisplayRole:
+ return item.text;
+ case Qt::ToolTipRole:
+ return item.toolTip;
+ case GroupRole:
+ return item.group;
+ case EnabledRole:
+ return item.enabled;
+ case SelectedRole:
+ return item.selected;
+ case IsSeparatorRole:
+ return false;
+ }
+
+ return QVariant();
+}
+
+void PopupMenuItemModel::select(int index)
+{
+ int oldIndex = m_selectedModelIndex;
+ if (index == oldIndex)
+ return;
+ if (index < 0 || index >= m_items.size())
+ return;
+ Item& item = m_items[index];
+ if (!item.enabled)
+ return;
+
+ Item& oldItem = m_items[oldIndex];
+ oldItem.selected = false;
+ item.selected = true;
+ m_selectedModelIndex = index;
+
+ emit dataChanged(this->index(oldIndex), this->index(oldIndex));
+ emit dataChanged(this->index(index), this->index(index));
+}
+
+int PopupMenuItemModel::selectedOriginalIndex() const
+{
+ if (m_selectedModelIndex == -1)
+ return -1;
+ return m_items[m_selectedModelIndex].originalIndex;
+}
+
+void PopupMenuItemModel::buildItems(const Vector<WebPopupItem>& webPopupItems, int selectedOriginalIndex)
+{
+ QString currentGroup;
+ m_items.reserveInitialCapacity(webPopupItems.size());
+ for (int i = 0; i < webPopupItems.size(); i++) {
+ const WebPopupItem& webPopupItem = webPopupItems[i];
+ if (webPopupItem.m_isLabel) {
+ currentGroup = webPopupItem.m_text;
+ continue;
+ }
+ const bool selected = i == selectedOriginalIndex;
+ if (selected)
+ m_selectedModelIndex = m_items.size();
+ m_items.append(Item(webPopupItem, currentGroup, i, selected));
+ }
+}
+
+WebPopupMenuProxyQt::WebPopupMenuProxyQt(WebPopupMenuProxy::Client* client, QQuickWebView* webView)
+ : WebPopupMenuProxy(client)
+ , m_webView(webView)
+{
+}
+
+WebPopupMenuProxyQt::~WebPopupMenuProxyQt()
+{
+}
+
+void WebPopupMenuProxyQt::showPopupMenu(const IntRect& rect, WebCore::TextDirection, double, const Vector<WebPopupItem>& items, const PlatformPopupMenuData&, int32_t selectedIndex)
+{
+ m_selectedIndex = selectedIndex;
+
+ ItemSelectorContextObject* contextObject = new ItemSelectorContextObject(rect, items, m_selectedIndex);
+ createItem(contextObject);
+ if (!m_itemSelector) {
+ notifyValueChanged();
+ return;
+ }
+}
+
+void WebPopupMenuProxyQt::hidePopupMenu()
+{
+ m_itemSelector.clear();
+ m_context.clear();
+ notifyValueChanged();
+}
+
+void WebPopupMenuProxyQt::selectIndex(int index)
+{
+ m_selectedIndex = index;
+}
+
+void WebPopupMenuProxyQt::createItem(QObject* contextObject)
+{
+ QDeclarativeComponent* component = m_webView->experimental()->itemSelector();
+ if (!component) {
+ delete contextObject;
+ return;
+ }
+
+ createContext(component, contextObject);
+ QObject* object = component->beginCreate(m_context.get());
+ if (!object) {
+ m_context.clear();
+ return;
+ }
+
+ m_itemSelector = adoptPtr(qobject_cast<QQuickItem*>(object));
+ if (!m_itemSelector) {
+ m_context.clear();
+ m_itemSelector.clear();
+ return;
+ }
+
+ connect(contextObject, SIGNAL(acceptedWithOriginalIndex(int)), SLOT(selectIndex(int)));
+
+ // We enqueue these because they are triggered by m_itemSelector and will lead to its destruction.
+ connect(contextObject, SIGNAL(acceptedWithOriginalIndex(int)), SLOT(hidePopupMenu()), Qt::QueuedConnection);
+ connect(contextObject, SIGNAL(rejected()), SLOT(hidePopupMenu()), Qt::QueuedConnection);
+
+ QQuickWebViewPrivate::get(m_webView)->setViewInAttachedProperties(m_itemSelector.get());
+ component->completeCreate();
+
+ m_itemSelector->setParentItem(m_webView);
+}
+
+void WebPopupMenuProxyQt::createContext(QDeclarativeComponent* component, QObject* contextObject)
+{
+ QDeclarativeContext* baseContext = component->creationContext();
+ if (!baseContext)
+ baseContext = QDeclarativeEngine::contextForObject(m_webView);
+ m_context = adoptPtr(new QDeclarativeContext(baseContext));
+
+ contextObject->setParent(m_context.get());
+ m_context->setContextProperty(QLatin1String("model"), contextObject);
+ m_context->setContextObject(contextObject);
+}
+
+void WebPopupMenuProxyQt::notifyValueChanged()
+{
+ if (m_client) {
+ m_client->valueChangedForPopupMenu(this, m_selectedIndex);
+ invalidate();
+ }
+}
+
+} // namespace WebKit
+
+// Since we define QObjects in WebPopupMenuProxyQt.cpp, this will trigger moc to run on .cpp.
+#include "WebPopupMenuProxyQt.moc"
+
+// And we can't compile the moc for WebPopupMenuProxyQt.h by itself, since it doesn't include "config.h"
+#include "moc_WebPopupMenuProxyQt.cpp"
diff --git a/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.h b/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.h
new file mode 100644
index 000000000..ea22bbdd6
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebPopupMenuProxyQt_h
+#define WebPopupMenuProxyQt_h
+
+#include "WebPopupMenuProxy.h"
+
+#include <QtCore/QObject>
+#include <wtf/OwnPtr.h>
+
+class QDeclarativeComponent;
+class QDeclarativeContext;
+class QQuickWebView;
+class QQuickItem;
+
+namespace WebKit {
+
+class WebPopupMenuProxyQt : public QObject, public WebPopupMenuProxy {
+ Q_OBJECT
+
+public:
+ static PassRefPtr<WebPopupMenuProxyQt> create(WebPopupMenuProxy::Client* client, QQuickWebView* webView)
+ {
+ return adoptRef(new WebPopupMenuProxyQt(client, webView));
+ }
+ ~WebPopupMenuProxyQt();
+
+ virtual void showPopupMenu(const WebCore::IntRect&, WebCore::TextDirection, double pageScaleFactor, const Vector<WebPopupItem>&, const PlatformPopupMenuData&, int32_t selectedIndex);
+
+public Q_SLOTS:
+ virtual void hidePopupMenu();
+
+private Q_SLOTS:
+ void selectIndex(int);
+
+private:
+ WebPopupMenuProxyQt(WebPopupMenuProxy::Client*, QQuickWebView*);
+ void createItem(QObject*);
+ void createContext(QDeclarativeComponent*, QObject*);
+
+ void notifyValueChanged();
+
+ OwnPtr<QDeclarativeContext> m_context;
+ OwnPtr<QQuickItem> m_itemSelector;
+
+ QQuickWebView* m_webView;
+ int32_t m_selectedIndex;
+};
+
+} // namespace WebKit
+
+#endif // WebPopupMenuProxyQt_h
diff --git a/Source/WebKit2/UIProcess/qt/WebPreferencesQt.cpp b/Source/WebKit2/UIProcess/qt/WebPreferencesQt.cpp
new file mode 100644
index 000000000..fae4a2d76
--- /dev/null
+++ b/Source/WebKit2/UIProcess/qt/WebPreferencesQt.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebPreferences.h"
+
+namespace WebKit {
+
+void WebPreferences::platformInitializeStore()
+{
+}
+
+void WebPreferences::platformUpdateStringValueForKey(const String&, const String&)
+{
+}
+
+void WebPreferences::platformUpdateBoolValueForKey(const String&, bool)
+{
+}
+
+void WebPreferences::platformUpdateUInt32ValueForKey(const String&, uint32_t)
+{
+}
+
+void WebPreferences::platformUpdateDoubleValueForKey(const String&, double)
+{
+}
+
+} // namespace WebKit