| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "content/common/input/web_input_event_traits.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/strings/stringprintf.h" | |
| 9 | |
| 10 using base::StringAppendF; | |
| 11 using base::SStringPrintf; | |
| 12 using blink::WebGestureEvent; | |
| 13 using blink::WebInputEvent; | |
| 14 using blink::WebKeyboardEvent; | |
| 15 using blink::WebMouseEvent; | |
| 16 using blink::WebMouseWheelEvent; | |
| 17 using blink::WebTouchEvent; | |
| 18 using blink::WebTouchPoint; | |
| 19 | |
| 20 namespace content { | |
| 21 namespace { | |
| 22 | |
| 23 void ApppendEventDetails(const WebKeyboardEvent& event, std::string* result) { | |
| 24 StringAppendF(result, | |
| 25 "{\n WinCode: %d\n NativeCode: %d\n IsSystem: %d\n" | |
| 26 " Text: %s\n UnmodifiedText: %s\n}", | |
| 27 event.windowsKeyCode, | |
| 28 event.nativeKeyCode, | |
| 29 event.isSystemKey, | |
| 30 reinterpret_cast<const char*>(event.text), | |
| 31 reinterpret_cast<const char*>(event.unmodifiedText)); | |
| 32 } | |
| 33 | |
| 34 void ApppendEventDetails(const WebMouseEvent& event, std::string* result) { | |
| 35 StringAppendF(result, | |
| 36 "{\n Button: %d\n Pos: (%d, %d)\n WindowPos: (%d, %d)\n" | |
| 37 " GlobalPos: (%d, %d)\n Movement: (%d, %d)\n Clicks: %d\n}", | |
| 38 event.button, | |
| 39 event.x, | |
| 40 event.y, | |
| 41 event.windowX, | |
| 42 event.windowY, | |
| 43 event.globalX, | |
| 44 event.globalY, | |
| 45 event.movementX, | |
| 46 event.movementY, | |
| 47 event.clickCount); | |
| 48 } | |
| 49 | |
| 50 void ApppendEventDetails(const WebMouseWheelEvent& event, std::string* result) { | |
| 51 StringAppendF( | |
| 52 result, | |
| 53 "{\n Delta: (%f, %f)\n WheelTicks: (%f, %f)\n Accel: (%f, %f)\n" | |
| 54 " ScrollByPage: %d\n HasPreciseScrollingDeltas: %d\n" | |
| 55 " Phase: (%d, %d)", | |
| 56 event.deltaX, event.deltaY, event.wheelTicksX, event.wheelTicksY, | |
| 57 event.accelerationRatioX, event.accelerationRatioY, event.scrollByPage, | |
| 58 event.hasPreciseScrollingDeltas, event.phase, event.momentumPhase); | |
| 59 } | |
| 60 | |
| 61 void ApppendEventDetails(const WebGestureEvent& event, std::string* result) { | |
| 62 StringAppendF(result, | |
| 63 "{\n Pos: (%d, %d)\n GlobalPos: (%d, %d)\n SourceDevice: %d\n" | |
| 64 " RawData: (%f, %f, %f, %f, %d)\n}", | |
| 65 event.x, | |
| 66 event.y, | |
| 67 event.globalX, | |
| 68 event.globalY, | |
| 69 event.sourceDevice, | |
| 70 event.data.scrollUpdate.deltaX, | |
| 71 event.data.scrollUpdate.deltaY, | |
| 72 event.data.scrollUpdate.velocityX, | |
| 73 event.data.scrollUpdate.velocityY, | |
| 74 event.data.scrollUpdate.previousUpdateInSequencePrevented); | |
| 75 } | |
| 76 | |
| 77 void ApppendTouchPointDetails(const WebTouchPoint& point, std::string* result) { | |
| 78 StringAppendF(result, | |
| 79 " (ID: %d, State: %d, ScreenPos: (%f, %f), Pos: (%f, %f)," | |
| 80 " Radius: (%f, %f), Rot: %f, Force: %f," | |
| 81 " Tilt: (%d, %d)),\n", | |
| 82 point.id, | |
| 83 point.state, | |
| 84 point.screenPosition.x, | |
| 85 point.screenPosition.y, | |
| 86 point.position.x, | |
| 87 point.position.y, | |
| 88 point.radiusX, | |
| 89 point.radiusY, | |
| 90 point.rotationAngle, | |
| 91 point.force, | |
| 92 point.tiltX, | |
| 93 point.tiltY); | |
| 94 } | |
| 95 | |
| 96 void ApppendEventDetails(const WebTouchEvent& event, std::string* result) { | |
| 97 StringAppendF(result, | |
| 98 "{\n Touches: %u, DispatchType: %d, CausesScrolling: %d," | |
| 99 " uniqueTouchEventId: %u\n[\n", | |
| 100 event.touchesLength, event.dispatchType, | |
| 101 event.movedBeyondSlopRegion, event.uniqueTouchEventId); | |
| 102 for (unsigned i = 0; i < event.touchesLength; ++i) | |
| 103 ApppendTouchPointDetails(event.touches[i], result); | |
| 104 result->append(" ]\n}"); | |
| 105 } | |
| 106 | |
| 107 struct WebInputEventToString { | |
| 108 template <class EventType> | |
| 109 bool Execute(const WebInputEvent& event, std::string* result) const { | |
| 110 SStringPrintf(result, "%s (Time: %lf, Modifiers: %d)\n", | |
| 111 WebInputEventTraits::GetName(event.type), | |
| 112 event.timeStampSeconds, | |
| 113 event.modifiers); | |
| 114 const EventType& typed_event = static_cast<const EventType&>(event); | |
| 115 ApppendEventDetails(typed_event, result); | |
| 116 return true; | |
| 117 } | |
| 118 }; | |
| 119 | |
| 120 struct WebInputEventSize { | |
| 121 template <class EventType> | |
| 122 bool Execute(WebInputEvent::Type /* type */, size_t* type_size) const { | |
| 123 *type_size = sizeof(EventType); | |
| 124 return true; | |
| 125 } | |
| 126 }; | |
| 127 | |
| 128 struct WebInputEventClone { | |
| 129 template <class EventType> | |
| 130 bool Execute(const WebInputEvent& event, | |
| 131 ScopedWebInputEvent* scoped_event) const { | |
| 132 DCHECK_EQ(sizeof(EventType), event.size); | |
| 133 *scoped_event = ScopedWebInputEvent( | |
| 134 new EventType(static_cast<const EventType&>(event))); | |
| 135 return true; | |
| 136 } | |
| 137 }; | |
| 138 | |
| 139 struct WebInputEventDelete { | |
| 140 template <class EventType> | |
| 141 bool Execute(WebInputEvent* event, bool* /* dummy_var */) const { | |
| 142 if (!event) | |
| 143 return false; | |
| 144 DCHECK_EQ(sizeof(EventType), event->size); | |
| 145 delete static_cast<EventType*>(event); | |
| 146 return true; | |
| 147 } | |
| 148 }; | |
| 149 | |
| 150 template <typename Operator, typename ArgIn, typename ArgOut> | |
| 151 bool Apply(Operator op, | |
| 152 WebInputEvent::Type type, | |
| 153 const ArgIn& arg_in, | |
| 154 ArgOut* arg_out) { | |
| 155 if (WebInputEvent::isMouseEventType(type)) | |
| 156 return op.template Execute<WebMouseEvent>(arg_in, arg_out); | |
| 157 else if (type == WebInputEvent::MouseWheel) | |
| 158 return op.template Execute<WebMouseWheelEvent>(arg_in, arg_out); | |
| 159 else if (WebInputEvent::isKeyboardEventType(type)) | |
| 160 return op.template Execute<WebKeyboardEvent>(arg_in, arg_out); | |
| 161 else if (WebInputEvent::isTouchEventType(type)) | |
| 162 return op.template Execute<WebTouchEvent>(arg_in, arg_out); | |
| 163 else if (WebInputEvent::isGestureEventType(type)) | |
| 164 return op.template Execute<WebGestureEvent>(arg_in, arg_out); | |
| 165 | |
| 166 NOTREACHED() << "Unknown webkit event type " << type; | |
| 167 return false; | |
| 168 } | |
| 169 | |
| 170 } // namespace | |
| 171 | |
| 172 const char* WebInputEventTraits::GetName(WebInputEvent::Type type) { | |
| 173 #define CASE_TYPE(t) case WebInputEvent::t: return #t | |
| 174 switch(type) { | |
| 175 CASE_TYPE(Undefined); | |
| 176 CASE_TYPE(MouseDown); | |
| 177 CASE_TYPE(MouseUp); | |
| 178 CASE_TYPE(MouseMove); | |
| 179 CASE_TYPE(MouseEnter); | |
| 180 CASE_TYPE(MouseLeave); | |
| 181 CASE_TYPE(ContextMenu); | |
| 182 CASE_TYPE(MouseWheel); | |
| 183 CASE_TYPE(RawKeyDown); | |
| 184 CASE_TYPE(KeyDown); | |
| 185 CASE_TYPE(KeyUp); | |
| 186 CASE_TYPE(Char); | |
| 187 CASE_TYPE(GestureScrollBegin); | |
| 188 CASE_TYPE(GestureScrollEnd); | |
| 189 CASE_TYPE(GestureScrollUpdate); | |
| 190 CASE_TYPE(GestureFlingStart); | |
| 191 CASE_TYPE(GestureFlingCancel); | |
| 192 CASE_TYPE(GestureShowPress); | |
| 193 CASE_TYPE(GestureTap); | |
| 194 CASE_TYPE(GestureTapUnconfirmed); | |
| 195 CASE_TYPE(GestureTapDown); | |
| 196 CASE_TYPE(GestureTapCancel); | |
| 197 CASE_TYPE(GestureDoubleTap); | |
| 198 CASE_TYPE(GestureTwoFingerTap); | |
| 199 CASE_TYPE(GestureLongPress); | |
| 200 CASE_TYPE(GestureLongTap); | |
| 201 CASE_TYPE(GesturePinchBegin); | |
| 202 CASE_TYPE(GesturePinchEnd); | |
| 203 CASE_TYPE(GesturePinchUpdate); | |
| 204 CASE_TYPE(TouchStart); | |
| 205 CASE_TYPE(TouchMove); | |
| 206 CASE_TYPE(TouchEnd); | |
| 207 CASE_TYPE(TouchCancel); | |
| 208 CASE_TYPE(TouchScrollStarted); | |
| 209 default: | |
| 210 // Must include default to let blink::WebInputEvent add new event types | |
| 211 // before they're added here. | |
| 212 DLOG(WARNING) << | |
| 213 "Unhandled WebInputEvent type in WebInputEventTraits::GetName.\n"; | |
| 214 break; | |
| 215 } | |
| 216 #undef CASE_TYPE | |
| 217 return ""; | |
| 218 } | |
| 219 | |
| 220 std::string WebInputEventTraits::ToString(const WebInputEvent& event) { | |
| 221 std::string result; | |
| 222 Apply(WebInputEventToString(), event.type, event, &result); | |
| 223 return result; | |
| 224 } | |
| 225 | |
| 226 size_t WebInputEventTraits::GetSize(WebInputEvent::Type type) { | |
| 227 size_t size = 0; | |
| 228 Apply(WebInputEventSize(), type, type, &size); | |
| 229 return size; | |
| 230 } | |
| 231 | |
| 232 ScopedWebInputEvent WebInputEventTraits::Clone(const WebInputEvent& event) { | |
| 233 ScopedWebInputEvent scoped_event; | |
| 234 Apply(WebInputEventClone(), event.type, event, &scoped_event); | |
| 235 return scoped_event; | |
| 236 } | |
| 237 | |
| 238 void WebInputEventTraits::Delete(WebInputEvent* event) { | |
| 239 if (!event) | |
| 240 return; | |
| 241 bool dummy_var = false; | |
| 242 Apply(WebInputEventDelete(), event->type, event, &dummy_var); | |
| 243 } | |
| 244 | |
| 245 bool WebInputEventTraits::ShouldBlockEventStream(const WebInputEvent& event) { | |
| 246 switch (event.type) { | |
| 247 case WebInputEvent::MouseDown: | |
| 248 case WebInputEvent::MouseUp: | |
| 249 case WebInputEvent::MouseEnter: | |
| 250 case WebInputEvent::MouseLeave: | |
| 251 case WebInputEvent::ContextMenu: | |
| 252 case WebInputEvent::GestureScrollBegin: | |
| 253 case WebInputEvent::GestureScrollEnd: | |
| 254 case WebInputEvent::GestureShowPress: | |
| 255 case WebInputEvent::GestureTapUnconfirmed: | |
| 256 case WebInputEvent::GestureTapDown: | |
| 257 case WebInputEvent::GestureTapCancel: | |
| 258 case WebInputEvent::GesturePinchBegin: | |
| 259 case WebInputEvent::GesturePinchEnd: | |
| 260 return false; | |
| 261 | |
| 262 // TouchCancel and TouchScrollStarted should always be non-blocking. | |
| 263 case WebInputEvent::TouchCancel: | |
| 264 case WebInputEvent::TouchScrollStarted: | |
| 265 DCHECK_NE(WebInputEvent::Blocking, | |
| 266 static_cast<const WebTouchEvent&>(event).dispatchType); | |
| 267 return false; | |
| 268 | |
| 269 // Touch start and touch end indicate whether they are non-blocking | |
| 270 // (aka uncancelable) on the event. | |
| 271 case WebInputEvent::TouchStart: | |
| 272 case WebInputEvent::TouchEnd: | |
| 273 return static_cast<const WebTouchEvent&>(event).dispatchType == | |
| 274 WebInputEvent::Blocking; | |
| 275 | |
| 276 // Touch move events may be non-blocking but are always explicitly | |
| 277 // acknowledge by the renderer so they block the event stream. | |
| 278 case WebInputEvent::TouchMove: | |
| 279 default: | |
| 280 return true; | |
| 281 } | |
| 282 } | |
| 283 | |
| 284 bool WebInputEventTraits::CanCauseScroll( | |
| 285 const blink::WebMouseWheelEvent& event) { | |
| 286 #if defined(USE_AURA) | |
| 287 // Scroll events generated from the mouse wheel when the control key is held | |
| 288 // don't trigger scrolling. Instead, they may cause zooming. | |
| 289 return event.hasPreciseScrollingDeltas || | |
| 290 (event.modifiers & blink::WebInputEvent::ControlKey) == 0; | |
| 291 #else | |
| 292 return true; | |
| 293 #endif | |
| 294 } | |
| 295 | |
| 296 uint32_t WebInputEventTraits::GetUniqueTouchEventId( | |
| 297 const WebInputEvent& event) { | |
| 298 if (WebInputEvent::isTouchEventType(event.type)) { | |
| 299 return static_cast<const WebTouchEvent&>(event).uniqueTouchEventId; | |
| 300 } | |
| 301 return 0U; | |
| 302 } | |
| 303 | |
| 304 } // namespace content | |
| OLD | NEW |