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 // TODO(joth): Raw event co-ordinates.
190 touch
.screenPosition
= touch
.position
;
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 blink::WebTouchEvent result
;
220 WebTouchEventTraits::ResetType(
221 ToWebInputEventType(event
.GetAction()),
222 (event
.GetEventTime() - base::TimeTicks()).InSecondsF(),
225 result
.touchesLength
=
226 std::min(event
.GetPointerCount(),
227 static_cast<size_t>(WebTouchEvent::touchesLengthCap
));
228 DCHECK_GT(result
.touchesLength
, 0U);
230 for (size_t i
= 0; i
< result
.touchesLength
; ++i
)
231 result
.touches
[i
] = CreateWebTouchPoint(event
, i
);
236 WebGestureEvent
CreateWebGestureEventFromGestureEventData(
237 const ui::GestureEventData
& data
) {
238 WebGestureEvent gesture
;
241 gesture
.timeStampSeconds
= (data
.time
- base::TimeTicks()).InSecondsF();
242 gesture
.sourceDevice
= WebGestureEvent::Touchscreen
;
245 case ui::ET_GESTURE_SHOW_PRESS
:
246 gesture
.type
= WebInputEvent::GestureShowPress
;
247 gesture
.data
.showPress
.width
= data
.details
.bounding_box_f().width();
248 gesture
.data
.showPress
.height
= data
.details
.bounding_box_f().height();
250 case ui::ET_GESTURE_DOUBLE_TAP
:
251 gesture
.type
= WebInputEvent::GestureDoubleTap
;
252 DCHECK_EQ(1, data
.details
.tap_count());
253 gesture
.data
.tap
.tapCount
= data
.details
.tap_count();
254 gesture
.data
.tap
.width
= data
.details
.bounding_box_f().width();
255 gesture
.data
.tap
.height
= data
.details
.bounding_box_f().height();
257 case ui::ET_GESTURE_TAP
:
258 gesture
.type
= WebInputEvent::GestureTap
;
259 DCHECK_EQ(1, data
.details
.tap_count());
260 gesture
.data
.tap
.tapCount
= data
.details
.tap_count();
261 gesture
.data
.tap
.width
= data
.details
.bounding_box_f().width();
262 gesture
.data
.tap
.height
= data
.details
.bounding_box_f().height();
264 case ui::ET_GESTURE_TAP_UNCONFIRMED
:
265 gesture
.type
= WebInputEvent::GestureTapUnconfirmed
;
266 DCHECK_EQ(1, data
.details
.tap_count());
267 gesture
.data
.tap
.tapCount
= data
.details
.tap_count();
268 gesture
.data
.tap
.width
= data
.details
.bounding_box_f().width();
269 gesture
.data
.tap
.height
= data
.details
.bounding_box_f().height();
271 case ui::ET_GESTURE_LONG_PRESS
:
272 gesture
.type
= WebInputEvent::GestureLongPress
;
273 gesture
.data
.longPress
.width
= data
.details
.bounding_box_f().width();
274 gesture
.data
.longPress
.height
= data
.details
.bounding_box_f().height();
276 case ui::ET_GESTURE_LONG_TAP
:
277 gesture
.type
= WebInputEvent::GestureLongTap
;
278 gesture
.data
.longPress
.width
= data
.details
.bounding_box_f().width();
279 gesture
.data
.longPress
.height
= data
.details
.bounding_box_f().height();
281 case ui::ET_GESTURE_SCROLL_BEGIN
:
282 gesture
.type
= WebInputEvent::GestureScrollBegin
;
283 gesture
.data
.scrollBegin
.deltaXHint
= data
.details
.scroll_x_hint();
284 gesture
.data
.scrollBegin
.deltaYHint
= data
.details
.scroll_y_hint();
286 case ui::ET_GESTURE_SCROLL_UPDATE
:
287 gesture
.type
= WebInputEvent::GestureScrollUpdate
;
288 gesture
.data
.scrollUpdate
.deltaX
= data
.details
.scroll_x();
289 gesture
.data
.scrollUpdate
.deltaY
= data
.details
.scroll_y();
291 case ui::ET_GESTURE_SCROLL_END
:
292 gesture
.type
= WebInputEvent::GestureScrollEnd
;
294 case ui::ET_SCROLL_FLING_START
:
295 gesture
.type
= WebInputEvent::GestureFlingStart
;
296 gesture
.data
.flingStart
.velocityX
= data
.details
.velocity_x();
297 gesture
.data
.flingStart
.velocityY
= data
.details
.velocity_y();
299 case ui::ET_SCROLL_FLING_CANCEL
:
300 gesture
.type
= WebInputEvent::GestureFlingCancel
;
302 case ui::ET_GESTURE_PINCH_BEGIN
:
303 gesture
.type
= WebInputEvent::GesturePinchBegin
;
305 case ui::ET_GESTURE_PINCH_UPDATE
:
306 gesture
.type
= WebInputEvent::GesturePinchUpdate
;
307 gesture
.data
.pinchUpdate
.scale
= data
.details
.scale();
309 case ui::ET_GESTURE_PINCH_END
:
310 gesture
.type
= WebInputEvent::GesturePinchEnd
;
312 case ui::ET_GESTURE_TAP_CANCEL
:
313 gesture
.type
= WebInputEvent::GestureTapCancel
;
315 case ui::ET_GESTURE_TAP_DOWN
:
316 gesture
.type
= WebInputEvent::GestureTapDown
;
317 gesture
.data
.tapDown
.width
= data
.details
.bounding_box_f().width();
318 gesture
.data
.tapDown
.height
= data
.details
.bounding_box_f().height();
320 case ui::ET_GESTURE_BEGIN
:
321 case ui::ET_GESTURE_END
:
322 NOTREACHED() << "ET_GESTURE_BEGIN and ET_GESTURE_END are only produced "
323 << "in Aura, and should never end up here.";
326 NOTREACHED() << "ui::EventType provided wasn't a valid gesture event.";
333 } // namespace content