|
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 |
|
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 |
|
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 |
|
107 static inline const 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 |
|
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 |
|
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. |
|
162 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) |
|
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 |
|
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 |
|
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 |
|
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 |
|
225 for (int i = 0; i < event.touchPointsLength; ++i) |
|
226 m_touchPoints.append(PlatformTouchPointBuilder(widget, event.touchPoints[i])); |
|
227 } |
|
228 #endif |
|
229 |
|
230 static int getWebInputModifiers(const UIEventWithKeyState& event) |
|
231 { |
|
232 int modifiers = 0; |
|
233 if (event.ctrlKey()) |
|
234 modifiers |= WebInputEvent::ControlKey; |
|
235 if (event.shiftKey()) |
|
236 modifiers |= WebInputEvent::ShiftKey; |
|
237 if (event.altKey()) |
|
238 modifiers |= WebInputEvent::AltKey; |
|
239 if (event.metaKey()) |
|
240 modifiers |= WebInputEvent::MetaKey; |
|
241 return modifiers; |
|
242 } |
|
243 |
|
244 WebMouseEventBuilder::WebMouseEventBuilder(const ScrollView* view, const MouseEvent& event) |
|
245 { |
|
246 if (event.type() == eventNames().mousemoveEvent) |
|
247 type = WebInputEvent::MouseMove; |
|
248 else if (event.type() == eventNames().mouseoutEvent) |
|
249 type = WebInputEvent::MouseLeave; |
|
250 else if (event.type() == eventNames().mouseoverEvent) |
|
251 type = WebInputEvent::MouseEnter; |
|
252 else if (event.type() == eventNames().mousedownEvent) |
|
253 type = WebInputEvent::MouseDown; |
|
254 else if (event.type() == eventNames().mouseupEvent) |
|
255 type = WebInputEvent::MouseUp; |
|
256 else |
|
257 return; // Skip all other mouse events. |
|
258 timeStampSeconds = event.timeStamp() * 1.0e-3; |
|
259 switch (event.button()) { |
|
260 case LeftButton: |
|
261 button = WebMouseEvent::ButtonLeft; |
|
262 break; |
|
263 case MiddleButton: |
|
264 button = WebMouseEvent::ButtonMiddle; |
|
265 break; |
|
266 case RightButton: |
|
267 button = WebMouseEvent::ButtonRight; |
|
268 break; |
|
269 } |
|
270 modifiers = getWebInputModifiers(event); |
|
271 if (event.buttonDown()) { |
|
272 switch (event.button()) { |
|
273 case LeftButton: |
|
274 modifiers |= WebInputEvent::LeftButtonDown; |
|
275 break; |
|
276 case MiddleButton: |
|
277 modifiers |= WebInputEvent::MiddleButtonDown; |
|
278 break; |
|
279 case RightButton: |
|
280 modifiers |= WebInputEvent::RightButtonDown; |
|
281 break; |
|
282 } |
|
283 } |
|
284 IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY())); |
|
285 globalX = event.screenX(); |
|
286 globalY = event.screenY(); |
|
287 windowX = p.x(); |
|
288 windowY = p.y(); |
|
289 x = event.offsetX(); |
|
290 y = event.offsetY(); |
|
291 clickCount = event.detail(); |
|
292 } |
|
293 |
|
294 WebMouseWheelEventBuilder::WebMouseWheelEventBuilder(const ScrollView* view, const WheelEvent& event) |
|
295 { |
|
296 if (event.type() != eventNames().mousewheelEvent) |
|
297 return; |
|
298 type = WebInputEvent::MouseWheel; |
|
299 timeStampSeconds = event.timeStamp() * 1.0e-3; |
|
300 modifiers = getWebInputModifiers(event); |
|
301 IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY())); |
|
302 globalX = event.screenX(); |
|
303 globalY = event.screenY(); |
|
304 windowX = p.x(); |
|
305 windowY = p.y(); |
|
306 x = event.offsetX(); |
|
307 y = event.offsetY(); |
|
308 deltaX = static_cast<float>(event.rawDeltaX()); |
|
309 deltaY = static_cast<float>(event.rawDeltaY()); |
|
310 // The 120 is from WheelEvent::initWheelEvent(). |
|
311 wheelTicksX = static_cast<float>(event.wheelDeltaX()) / 120; |
|
312 wheelTicksY = static_cast<float>(event.wheelDeltaY()) / 120; |
|
313 scrollByPage = event.granularity() == WheelEvent::Page; |
|
314 } |
|
315 |
|
316 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event) |
|
317 { |
|
318 if (event.type() == eventNames().keydownEvent) |
|
319 type = KeyDown; |
|
320 else if (event.type() == eventNames().keyupEvent) |
|
321 type = WebInputEvent::KeyUp; |
|
322 else if (event.type() == eventNames().keypressEvent) |
|
323 type = WebInputEvent::Char; |
|
324 else |
|
325 return; // Skip all other keyboard events. |
|
326 modifiers = getWebInputModifiers(event); |
|
327 timeStampSeconds = event.timeStamp() * 1.0e-3; |
|
328 windowsKeyCode = event.keyCode(); |
|
329 nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode(); |
|
330 unsigned int numChars = std::min(event.keyEvent()->text().length(), |
|
331 static_cast<unsigned int>(WebKeyboardEvent::textLengthCap)); |
|
332 for (unsigned int i = 0; i < numChars; i++) { |
|
333 text[i] = event.keyEvent()->text()[i]; |
|
334 unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i]; |
|
335 } |
|
336 } |
|
337 |
|
338 } // namespace WebKit |