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 |