1/*
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "EventHandler.h"
29
30#include "ChromiumDataObject.h"
31#include "ClipboardChromium.h"
32#include "Cursor.h"
33#include "FloatPoint.h"
34#include "FocusController.h"
35#include "FrameView.h"
36#include "Frame.h"
37#include "HitTestRequest.h"
38#include "HitTestResult.h"
39#include "MouseEventWithHitTestResults.h"
40#include "NotImplemented.h"
41#include "Page.h"
42#include "PlatformKeyboardEvent.h"
43#include "PlatformWheelEvent.h"
44#include "RenderWidget.h"
45#include "SelectionController.h"
46
47namespace WebCore {
48
49#if OS(DARWIN)
50const double EventHandler::TextDragDelay = 0.15;
51#else
52const double EventHandler::TextDragDelay = 0.0;
53#endif
54
55bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
56{
57    // If we're clicking into a frame that is selected, the frame will appear
58    // greyed out even though we're clicking on the selection.  This looks
59    // really strange (having the whole frame be greyed out), so we deselect the
60    // selection.
61    IntPoint p = m_frame->view()->windowToContents(mev.event().pos());
62    if (m_frame->selection()->contains(p)) {
63        VisiblePosition visiblePos(
64            targetNode(mev)->renderer()->positionForPoint(mev.localPoint()));
65        VisibleSelection newSelection(visiblePos);
66        if (m_frame->selection()->shouldChangeSelection(newSelection))
67            m_frame->selection()->setSelection(newSelection);
68    }
69
70    subframe->eventHandler()->handleMousePressEvent(mev.event());
71    return true;
72}
73
74bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, HitTestResult* hoveredNode)
75{
76    if (m_mouseDownMayStartDrag && !m_mouseDownWasInSubframe)
77        return false;
78    subframe->eventHandler()->handleMouseMoveEvent(mev.event(), hoveredNode);
79    return true;
80}
81
82bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
83{
84    subframe->eventHandler()->handleMouseReleaseEvent(mev.event());
85    return true;
86}
87
88bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& wheelEvent, Widget* widget)
89{
90    // We can sometimes get a null widget!  EventHandlerMac handles a null
91    // widget by returning false, so we do the same.
92    if (!widget)
93        return false;
94
95    // If not a FrameView, then probably a plugin widget.  Those will receive
96    // the event via an EventTargetNode dispatch when this returns false.
97    if (!widget->isFrameView())
98        return false;
99
100    return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(wheelEvent);
101}
102
103bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
104{
105    // Figure out which view to send the event to.
106    if (!targetNode(event) || !targetNode(event)->renderer() || !targetNode(event)->renderer()->isWidget())
107        return false;
108    return passMouseDownEventToWidget(toRenderWidget(targetNode(event)->renderer())->widget());
109}
110
111bool EventHandler::passMouseDownEventToWidget(Widget* widget)
112{
113    notImplemented();
114    return false;
115}
116
117bool EventHandler::tabsToAllFormControls(KeyboardEvent*) const
118{
119    return true;
120}
121
122bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const
123{
124    // FIXME: EventHandlerWin.cpp does the following:
125    // return event.activatedWebView();
126    return false;
127}
128
129PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
130{
131    RefPtr<ChromiumDataObject> dataObject = ChromiumDataObject::create(Clipboard::DragAndDrop);
132    return ClipboardChromium::create(Clipboard::DragAndDrop, dataObject.get(), ClipboardWritable, m_frame);
133}
134
135void EventHandler::focusDocumentView()
136{
137    Page* page = m_frame->page();
138    if (!page)
139        return;
140    page->focusController()->setFocusedFrame(m_frame);
141}
142
143bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
144{
145    return passMouseDownEventToWidget(renderWidget->widget());
146}
147
148unsigned EventHandler::accessKeyModifiers()
149{
150#if OS(DARWIN)
151    return PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey;
152#else
153    return PlatformKeyboardEvent::AltKey;
154#endif
155}
156
157#if OS(LINUX) || OS(FREEBSD)
158// GTK+ must scroll horizontally if the mouse pointer is on top of the
159// horizontal scrollbar while scrolling with the wheel.
160// This code comes from gtk/EventHandlerGtk.cpp.
161bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult& result) const
162{
163    return result.scrollbar() && result.scrollbar()->orientation() == HorizontalScrollbar;
164}
165#endif
166
167} // namespace WebCore
168