blob: d79c2970f26bd8ff5182ef9a8629258f7dae406c [file] [log] [blame]
/*
* Copyright (C) 2011 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 "EventDispatcher.h"
#include "EventDispatcherMessages.h"
#include "WebEvent.h"
#include "WebEventConversion.h"
#include "WebPage.h"
#include "WebPageProxyMessages.h"
#include "WebProcess.h"
#include <WebCore/Page.h>
#include <WebCore/RunLoop.h>
#include <wtf/MainThread.h>
#if ENABLE(THREADED_SCROLLING)
#include <WebCore/ScrollingCoordinator.h>
#include <WebCore/ScrollingThread.h>
#include <WebCore/ScrollingTree.h>
#endif
using namespace WebCore;
namespace WebKit {
PassRefPtr<EventDispatcher> EventDispatcher::create()
{
return adoptRef(new EventDispatcher);
}
EventDispatcher::EventDispatcher()
: m_queue(WorkQueue::create("com.apple.WebKit.EventDispatcher"))
{
}
EventDispatcher::~EventDispatcher()
{
}
#if ENABLE(THREADED_SCROLLING)
void EventDispatcher::addScrollingTreeForPage(WebPage* webPage)
{
MutexLocker locker(m_scrollingTreesMutex);
ASSERT(webPage->corePage()->scrollingCoordinator());
ASSERT(!m_scrollingTrees.contains(webPage->pageID()));
m_scrollingTrees.set(webPage->pageID(), webPage->corePage()->scrollingCoordinator()->scrollingTree());
}
void EventDispatcher::removeScrollingTreeForPage(WebPage* webPage)
{
MutexLocker locker(m_scrollingTreesMutex);
ASSERT(m_scrollingTrees.contains(webPage->pageID()));
m_scrollingTrees.remove(webPage->pageID());
}
#endif
void EventDispatcher::initializeConnection(CoreIPC::Connection* connection)
{
connection->addWorkQueueMessageReceiver(Messages::EventDispatcher::messageReceiverName(), m_queue.get(), this);
}
void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent, bool canGoBack, bool canGoForward)
{
#if ENABLE(THREADED_SCROLLING)
MutexLocker locker(m_scrollingTreesMutex);
if (ScrollingTree* scrollingTree = m_scrollingTrees.get(pageID)) {
PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
// FIXME: It's pretty horrible that we're updating the back/forward state here.
// WebCore should always know the current state and know when it changes so the
// scrolling tree can be notified.
// We only need to do this at the beginning of the gesture.
if (platformWheelEvent.phase() == PlatformWheelEventPhaseBegan)
ScrollingThread::dispatch(bind(&ScrollingTree::updateBackForwardState, scrollingTree, canGoBack, canGoForward));
ScrollingTree::EventResult result = scrollingTree->tryToHandleWheelEvent(platformWheelEvent);
if (result == ScrollingTree::DidHandleEvent || result == ScrollingTree::DidNotHandleEvent) {
sendDidReceiveEvent(pageID, wheelEvent, result == ScrollingTree::DidHandleEvent);
return;
}
}
#else
UNUSED_PARAM(canGoBack);
UNUSED_PARAM(canGoForward);
#endif
RunLoop::main()->dispatch(bind(&EventDispatcher::dispatchWheelEvent, this, pageID, wheelEvent));
}
#if ENABLE(GESTURE_EVENTS)
void EventDispatcher::gestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent)
{
RunLoop::main()->dispatch(bind(&EventDispatcher::dispatchGestureEvent, this, pageID, gestureEvent));
}
#endif
void EventDispatcher::dispatchWheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent)
{
ASSERT(isMainThread());
WebPage* webPage = WebProcess::shared().webPage(pageID);
if (!webPage)
return;
webPage->wheelEvent(wheelEvent);
}
#if ENABLE(GESTURE_EVENTS)
void EventDispatcher::dispatchGestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent)
{
ASSERT(isMainThread());
WebPage* webPage = WebProcess::shared().webPage(pageID);
if (!webPage)
return;
webPage->gestureEvent(gestureEvent);
}
#endif
#if ENABLE(THREADED_SCROLLING)
void EventDispatcher::sendDidReceiveEvent(uint64_t pageID, const WebEvent& event, bool didHandleEvent)
{
WebProcess::shared().connection()->send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(event.type()), didHandleEvent), pageID);
}
#endif
} // namespace WebKit