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 "Widget.h"
44
45 using namespace WebCore;
46
47 namespace WebKit {
48
49 // MakePlatformMouseEvent -----------------------------------------------------
50
PlatformMouseEventBuilder(Widget * widget,const WebMouseEvent & e)51 PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, const WebMouseEvent& e)
52 {
53 // FIXME: widget is always toplevel, unless it's a popup. We may be able
54 // to get rid of this once we abstract popups into a WebKit API.
55 m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
56 m_globalPosition = IntPoint(e.globalX, e.globalY);
57 m_button = static_cast<MouseButton>(e.button);
58 m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
59 m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
60 m_altKey = (e.modifiers & WebInputEvent::AltKey);
61 m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
62 m_modifierFlags = e.modifiers;
63 m_timestamp = e.timeStampSeconds;
64 m_clickCount = e.clickCount;
65
66 switch (e.type) {
67 case WebInputEvent::MouseMove:
68 case WebInputEvent::MouseLeave: // synthesize a move event
69 m_eventType = MouseEventMoved;
70 break;
71
72 case WebInputEvent::MouseDown:
73 m_eventType = MouseEventPressed;
74 break;
75
76 case WebInputEvent::MouseUp:
77 m_eventType = MouseEventReleased;
78 break;
79
80 default:
81 ASSERT_NOT_REACHED();
82 }
83 }
84
85 // PlatformWheelEventBuilder --------------------------------------------------
86
PlatformWheelEventBuilder(Widget * widget,const WebMouseWheelEvent & e)87 PlatformWheelEventBuilder::PlatformWheelEventBuilder(Widget* widget, const WebMouseWheelEvent& e)
88 {
89 m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
90 m_globalPosition = IntPoint(e.globalX, e.globalY);
91 m_deltaX = e.deltaX;
92 m_deltaY = e.deltaY;
93 m_wheelTicksX = e.wheelTicksX;
94 m_wheelTicksY = e.wheelTicksY;
95 m_isAccepted = false;
96 m_granularity = e.scrollByPage ?
97 ScrollByPageWheelEvent : ScrollByPixelWheelEvent;
98 m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
99 m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
100 m_altKey = (e.modifiers & WebInputEvent::AltKey);
101 m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
102 }
103
104 // MakePlatformKeyboardEvent --------------------------------------------------
105
toPlatformKeyboardEventType(WebInputEvent::Type type)106 static inline const PlatformKeyboardEvent::Type toPlatformKeyboardEventType(WebInputEvent::Type type)
107 {
108 switch (type) {
109 case WebInputEvent::KeyUp:
110 return PlatformKeyboardEvent::KeyUp;
111 case WebInputEvent::KeyDown:
112 return PlatformKeyboardEvent::KeyDown;
113 case WebInputEvent::RawKeyDown:
114 return PlatformKeyboardEvent::RawKeyDown;
115 case WebInputEvent::Char:
116 return PlatformKeyboardEvent::Char;
117 default:
118 ASSERT_NOT_REACHED();
119 }
120 return PlatformKeyboardEvent::KeyDown;
121 }
122
PlatformKeyboardEventBuilder(const WebKeyboardEvent & e)123 PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder(const WebKeyboardEvent& e)
124 {
125 m_type = toPlatformKeyboardEventType(e.type);
126 m_text = String(e.text);
127 m_unmodifiedText = String(e.unmodifiedText);
128 m_keyIdentifier = String(e.keyIdentifier);
129 m_autoRepeat = (e.modifiers & WebInputEvent::IsAutoRepeat);
130 m_windowsVirtualKeyCode = e.windowsKeyCode;
131 m_nativeVirtualKeyCode = e.nativeKeyCode;
132 m_isKeypad = (e.modifiers & WebInputEvent::IsKeyPad);
133 m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
134 m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
135 m_altKey = (e.modifiers & WebInputEvent::AltKey);
136 m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
137 m_isSystemKey = e.isSystemKey;
138 }
139
setKeyType(Type type)140 void PlatformKeyboardEventBuilder::setKeyType(Type type)
141 {
142 // According to the behavior of Webkit in Windows platform,
143 // we need to convert KeyDown to RawKeydown and Char events
144 // See WebKit/WebKit/Win/WebView.cpp
145 ASSERT(m_type == KeyDown);
146 ASSERT(type == RawKeyDown || type == Char);
147 m_type = type;
148
149 if (type == RawKeyDown) {
150 m_text = String();
151 m_unmodifiedText = String();
152 } else {
153 m_keyIdentifier = String();
154 m_windowsVirtualKeyCode = 0;
155 }
156 }
157
158 // Please refer to bug http://b/issue?id=961192, which talks about Webkit
159 // keyboard event handling changes. It also mentions the list of keys
160 // which don't have associated character events.
isCharacterKey() const161 bool PlatformKeyboardEventBuilder::isCharacterKey() const
162 {
163 switch (windowsVirtualKeyCode()) {
164 case VKEY_BACK:
165 case VKEY_ESCAPE:
166 return false;
167 }
168 return true;
169 }
170
getWebInputModifiers(const UIEventWithKeyState & event)171 static int getWebInputModifiers(const UIEventWithKeyState& event)
172 {
173 int modifiers = 0;
174 if (event.ctrlKey())
175 modifiers |= WebInputEvent::ControlKey;
176 if (event.shiftKey())
177 modifiers |= WebInputEvent::ShiftKey;
178 if (event.altKey())
179 modifiers |= WebInputEvent::AltKey;
180 if (event.metaKey())
181 modifiers |= WebInputEvent::MetaKey;
182 return modifiers;
183 }
184
WebMouseEventBuilder(const ScrollView * view,const MouseEvent & event)185 WebMouseEventBuilder::WebMouseEventBuilder(const ScrollView* view, const MouseEvent& event)
186 {
187 if (event.type() == eventNames().mousemoveEvent)
188 type = WebInputEvent::MouseMove;
189 else if (event.type() == eventNames().mouseoutEvent)
190 type = WebInputEvent::MouseLeave;
191 else if (event.type() == eventNames().mouseoverEvent)
192 type = WebInputEvent::MouseEnter;
193 else if (event.type() == eventNames().mousedownEvent)
194 type = WebInputEvent::MouseDown;
195 else if (event.type() == eventNames().mouseupEvent)
196 type = WebInputEvent::MouseUp;
197 else
198 return; // Skip all other mouse events.
199 timeStampSeconds = event.timeStamp() * 1.0e-3;
200 switch (event.button()) {
201 case LeftButton:
202 button = WebMouseEvent::ButtonLeft;
203 break;
204 case MiddleButton:
205 button = WebMouseEvent::ButtonMiddle;
206 break;
207 case RightButton:
208 button = WebMouseEvent::ButtonRight;
209 break;
210 }
211 modifiers = getWebInputModifiers(event);
212 if (event.buttonDown()) {
213 switch (event.button()) {
214 case LeftButton:
215 modifiers |= WebInputEvent::LeftButtonDown;
216 break;
217 case MiddleButton:
218 modifiers |= WebInputEvent::MiddleButtonDown;
219 break;
220 case RightButton:
221 modifiers |= WebInputEvent::RightButtonDown;
222 break;
223 }
224 }
225 IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY()));
226 globalX = event.screenX();
227 globalY = event.screenY();
228 windowX = p.x();
229 windowY = p.y();
230 x = event.offsetX();
231 y = event.offsetY();
232 clickCount = event.detail();
233 }
234
WebKeyboardEventBuilder(const KeyboardEvent & event)235 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event)
236 {
237 if (event.type() == eventNames().keydownEvent)
238 type = KeyDown;
239 else if (event.type() == eventNames().keyupEvent)
240 type = WebInputEvent::KeyUp;
241 else if (event.type() == eventNames().keypressEvent)
242 type = WebInputEvent::Char;
243 else
244 return; // Skip all other keyboard events.
245 modifiers = getWebInputModifiers(event);
246 timeStampSeconds = event.timeStamp() * 1.0e-3;
247 windowsKeyCode = event.keyCode();
248 nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode();
249 unsigned int numChars = std::min(event.keyEvent()->text().length(),
250 static_cast<unsigned int>(WebKeyboardEvent::textLengthCap));
251 for (unsigned int i = 0; i < numChars; i++) {
252 text[i] = event.keyEvent()->text()[i];
253 unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i];
254 }
255 }
256
257 } // namespace WebKit
258