• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 Google 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 are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "config.h"
32 #include "WebInputEventConversion.h"
33 
34 #include "EventNames.h"
35 #include "KeyboardCodes.h"
36 #include "KeyboardEvent.h"
37 #include "MouseEvent.h"
38 #include "PlatformKeyboardEvent.h"
39 #include "PlatformMouseEvent.h"
40 #include "PlatformWheelEvent.h"
41 #include "ScrollView.h"
42 #include "WebInputEvent.h"
43 #include "WheelEvent.h"
44 #include "Widget.h"
45 
46 using namespace WebCore;
47 
48 namespace WebKit {
49 
50 // MakePlatformMouseEvent -----------------------------------------------------
51 
PlatformMouseEventBuilder(Widget * widget,const WebMouseEvent & e)52 PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, const WebMouseEvent& e)
53 {
54     // FIXME: widget is always toplevel, unless it's a popup.  We may be able
55     // to get rid of this once we abstract popups into a WebKit API.
56     m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
57     m_globalPosition = IntPoint(e.globalX, e.globalY);
58     m_button = static_cast<MouseButton>(e.button);
59     m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
60     m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
61     m_altKey = (e.modifiers & WebInputEvent::AltKey);
62     m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
63     m_modifierFlags = e.modifiers;
64     m_timestamp = e.timeStampSeconds;
65     m_clickCount = e.clickCount;
66 
67     switch (e.type) {
68     case WebInputEvent::MouseMove:
69     case WebInputEvent::MouseLeave:  // synthesize a move event
70         m_eventType = MouseEventMoved;
71         break;
72 
73     case WebInputEvent::MouseDown:
74         m_eventType = MouseEventPressed;
75         break;
76 
77     case WebInputEvent::MouseUp:
78         m_eventType = MouseEventReleased;
79         break;
80 
81     default:
82         ASSERT_NOT_REACHED();
83     }
84 }
85 
86 // PlatformWheelEventBuilder --------------------------------------------------
87 
PlatformWheelEventBuilder(Widget * widget,const WebMouseWheelEvent & e)88 PlatformWheelEventBuilder::PlatformWheelEventBuilder(Widget* widget, const WebMouseWheelEvent& e)
89 {
90     m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
91     m_globalPosition = IntPoint(e.globalX, e.globalY);
92     m_deltaX = e.deltaX;
93     m_deltaY = e.deltaY;
94     m_wheelTicksX = e.wheelTicksX;
95     m_wheelTicksY = e.wheelTicksY;
96     m_isAccepted = false;
97     m_granularity = e.scrollByPage ?
98         ScrollByPageWheelEvent : ScrollByPixelWheelEvent;
99     m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
100     m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
101     m_altKey = (e.modifiers & WebInputEvent::AltKey);
102     m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
103 }
104 
105 // MakePlatformKeyboardEvent --------------------------------------------------
106 
toPlatformKeyboardEventType(WebInputEvent::Type type)107 static inline PlatformKeyboardEvent::Type toPlatformKeyboardEventType(WebInputEvent::Type type)
108 {
109     switch (type) {
110     case WebInputEvent::KeyUp:
111         return PlatformKeyboardEvent::KeyUp;
112     case WebInputEvent::KeyDown:
113         return PlatformKeyboardEvent::KeyDown;
114     case WebInputEvent::RawKeyDown:
115         return PlatformKeyboardEvent::RawKeyDown;
116     case WebInputEvent::Char:
117         return PlatformKeyboardEvent::Char;
118     default:
119         ASSERT_NOT_REACHED();
120     }
121     return PlatformKeyboardEvent::KeyDown;
122 }
123 
PlatformKeyboardEventBuilder(const WebKeyboardEvent & e)124 PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder(const WebKeyboardEvent& e)
125 {
126     m_type = toPlatformKeyboardEventType(e.type);
127     m_text = String(e.text);
128     m_unmodifiedText = String(e.unmodifiedText);
129     m_keyIdentifier = String(e.keyIdentifier);
130     m_autoRepeat = (e.modifiers & WebInputEvent::IsAutoRepeat);
131     m_windowsVirtualKeyCode = e.windowsKeyCode;
132     m_nativeVirtualKeyCode = e.nativeKeyCode;
133     m_isKeypad = (e.modifiers & WebInputEvent::IsKeyPad);
134     m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
135     m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
136     m_altKey = (e.modifiers & WebInputEvent::AltKey);
137     m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
138     m_isSystemKey = e.isSystemKey;
139 }
140 
setKeyType(Type type)141 void PlatformKeyboardEventBuilder::setKeyType(Type type)
142 {
143     // According to the behavior of Webkit in Windows platform,
144     // we need to convert KeyDown to RawKeydown and Char events
145     // See WebKit/WebKit/Win/WebView.cpp
146     ASSERT(m_type == KeyDown);
147     ASSERT(type == RawKeyDown || type == Char);
148     m_type = type;
149 
150     if (type == RawKeyDown) {
151         m_text = String();
152         m_unmodifiedText = String();
153     } else {
154         m_keyIdentifier = String();
155         m_windowsVirtualKeyCode = 0;
156     }
157 }
158 
159 // Please refer to bug http://b/issue?id=961192, which talks about Webkit
160 // keyboard event handling changes. It also mentions the list of keys
161 // which don't have associated character events.
isCharacterKey() const162 bool PlatformKeyboardEventBuilder::isCharacterKey() const
163 {
164     switch (windowsVirtualKeyCode()) {
165     case VKEY_BACK:
166     case VKEY_ESCAPE:
167         return false;
168     }
169     return true;
170 }
171 
172 #if ENABLE(TOUCH_EVENTS)
toPlatformTouchEventType(const WebInputEvent::Type type)173 static inline TouchEventType toPlatformTouchEventType(const WebInputEvent::Type type)
174 {
175     switch (type) {
176     case WebInputEvent::TouchStart:
177         return TouchStart;
178     case WebInputEvent::TouchMove:
179         return TouchMove;
180     case WebInputEvent::TouchEnd:
181         return TouchEnd;
182     case WebInputEvent::TouchCancel:
183         return TouchCancel;
184     default:
185         ASSERT_NOT_REACHED();
186     }
187     return TouchStart;
188 }
189 
toPlatformTouchPointState(const WebTouchPoint::State state)190 static inline PlatformTouchPoint::State toPlatformTouchPointState(const WebTouchPoint::State state)
191 {
192     switch (state) {
193     case WebTouchPoint::StateReleased:
194         return PlatformTouchPoint::TouchReleased;
195     case WebTouchPoint::StatePressed:
196         return PlatformTouchPoint::TouchPressed;
197     case WebTouchPoint::StateMoved:
198         return PlatformTouchPoint::TouchMoved;
199     case WebTouchPoint::StateStationary:
200         return PlatformTouchPoint::TouchStationary;
201     case WebTouchPoint::StateCancelled:
202         return PlatformTouchPoint::TouchCancelled;
203     case WebTouchPoint::StateUndefined:
204         ASSERT_NOT_REACHED();
205     }
206     return PlatformTouchPoint::TouchReleased;
207 }
208 
PlatformTouchPointBuilder(Widget * widget,const WebTouchPoint & point)209 PlatformTouchPointBuilder::PlatformTouchPointBuilder(Widget* widget, const WebTouchPoint& point)
210 {
211     m_id = point.id;
212     m_state = toPlatformTouchPointState(point.state);
213     m_pos = widget->convertFromContainingWindow(point.position);
214     m_screenPos = point.screenPosition;
215 }
216 
PlatformTouchEventBuilder(Widget * widget,const WebTouchEvent & event)217 PlatformTouchEventBuilder::PlatformTouchEventBuilder(Widget* widget, const WebTouchEvent& event)
218 {
219     m_type = toPlatformTouchEventType(event.type);
220     m_ctrlKey = event.modifiers & WebInputEvent::ControlKey;
221     m_altKey = event.modifiers & WebInputEvent::AltKey;
222     m_shiftKey = event.modifiers & WebInputEvent::ShiftKey;
223     m_metaKey = event.modifiers & WebInputEvent::MetaKey;
224     m_timestamp = event.timeStampSeconds;
225 
226     for (int i = 0; i < event.touchPointsLength; ++i)
227         m_touchPoints.append(PlatformTouchPointBuilder(widget, event.touchPoints[i]));
228 }
229 #endif
230 
getWebInputModifiers(const UIEventWithKeyState & event)231 static int getWebInputModifiers(const UIEventWithKeyState& event)
232 {
233     int modifiers = 0;
234     if (event.ctrlKey())
235         modifiers |= WebInputEvent::ControlKey;
236     if (event.shiftKey())
237         modifiers |= WebInputEvent::ShiftKey;
238     if (event.altKey())
239         modifiers |= WebInputEvent::AltKey;
240     if (event.metaKey())
241         modifiers |= WebInputEvent::MetaKey;
242     return modifiers;
243 }
244 
WebMouseEventBuilder(const Widget * widget,const MouseEvent & event)245 WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const MouseEvent& event)
246 {
247     if (event.type() == eventNames().mousemoveEvent)
248         type = WebInputEvent::MouseMove;
249     else if (event.type() == eventNames().mouseoutEvent)
250         type = WebInputEvent::MouseLeave;
251     else if (event.type() == eventNames().mouseoverEvent)
252         type = WebInputEvent::MouseEnter;
253     else if (event.type() == eventNames().mousedownEvent)
254         type = WebInputEvent::MouseDown;
255     else if (event.type() == eventNames().mouseupEvent)
256         type = WebInputEvent::MouseUp;
257     else if (event.type() == eventNames().contextmenuEvent)
258         type = WebInputEvent::ContextMenu;
259     else
260         return; // Skip all other mouse events.
261     timeStampSeconds = event.timeStamp() * 1.0e-3;
262     switch (event.button()) {
263     case LeftButton:
264         button = WebMouseEvent::ButtonLeft;
265         break;
266     case MiddleButton:
267         button = WebMouseEvent::ButtonMiddle;
268         break;
269     case RightButton:
270         button = WebMouseEvent::ButtonRight;
271         break;
272     }
273     modifiers = getWebInputModifiers(event);
274     if (event.buttonDown()) {
275         switch (event.button()) {
276         case LeftButton:
277             modifiers |= WebInputEvent::LeftButtonDown;
278             break;
279         case MiddleButton:
280             modifiers |= WebInputEvent::MiddleButtonDown;
281             break;
282         case RightButton:
283             modifiers |= WebInputEvent::RightButtonDown;
284             break;
285         }
286     }
287     ScrollView* view = widget->parent();
288     IntPoint p = view->contentsToWindow(
289         IntPoint(event.absoluteLocation().x(), event.absoluteLocation().y()));
290     globalX = event.screenX();
291     globalY = event.screenY();
292     windowX = p.x();
293     windowY = p.y();
294     x = event.absoluteLocation().x() - widget->pos().x();
295     y = event.absoluteLocation().y() - widget->pos().y();
296     clickCount = event.detail();
297 }
298 
WebMouseWheelEventBuilder(const Widget * widget,const WheelEvent & event)299 WebMouseWheelEventBuilder::WebMouseWheelEventBuilder(const Widget* widget, const WheelEvent& event)
300 {
301     if (event.type() != eventNames().mousewheelEvent)
302         return;
303     type = WebInputEvent::MouseWheel;
304     timeStampSeconds = event.timeStamp() * 1.0e-3;
305     modifiers = getWebInputModifiers(event);
306     ScrollView* view = widget->parent();
307     IntPoint p = view->contentsToWindow(
308         IntPoint(event.absoluteLocation().x(), event.absoluteLocation().y()));
309     globalX = event.screenX();
310     globalY = event.screenY();
311     windowX = p.x();
312     windowY = p.y();
313     x = event.absoluteLocation().x() - widget->pos().x();
314     y = event.absoluteLocation().y() - widget->pos().y();
315     deltaX = static_cast<float>(event.rawDeltaX());
316     deltaY = static_cast<float>(event.rawDeltaY());
317     // The 120 is from WheelEvent::initWheelEvent().
318     wheelTicksX = static_cast<float>(event.wheelDeltaX()) / 120;
319     wheelTicksY = static_cast<float>(event.wheelDeltaY()) / 120;
320     scrollByPage = event.granularity() == WheelEvent::Page;
321 }
322 
WebKeyboardEventBuilder(const KeyboardEvent & event)323 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event)
324 {
325     if (event.type() == eventNames().keydownEvent)
326         type = KeyDown;
327     else if (event.type() == eventNames().keyupEvent)
328         type = WebInputEvent::KeyUp;
329     else if (event.type() == eventNames().keypressEvent)
330         type = WebInputEvent::Char;
331     else
332         return; // Skip all other keyboard events.
333     modifiers = getWebInputModifiers(event);
334     timeStampSeconds = event.timeStamp() * 1.0e-3;
335     windowsKeyCode = event.keyCode();
336 
337     // The platform keyevent does not exist if the event was created using
338     // initKeyboardEvent.
339     if (!event.keyEvent())
340         return;
341     nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode();
342     unsigned int numChars = std::min(event.keyEvent()->text().length(),
343         static_cast<unsigned int>(WebKeyboardEvent::textLengthCap));
344     for (unsigned int i = 0; i < numChars; i++) {
345         text[i] = event.keyEvent()->text()[i];
346         unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i];
347     }
348 }
349 
350 } // namespace WebKit
351