1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/input/web_input_event_util.h"
7 #include "base/strings/string_util.h"
8 #include "content/common/input/web_touch_event_traits.h"
9 #include "ui/events/gesture_detection/gesture_event_data.h"
10 #include "ui/events/gesture_detection/motion_event.h"
12 using blink::WebGestureEvent
;
13 using blink::WebInputEvent
;
14 using blink::WebTouchEvent
;
15 using blink::WebTouchPoint
;
16 using ui::MotionEvent
;
20 const char* GetKeyIdentifier(ui::KeyboardCode key_code
) {
24 case ui::VKEY_CONTROL
:
28 case ui::VKEY_CAPITAL
:
41 case ui::VKEY_EXECUTE
:
105 case ui::VKEY_SNAPSHOT
:
106 return "PrintScreen";
109 case ui::VKEY_SCROLL
:
111 case ui::VKEY_SELECT
:
115 case ui::VKEY_DELETE
:
116 return "U+007F"; // Standard says that DEL becomes U+007F.
117 case ui::VKEY_MEDIA_NEXT_TRACK
:
118 return "MediaNextTrack";
119 case ui::VKEY_MEDIA_PREV_TRACK
:
120 return "MediaPreviousTrack";
121 case ui::VKEY_MEDIA_STOP
:
123 case ui::VKEY_MEDIA_PLAY_PAUSE
:
124 return "MediaPlayPause";
125 case ui::VKEY_VOLUME_MUTE
:
127 case ui::VKEY_VOLUME_DOWN
:
129 case ui::VKEY_VOLUME_UP
:
136 WebInputEvent::Type
ToWebInputEventType(MotionEvent::Action action
) {
138 case MotionEvent::ACTION_DOWN
:
139 return WebInputEvent::TouchStart
;
140 case MotionEvent::ACTION_MOVE
:
141 return WebInputEvent::TouchMove
;
142 case MotionEvent::ACTION_UP
:
143 return WebInputEvent::TouchEnd
;
144 case MotionEvent::ACTION_CANCEL
:
145 return WebInputEvent::TouchCancel
;
146 case MotionEvent::ACTION_POINTER_DOWN
:
147 return WebInputEvent::TouchStart
;
148 case MotionEvent::ACTION_POINTER_UP
:
149 return WebInputEvent::TouchEnd
;
151 NOTREACHED() << "Invalid MotionEvent::Action.";
152 return WebInputEvent::Undefined
;
155 // Note that |is_action_pointer| is meaningful only in the context of
156 // |ACTION_POINTER_UP| and |ACTION_POINTER_DOWN|; other actions map directly to
157 // WebTouchPoint::State.
158 WebTouchPoint::State
ToWebTouchPointState(MotionEvent::Action action
,
159 bool is_action_pointer
) {
161 case MotionEvent::ACTION_DOWN
:
162 return WebTouchPoint::StatePressed
;
163 case MotionEvent::ACTION_MOVE
:
164 return WebTouchPoint::StateMoved
;
165 case MotionEvent::ACTION_UP
:
166 return WebTouchPoint::StateReleased
;
167 case MotionEvent::ACTION_CANCEL
:
168 return WebTouchPoint::StateCancelled
;
169 case MotionEvent::ACTION_POINTER_DOWN
:
170 return is_action_pointer
? WebTouchPoint::StatePressed
171 : WebTouchPoint::StateStationary
;
172 case MotionEvent::ACTION_POINTER_UP
:
173 return is_action_pointer
? WebTouchPoint::StateReleased
174 : WebTouchPoint::StateStationary
;
176 NOTREACHED() << "Invalid MotionEvent::Action.";
177 return WebTouchPoint::StateUndefined
;
180 WebTouchPoint
CreateWebTouchPoint(const MotionEvent
& event
,
181 size_t pointer_index
) {
183 touch
.id
= event
.GetPointerId(pointer_index
);
184 touch
.state
= ToWebTouchPointState(
186 static_cast<int>(pointer_index
) == event
.GetActionIndex());
187 touch
.position
.x
= event
.GetX(pointer_index
);
188 touch
.position
.y
= event
.GetY(pointer_index
);
189 touch
.screenPosition
.x
= event
.GetRawX(pointer_index
);
190 touch
.screenPosition
.y
= event
.GetRawY(pointer_index
);
191 touch
.radiusX
= touch
.radiusY
= event
.GetTouchMajor(pointer_index
) * 0.5f
;
192 touch
.force
= event
.GetPressure(pointer_index
);
201 void UpdateWindowsKeyCodeAndKeyIdentifier(blink::WebKeyboardEvent
* event
,
202 ui::KeyboardCode windows_key_code
) {
203 event
->windowsKeyCode
= windows_key_code
;
205 const char* id
= GetKeyIdentifier(windows_key_code
);
207 base::strlcpy(event
->keyIdentifier
, id
, sizeof(event
->keyIdentifier
) - 1);
209 base::snprintf(event
->keyIdentifier
,
210 sizeof(event
->keyIdentifier
),
212 base::ToUpperASCII(static_cast<int>(windows_key_code
)));
216 blink::WebTouchEvent
CreateWebTouchEventFromMotionEvent(
217 const ui::MotionEvent
& event
) {
218 COMPILE_ASSERT(static_cast<int>(MotionEvent::MAX_TOUCH_POINT_COUNT
) ==
219 static_cast<int>(blink::WebTouchEvent::touchesLengthCap
),
220 inconsistent_maximum_number_of_active_touch_points
);
222 blink::WebTouchEvent result
;
224 WebTouchEventTraits::ResetType(
225 ToWebInputEventType(event
.GetAction()),
226 (event
.GetEventTime() - base::TimeTicks()).InSecondsF(),
229 result
.touchesLength
=
230 std::min(event
.GetPointerCount(),
231 static_cast<size_t>(WebTouchEvent::touchesLengthCap
));
232 DCHECK_GT(result
.touchesLength
, 0U);
234 for (size_t i
= 0; i
< result
.touchesLength
; ++i
)
235 result
.touches
[i
] = CreateWebTouchPoint(event
, i
);
240 WebGestureEvent
CreateWebGestureEventFromGestureEventData(
241 const ui::GestureEventData
& data
) {
242 WebGestureEvent gesture
;
245 gesture
.globalX
= data
.raw_x
;
246 gesture
.globalY
= data
.raw_y
;
247 gesture
.timeStampSeconds
= (data
.time
- base::TimeTicks()).InSecondsF();
248 gesture
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
250 switch (data
.type()) {
251 case ui::ET_GESTURE_SHOW_PRESS
:
252 gesture
.type
= WebInputEvent::GestureShowPress
;
253 gesture
.data
.showPress
.width
= data
.details
.bounding_box_f().width();
254 gesture
.data
.showPress
.height
= data
.details
.bounding_box_f().height();
256 case ui::ET_GESTURE_DOUBLE_TAP
:
257 gesture
.type
= WebInputEvent::GestureDoubleTap
;
258 DCHECK_EQ(1, data
.details
.tap_count());
259 gesture
.data
.tap
.tapCount
= data
.details
.tap_count();
260 gesture
.data
.tap
.width
= data
.details
.bounding_box_f().width();
261 gesture
.data
.tap
.height
= data
.details
.bounding_box_f().height();
263 case ui::ET_GESTURE_TAP
:
264 gesture
.type
= WebInputEvent::GestureTap
;
265 DCHECK_EQ(1, data
.details
.tap_count());
266 gesture
.data
.tap
.tapCount
= data
.details
.tap_count();
267 gesture
.data
.tap
.width
= data
.details
.bounding_box_f().width();
268 gesture
.data
.tap
.height
= data
.details
.bounding_box_f().height();
270 case ui::ET_GESTURE_TAP_UNCONFIRMED
:
271 gesture
.type
= WebInputEvent::GestureTapUnconfirmed
;
272 DCHECK_EQ(1, data
.details
.tap_count());
273 gesture
.data
.tap
.tapCount
= data
.details
.tap_count();
274 gesture
.data
.tap
.width
= data
.details
.bounding_box_f().width();
275 gesture
.data
.tap
.height
= data
.details
.bounding_box_f().height();
277 case ui::ET_GESTURE_LONG_PRESS
:
278 gesture
.type
= WebInputEvent::GestureLongPress
;
279 gesture
.data
.longPress
.width
= data
.details
.bounding_box_f().width();
280 gesture
.data
.longPress
.height
= data
.details
.bounding_box_f().height();
282 case ui::ET_GESTURE_LONG_TAP
:
283 gesture
.type
= WebInputEvent::GestureLongTap
;
284 gesture
.data
.longPress
.width
= data
.details
.bounding_box_f().width();
285 gesture
.data
.longPress
.height
= data
.details
.bounding_box_f().height();
287 case ui::ET_GESTURE_SCROLL_BEGIN
:
288 gesture
.type
= WebInputEvent::GestureScrollBegin
;
289 gesture
.data
.scrollBegin
.deltaXHint
= data
.details
.scroll_x_hint();
290 gesture
.data
.scrollBegin
.deltaYHint
= data
.details
.scroll_y_hint();
292 case ui::ET_GESTURE_SCROLL_UPDATE
:
293 gesture
.type
= WebInputEvent::GestureScrollUpdate
;
294 gesture
.data
.scrollUpdate
.deltaX
= data
.details
.scroll_x();
295 gesture
.data
.scrollUpdate
.deltaY
= data
.details
.scroll_y();
297 case ui::ET_GESTURE_SCROLL_END
:
298 gesture
.type
= WebInputEvent::GestureScrollEnd
;
300 case ui::ET_SCROLL_FLING_START
:
301 gesture
.type
= WebInputEvent::GestureFlingStart
;
302 gesture
.data
.flingStart
.velocityX
= data
.details
.velocity_x();
303 gesture
.data
.flingStart
.velocityY
= data
.details
.velocity_y();
305 case ui::ET_SCROLL_FLING_CANCEL
:
306 gesture
.type
= WebInputEvent::GestureFlingCancel
;
308 case ui::ET_GESTURE_PINCH_BEGIN
:
309 gesture
.type
= WebInputEvent::GesturePinchBegin
;
311 case ui::ET_GESTURE_PINCH_UPDATE
:
312 gesture
.type
= WebInputEvent::GesturePinchUpdate
;
313 gesture
.data
.pinchUpdate
.scale
= data
.details
.scale();
315 case ui::ET_GESTURE_PINCH_END
:
316 gesture
.type
= WebInputEvent::GesturePinchEnd
;
318 case ui::ET_GESTURE_TAP_CANCEL
:
319 gesture
.type
= WebInputEvent::GestureTapCancel
;
321 case ui::ET_GESTURE_TAP_DOWN
:
322 gesture
.type
= WebInputEvent::GestureTapDown
;
323 gesture
.data
.tapDown
.width
= data
.details
.bounding_box_f().width();
324 gesture
.data
.tapDown
.height
= data
.details
.bounding_box_f().height();
326 case ui::ET_GESTURE_BEGIN
:
327 case ui::ET_GESTURE_END
:
328 NOTREACHED() << "ET_GESTURE_BEGIN and ET_GESTURE_END are only produced "
329 << "in Aura, and should never end up here.";
332 NOTREACHED() << "ui::EventType provided wasn't a valid gesture event.";
339 } // namespace content