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 #include "content/common/input/web_input_event_traits.h" | 5 #include "content/common/input/web_input_event_traits.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 | 8 |
9 using WebKit::WebGestureEvent; | 9 using WebKit::WebGestureEvent; |
10 using WebKit::WebInputEvent; | 10 using WebKit::WebInputEvent; |
11 using WebKit::WebKeyboardEvent; | 11 using WebKit::WebKeyboardEvent; |
12 using WebKit::WebMouseEvent; | 12 using WebKit::WebMouseEvent; |
13 using WebKit::WebMouseWheelEvent; | 13 using WebKit::WebMouseWheelEvent; |
14 using WebKit::WebTouchEvent; | 14 using WebKit::WebTouchEvent; |
15 | 15 |
16 namespace content { | 16 namespace content { |
17 namespace { | 17 namespace { |
18 | 18 |
| 19 bool CanCoalesce(const WebKeyboardEvent& event_to_coalesce, |
| 20 const WebKeyboardEvent& event) { |
| 21 return false; |
| 22 } |
| 23 |
| 24 void Coalesce(const WebKeyboardEvent& event_to_coalesce, |
| 25 WebKeyboardEvent* event) { |
| 26 DCHECK(CanCoalesce(event_to_coalesce, *event)); |
| 27 } |
| 28 |
| 29 bool CanCoalesce(const WebMouseEvent& event_to_coalesce, |
| 30 const WebMouseEvent& event) { |
| 31 return event.type == event_to_coalesce.type && |
| 32 event.type == WebInputEvent::MouseMove; |
| 33 } |
| 34 |
| 35 void Coalesce(const WebMouseEvent& event_to_coalesce, WebMouseEvent* event) { |
| 36 DCHECK(CanCoalesce(event_to_coalesce, *event)); |
| 37 // Accumulate movement deltas. |
| 38 int x = event->movementX; |
| 39 int y = event->movementY; |
| 40 *event = event_to_coalesce; |
| 41 event->movementX += x; |
| 42 event->movementY += y; |
| 43 } |
| 44 |
| 45 bool CanCoalesce(const WebMouseWheelEvent& event_to_coalesce, |
| 46 const WebMouseWheelEvent& event) { |
| 47 return event.modifiers == event_to_coalesce.modifiers && |
| 48 event.scrollByPage == event_to_coalesce.scrollByPage && |
| 49 event.phase == event_to_coalesce.phase && |
| 50 event.momentumPhase == event_to_coalesce.momentumPhase && |
| 51 event.hasPreciseScrollingDeltas == |
| 52 event_to_coalesce.hasPreciseScrollingDeltas; |
| 53 } |
| 54 |
| 55 float GetUnacceleratedDelta(float accelerated_delta, float acceleration_ratio) { |
| 56 return accelerated_delta * acceleration_ratio; |
| 57 } |
| 58 |
| 59 float GetAccelerationRatio(float accelerated_delta, float unaccelerated_delta) { |
| 60 if (unaccelerated_delta == 0.f || accelerated_delta == 0.f) |
| 61 return 1.f; |
| 62 return unaccelerated_delta / accelerated_delta; |
| 63 } |
| 64 |
| 65 void Coalesce(const WebMouseWheelEvent& event_to_coalesce, |
| 66 WebMouseWheelEvent* event) { |
| 67 DCHECK(CanCoalesce(event_to_coalesce, *event)); |
| 68 float unaccelerated_x = |
| 69 GetUnacceleratedDelta(event->deltaX, |
| 70 event->accelerationRatioX) + |
| 71 GetUnacceleratedDelta(event_to_coalesce.deltaX, |
| 72 event_to_coalesce.accelerationRatioX); |
| 73 float unaccelerated_y = |
| 74 GetUnacceleratedDelta(event->deltaY, |
| 75 event->accelerationRatioY) + |
| 76 GetUnacceleratedDelta(event_to_coalesce.deltaY, |
| 77 event_to_coalesce.accelerationRatioY); |
| 78 event->deltaX += event_to_coalesce.deltaX; |
| 79 event->deltaY += event_to_coalesce.deltaY; |
| 80 event->wheelTicksX += event_to_coalesce.wheelTicksX; |
| 81 event->wheelTicksY += event_to_coalesce.wheelTicksY; |
| 82 event->accelerationRatioX = |
| 83 GetAccelerationRatio(event->deltaX, unaccelerated_x); |
| 84 event->accelerationRatioY = |
| 85 GetAccelerationRatio(event->deltaY, unaccelerated_y); |
| 86 DCHECK_GE(event_to_coalesce.timeStampSeconds, event->timeStampSeconds); |
| 87 event->timeStampSeconds = event_to_coalesce.timeStampSeconds; |
| 88 } |
| 89 |
| 90 bool CanCoalesce(const WebTouchEvent& event_to_coalesce, |
| 91 const WebTouchEvent& event) { |
| 92 return event.type == event_to_coalesce.type && |
| 93 event.type == WebInputEvent::TouchMove && |
| 94 event.modifiers == event_to_coalesce.modifiers && |
| 95 event.touchesLength == event_to_coalesce.touchesLength; |
| 96 } |
| 97 |
| 98 void Coalesce(const WebTouchEvent& event_to_coalesce, WebTouchEvent* event) { |
| 99 DCHECK(CanCoalesce(event_to_coalesce, *event)); |
| 100 // The WebTouchPoints include absolute position information. So it is |
| 101 // sufficient to simply replace the previous event with the new event-> |
| 102 // However, it is necessary to make sure that all the points have the |
| 103 // correct state, i.e. the touch-points that moved in the last event, but |
| 104 // didn't change in the current event, will have Stationary state. It is |
| 105 // necessary to change them back to Moved state. |
| 106 WebTouchEvent old_event = *event; |
| 107 *event = event_to_coalesce; |
| 108 for (unsigned i = 0; i < event->touchesLength; ++i) { |
| 109 if (old_event.touches[i].state == WebKit::WebTouchPoint::StateMoved) |
| 110 event->touches[i].state = WebKit::WebTouchPoint::StateMoved; |
| 111 } |
| 112 } |
| 113 |
| 114 bool CanCoalesce(const WebGestureEvent& event_to_coalesce, |
| 115 const WebGestureEvent& event) { |
| 116 return event.type == event_to_coalesce.type && |
| 117 event.type == WebInputEvent::GestureScrollUpdate && |
| 118 event.modifiers == event_to_coalesce.modifiers; |
| 119 } |
| 120 |
| 121 void Coalesce(const WebGestureEvent& event_to_coalesce, |
| 122 WebGestureEvent* event) { |
| 123 DCHECK(CanCoalesce(event_to_coalesce, *event)); |
| 124 event->data.scrollUpdate.deltaX += event_to_coalesce.data.scrollUpdate.deltaX; |
| 125 event->data.scrollUpdate.deltaY += event_to_coalesce.data.scrollUpdate.deltaY; |
| 126 } |
| 127 |
19 struct WebInputEventSize { | 128 struct WebInputEventSize { |
20 template <class EventType> | 129 template <class EventType> |
21 void Execute(WebInputEvent::Type /* type */, size_t* type_size) const { | 130 bool Execute(WebInputEvent::Type /* type */, size_t* type_size) const { |
22 *type_size = sizeof(EventType); | 131 *type_size = sizeof(EventType); |
| 132 return true; |
23 } | 133 } |
24 }; | 134 }; |
25 | 135 |
26 struct WebInputEventClone { | 136 struct WebInputEventClone { |
27 template <class EventType> | 137 template <class EventType> |
28 void Execute(const WebInputEvent& event, | 138 bool Execute(const WebInputEvent& event, |
29 ScopedWebInputEvent* scoped_event) const { | 139 ScopedWebInputEvent* scoped_event) const { |
30 DCHECK_EQ(sizeof(EventType), event.size); | 140 DCHECK_EQ(sizeof(EventType), event.size); |
31 *scoped_event = ScopedWebInputEvent( | 141 *scoped_event = ScopedWebInputEvent( |
32 new EventType(static_cast<const EventType&>(event))); | 142 new EventType(static_cast<const EventType&>(event))); |
| 143 return true; |
33 } | 144 } |
34 }; | 145 }; |
35 | 146 |
36 struct WebInputEventDelete { | 147 struct WebInputEventDelete { |
37 template <class EventType> | 148 template <class EventType> |
38 void Execute(WebInputEvent* event, bool* /* dummy_var */) const { | 149 bool Execute(WebInputEvent* event, bool* /* dummy_var */) const { |
39 if (!event) | 150 if (!event) |
40 return; | 151 return false; |
41 DCHECK_EQ(sizeof(EventType), event->size); | 152 DCHECK_EQ(sizeof(EventType), event->size); |
42 delete static_cast<EventType*>(event); | 153 delete static_cast<EventType*>(event); |
| 154 return true; |
| 155 } |
| 156 }; |
| 157 |
| 158 struct WebInputEventCanCoalesce { |
| 159 template <class EventType> |
| 160 bool Execute(const WebInputEvent& event_to_coalesce, |
| 161 const WebInputEvent* event) const { |
| 162 if (event_to_coalesce.type != event->type) |
| 163 return false; |
| 164 DCHECK_EQ(sizeof(EventType), event->size); |
| 165 DCHECK_EQ(sizeof(EventType), event_to_coalesce.size); |
| 166 return CanCoalesce(static_cast<const EventType&>(event_to_coalesce), |
| 167 *static_cast<const EventType*>(event)); |
| 168 } |
| 169 }; |
| 170 |
| 171 struct WebInputEventCoalesce { |
| 172 template <class EventType> |
| 173 bool Execute(const WebInputEvent& event_to_coalesce, |
| 174 WebInputEvent* event) const { |
| 175 Coalesce(static_cast<const EventType&>(event_to_coalesce), |
| 176 static_cast<EventType*>(event)); |
| 177 return true; |
43 } | 178 } |
44 }; | 179 }; |
45 | 180 |
46 template <typename Operator, typename ArgIn, typename ArgOut> | 181 template <typename Operator, typename ArgIn, typename ArgOut> |
47 void Apply(Operator op, | 182 bool Apply(Operator op, |
48 WebInputEvent::Type type, | 183 WebInputEvent::Type type, |
49 const ArgIn& arg_in, | 184 const ArgIn& arg_in, |
50 ArgOut* arg_out) { | 185 ArgOut* arg_out) { |
51 if (WebInputEvent::isMouseEventType(type)) | 186 if (WebInputEvent::isMouseEventType(type)) |
52 op.template Execute<WebMouseEvent>(arg_in, arg_out); | 187 return op.template Execute<WebMouseEvent>(arg_in, arg_out); |
53 else if (type == WebInputEvent::MouseWheel) | 188 else if (type == WebInputEvent::MouseWheel) |
54 op.template Execute<WebMouseWheelEvent>(arg_in, arg_out); | 189 return op.template Execute<WebMouseWheelEvent>(arg_in, arg_out); |
55 else if (WebInputEvent::isKeyboardEventType(type)) | 190 else if (WebInputEvent::isKeyboardEventType(type)) |
56 op.template Execute<WebKeyboardEvent>(arg_in, arg_out); | 191 return op.template Execute<WebKeyboardEvent>(arg_in, arg_out); |
57 else if (WebInputEvent::isTouchEventType(type)) | 192 else if (WebInputEvent::isTouchEventType(type)) |
58 op.template Execute<WebTouchEvent>(arg_in, arg_out); | 193 return op.template Execute<WebTouchEvent>(arg_in, arg_out); |
59 else if (WebInputEvent::isGestureEventType(type)) | 194 else if (WebInputEvent::isGestureEventType(type)) |
60 op.template Execute<WebGestureEvent>(arg_in, arg_out); | 195 return op.template Execute<WebGestureEvent>(arg_in, arg_out); |
61 else | 196 |
62 NOTREACHED() << "Unknown webkit event type " << type; | 197 NOTREACHED() << "Unknown webkit event type " << type; |
| 198 return false; |
63 } | 199 } |
64 | 200 |
65 } // namespace | 201 } // namespace |
66 | 202 |
67 size_t WebInputEventTraits::GetSize(WebInputEvent::Type type) { | 203 size_t WebInputEventTraits::GetSize(WebInputEvent::Type type) { |
68 size_t size = 0; | 204 size_t size = 0; |
69 Apply(WebInputEventSize(), type, type, &size); | 205 Apply(WebInputEventSize(), type, type, &size); |
70 return size; | 206 return size; |
71 } | 207 } |
72 | 208 |
73 ScopedWebInputEvent WebInputEventTraits::Clone(const WebInputEvent& event) { | 209 ScopedWebInputEvent WebInputEventTraits::Clone(const WebInputEvent& event) { |
74 ScopedWebInputEvent scoped_event; | 210 ScopedWebInputEvent scoped_event; |
75 Apply(WebInputEventClone(), event.type, event, &scoped_event); | 211 Apply(WebInputEventClone(), event.type, event, &scoped_event); |
76 return scoped_event.Pass(); | 212 return scoped_event.Pass(); |
77 } | 213 } |
78 | 214 |
79 void WebInputEventTraits::Delete(WebInputEvent* event) { | 215 void WebInputEventTraits::Delete(WebInputEvent* event) { |
80 if (!event) | 216 if (!event) |
81 return; | 217 return; |
82 bool dummy_var = false; | 218 bool dummy_var = false; |
83 Apply(WebInputEventDelete(), event->type, event, &dummy_var); | 219 Apply(WebInputEventDelete(), event->type, event, &dummy_var); |
84 } | 220 } |
85 | 221 |
| 222 bool WebInputEventTraits::CanCoalesce(const WebInputEvent& event_to_coalesce, |
| 223 const WebInputEvent& event) { |
| 224 // Early out before casting. |
| 225 if (event_to_coalesce.type != event.type) |
| 226 return false; |
| 227 return Apply(WebInputEventCanCoalesce(), |
| 228 event.type, |
| 229 event_to_coalesce, |
| 230 &event); |
| 231 } |
| 232 |
| 233 void WebInputEventTraits::Coalesce(const WebInputEvent& event_to_coalesce, |
| 234 WebInputEvent* event) { |
| 235 DCHECK(event); |
| 236 Apply(WebInputEventCoalesce(), event->type, event_to_coalesce, event); |
| 237 } |
| 238 |
86 } // namespace content | 239 } // namespace content |
OLD | NEW |