1/* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "EventDispatcher.h" 28 29#include "EventDispatcherMessages.h" 30#include "WebEvent.h" 31#include "WebEventConversion.h" 32#include "WebPage.h" 33#include "WebPageProxyMessages.h" 34#include "WebProcess.h" 35#include <WebCore/Page.h> 36#include <WebCore/RunLoop.h> 37#include <wtf/MainThread.h> 38 39#if ENABLE(THREADED_SCROLLING) 40#include <WebCore/ScrollingCoordinator.h> 41#include <WebCore/ScrollingThread.h> 42#include <WebCore/ScrollingTree.h> 43#endif 44 45using namespace WebCore; 46 47namespace WebKit { 48 49PassRefPtr<EventDispatcher> EventDispatcher::create() 50{ 51 return adoptRef(new EventDispatcher); 52} 53 54EventDispatcher::EventDispatcher() 55 : m_queue(WorkQueue::create("com.apple.WebKit.EventDispatcher")) 56{ 57} 58 59EventDispatcher::~EventDispatcher() 60{ 61} 62 63#if ENABLE(THREADED_SCROLLING) 64void EventDispatcher::addScrollingTreeForPage(WebPage* webPage) 65{ 66 MutexLocker locker(m_scrollingTreesMutex); 67 68 ASSERT(webPage->corePage()->scrollingCoordinator()); 69 ASSERT(!m_scrollingTrees.contains(webPage->pageID())); 70 m_scrollingTrees.set(webPage->pageID(), webPage->corePage()->scrollingCoordinator()->scrollingTree()); 71} 72 73void EventDispatcher::removeScrollingTreeForPage(WebPage* webPage) 74{ 75 MutexLocker locker(m_scrollingTreesMutex); 76 ASSERT(m_scrollingTrees.contains(webPage->pageID())); 77 78 m_scrollingTrees.remove(webPage->pageID()); 79} 80#endif 81 82void EventDispatcher::initializeConnection(CoreIPC::Connection* connection) 83{ 84 connection->addWorkQueueMessageReceiver(Messages::EventDispatcher::messageReceiverName(), m_queue.get(), this); 85} 86 87void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent, bool canGoBack, bool canGoForward) 88{ 89#if ENABLE(THREADED_SCROLLING) 90 MutexLocker locker(m_scrollingTreesMutex); 91 if (ScrollingTree* scrollingTree = m_scrollingTrees.get(pageID)) { 92 PlatformWheelEvent platformWheelEvent = platform(wheelEvent); 93 94 // FIXME: It's pretty horrible that we're updating the back/forward state here. 95 // WebCore should always know the current state and know when it changes so the 96 // scrolling tree can be notified. 97 // We only need to do this at the beginning of the gesture. 98 if (platformWheelEvent.phase() == PlatformWheelEventPhaseBegan) 99 ScrollingThread::dispatch(bind(&ScrollingTree::updateBackForwardState, scrollingTree, canGoBack, canGoForward)); 100 101 ScrollingTree::EventResult result = scrollingTree->tryToHandleWheelEvent(platformWheelEvent); 102 if (result == ScrollingTree::DidHandleEvent || result == ScrollingTree::DidNotHandleEvent) { 103 sendDidReceiveEvent(pageID, wheelEvent, result == ScrollingTree::DidHandleEvent); 104 return; 105 } 106 } 107#else 108 UNUSED_PARAM(canGoBack); 109 UNUSED_PARAM(canGoForward); 110#endif 111 112 RunLoop::main()->dispatch(bind(&EventDispatcher::dispatchWheelEvent, this, pageID, wheelEvent)); 113} 114 115#if ENABLE(GESTURE_EVENTS) 116void EventDispatcher::gestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent) 117{ 118 RunLoop::main()->dispatch(bind(&EventDispatcher::dispatchGestureEvent, this, pageID, gestureEvent)); 119} 120#endif 121 122void EventDispatcher::dispatchWheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent) 123{ 124 ASSERT(isMainThread()); 125 126 WebPage* webPage = WebProcess::shared().webPage(pageID); 127 if (!webPage) 128 return; 129 130 webPage->wheelEvent(wheelEvent); 131} 132 133#if ENABLE(GESTURE_EVENTS) 134void EventDispatcher::dispatchGestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent) 135{ 136 ASSERT(isMainThread()); 137 138 WebPage* webPage = WebProcess::shared().webPage(pageID); 139 if (!webPage) 140 return; 141 142 webPage->gestureEvent(gestureEvent); 143} 144#endif 145 146#if ENABLE(THREADED_SCROLLING) 147void EventDispatcher::sendDidReceiveEvent(uint64_t pageID, const WebEvent& event, bool didHandleEvent) 148{ 149 WebProcess::shared().parentProcessConnection()->send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(event.type()), didHandleEvent), pageID); 150} 151#endif 152 153} // namespace WebKit 154