| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // MSVC++ requires this to be set before any other includes to get M_PI. | 5 // MSVC++ requires this to be set before any other includes to get M_PI. |
| 6 #define _USE_MATH_DEFINES | 6 #define _USE_MATH_DEFINES |
| 7 | 7 |
| 8 #include "content/browser/renderer_host/input/web_input_event_util.h" | 8 #include "content/browser/renderer_host/input/web_input_event_util.h" |
| 9 | 9 |
| 10 #include <cmath> | 10 #include <cmath> |
| 11 | 11 |
| 12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 13 #include "content/common/input/web_touch_event_traits.h" | 13 #include "content/common/input/web_touch_event_traits.h" |
| 14 #include "ui/events/blink/blink_event_util.h" |
| 14 #include "ui/events/event_constants.h" | 15 #include "ui/events/event_constants.h" |
| 15 #include "ui/events/gesture_detection/gesture_event_data.h" | 16 #include "ui/events/gesture_detection/gesture_event_data.h" |
| 16 #include "ui/events/gesture_detection/motion_event.h" | 17 #include "ui/events/gesture_detection/motion_event.h" |
| 17 #include "ui/gfx/geometry/safe_integer_conversions.h" | 18 #include "ui/gfx/geometry/safe_integer_conversions.h" |
| 18 | 19 |
| 19 using blink::WebGestureEvent; | 20 using blink::WebGestureEvent; |
| 20 using blink::WebInputEvent; | 21 using blink::WebInputEvent; |
| 21 using blink::WebTouchEvent; | 22 using blink::WebTouchEvent; |
| 22 using blink::WebTouchPoint; | 23 using blink::WebTouchPoint; |
| 23 using ui::MotionEvent; | 24 using ui::MotionEvent; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 return "VolumeMute"; | 134 return "VolumeMute"; |
| 134 case ui::VKEY_VOLUME_DOWN: | 135 case ui::VKEY_VOLUME_DOWN: |
| 135 return "VolumeDown"; | 136 return "VolumeDown"; |
| 136 case ui::VKEY_VOLUME_UP: | 137 case ui::VKEY_VOLUME_UP: |
| 137 return "VolumeUp"; | 138 return "VolumeUp"; |
| 138 default: | 139 default: |
| 139 return NULL; | 140 return NULL; |
| 140 }; | 141 }; |
| 141 } | 142 } |
| 142 | 143 |
| 143 WebInputEvent::Type ToWebInputEventType(MotionEvent::Action action) { | |
| 144 switch (action) { | |
| 145 case MotionEvent::ACTION_DOWN: | |
| 146 return WebInputEvent::TouchStart; | |
| 147 case MotionEvent::ACTION_MOVE: | |
| 148 return WebInputEvent::TouchMove; | |
| 149 case MotionEvent::ACTION_UP: | |
| 150 return WebInputEvent::TouchEnd; | |
| 151 case MotionEvent::ACTION_CANCEL: | |
| 152 return WebInputEvent::TouchCancel; | |
| 153 case MotionEvent::ACTION_POINTER_DOWN: | |
| 154 return WebInputEvent::TouchStart; | |
| 155 case MotionEvent::ACTION_POINTER_UP: | |
| 156 return WebInputEvent::TouchEnd; | |
| 157 } | |
| 158 NOTREACHED() << "Invalid MotionEvent::Action."; | |
| 159 return WebInputEvent::Undefined; | |
| 160 } | |
| 161 | |
| 162 // Note that |is_action_pointer| is meaningful only in the context of | |
| 163 // |ACTION_POINTER_UP| and |ACTION_POINTER_DOWN|; other actions map directly to | |
| 164 // WebTouchPoint::State. | |
| 165 WebTouchPoint::State ToWebTouchPointState(const MotionEvent& event, | |
| 166 size_t pointer_index) { | |
| 167 switch (event.GetAction()) { | |
| 168 case MotionEvent::ACTION_DOWN: | |
| 169 return WebTouchPoint::StatePressed; | |
| 170 case MotionEvent::ACTION_MOVE: | |
| 171 return WebTouchPoint::StateMoved; | |
| 172 case MotionEvent::ACTION_UP: | |
| 173 return WebTouchPoint::StateReleased; | |
| 174 case MotionEvent::ACTION_CANCEL: | |
| 175 return WebTouchPoint::StateCancelled; | |
| 176 case MotionEvent::ACTION_POINTER_DOWN: | |
| 177 return static_cast<int>(pointer_index) == event.GetActionIndex() | |
| 178 ? WebTouchPoint::StatePressed | |
| 179 : WebTouchPoint::StateStationary; | |
| 180 case MotionEvent::ACTION_POINTER_UP: | |
| 181 return static_cast<int>(pointer_index) == event.GetActionIndex() | |
| 182 ? WebTouchPoint::StateReleased | |
| 183 : WebTouchPoint::StateStationary; | |
| 184 } | |
| 185 NOTREACHED() << "Invalid MotionEvent::Action."; | |
| 186 return WebTouchPoint::StateUndefined; | |
| 187 } | |
| 188 | |
| 189 WebTouchPoint CreateWebTouchPoint(const MotionEvent& event, | |
| 190 size_t pointer_index) { | |
| 191 WebTouchPoint touch; | |
| 192 touch.id = event.GetPointerId(pointer_index); | |
| 193 touch.state = ToWebTouchPointState(event, pointer_index); | |
| 194 touch.position.x = event.GetX(pointer_index); | |
| 195 touch.position.y = event.GetY(pointer_index); | |
| 196 touch.screenPosition.x = event.GetRawX(pointer_index); | |
| 197 touch.screenPosition.y = event.GetRawY(pointer_index); | |
| 198 | |
| 199 // A note on touch ellipse specifications: | |
| 200 // | |
| 201 // Android MotionEvent provides the major and minor axes of the touch ellipse, | |
| 202 // as well as the orientation of the major axis clockwise from vertical, in | |
| 203 // radians. See: | |
| 204 // http://developer.android.com/reference/android/view/MotionEvent.html | |
| 205 // | |
| 206 // The proposed extension to W3C Touch Events specifies the touch ellipse | |
| 207 // using two radii along x- & y-axes and a positive acute rotation angle in | |
| 208 // degrees. See: | |
| 209 // http://dvcs.w3.org/hg/webevents/raw-file/default/touchevents.html | |
| 210 | |
| 211 float major_radius = event.GetTouchMajor(pointer_index) / 2.f; | |
| 212 float minor_radius = event.GetTouchMinor(pointer_index) / 2.f; | |
| 213 | |
| 214 DCHECK_LE(minor_radius, major_radius); | |
| 215 DCHECK_IMPLIES(major_radius, minor_radius); | |
| 216 | |
| 217 float orientation_deg = event.GetOrientation(pointer_index) * 180.f / M_PI; | |
| 218 DCHECK_GE(major_radius, 0); | |
| 219 DCHECK_GE(minor_radius, 0); | |
| 220 DCHECK_GE(major_radius, minor_radius); | |
| 221 // Allow a small bound tolerance to account for floating point conversion. | |
| 222 DCHECK_GT(orientation_deg, -90.01f); | |
| 223 DCHECK_LT(orientation_deg, 90.01f); | |
| 224 if (orientation_deg >= 0) { | |
| 225 // The case orientation_deg == 0 is handled here on purpose: although the | |
| 226 // 'else' block is equivalent in this case, we want to pass the 0 value | |
| 227 // unchanged (and 0 is the default value for many devices that don't | |
| 228 // report elliptical touches). | |
| 229 touch.radiusX = minor_radius; | |
| 230 touch.radiusY = major_radius; | |
| 231 touch.rotationAngle = orientation_deg; | |
| 232 } else { | |
| 233 touch.radiusX = major_radius; | |
| 234 touch.radiusY = minor_radius; | |
| 235 touch.rotationAngle = orientation_deg + 90; | |
| 236 } | |
| 237 | |
| 238 touch.force = event.GetPressure(pointer_index); | |
| 239 | |
| 240 return touch; | |
| 241 } | |
| 242 | |
| 243 } // namespace | 144 } // namespace |
| 244 | 145 |
| 245 namespace content { | 146 namespace content { |
| 246 | 147 |
| 247 void UpdateWindowsKeyCodeAndKeyIdentifier(blink::WebKeyboardEvent* event, | 148 void UpdateWindowsKeyCodeAndKeyIdentifier(blink::WebKeyboardEvent* event, |
| 248 ui::KeyboardCode windows_key_code) { | 149 ui::KeyboardCode windows_key_code) { |
| 249 event->windowsKeyCode = windows_key_code; | 150 event->windowsKeyCode = windows_key_code; |
| 250 | 151 |
| 251 const char* id = GetKeyIdentifier(windows_key_code); | 152 const char* id = GetKeyIdentifier(windows_key_code); |
| 252 if (id) { | 153 if (id) { |
| 253 base::strlcpy(event->keyIdentifier, id, sizeof(event->keyIdentifier) - 1); | 154 base::strlcpy(event->keyIdentifier, id, sizeof(event->keyIdentifier) - 1); |
| 254 } else { | 155 } else { |
| 255 base::snprintf(event->keyIdentifier, | 156 base::snprintf(event->keyIdentifier, |
| 256 sizeof(event->keyIdentifier), | 157 sizeof(event->keyIdentifier), |
| 257 "U+%04X", | 158 "U+%04X", |
| 258 base::ToUpperASCII(static_cast<int>(windows_key_code))); | 159 base::ToUpperASCII(static_cast<int>(windows_key_code))); |
| 259 } | 160 } |
| 260 } | 161 } |
| 261 | 162 |
| 262 blink::WebTouchEvent CreateWebTouchEventFromMotionEvent( | |
| 263 const ui::MotionEvent& event, | |
| 264 bool may_cause_scrolling) { | |
| 265 static_assert(static_cast<int>(MotionEvent::MAX_TOUCH_POINT_COUNT) == | |
| 266 static_cast<int>(blink::WebTouchEvent::touchesLengthCap), | |
| 267 "inconsistent maximum number of active touch points"); | |
| 268 | |
| 269 blink::WebTouchEvent result; | |
| 270 | |
| 271 WebTouchEventTraits::ResetType( | |
| 272 ToWebInputEventType(event.GetAction()), | |
| 273 (event.GetEventTime() - base::TimeTicks()).InSecondsF(), | |
| 274 &result); | |
| 275 result.causesScrollingIfUncanceled = may_cause_scrolling; | |
| 276 | |
| 277 result.modifiers = EventFlagsToWebEventModifiers(event.GetFlags()); | |
| 278 result.touchesLength = | |
| 279 std::min(event.GetPointerCount(), | |
| 280 static_cast<size_t>(WebTouchEvent::touchesLengthCap)); | |
| 281 DCHECK_GT(result.touchesLength, 0U); | |
| 282 | |
| 283 for (size_t i = 0; i < result.touchesLength; ++i) | |
| 284 result.touches[i] = CreateWebTouchPoint(event, i); | |
| 285 | |
| 286 return result; | |
| 287 } | |
| 288 | |
| 289 WebGestureEvent CreateWebGestureEvent(const ui::GestureEventDetails& details, | |
| 290 base::TimeDelta timestamp, | |
| 291 const gfx::PointF& location, | |
| 292 const gfx::PointF& raw_location, | |
| 293 int flags) { | |
| 294 WebGestureEvent gesture; | |
| 295 gesture.timeStampSeconds = timestamp.InSecondsF(); | |
| 296 gesture.x = gfx::ToFlooredInt(location.x()); | |
| 297 gesture.y = gfx::ToFlooredInt(location.y()); | |
| 298 gesture.globalX = gfx::ToFlooredInt(raw_location.x()); | |
| 299 gesture.globalY = gfx::ToFlooredInt(raw_location.y()); | |
| 300 gesture.modifiers = EventFlagsToWebEventModifiers(flags); | |
| 301 gesture.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
| 302 | |
| 303 switch (details.type()) { | |
| 304 case ui::ET_GESTURE_SHOW_PRESS: | |
| 305 gesture.type = WebInputEvent::GestureShowPress; | |
| 306 gesture.data.showPress.width = details.bounding_box_f().width(); | |
| 307 gesture.data.showPress.height = details.bounding_box_f().height(); | |
| 308 break; | |
| 309 case ui::ET_GESTURE_DOUBLE_TAP: | |
| 310 gesture.type = WebInputEvent::GestureDoubleTap; | |
| 311 DCHECK_EQ(1, details.tap_count()); | |
| 312 gesture.data.tap.tapCount = details.tap_count(); | |
| 313 gesture.data.tap.width = details.bounding_box_f().width(); | |
| 314 gesture.data.tap.height = details.bounding_box_f().height(); | |
| 315 break; | |
| 316 case ui::ET_GESTURE_TAP: | |
| 317 gesture.type = WebInputEvent::GestureTap; | |
| 318 DCHECK_GE(details.tap_count(), 1); | |
| 319 gesture.data.tap.tapCount = details.tap_count(); | |
| 320 gesture.data.tap.width = details.bounding_box_f().width(); | |
| 321 gesture.data.tap.height = details.bounding_box_f().height(); | |
| 322 break; | |
| 323 case ui::ET_GESTURE_TAP_UNCONFIRMED: | |
| 324 gesture.type = WebInputEvent::GestureTapUnconfirmed; | |
| 325 DCHECK_EQ(1, details.tap_count()); | |
| 326 gesture.data.tap.tapCount = details.tap_count(); | |
| 327 gesture.data.tap.width = details.bounding_box_f().width(); | |
| 328 gesture.data.tap.height = details.bounding_box_f().height(); | |
| 329 break; | |
| 330 case ui::ET_GESTURE_LONG_PRESS: | |
| 331 gesture.type = WebInputEvent::GestureLongPress; | |
| 332 gesture.data.longPress.width = details.bounding_box_f().width(); | |
| 333 gesture.data.longPress.height = details.bounding_box_f().height(); | |
| 334 break; | |
| 335 case ui::ET_GESTURE_LONG_TAP: | |
| 336 gesture.type = WebInputEvent::GestureLongTap; | |
| 337 gesture.data.longPress.width = details.bounding_box_f().width(); | |
| 338 gesture.data.longPress.height = details.bounding_box_f().height(); | |
| 339 break; | |
| 340 case ui::ET_GESTURE_TWO_FINGER_TAP: | |
| 341 gesture.type = blink::WebInputEvent::GestureTwoFingerTap; | |
| 342 gesture.data.twoFingerTap.firstFingerWidth = details.first_finger_width(); | |
| 343 gesture.data.twoFingerTap.firstFingerHeight = | |
| 344 details.first_finger_height(); | |
| 345 break; | |
| 346 case ui::ET_GESTURE_SCROLL_BEGIN: | |
| 347 gesture.type = WebInputEvent::GestureScrollBegin; | |
| 348 gesture.data.scrollBegin.deltaXHint = details.scroll_x_hint(); | |
| 349 gesture.data.scrollBegin.deltaYHint = details.scroll_y_hint(); | |
| 350 break; | |
| 351 case ui::ET_GESTURE_SCROLL_UPDATE: | |
| 352 gesture.type = WebInputEvent::GestureScrollUpdate; | |
| 353 gesture.data.scrollUpdate.deltaX = details.scroll_x(); | |
| 354 gesture.data.scrollUpdate.deltaY = details.scroll_y(); | |
| 355 gesture.data.scrollUpdate.previousUpdateInSequencePrevented = | |
| 356 details.previous_scroll_update_in_sequence_prevented(); | |
| 357 break; | |
| 358 case ui::ET_GESTURE_SCROLL_END: | |
| 359 gesture.type = WebInputEvent::GestureScrollEnd; | |
| 360 break; | |
| 361 case ui::ET_SCROLL_FLING_START: | |
| 362 gesture.type = WebInputEvent::GestureFlingStart; | |
| 363 gesture.data.flingStart.velocityX = details.velocity_x(); | |
| 364 gesture.data.flingStart.velocityY = details.velocity_y(); | |
| 365 break; | |
| 366 case ui::ET_SCROLL_FLING_CANCEL: | |
| 367 gesture.type = WebInputEvent::GestureFlingCancel; | |
| 368 break; | |
| 369 case ui::ET_GESTURE_PINCH_BEGIN: | |
| 370 gesture.type = WebInputEvent::GesturePinchBegin; | |
| 371 break; | |
| 372 case ui::ET_GESTURE_PINCH_UPDATE: | |
| 373 gesture.type = WebInputEvent::GesturePinchUpdate; | |
| 374 gesture.data.pinchUpdate.scale = details.scale(); | |
| 375 break; | |
| 376 case ui::ET_GESTURE_PINCH_END: | |
| 377 gesture.type = WebInputEvent::GesturePinchEnd; | |
| 378 break; | |
| 379 case ui::ET_GESTURE_TAP_CANCEL: | |
| 380 gesture.type = WebInputEvent::GestureTapCancel; | |
| 381 break; | |
| 382 case ui::ET_GESTURE_TAP_DOWN: | |
| 383 gesture.type = WebInputEvent::GestureTapDown; | |
| 384 gesture.data.tapDown.width = details.bounding_box_f().width(); | |
| 385 gesture.data.tapDown.height = details.bounding_box_f().height(); | |
| 386 break; | |
| 387 case ui::ET_GESTURE_BEGIN: | |
| 388 case ui::ET_GESTURE_END: | |
| 389 case ui::ET_GESTURE_SWIPE: | |
| 390 // The caller is responsible for discarding these gestures appropriately. | |
| 391 gesture.type = WebInputEvent::Undefined; | |
| 392 break; | |
| 393 default: | |
| 394 NOTREACHED() << "ui::EventType provided wasn't a valid gesture event: " | |
| 395 << details.type(); | |
| 396 } | |
| 397 | |
| 398 return gesture; | |
| 399 } | |
| 400 | |
| 401 WebGestureEvent CreateWebGestureEventFromGestureEventData( | |
| 402 const ui::GestureEventData& data) { | |
| 403 return CreateWebGestureEvent(data.details, | |
| 404 data.time - base::TimeTicks(), | |
| 405 gfx::PointF(data.x, data.y), | |
| 406 gfx::PointF(data.raw_x, data.raw_y), | |
| 407 data.flags); | |
| 408 } | |
| 409 | |
| 410 int EventFlagsToWebEventModifiers(int flags) { | |
| 411 int modifiers = 0; | |
| 412 | |
| 413 if (flags & ui::EF_SHIFT_DOWN) | |
| 414 modifiers |= blink::WebInputEvent::ShiftKey; | |
| 415 if (flags & ui::EF_CONTROL_DOWN) | |
| 416 modifiers |= blink::WebInputEvent::ControlKey; | |
| 417 if (flags & ui::EF_ALT_DOWN) | |
| 418 modifiers |= blink::WebInputEvent::AltKey; | |
| 419 if (flags & ui::EF_COMMAND_DOWN) | |
| 420 modifiers |= blink::WebInputEvent::MetaKey; | |
| 421 | |
| 422 if (flags & ui::EF_LEFT_MOUSE_BUTTON) | |
| 423 modifiers |= blink::WebInputEvent::LeftButtonDown; | |
| 424 if (flags & ui::EF_MIDDLE_MOUSE_BUTTON) | |
| 425 modifiers |= blink::WebInputEvent::MiddleButtonDown; | |
| 426 if (flags & ui::EF_RIGHT_MOUSE_BUTTON) | |
| 427 modifiers |= blink::WebInputEvent::RightButtonDown; | |
| 428 if (flags & ui::EF_CAPS_LOCK_DOWN) | |
| 429 modifiers |= blink::WebInputEvent::CapsLockOn; | |
| 430 if (flags & ui::EF_IS_REPEAT) | |
| 431 modifiers |= blink::WebInputEvent::IsAutoRepeat; | |
| 432 if (flags & ui::EF_NUMPAD_KEY) | |
| 433 modifiers |= blink::WebInputEvent::IsKeyPad; | |
| 434 | |
| 435 return modifiers; | |
| 436 } | |
| 437 | |
| 438 int WebEventModifiersToEventFlags(int modifiers) { | 163 int WebEventModifiersToEventFlags(int modifiers) { |
| 439 int flags = 0; | 164 int flags = 0; |
| 440 | 165 |
| 441 if (modifiers & blink::WebInputEvent::ShiftKey) | 166 if (modifiers & blink::WebInputEvent::ShiftKey) |
| 442 flags |= ui::EF_SHIFT_DOWN; | 167 flags |= ui::EF_SHIFT_DOWN; |
| 443 if (modifiers & blink::WebInputEvent::ControlKey) | 168 if (modifiers & blink::WebInputEvent::ControlKey) |
| 444 flags |= ui::EF_CONTROL_DOWN; | 169 flags |= ui::EF_CONTROL_DOWN; |
| 445 if (modifiers & blink::WebInputEvent::AltKey) | 170 if (modifiers & blink::WebInputEvent::AltKey) |
| 446 flags |= ui::EF_ALT_DOWN; | 171 flags |= ui::EF_ALT_DOWN; |
| 447 if (modifiers & blink::WebInputEvent::MetaKey) | 172 if (modifiers & blink::WebInputEvent::MetaKey) |
| 448 flags |= ui::EF_COMMAND_DOWN; | 173 flags |= ui::EF_COMMAND_DOWN; |
| 449 | 174 |
| 450 if (modifiers & blink::WebInputEvent::LeftButtonDown) | 175 if (modifiers & blink::WebInputEvent::LeftButtonDown) |
| 451 flags |= ui::EF_LEFT_MOUSE_BUTTON; | 176 flags |= ui::EF_LEFT_MOUSE_BUTTON; |
| 452 if (modifiers & blink::WebInputEvent::MiddleButtonDown) | 177 if (modifiers & blink::WebInputEvent::MiddleButtonDown) |
| 453 flags |= ui::EF_MIDDLE_MOUSE_BUTTON; | 178 flags |= ui::EF_MIDDLE_MOUSE_BUTTON; |
| 454 if (modifiers & blink::WebInputEvent::RightButtonDown) | 179 if (modifiers & blink::WebInputEvent::RightButtonDown) |
| 455 flags |= ui::EF_RIGHT_MOUSE_BUTTON; | 180 flags |= ui::EF_RIGHT_MOUSE_BUTTON; |
| 456 if (modifiers & blink::WebInputEvent::CapsLockOn) | 181 if (modifiers & blink::WebInputEvent::CapsLockOn) |
| 457 flags |= ui::EF_CAPS_LOCK_DOWN; | 182 flags |= ui::EF_CAPS_LOCK_DOWN; |
| 458 if (modifiers & blink::WebInputEvent::IsAutoRepeat) | 183 if (modifiers & blink::WebInputEvent::IsAutoRepeat) |
| 459 flags |= ui::EF_IS_REPEAT; | 184 flags |= ui::EF_IS_REPEAT; |
| 460 if (modifiers & blink::WebInputEvent::IsKeyPad) | 185 if (modifiers & blink::WebInputEvent::IsKeyPad) |
| 461 flags |= ui::EF_NUMPAD_KEY; | 186 flags |= ui::EF_NUMPAD_KEY; |
| 462 | 187 |
| 463 return flags; | 188 return flags; |
| 464 } | 189 } |
| 465 | 190 |
| 466 } // namespace content | 191 } // namespace content |
| OLD | NEW |