Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
pointer_data_packet_converter.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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 "flutter/lib/ui/window/pointer_data_packet_converter.h"
6
7#include <cmath>
8#include <cstring>
9
10#include "flutter/fml/logging.h"
11
12namespace flutter {
13
15
17
18std::unique_ptr<PointerDataPacket> PointerDataPacketConverter::Convert(
19 std::unique_ptr<PointerDataPacket> packet) {
20 std::vector<PointerData> converted_pointers;
21 // Converts each pointer data in the buffer and stores it in the
22 // converted_pointers.
23 for (size_t i = 0; i < packet->GetLength(); i++) {
24 PointerData pointer_data = packet->GetPointerData(i);
25 ConvertPointerData(pointer_data, converted_pointers);
26 }
27
28 // Writes converted_pointers into converted_packet.
29 auto converted_packet =
30 std::make_unique<flutter::PointerDataPacket>(converted_pointers.size());
31 size_t count = 0;
32 for (auto& converted_pointer : converted_pointers) {
33 converted_packet->SetPointerData(count++, converted_pointer);
34 }
35
36 return converted_packet;
37}
38
39void PointerDataPacketConverter::ConvertPointerData(
40 PointerData pointer_data,
41 std::vector<PointerData>& converted_pointers) {
42 if (pointer_data.signal_kind == PointerData::SignalKind::kNone) {
43 switch (pointer_data.change) {
45 // Android's three finger gesture will send a cancel event
46 // to a non-existing pointer. Drops the cancel if pointer
47 // is not previously added.
48 // https://github.com/flutter/flutter/issues/20517
49 auto iter = states_.find(pointer_data.device);
50 if (iter != states_.end()) {
51 PointerState state = iter->second;
52 FML_DCHECK(state.is_down);
53 UpdatePointerIdentifier(pointer_data, state, false);
54
55 if (LocationNeedsUpdate(pointer_data, state)) {
56 // Synthesizes a move event if the location does not match.
57 PointerData synthesized_move_event = pointer_data;
58 synthesized_move_event.change = PointerData::Change::kMove;
59 synthesized_move_event.synthesized = 1;
60
61 UpdateDeltaAndState(synthesized_move_event, state);
62 converted_pointers.push_back(synthesized_move_event);
63 }
64
65 state.is_down = false;
66 states_[pointer_data.device] = state;
67 converted_pointers.push_back(pointer_data);
68 }
69 break;
70 }
72 FML_DCHECK(states_.find(pointer_data.device) == states_.end());
73 EnsurePointerState(pointer_data);
74 converted_pointers.push_back(pointer_data);
75 break;
76 }
78 // Makes sure we have an existing pointer
79 auto iter = states_.find(pointer_data.device);
80 FML_DCHECK(iter != states_.end());
81 PointerState state = iter->second;
82
83 if (state.is_down) {
84 // Synthesizes cancel event if the pointer is down.
85 PointerData synthesized_cancel_event = pointer_data;
86 synthesized_cancel_event.change = PointerData::Change::kCancel;
87 synthesized_cancel_event.synthesized = 1;
88 UpdatePointerIdentifier(synthesized_cancel_event, state, false);
89
90 state.is_down = false;
91 states_[synthesized_cancel_event.device] = state;
92 converted_pointers.push_back(synthesized_cancel_event);
93 }
94
95 if (LocationNeedsUpdate(pointer_data, state)) {
96 // Synthesizes a hover event if the location does not match.
97 PointerData synthesized_hover_event = pointer_data;
98 synthesized_hover_event.change = PointerData::Change::kHover;
99 synthesized_hover_event.synthesized = 1;
100
101 UpdateDeltaAndState(synthesized_hover_event, state);
102 converted_pointers.push_back(synthesized_hover_event);
103 }
104
105 states_.erase(pointer_data.device);
106 converted_pointers.push_back(pointer_data);
107 break;
108 }
110 auto iter = states_.find(pointer_data.device);
111 PointerState state;
112 if (iter == states_.end()) {
113 // Synthesizes add event if the pointer is not previously added.
114 PointerData synthesized_add_event = pointer_data;
115 synthesized_add_event.change = PointerData::Change::kAdd;
116 synthesized_add_event.synthesized = 1;
117 synthesized_add_event.buttons = 0;
118 state = EnsurePointerState(synthesized_add_event);
119 converted_pointers.push_back(synthesized_add_event);
120 } else {
121 state = iter->second;
122 }
123
124 FML_DCHECK(!state.is_down);
125 state.buttons = pointer_data.buttons;
126 if (LocationNeedsUpdate(pointer_data, state)) {
127 UpdateDeltaAndState(pointer_data, state);
128 converted_pointers.push_back(pointer_data);
129 }
130 break;
131 }
133 auto iter = states_.find(pointer_data.device);
134 PointerState state;
135 if (iter == states_.end()) {
136 // Synthesizes a add event if the pointer is not previously added.
137 PointerData synthesized_add_event = pointer_data;
138 synthesized_add_event.change = PointerData::Change::kAdd;
139 synthesized_add_event.synthesized = 1;
140 synthesized_add_event.buttons = 0;
141 state = EnsurePointerState(synthesized_add_event);
142 converted_pointers.push_back(synthesized_add_event);
143 } else {
144 state = iter->second;
145 }
146
147 FML_DCHECK(!state.is_down);
148 if (LocationNeedsUpdate(pointer_data, state)) {
149 // Synthesizes a hover event if the location does not match.
150 PointerData synthesized_hover_event = pointer_data;
151 synthesized_hover_event.change = PointerData::Change::kHover;
152 synthesized_hover_event.synthesized = 1;
153 synthesized_hover_event.buttons = 0;
154
155 UpdateDeltaAndState(synthesized_hover_event, state);
156 converted_pointers.push_back(synthesized_hover_event);
157 }
158
159 UpdatePointerIdentifier(pointer_data, state, true);
160 state.is_down = true;
161 state.buttons = pointer_data.buttons;
162 states_[pointer_data.device] = state;
163 converted_pointers.push_back(pointer_data);
164 break;
165 }
167 // Makes sure we have an existing pointer in down state
168 auto iter = states_.find(pointer_data.device);
169 FML_DCHECK(iter != states_.end());
170 PointerState state = iter->second;
171 FML_DCHECK(state.is_down);
172
173 UpdatePointerIdentifier(pointer_data, state, false);
174 UpdateDeltaAndState(pointer_data, state);
175 state.buttons = pointer_data.buttons;
176 converted_pointers.push_back(pointer_data);
177 break;
178 }
180 // Makes sure we have an existing pointer in down state
181 auto iter = states_.find(pointer_data.device);
182 FML_DCHECK(iter != states_.end());
183 PointerState state = iter->second;
184 FML_DCHECK(state.is_down);
185
186 UpdatePointerIdentifier(pointer_data, state, false);
187
188 if (LocationNeedsUpdate(pointer_data, state)) {
189 // Synthesizes a move event if the location does not match.
190 PointerData synthesized_move_event = pointer_data;
191 synthesized_move_event.change = PointerData::Change::kMove;
192 synthesized_move_event.buttons = state.buttons;
193 synthesized_move_event.synthesized = 1;
194
195 UpdateDeltaAndState(synthesized_move_event, state);
196 converted_pointers.push_back(synthesized_move_event);
197 }
198
199 state.is_down = false;
200 state.buttons = pointer_data.buttons;
201 states_[pointer_data.device] = state;
202 converted_pointers.push_back(pointer_data);
203 break;
204 }
206 // Makes sure we have an existing pointer
207 auto iter = states_.find(pointer_data.device);
208 PointerState state;
209 if (iter == states_.end()) {
210 // Synthesizes add event if the pointer is not previously added.
211 PointerData synthesized_add_event = pointer_data;
212 synthesized_add_event.change = PointerData::Change::kAdd;
213 synthesized_add_event.synthesized = 1;
214 synthesized_add_event.buttons = 0;
215 state = EnsurePointerState(synthesized_add_event);
216 converted_pointers.push_back(synthesized_add_event);
217 } else {
218 state = iter->second;
219 }
220 FML_DCHECK(!state.is_down);
221 FML_DCHECK(!state.is_pan_zoom_active);
222 if (LocationNeedsUpdate(pointer_data, state)) {
223 // Synthesizes a hover event if the location does not match.
224 PointerData synthesized_hover_event = pointer_data;
225 synthesized_hover_event.change = PointerData::Change::kHover;
226 synthesized_hover_event.synthesized = 1;
227 synthesized_hover_event.buttons = 0;
228
229 UpdateDeltaAndState(synthesized_hover_event, state);
230 converted_pointers.push_back(synthesized_hover_event);
231 }
232
233 UpdatePointerIdentifier(pointer_data, state, true);
234 state.is_pan_zoom_active = true;
235 state.pan_x = 0;
236 state.pan_y = 0;
237 state.scale = 1;
238 state.rotation = 0;
239 states_[pointer_data.device] = state;
240 converted_pointers.push_back(pointer_data);
241 break;
242 }
244 // Makes sure we have an existing pointer in pan_zoom_active state
245 auto iter = states_.find(pointer_data.device);
246 FML_DCHECK(iter != states_.end());
247 PointerState state = iter->second;
248 FML_DCHECK(!state.is_down);
249 FML_DCHECK(state.is_pan_zoom_active);
250
251 UpdatePointerIdentifier(pointer_data, state, false);
252 UpdateDeltaAndState(pointer_data, state);
253
254 converted_pointers.push_back(pointer_data);
255 break;
256 }
258 // Makes sure we have an existing pointer in pan_zoom_active state
259 auto iter = states_.find(pointer_data.device);
260 FML_DCHECK(iter != states_.end());
261 PointerState state = iter->second;
262 FML_DCHECK(state.is_pan_zoom_active);
263
264 UpdatePointerIdentifier(pointer_data, state, false);
265
266 if (LocationNeedsUpdate(pointer_data, state)) {
267 // Synthesizes an update event if the location does not match.
268 PointerData synthesized_move_event = pointer_data;
269 synthesized_move_event.change = PointerData::Change::kPanZoomUpdate;
270 synthesized_move_event.pan_x = state.pan_x;
271 synthesized_move_event.pan_y = state.pan_y;
272 synthesized_move_event.pan_delta_x = 0;
273 synthesized_move_event.pan_delta_y = 0;
274 synthesized_move_event.scale = state.scale;
275 synthesized_move_event.rotation = state.rotation;
276 synthesized_move_event.synthesized = 1;
277
278 UpdateDeltaAndState(synthesized_move_event, state);
279 converted_pointers.push_back(synthesized_move_event);
280 }
281
282 state.is_pan_zoom_active = false;
283 states_[pointer_data.device] = state;
284 converted_pointers.push_back(pointer_data);
285 break;
286 }
287 default: {
288 converted_pointers.push_back(pointer_data);
289 break;
290 }
291 }
292 } else {
293 switch (pointer_data.signal_kind) {
297 // Makes sure we have an existing pointer
298 auto iter = states_.find(pointer_data.device);
299 PointerState state;
300
301 if (iter == states_.end()) {
302 // Synthesizes a add event if the pointer is not previously added.
303 PointerData synthesized_add_event = pointer_data;
304 synthesized_add_event.signal_kind = PointerData::SignalKind::kNone;
305 synthesized_add_event.change = PointerData::Change::kAdd;
306 synthesized_add_event.synthesized = 1;
307 synthesized_add_event.buttons = 0;
308 state = EnsurePointerState(synthesized_add_event);
309 converted_pointers.push_back(synthesized_add_event);
310 } else {
311 state = iter->second;
312 }
313
314 if (LocationNeedsUpdate(pointer_data, state)) {
315 if (state.is_down) {
316 // Synthesizes a move event if the pointer is down.
317 PointerData synthesized_move_event = pointer_data;
318 synthesized_move_event.signal_kind = PointerData::SignalKind::kNone;
319 synthesized_move_event.change = PointerData::Change::kMove;
320 synthesized_move_event.buttons = state.buttons;
321 synthesized_move_event.synthesized = 1;
322
323 UpdateDeltaAndState(synthesized_move_event, state);
324 converted_pointers.push_back(synthesized_move_event);
325 } else {
326 // Synthesizes a hover event if the pointer is up.
327 PointerData synthesized_hover_event = pointer_data;
328 synthesized_hover_event.signal_kind =
330 synthesized_hover_event.change = PointerData::Change::kHover;
331 synthesized_hover_event.buttons = 0;
332 synthesized_hover_event.synthesized = 1;
333
334 UpdateDeltaAndState(synthesized_hover_event, state);
335 converted_pointers.push_back(synthesized_hover_event);
336 }
337 }
338
339 converted_pointers.push_back(pointer_data);
340 break;
341 }
342 default: {
343 // Ignores unknown signal kind.
344 break;
345 }
346 }
347 }
348}
349
350PointerState PointerDataPacketConverter::EnsurePointerState(
351 PointerData pointer_data) {
352 PointerState state;
353 state.pointer_identifier = 0;
354 state.is_down = false;
355 state.is_pan_zoom_active = false;
356 state.physical_x = pointer_data.physical_x;
357 state.physical_y = pointer_data.physical_y;
358 state.pan_x = 0;
359 state.pan_y = 0;
360 states_[pointer_data.device] = state;
361 return state;
362}
363
364void PointerDataPacketConverter::UpdateDeltaAndState(PointerData& pointer_data,
365 PointerState& state) {
366 pointer_data.physical_delta_x = pointer_data.physical_x - state.physical_x;
367 pointer_data.physical_delta_y = pointer_data.physical_y - state.physical_y;
368 pointer_data.pan_delta_x = pointer_data.pan_x - state.pan_x;
369 pointer_data.pan_delta_y = pointer_data.pan_y - state.pan_y;
370 state.physical_x = pointer_data.physical_x;
371 state.physical_y = pointer_data.physical_y;
372 state.pan_x = pointer_data.pan_x;
373 state.pan_y = pointer_data.pan_y;
374 state.scale = pointer_data.scale;
375 state.rotation = pointer_data.rotation;
376 states_[pointer_data.device] = state;
377}
378
379bool PointerDataPacketConverter::LocationNeedsUpdate(
380 const PointerData pointer_data,
381 const PointerState state) {
382 return state.physical_x != pointer_data.physical_x ||
383 state.physical_y != pointer_data.physical_y;
384}
385
386void PointerDataPacketConverter::UpdatePointerIdentifier(
387 PointerData& pointer_data,
388 PointerState& state,
389 bool start_new_pointer) {
390 if (start_new_pointer) {
391 state.pointer_identifier = ++pointer_;
392 states_[pointer_data.device] = state;
393 }
394 pointer_data.pointer_identifier = state.pointer_identifier;
395}
396
397} // namespace flutter
int count
std::unique_ptr< PointerDataPacket > Convert(std::unique_ptr< PointerDataPacket > packet)
Converts pointer data packet into a form that framework understands. The raw pointer data packet from...
AtkStateType state
#define FML_DCHECK(condition)
Definition logging.h:103